I don't know about other browsers, but this works OK on Chrome.
It also highlights new comments and collapses threads without new comments on repeat visits. HN now feels unusable without it in scenarios where I can't use a userscript :-/
As I understand it.
https://chrome.google.com/webstore/detail/hacker-news-enhanc...
I don't see that collapsing comments would really add much value, especially if the state is to kept per user per comment in the backend.
If you don't care about state, I feel reasonably sure that you could Greasemonkey your way out of not having that feature.
I wrote this a while ago, which seems to work. I reused the vote arrow with 1/4-turn rotation, placed on the other side of the comment header line to avoid confusion.
javascript:(function()%7Bfunction%20getScript(url,success)%7Bvar%20script=document.createElement('script');script.src=url;var%20head=document.getElementsByTagName('head')%5B0%5D,done=false;script.onload=script.onreadystatechange=function()%7Bif(!done&&(!this.readyState%7C%7Cthis.readyState=='loaded'%7C%7Cthis.readyState=='complete'))%7Bdone=true;success();script.onload=script.onreadystatechange=null;head.removeChild(script)%7D%7D;head.appendChild(script)%7DgetScript('//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js',function()%7Bif(typeof%20jQuery!=='undefined')%7Bif(!$('body').hasClass('collapsible-comments'))%7B$('body').addClass('collapsible-comments');var%20span_html='%3Cspan%20style=%5C'cursor:pointer;margin-right:10px;%5C'%20class=%5C'expand-handle%5C'%3E%5B-%5D%3C/span%3E';if(window.location.href.indexOf('item?id=')!=-1)%7B$('center%20%3E%20table%20%3E%20tbody%20%3E%20tr:eq(2)%20%3E%20td%20%3E%20table:eq(1)%20span.comhead').prepend(span_html)%7Delse%20if(window.location.href.indexOf('threads?id=')!=-1)%7B$('center%20%3E%20table%20%3E%20tbody%20%3E%20tr%20%3E%20td%20%3E%20table%20span.comhead').prepend(span_html)%7D$('.expand-handle').live('click',function()%7Bcurrent_level_width=parseInt($(this).closest('tr').find('td:eq(0)%20%3E%20img').attr('width'),10);$(this).closest('table').closest('tr').nextAll().each(function(index,el)%7Bvar%20elWidth=parseInt($('tbody%20%3E%20tr%20%3E%20td%20%3E%20img',this).attr('width'),10);if(elWidth%3Ecurrent_level_width)%7Bif(elWidth%3C=inner_level_width)%7Binner_level_width=1000;$(this).hide()%7Dif(inner_level_width==1000&&$('.comment',this).css('display')=='none')%7Binner_level_width=elWidth%7D%7Delse%7Breturn%20false%7D%7D);inner_level_width=1000;$(this).text('%5B+%5D').addClass('expand-handle-collapsed').removeClass('expand-handle');$(this).closest('div').nextAll().hide();$(this).closest('div').parent().prev().hide();$(this).closest('div').css(%7B'margin-left':'18px','margin-bottom':'5px'%7D)%7D);$('.expand-handle-collapsed').live('click',function()%7Bcurrent_level_width=parseInt($(this).closest('tr').find('td%20%3E%20img').attr('width'),10);$(this).closest('table').closest('tr').nextAll().each(function(index,el)%7Bvar%20elWidth=parseInt($('tbody%20%3E%20tr%20%3E%20td%20%3E%20img',this).attr('width'),10);if(elWidth%3Ecurrent_level_width)%7Bif(elWidth%3C=inner_level_width)%7Binner_level_width=1000;$(this).show()%7Dif(inner_level_width==1000&&$('.comment',this).css('display')=='none')%7Binner_level_width=elWidth%7D%7Delse%7Breturn%20false%7D%7D);inner_level_width=1000;$(this).text('%5B-%5D').addClass('expand-handle').removeClass('expand-handle-collapsed');$(this).closest('div').nextAll().show();$(this).closest('div').parent().prev().show();$(this).closest('div').css(%7B'margin-left':'0','margin-bottom':'-10px'%7D)%7D)%7D%7D%7D);var%20current_level_width=0;var%20inner_level_width=1000%7D)();
I can't remember who wrote it, but it works.