[dw-free] Expand all comments on page
[commit: http://hg.dwscoalition.org/dw-free/rev/eec83fe603d3]
http://bugs.dwscoalition.org/show_bug.cgi?id=31
New link: "Expand all comments on page".
Patch by
allen.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=31
New link: "Expand all comments on page".
Patch by
Files modified:
- bin/upgrading/en.dat
- bin/upgrading/s2layers/core2.s2
- cgi-bin/LJ/S2/EntryPage.pm
- cgi-bin/LJ/Talk.pm
- cgi-bin/LJ/User.pm
- htdocs/js/jquery.threadexpander.js
- htdocs/js/thread_expander.js
- htdocs/talkread.bml
--------------------------------------------------------------------------------
diff -r 6c913dabed65 -r eec83fe603d3 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat Fri Sep 30 00:53:33 2011 +0800
+++ b/bin/upgrading/en.dat Fri Sep 30 01:13:39 2011 +0800
@@ -3903,6 +3903,8 @@
talk.error.suspendedentryreply=This entry has been suspended. You can't reply to it. <a [[aopts]]>Visit the journal</a>.
+talk.expandalllink=Expand All
+
talk.expandlink=Expand
talk.frozen=Replies frozen
diff -r 6c913dabed65 -r eec83fe603d3 bin/upgrading/s2layers/core2.s2
--- a/bin/upgrading/s2layers/core2.s2 Fri Sep 30 00:53:33 2011 +0800
+++ b/bin/upgrading/s2layers/core2.s2 Fri Sep 30 01:13:39 2011 +0800
@@ -487,7 +487,9 @@
{
var string view_mode "The current view mode (threaded, flat, top-only).";
var string url "The url for this entry page, complete with style argument if present.";
+ var int current_page "The currently displayed page";
var bool filter "True if the current view is filtered.";
+ var bool show_expand_all "True if we should show the expand_all option.";
function print () "Prints the nav bar, including the comment_pages bar";
}
@@ -5968,13 +5970,15 @@
function CommentNav::print
{
var string sep = $.url->contains( "?" ) ? "&" : "?";
+ var string page_arg = $.current_page > 1 ? "&page=$.current_page" : "";
print "<div class='comment-pages'>";
var string{} links = {
"flat" => """<a href="$.url${sep}view=flat#comments">Flat</a>""",
"threaded" => """<a href="$.url#comments">Threaded</a>""",
- "top-only" => """<a href="$.url${sep}view=top-only#comments">Top-Level Comments Only</a>"""
+ "top-only" => """<a href="$.url${sep}view=top-only#comments">Top-Level Comments Only</a>""",
+ "expand_all" => """<a href="$.url${sep}expand_all=1${page_arg}#comments" onClick="Expander.make(this,'$.url${sep}expand_all=1${page_arg}#comments',-1,false,false);return false;">Expand All</a>"""
};
if ( $.view_mode == "threaded" ) {
@@ -5985,6 +5989,9 @@
print "$links{"threaded"} | $links{"flat"}";
}
+ if ( $.show_expand_all ) {
+ print "<span id='expand_all'> | $links{"expand_all"}</span>";
+ }
print "</div>";
}
diff -r 6c913dabed65 -r eec83fe603d3 cgi-bin/LJ/S2/EntryPage.pm
--- a/cgi-bin/LJ/S2/EntryPage.pm Fri Sep 30 00:53:33 2011 +0800
+++ b/cgi-bin/LJ/S2/EntryPage.pm Fri Sep 30 01:13:39 2011 +0800
@@ -101,6 +101,8 @@
my $top_only_mode = ($view_arg =~ /\btop-only\b/);
my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef;
+ my $expand_all = ( $u->thread_expand_all( $remote ) && $get->{'expand_all'} );
+
my %userpic;
my %user;
my $copts = {
@@ -114,7 +116,7 @@
# user object is cached from call just made in EntryPage_entry
'up' => LJ::load_user($s2entry->{'poster'}->{'user'}),
'viewall' => $viewall,
- 'expand_all' => $opts->{expand_all},
+ 'expand_all' => $expand_all,
'filter' => $get->{comments},
};
@@ -377,6 +379,8 @@
u => $poster,
parent => $cmt->parent ? $cmt->parent->dtalkid : undef,
full => ($i->{full}),
+ deleted => $cmt->is_deleted,
+ screened => $cmt->is_screened,
};
$self->($self, $i->{'replies'}) if $has_threads;
}
@@ -415,11 +419,13 @@
$copts->{'out_itemfirst'} = $copts->{'out_itemlast'} = undef;
}
+ my $show_expand_all = $u->thread_expand_all( $remote ) && $copts->{out_has_collapsed} && ! $top_only_mode;
# creates the comment nav bar
$p->{'comment_nav'} = CommentNav({
'view_mode' => $flat_mode ? "flat" : $top_only_mode ? "top-only" : "threaded",
'url' => $entry->url( style_args => LJ::viewing_style_opts( %$get ) ),
'current_page' => $copts->{'out_page'},
+ 'show_expand_all' => $show_expand_all,
});
$p->{'comment_pages'} = ItemRange({
diff -r 6c913dabed65 -r eec83fe603d3 cgi-bin/LJ/Talk.pm
--- a/cgi-bin/LJ/Talk.pm Fri Sep 30 00:53:33 2011 +0800
+++ b/cgi-bin/LJ/Talk.pm Fri Sep 30 01:13:39 2011 +0800
@@ -916,6 +916,7 @@
# out_itemlast: last comment number on page (1-based, not db numbers)
# out_pagesize: size of each page
# out_items: number of total top level items
+# out_has_collpased: set by us; 0 if no collapsed messages, 1 if there are
#
# userpicref -- hashref to load userpics into, or undef to
# not load them.
@@ -1169,6 +1170,9 @@
my (@subjects_to_load, @subjects_ignored);
+ # track if there are any collapsed messages being displayed
+ my $has_collapsed = 0;
+
while (@check_for_children) {
my $cfc = shift @check_for_children;
@@ -1179,6 +1183,7 @@
## expand only the first child, then clear the flag
delete $expand_children{$cfc};
} else {
+ $has_collapsed = 1;
if ( $opts->{'top-only'} ) {
$posts->{$child}->{'hidden_child'} = 1;
}
@@ -1198,6 +1203,7 @@
$opts->{'out_itemlast'} = $itemlast;
$opts->{'out_pagesize'} = $page_size;
$opts->{'out_items'} = $top_replies;
+ $opts->{'out_has_collapsed'} = $has_collapsed;
# load text of posts
my ($posts_loaded, $subjects_loaded);
diff -r 6c913dabed65 -r eec83fe603d3 cgi-bin/LJ/User.pm
--- a/cgi-bin/LJ/User.pm Fri Sep 30 00:53:33 2011 +0800
+++ b/cgi-bin/LJ/User.pm Fri Sep 30 01:13:39 2011 +0800
@@ -3066,6 +3066,16 @@
return 0;
}
+# should allow expand-all for this user/journal
+sub thread_expand_all {
+ my ( $u, $remote ) = @_;
+
+ return 1 if $remote && $remote->get_cap( 'thread_expand_all' )
+ || $u->get_cap( 'thread_expand_all' );
+
+ return 0;
+}
+
#get/set Sticky Entry parent ID for settings menu
sub sticky_entry {
my ( $u, $input ) = @_;
diff -r 6c913dabed65 -r eec83fe603d3 htdocs/js/jquery.threadexpander.js
--- a/htdocs/js/jquery.threadexpander.js Fri Sep 30 00:53:33 2011 +0800
+++ b/htdocs/js/jquery.threadexpander.js Fri Sep 30 01:13:39 2011 +0800
@@ -23,8 +23,23 @@
if (includeSelf) {
returnValue.push(talkid);
}
- for (var i = 0; i < LJ[talkid].rc.length; i++) {
- returnValue = returnValue.concat(getReplies(LJ, LJ[talkid].rc[i], true));
+ if (LJ[talkid] && LJ[talkid].rc) {
+ for (var i = 0; i < LJ[talkid].rc.length; i++) {
+ returnValue = returnValue.concat(getReplies(LJ, LJ[talkid].rc[i], true));
+ }
+ }
+ return returnValue;
+ }
+
+ /**
+ * Returns all of the unexpanded comments on this page.
+ */
+ function getUnexpandedComments(LJ) {
+ var returnValue = [];
+ for (var talkid in LJ) {
+ if (LJ[talkid].hasOwnProperty("full") && ! LJ[talkid].full && ! LJ[talkid].deleted && ! LJ[talkid].screened) {
+ returnValue.push(talkid);
+ }
}
return returnValue;
}
@@ -55,14 +70,31 @@
datatype: "html",
timeout: 30000,
success: function(data) {
- element.doJqExpand(LJ, data, talkid, isS1, unhide);
- },
+ var updateCount = element.doJqExpand(LJ, data, talkid, isS1, unhide);
+ // if we didn't update any comments, something must have gone wrong
+ if (updateCount == 0) {
+ showExpanderError($.threadexpander.config.text.error_nomatches);
+ } else if (unhide) {
+ element.unhideComments(LJ, talkid, isS1);
+ }
+
+ // remove the expand_all option if all comments are expanded
+ var expand_all_span = $('#expand_all');
+ if (expand_all_span.length > 0) {
+ if (getUnexpandedComments(LJ).length == 0) {
+ expand_all_span.fadeOut('fast');
+ } else if (talkid < 0) {
+ img.remove();
+ element.removeClass("disabled").fadeTo("fast", 1.0);
+ }
+ }
+ },
error: function(jqXHR, textStatus, errorThrown) {
- img.remove();
- element.removeClass("disabled");
- element.fadeTo("fast", 1.0);
- showExpanderError($.threadexpander.config.text.error);
- }
+ img.remove();
+ element.removeClass("disabled");
+ element.fadeTo("fast", 1.0);
+ showExpanderError($.threadexpander.config.text.error);
+ }
} );
};
@@ -70,39 +102,61 @@
$.fn.doJqExpand = function(LJ, data, talkid, isS1, unhide) {
var updateCount = 0;
// check for matching expansions on the page
- var replies = getReplies(LJ, talkid, true);
- for (var cmtIdCnt = 0; cmtIdCnt < replies.length; cmtIdCnt++) {
- var cmtId = replies[cmtIdCnt];
- // if we're a valid comment, and either the comment is not expanded
- // or it's the original comment, then it's valid to expand it.
- if (/^\d*$/.test(cmtId) && (talkid == cmtId || (! LJ[cmtId].full))) {
- var cmtElement = $("#cmt" + cmtId);
- if (cmtElement) {
- var newComment = $("#cmt" + cmtId, data);
- if (newComment && newComment.attr('id') == 'cmt' + cmtId) {
- if (isS1) {
- var oldWidth = getS1SpacerObject(cmtElement).width();
- getS1SpacerObject(newComment).width(oldWidth);
+ var replies;
+ if (talkid > 0) {
+ replies = getReplies(LJ, talkid, true);
+ } else {
+ replies = getUnexpandedComments(LJ);
+ }
+
+ if (replies.length > 0) {
+ // get all comments and map them by id. this seems to be more efficient
+ // in jquery (at least for the results of an ajax request).
+ var newComments = $(".comment", data);
+ var newCommentMap = {};
+ newComments.each(function() {
+ newCommentMap[$(this).attr("id")] = $(this);
+ });
+
+ var cmtIdPrefix = isS1 ? "cmt" : "comment-cmt";
+ for (var cmtIdCnt = 0; cmtIdCnt < replies.length; cmtIdCnt++) {
+ var cmtId = replies[cmtIdCnt];
+ // if we're a valid comment, and either the comment is not expanded
+ // or it's the original comment, then it's valid to expand it.
+ if (/^\d*$/.test(cmtId) && (talkid == cmtId || (! LJ[cmtId].full))) {
+ var cmtElement = $('#' + cmtIdPrefix + cmtId);
+ if (cmtElement.length > 0) {
+ var newComment = newCommentMap[cmtIdPrefix + cmtId];
+ if (newComment) {
+ if (isS1) {
+ var oldWidth = getS1SpacerObject(cmtElement).width();
+ getS1SpacerObject(newComment).width(oldWidth);
+ }
+ cmtElement.html($(newComment).html())
+ .trigger( "updatedcontent.comment" );
+ $(".cmt_show_hide_default", cmtElement).show();
+
+ // don't mark partial comments as full; make sure that the
+ // loaded comments are full.
+ if (isS1) {
+ if ($('table.talk-comment', newComment).length > 0) {
+ LJ[cmtId].full = true;
+ }
+ } else {
+ if (newComment.parent().hasClass("full")) {
+ LJ[cmtId].full = true;
+ setFull(cmtElement, true);
+ }
+ }
+ updateCount++;
}
- cmtElement.html($(newComment).html())
- .trigger( "updatedcontent.comment" );
- $(".cmt_show_hide_default", cmtElement).show();
- LJ[cmtId].full = true;
- if (! isS1) {
- setFull(cmtElement, true);
- }
- updateCount++;
}
}
}
}
- // if we didn't update any comments, something must have gone wrong
- if (updateCount == 0) {
- showExpanderError($.threadexpander.config.text.error_nomatches);
- } else if (unhide) {
- this.unhideComments(LJ, talkid, isS1);
- }
+ return updateCount;
+
}
// returns the comment elements for the given talkids.
diff -r 6c913dabed65 -r eec83fe603d3 htdocs/js/thread_expander.js
--- a/htdocs/js/thread_expander.js Fri Sep 30 00:53:33 2011 +0800
+++ b/htdocs/js/thread_expander.js Fri Sep 30 01:13:39 2011 +0800
@@ -3,7 +3,7 @@
this.__caller__; // <a> HTML element from where Expander was called
this.url; // full url of thread to be expanded
this.id; // id of the thread
- this.onclick;
+ this.onclick;
this.stored_caller;
this.iframe; // iframe, where the thread will be loaded
this.is_S1; // bool flag, true == journal is in S1, false == in S2
@@ -22,7 +22,7 @@
}
Expander.prototype.getCanvas = function(id,context){
- return context.document.getElementById('cmt'+id);
+ return context.document.getElementById('cmt'+id);
}
Expander.prototype.parseLJ_cmtinfo = function(context,callback){
@@ -33,15 +33,15 @@
if(/^\d*$/.test(j) && (node = this.getCanvas(j,context))){
map[j] = {info:LJ[j],canvas:node};
if(typeof callback == 'function'){
- callback(j,map[j]);
+ callback(j,map[j]);
}
}
}
- return map;
+ return map;
}
Expander.prototype.loadingStateOn = function(){
- this.stored_caller = this.__caller__.cloneNode(true);
+ this.stored_caller = this.__caller__.cloneNode(true);
this.__caller__.setAttribute('already_clicked','already_clicked');
this.onclick = this.__caller__.onclick;
this.__caller__.onclick = function(){return false;}
@@ -49,11 +49,28 @@
}
Expander.prototype.loadingStateOff = function(){
- if(this.__caller__){
- // actually, the <a> element is removed from main window by
- // copying comment from ifame, so this code is not executed (?)
- this.__caller__.removeAttribute('already_clicked','already_clicked');
- if(this.__caller__.parentNode) this.__caller__.parentNode.replaceChild(this.stored_caller,this.__caller__);
+ var expand_all = document.getElementById("expand_all");
+ if (expand_all != null) {
+ // if all comments have been expanded, remove the expand_all entry
+ var LJ = window.LJ_cmtinfo;
+ var removeExpandAll = true;
+ for (var talkid in LJ) {
+ if (LJ[talkid].hasOwnProperty("full") && ! LJ[talkid].full && ! LJ[talkid].deleted && ! LJ[talkid].screened) {
+ removeExpandAll = false;
+ }
+ }
+ if (removeExpandAll) {
+ expand_all.parentNode.removeChild(expand_all);
+ }
+ }
+
+ if (this.__caller__) {
+ // only used on error, or when expand all fails to expand all.
+ // in most cases, the <a> element is removed from main window by
+ // copying comment from iframe, or above by the removeExpandAll
+ // logic, so this code is not executed.
+ this.__caller__.removeAttribute('already_clicked','already_clicked');
+ if (this.__caller__.parentNode) this.__caller__.parentNode.replaceChild(this.stored_caller,this.__caller__);
}
var obj = this;
// When frame is removed immediately, IE raises an error sometimes
@@ -61,7 +78,7 @@
}
Expander.prototype.killFrame = function(){
- document.body.removeChild(this.iframe);
+ document.body.removeChild(this.iframe);
}
Expander.prototype.isFullComment = function(comment){
@@ -92,30 +109,30 @@
//yet, this works until we have not changed the spacers url = 'dot.gif');
var img, imgs, found;
imgs = canvas.getElementsByTagName('img');
- if(!imgs)return false;
+ if(!imgs)return false;
for(var j=0;j<imgs.length;j++){
img=imgs[j];
if(/dot\.gif$/.test(img.src)){
found = true;
- break;
+ break;
}
}
- if(found&&img.width)return Number(img.width);
- else return false;
+ if(found&&img.width)return Number(img.width);
+ else return false;
}
Expander.prototype.setS1width = function(canvas,w){
var img, imgs, found;
imgs = canvas.getElementsByTagName('img');
- if(!imgs)return false;
+ if(!imgs)return false;
for(var j=0;j<imgs.length;j++){
img=imgs[j];
if(/dot\.gif$/.test(img.src)){
found = true;
- break;
+ break;
}
}
- if(found)img.setAttribute('width',w);
+ if(found)img.setAttribute('width',w);
}
Expander.prototype.onLoadHandler = function(iframe){
@@ -131,12 +148,12 @@
comments_intersection[id] = comments_page[id];
// copy comment from iframe to main window if
// 1) the comment is collapsed in main window and is full in iframe
- // 2) or this is the root comment of this thread (it may be full in
+ // 2) or this is the root comment of this thread (it may be full in
// main window too, it's copied so that to remove "expand" link from it)
if((!obj.isFullComment(comments_page[id]) && obj.isFullComment(new_comment)) || (id===obj.id)){
var w;
if(obj.is_S1){
- w =obj.getS1width(comments_page[id].canvas);
+ w =obj.getS1width(comments_page[id].canvas);
}
comments_page[id].canvas.innerHTML = new_comment.canvas.innerHTML;
if(obj.is_S1 && w!==null){
@@ -148,7 +165,7 @@
}
}//if(id in comments_page){
});
- this.killDuplicate(comments_intersection);
+ this.killDuplicate(comments_intersection);
this.loadingStateOff();
if ( typeof ContextualPopup.setup() != "undefined" )
ContextualPopup.setup();
@@ -158,7 +175,7 @@
//just for debugging
Expander.prototype.toString = function(){
- return '__'+this.id+'__';
+ return '__'+this.id+'__';
}
@@ -167,7 +184,7 @@
return false;
}
this.loadingStateOn();
-
+
var iframe;
if(/*@cc_on !@*/0){
// branch for IE
diff -r 6c913dabed65 -r eec83fe603d3 htdocs/talkread.bml
--- a/htdocs/talkread.bml Fri Sep 30 00:53:33 2011 +0800
+++ b/htdocs/talkread.bml Fri Sep 30 01:13:39 2011 +0800
@@ -64,6 +64,7 @@
thread talk.threadlink
threadroot talk.threadrootlink
expand talk.expandlink
+ expandall talk.expandalllink
replythis talk.replytothis
screened talk.screened
frozen talk.frozen
@@ -243,13 +244,13 @@
BML::ebml(\$event);
# make the title
-{
- my $subject = $item->{'subject'} || $event;
- # yes, the 3 param to text_trim is chars, and length returns bytes, but
- # it works, as bytes >= chars:
- $subject = LJ::CleanHTML::clean_and_trim_subject(\$subject, length($item->{'subject'}) || 40);
- $$title = "$u->{'user'}: $subject";
-}
+ {
+ my $subject = $item->{'subject'} || $event;
+ # yes, the 3 param to text_trim is chars, and length returns bytes, but
+ # it works, as bytes >= chars:
+ $subject = LJ::CleanHTML::clean_and_trim_subject(\$subject, length($item->{'subject'}) || 40);
+ $$title = "$u->{'user'}: $subject";
+ }
$ret .= "<p>";
$ret .= "<table summary='' id='poster'><tr>";
@@ -349,6 +350,8 @@
my $top_only = ($view_arg =~ /\btop-only\b/);
my $view_num = ($view_arg =~ /(\d+)/) ? $1 : undef;
+ my $expand_all = ( $u->thread_expand_all( $remote ) && $GET{'expand_all'} );
+
my %user;
my $opts = {
'flat' => $flat_mode,
@@ -361,6 +364,7 @@
'up' => $up,
'viewall' => $viewall,
'filter' => $GET{comments},
+ 'expand_all' => $expand_all,
};
my @comments = LJ::Talk::load_comments($u, $remote, "L", $itemid, $opts);
@@ -369,6 +373,8 @@
my $page = $opts->{out_page};
my $pages = $opts->{out_pages};
+ my $has_collapsed = $opts->{out_has_collapsed};
+
# this overrides the default self_link to add the #comments anchor
my $self_link = sub { BML::self_link( { page => $_[0] } ) . "#comments" };
my $nav = LJ::paging_bar( $page, $pages, { self_link => $self_link } );
@@ -393,7 +399,7 @@
my $tid = $post->{'talkid'};
my $dtid = $tid * 256 + $init->{'anum'};
- my $LJci = $LJ_cmtinfo{$dtid} = { rc => [], u => '', full => $post->{_loaded} };
+ my $LJci = $LJ_cmtinfo{$dtid} = { rc => [], u => '', full => $post->{_loaded}, deleted => ( $post->{state} eq "D" ), screened => ( $post->{state} eq "S" ) };
my $datepost = LJ::S2::sitescheme_secs_to_iso( $post->{datepost_unix}, tz => 1 );
@@ -423,7 +429,7 @@
my $hidestyle = $post->{'hidden_child'} ? " style=\"display: none;\"" : "";
if ($post->{'state'} eq "D") {
- $ret .= "<div id='$htmlid'><p><a name='$htmlid'></a><table summary='' class='delcomment'$hidestyle><tr>";
+ $ret .= "<div class='comment' id='$htmlid'><p><a name='$htmlid'></a><table summary='' class='delcomment'$hidestyle><tr>";
$ret .= "<td class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
$ret .= "<td>$ML{'.deletedpost'}</td>";
if ($post->{'hide_children'} && $post->{'children'} && @{$post->{'children'}}) {
@@ -507,7 +513,7 @@
$editreason = "($editreason)" if $editreason;
}
- $ret .= "<div id='$htmlid'><table summary='' width='100%' class='talk-comment'><tbody><tr>";
+ $ret .= "<div class='comment' id='$htmlid'><table summary='' width='100%' class='talk-comment'><tbody><tr>";
$ret .= "<td rowspan='2' class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
$ret .= "<td id='cmtbar$dtid' class='cmtbar $level $additional_classes' width='100%'>";
@@ -671,9 +677,9 @@
$ret .= BML::ml( 'talk.unhide', { num => $post->{'showable_children'} } );
$ret .= qq[</a>)</span>];
}
+ } else {
+ $ret .= qq[(<a href='$url' onClick="Expander.make(this,'$url','$dtid',true);return false;">$T{'expand'}</a>)];
}
- } else {
- $ret .= qq[(<a href='$url' onClick="Expander.make(this,'$url','$dtid',true);return false;">$T{'expand'}</a>)];
}
if ( $show_thread_expander ) {
if ( LJ::BetaFeatures->user_in_beta( $remote => "journaljquery" ) ) {
@@ -698,7 +704,7 @@
# link to message
my $url = LJ::Talk::talkargs( $talkurl, "thread=$dtid", $style_args ) . LJ::Talk::comment_anchor( $dtid );
- $ret .= "<div id='$htmlid'$hidestyle><table summary=''><tbody><tr>";
+ $ret .= "<div class='comment' id='$htmlid'$hidestyle><table summary=''><tbody><tr>";
$ret .= "<td class='spacer'><img src='$LJ::IMGPREFIX/dot.gif' alt='' height='1' width='" . ($opts->{'depth'} * 25) . "'></td>";
$ret .= "<td class='cmtpartial'>";
if ($post->{'state'} eq 'F') {
@@ -778,6 +784,11 @@
} elsif ( $view_mode eq "top-only" ) {
$ret .= "(<a href = '" . BML::self_link( { view => '' } ) . "#comments'>" . BML::ml('.commentnav.threaded') . "</a>) (<a href = '" . BML::self_link( { view => 'flat' } ) . "#comments'>" . BML::ml('.commentnav.flat') . "</a>)";
}
+
+ if ( $u->thread_expand_all( $remote ) && $has_collapsed && $view_mode ne "top-only" ) {
+ my $expand_all_url = $page > 1 ? BML::self_link( { expand_all => '1', page => $page } ) . "#comments" : BML::self_link( { expand_all => '1' } ) . "#comments";
+ $ret .= "<span id='expand_all'> (<a href=\"$expand_all_url\" onClick=\"Expander.make(this,'$expand_all_url',-1,true,false);return false;\">" . $T{expandall} . "</a>)</span>";
+ }
$ret .= "</b></p>";
$ret .= "<div align='center'>" . LJ::make_qr_target('top') . "</div>" if $remote;
--------------------------------------------------------------------------------

no subject
no subject
Edit: yep, seems that's why. Should that be included then?
no subject
no subject