Mercurial Hosting > nabble
diff src/nabble/view/naml/topic.naml @ 0:7ecd1a4ef557
add content
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 21 Mar 2019 19:15:52 -0600 |
parents | |
children | 18cf4872fd7f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/nabble/view/naml/topic.naml Thu Mar 21 19:15:52 2019 -0600 @@ -0,0 +1,1659 @@ +<macro name="topic" requires="servlet"> + <n.if.is_blog_topic> + <then.switch. value="[n.topic_view/]"> + <n.case value="[n.classic_view/]" do="[n.classic_blog_topic/]" /> + <n.case value="[n.list_view/]" do="[n.list_blog_topic/]" /> + <n.case value="[n.threaded_view/]" do="[n.threaded_blog_topic/]" /> + </then.switch.> + <else.switch. value="[n.topic_view/]"> + <n.case value="[n.classic_view/]" do="[n.classic_forum_topic/]" /> + <n.case value="[n.list_view/]" do="[n.list_forum_topic/]" /> + <n.case value="[n.threaded_view/]" do="[n.threaded_forum_topic/]" /> + </else.switch.> + </n.if.is_blog_topic> +</macro> + +<macro name="topic canonical path" requires="http_request"> + <n.get_node_from_parameter.topic_path + view="[n.get_parameter name='view'/]" + index_record="[n.get_parameter name='index_record'/]" + /> +</macro> + +<macro name="is_blog_topic"> + <n.regex_matches text="[n.node_page.page_node.app_or_root.type/]" pattern="news|gallery|blog"/> +</macro> + +<namespace name="blog_topic_namespace" /> +<namespace name="forum_topic_namespace" /> +<namespace name="classic_view_namespace" /> +<namespace name="list_view_namespace" /> +<namespace name="threaded_view_namespace" /> + +<subroutine name="classic_blog_topic" requires="basic,nabble,servlet"> + <n.classic_view_namespace.blog_topic_namespace.topic_html_page/> +</subroutine> + +<subroutine name="list_blog_topic" requires="basic,nabble,servlet"> + <n.list_view_namespace.blog_topic_namespace.topic_html_page/> +</subroutine> + +<subroutine name="threaded_blog_topic" requires="basic,nabble,servlet"> + <n.threaded_view_namespace.blog_topic_namespace.topic_html_page/> +</subroutine> + +<subroutine name="classic_forum_topic" requires="basic,nabble,servlet"> + <n.classic_view_namespace.forum_topic_namespace.topic_html_page/> +</subroutine> + +<subroutine name="list_forum_topic" requires="basic,nabble,servlet"> + <n.list_view_namespace.forum_topic_namespace.topic_html_page/> +</subroutine> + +<subroutine name="threaded_forum_topic" requires="basic,nabble,servlet"> + <n.threaded_view_namespace.forum_topic_namespace.topic_html_page/> +</subroutine> + + +<macro name="topic_html_page" requires="servlet"> + <n.topic_html/> +</macro> + +<macro name="topic_html" requires="servlet"> + <n.topic_min_html> + <head> + <n.topic_common_head/> + <n.topic_head/> + <n.topic_meta/> + <n.increment_view_count/> + </head> + <body> + <n.page_node.topic_hardcoded_notices/> + <n.newsflash/> + <n.topic_header/> + <n.topic_controls/> + <n.topic_contents.view_contents.page_node.topic_rows/> + <n.topic_footer/> + </body> + </n.topic_min_html> +</macro> + + +<macro name="topic_rows" requires="node,blog_topic_namespace,classic_view_namespace"> + <n.post_list. + sort="date-ascending" + start="[n.classic_index_record/]" + length="[n.classic_rows_per_page/]" + > + <n.preload_messages/> + <n.loop.classic_row/> + </n.post_list.> +</macro> + +<macro name="topic_rows" requires="node,blog_topic_namespace,list_view_namespace"> + <n.post_list. + sort="date-ascending" + start="1" + length="10000" + > + <n.preload_messages/> + <n.loop.current_node.clickable_post/> + </n.post_list.> +</macro> + +<macro name="topic_rows" requires="node,blog_topic_namespace,threaded_view_namespace"> + <n.children_list. start="0" length="10000"> + <n.loop.current_node.threaded_posts/> + </n.children_list.> +</macro> + +<macro name="topic_rows" requires="node,forum_topic_namespace,classic_view_namespace"> + <n.post_list. + sort="date-ascending" + start="[n.classic_index_record/]" + length="[n.classic_rows_per_page/]" + > + <n.preload_messages/> + <n.loop.classic_row/> + </n.post_list.> +</macro> + +<macro name="topic_rows" requires="node,forum_topic_namespace,list_view_namespace"> + <n.post_list. + sort="date-ascending" + start="0" + length="10000" + > + <n.preload_messages/> + <n.loop.current_node.clickable_post/> + </n.post_list.> +</macro> + +<macro name="topic_rows" requires="node,forum_topic_namespace,threaded_view_namespace"> + <n.threaded_posts/> +</macro> + + +<macro name="topic_min_html" parameters="head,body" requires="servlet"> + <n.node_page.> + <n.topic_caching/> + <n.check_that_is_post/> + <n.html> + <head> + <n.head/> + </head> + <body> + <n.body/> + <n.topic_bottom/> + </body> + </n.html> + </n.node_page.> +</macro> + +<macro name="topic_bottom"> + <n.comment.>To be overridden</n.comment.> +</macro> + +<macro name="topic_caching"> + <n.uncache_for.> + <n.descendant_changes.page_node.id/> + <n.bread_crumb_changes.page_node.id/> + </n.uncache_for.> +</macro> + +<macro name="topic_title" dot_parameter="ending"> + <title><n.compress.> + <n.page_node.topic_title_contents/> + <n.ending/> + </n.compress.></title> +</macro> + +<macro name="topic_title_contents" requires="node"> + <n.if.has_property name="page_title"> + <then.get_property name="page_title"/> + <else.default_topic_title_contents/> + </n.if.has_property> +</macro> + +<macro name="default_topic_title_contents" requires="node"> + <n.app_or_root.subject/> - + <n.subject/> +</macro> + +<macro name="topic_meta" requires="node_page,servlet"> + <n.if.equal value1="[n.topic_view/]" value2="[n.classic_view/]"> + <then> + <n.topic_meta_description/> + <n.topic_meta_keywords/> + </then> + <else> + <n.set_var. name='canonical_url'><n.page_node.topic_path view="[n.classic_view/]"/></n.set_var.> + <link rel="canonical" href="[n.var name='canonical_url'/]" /> + <META NAME="robots" CONTENT="noindex,follow"/> + </else> + </n.if.equal> +</macro> + +<macro name="topic_meta_description" requires="node_page"> + <META NAME="description" CONTENT="[n.page_number_in_brackets/][n.page_node.build_meta_description/]"/> +</macro> + +<macro name="topic_meta_keywords" requires="node_page"> + <META NAME="keywords" CONTENT="[n.page_node.build_meta_keywords/]"/> +</macro> + +<macro name="check_that_is_post"> + <n.if.page_node.is_app> + <then.redirect_to.page_node.url/> + </n.if.page_node.is_app> +</macro> + +<macro name="is_blog_style"> + <n.cache. var="is_blog_style"> + <n.regex_matches text="[n.page_node.app_or_root.type/]" pattern="news|gallery|blog"/> + </n.cache.> +</macro> + +<macro name="topic_common_head"> + <n.search_highlight_js/> + <n.message_width_js/> +</macro> + +<macro name="message_width_js"> + <script type="text/javascript"> + Nabble.messageTextWidth(); + </script> +</macro> + +<macro name="search_highlight_js"> + <script type="text/javascript"> + var terms = Nabble.getSearchTerms(); + var hasTurnOff = false; + Nabble.searchHighlight = function($elem) { + if (terms != null && terms.length > 0) { + $elem.each(function() { + Nabble.highlightSearchTerms(terms, this); + }); + if (Nabble.hasHighlightedTerms && !hasTurnOff) { + var turnOffLink = '<span id="turn-off-highlight-control"><span class="highlight"> X </span> '; + turnOffLink += '<a href="javascript:void(0)" onclick="Nabble.turnOffHighlight()"><t>Turn off highlighting</t></a></span>'; + $('#topics-controls-right').prepend(turnOffLink); + hasTurnOff = true; + } + } + }; + Nabble.turnOffHighlight = function() { + Nabble.deleteCookie("query"); + Nabble.deleteCookie("searchuser"); + Nabble.deleteCookie("searchterms"); + $('span.search-highlight').removeClass('bold highlight'); + $('#turn-off-highlight-control').hide(); + }; + </script> +</macro> + +<macro name="topic_head" requires="classic_view_namespace"> + <n.compress.> + <n.search_terms_js selector="h2.post-subject,div.message-text"/> + <n.classic_js/> + <n.if.has_small_avatar> + <then.classic_stylesheet_small_avatar/> + <else.classic_stylesheet_big_avatar/> + </n.if.has_small_avatar> + </n.compress.> + + <n.topic_title.> + <n.hide_if_equals. value1="[n.topic_page_number/]" value2="1"> + | <t>Page <t.number.topic_page_number/></t> + </n.hide_if_equals.> + </n.topic_title.> +</macro> + +<macro name="page_number_in_brackets"> + <n.hide_if_equals. value1="[n.topic_page_number/]" value2="1"> + [<t>Page <t.number.topic_page_number/></t>]<n.space/> + </n.hide_if_equals.> +</macro> + +<macro name="has_small_avatar"> + <n.is_blog_style/> +</macro> + +<macro name="search_terms_js" parameters="selector"> + <script type="text/javascript"> + $(document).ready(function() { + Nabble.searchHighlight($('<n.selector/>')); + }); + </script> + <n.call_later value="[n.page_node.id/]" param="searchSpecial"/> +</macro> + +<macro name="search_terms_special_js"> + <n.param_loop. param="searchSpecial"> + var nodeIds = [<n.page_node.as_node_page.search_namespace.descendants_ids_matching_search_query/>]; + for (var i=0; i <n.lt/> nodeIds.length; i++) + $('span.post-date'+nodeIds[i]).addClass('highlight'); + </n.param_loop.> +</macro> + +<macro name="topic_head" requires="list_view_namespace"> + <n.compress.> + <n.tooltip_head/> + <n.search_terms_js selector="span.post-subject"/> + <n.ajax_posts_js view_name="list"/> + <n.list_stylesheet/> + </n.compress.> + <n.topic_title.> + | <t>List View</t> + </n.topic_title.> +</macro> + +<macro name="topic_head" requires="threaded_view_namespace"> + <n.compress.> + <n.tooltip_head/> + <n.search_terms_js selector="span.post-subject"/> + <n.ajax_posts_js view_name="threaded"/> + <n.tree_panning_js/> + <n.threaded_stylesheet/> + </n.compress.> + <n.topic_title.> + | <t>Threaded View</t> + </n.topic_title.> +</macro> + +<macro name="topic_contents" dot_parameter="contents" requires="forum_topic_namespace"> + <n.topic_contents_div.contents /> +</macro> + +<macro name="topic_contents_div" dot_parameter="contents"> + <div id="topic-contents" style="margin-top:1em;clear:both"> + <n.contents/> + </div> +</macro> + +<macro name="classic_row_count" requires="blog_topic_namespace"> + <n.page_node.replies/> +</macro> + +<macro name="classic_row_count" requires="forum_topic_namespace"> + <n.page_node.descendant_count/> +</macro> + +<macro name="classic_row" requires="node_list"> + <n.if.has_small_avatar> + <then.current_node.classic_row_with_small_avatar/> + <else.current_node.classic_row_with_big_avatar/> + </n.if.has_small_avatar> + <n.if.is_last_element> + <then.current_node.mark_as_visited/> + </n.if.is_last_element> +</macro> + +<macro name="mark_as_visited" requires="node"> + <n.call_later value="[n.id/]" param="markVisited"/> +</macro> + +<macro name="mark_as_visited_js"> + <n.if.visitor.is_registered> + <then> + <n.param_loop. param="markVisited"> + <n.if_node_parameter_is_valid.> + <n.visitor.mark_visited node="[n.page_node.topic_node/]" last_node_id="[n.page_node.id/]"/> + </n.if_node_parameter_is_valid.> + </n.param_loop.> + </then> + </n.if.visitor.is_registered> +</macro> + +<macro name="classic_pagination" parameters="margin,row_count"> + <n.paging. + total_rows="[n.row_count/]" + current_row="[n.classic_index_record/]" + rows_per_page="[n.classic_rows_per_page/]" + > + <n.generic_paging> + <margin><n.margin/></margin> + <url><n.page_node.topic_path view="[n.classic_view/]" index_record="[n.page_row/]"/></url> + </n.generic_paging> + </n.paging.> +</macro> + +<macro name="classic_stylesheet_big_avatar"> + <style type="text/css"> + div.classic-header { + height:2.2em; + clear:both; + overflow:hidden; + } + div.classic-author-name { + float:left; + width: 140px; + overflow: hidden; + text-align:center; + font-weight:bold; + } + div.classic-subject-line { + left:.5em; + overflow:hidden; + height:1.3em; + position:relative; + } + div.classic-right-menu { + float:right; + padding-left:1em; + } + div.classic-bar { + padding:.5em .3em; + clear:both; + height:1.8em; + } + table.classic-body { + border-collapse:collapse; + margin-bottom:1em; + table-layout: fixed; + width:100%; + } + td.classic-author { + vertical-align: top; + text-align:center; + width:140px; + padding-bottom:1em; + } + td.classic-message { + vertical-align:top; + padding:1em; + } + div.message-text { + cursor:text; + overflow-x:auto; + } + div.avatar-inner { + margin-left:20px; + } + div.avatar-outer { + width:140px; + text-align:left; + } + div.avatar-label { + white-space:nowrap; + font-size:80%; + } + </style> +</macro> + +<macro name="classic_stylesheet_small_avatar"> + <style type="text/css"> + div.classic-header { + height:2.2em; + min-height:33px; + clear:both; + overflow:hidden; + } + div.classic-bar { + padding:0 .4em .7em; + clear:both; + height:1.7em; + min-height:33px; + } + table.classic-author-name { + border-spacing:0; + width: 140px; + float:left; + } + table.classic-author-name td { + overflow-x: hidden; + height:2.2em; + } + table.classic-author-name td.avatar { + width:30px; + overflow:visible; + } + div.classic-subject-line { + left:.5em; + overflow-x:hidden; + line-height:2.4em; + position:relative; + } + div.classic-right-menu { + float:right; + line-height:2.4em; + padding-left:1em; + } + table.classic-body { + border-collapse:collapse; + margin-bottom:1em; + table-layout: fixed; + width:100%; + } + td.classic-author { + vertical-align: top; + text-align:center; + width:5px; + padding:1em 0; + } + td.classic-message { + vertical-align:top; + padding:1em; + } + div.message-text { + cursor:text; + overflow-x:auto; + } + </style> +</macro> + +<macro name="classic_row_with_small_avatar" requires="node, node_list"> + <div class="classic-row"> + <div class="classic-header"> + <div class="classic-bar shaded-bg-color rounded-top"> + <table class="classic-author-name"> + <tr> + <td class="avatar"><n.owner.avatar border_class="medium-border-color"/></td> + <td class="bold nowrap"><n.owner.user_link class="owner-link"/></td> + </tr> + </table> + <div class="classic-right-menu shaded-bg-color weak-color"> + <n.reply_link/> | + <n.threaded_link/> | + <n.post_dropdown/> + </div> + <div class="classic-subject-line"> + <n.classic_post_date/> + <n.classic_subject_line/> + </div> + </div> + </div> + <table class="classic-body"> + <tr> + <td class="classic-author shaded-bg-color rounded-bottom"> + <n.red_arrow_icon/> + </td> + <td class="classic-message"> + <n.classic_message_cell/> + </td> + </tr> + </table> + </div> +</macro> + +<macro name="classic_row_with_big_avatar" requires="node, node_list"> + <div class="classic-row"> + <div class="classic-header"> + <div class="classic-bar shaded-bg-color rounded-top"> + <div class="classic-author-name nowrap"> + <n.owner.user_link/> + </div> + <div class="classic-right-menu shaded-bg-color weak-color"> + <n.reply_link/> | + <n.threaded_link/> | + <n.post_dropdown/> + </div> + <div class="classic-subject-line"> + <n.red_arrow_icon/> + <n.classic_post_date/> + <n.classic_subject_line/> + </div> + </div> + </div> + <table class="classic-body"> + <tr> + <td class="classic-author shaded-bg-color rounded-bottom"> + <n.classic_big_avatar_cell/> + </td> + <td class="classic-message"> + <n.classic_message_cell/> + </td> + </tr> + </table> + </div> +</macro> + +<macro name="classic_big_avatar_cell" requires="node"> + <div class="avatar-outer"> + <div class="avatar-inner"> + <n.owner.avatar size="big" border_class="medium-border-color"/> + </div> + </div> + <n.avatar_label condition="[n.owner.is_site_admin/]" label="[b][t]Administrator[/t][/b]"/> + <n.avatar_label condition="[n.owner.is_banned/]" label="[t]Banned User[/t]"/> + <n.owner.post_count/> +</macro> + +<macro name="avatar_label" parameters="condition" dot_parameter="label"> + <n.if.condition> + <then> + <div class="avatar-label weak-color"><n.label/></div> + </then> + </n.if.condition> +</macro> + +<macro name="classic_message_cell" requires="node"> + <n.pending_notice/> + <n.updated_notice/> + <n.reply_notice/> + <n.message_text/> +</macro> + +<macro name="post_count" requires="user"> + <div class="post-count[n.user_tag_id/] avatar-label weak-color"></div> + <n.call_later value="[n.id/]" param="postCount"/> +</macro> + +<macro name="post_count_js"> + <n.param_loop. param="postCount"> + <n.if.not.page_user.is_deactivated> + <then> + $('div.post-count<n.page_user.user_tag_id/>') + .html('<n.one_or_many n="[n.page_user.post_count_value/]" one_text="[t]post[/t]" many_text="[t]posts[/t]"/>'); + </then> + </n.if.not.page_user.is_deactivated> + </n.param_loop.> +</macro> + +<macro name="updated_notice" requires="node"> + <n.if.was_updated> + <then> + <div class="weak-color" style="font-size:80%;padding-bottom:1em"> + <t>This post was updated on <t.date.when_updated.long_format/>.</t> + </div> + </then> + </n.if.was_updated> +</macro> + +<macro name="pending_notice" requires="node"> + <n.if.is_pending> + <then> + <div class="info-message rounded" style="padding:.5em;margin:-.8em -.8em .8em -.8em;font-size:90%"> + <t>This post has NOT been accepted by the mailing list yet.</t> + </div> + </then> + </n.if.is_pending> +</macro> + +<macro name="reply_notice" requires="node"> + <n.if.both condition1="[n.has_previous_node/]" condition2="[n.not.parent_node.equals.previous_node/]"> + <then> + <div class="weak-color" style="font-size:80%;padding-bottom:1em"> + <t>In reply to <n.parent_link.>this post</n.parent_link.> by <t.author.parent_node.owner.name/></t> + </div> + </then> + </n.if.both> +</macro> + +<macro name="parent_link" dot_parameter="text" requires="node"> + <a href="[n.parent_node.url/]" rel="nofollow"><n.text/></a> +</macro> + +<macro name="classic_subject_line" requires="node"> + <h2 class="post-subject float-left adbayes-content" style="width:30%;overflow:visible;font-family:inherit"> + <n.break_up.subject/> + </h2> +</macro> + +<macro name="red_arrow_icon" requires="node"> + <span id="red-arrow[n.id/]" class="float-left invisible" style="margin-top:.2em"> + <img title="Selected post" width="15" height="15" src="/images/arrow.png" alt="Selected post"/> + </span> +</macro> + +<macro name="all_posts_js_array"> + <n.page_node.post_list. + sort="date-ascending" + start="0" + length="10000" + > + <n.loop.> + <n.if.not.is_first_element> + <then>,</then> + </n.if.not.is_first_element> + <n.current_node.id/> + </n.loop.> + </n.page_node.post_list.> +</macro> + +<macro name="all_urls_js_array"> + <n.page_node.post_list. + sort="date-ascending" + start="0" + length="10000" + > + <n.no_output.next_node/> + <n.all_urls_js_array_url/> + <n.loop. by="[n.classic_rows_per_page/]"> + ,<n.all_urls_js_array_url/> + </n.loop.> + </n.page_node.post_list.> +</macro> + +<macro name="all_urls_js_array_url"> + "<n.page_node.topic_path view="[n.classic_view/]" index_record="[n.current_index/]"/>" +</macro> + +<macro name="classic_js"> + <script type="text/javascript"> + var _hash = Nabble.hash(); + if (_hash) { + (function(){ + var post = _hash.substr(2); + var allPosts = [<n.compress.all_posts_js_array/>]; + var allURLs = [<n.compress.all_urls_js_array/>]; + var iPost = allPosts.indexOf(parseInt(post)); + var lower = <n.default. to="0"><n.classic_index_record/></n.default.>; + var upper = lower + <n.classic_rows_per_page/>; +<![CDATA[ + if (iPost != -1 && (iPost < lower || iPost >= upper)) +]]> + location.replace(allURLs[Math.floor(iPost/<n.classic_rows_per_page/>)]+_hash); + })(); + } + + $(document).ready(function() { + var rootId = '<n.page_node.id/>'; +<![CDATA[ + var currentPostId = rootId; + var isChangingViews = _hash == '#none'; + if (_hash && !isChangingViews) + currentPostId = _hash.substr(2); + + Nabble.hideQuotes(); + + function scrollToSelectedPost() { + var $arrow = $('#red-arrow'+currentPostId).show(); + if ($arrow.size() > 0) { + var isRootPost = currentPostId == rootId; + if (Nabble.isEmbedded) { + if (Nabble.canScroll()) scrollTo(0, 0); + var y = isChangingViews? null : isRootPost? 1 : $arrow.parents('div.classic-row').offset().top; + Nabble.resizeFrames('', y); + } else if (Nabble.canScroll() && !isRootPost) { + var yPos = $arrow.offset().top; + scrollTo(0,yPos-20); + } + } else { + if (Nabble.isEmbedded && Nabble.canScroll()) { + Nabble.resizeFrames('', 1); + } else { + var tb = $('div.top-bar').get(0); + if (tb) + tb.scrollIntoView(); + } + } + }; + $(window).load(scrollToSelectedPost); + + if (Nabble.isEmbedded) { + $('div.message-text img').load(Nabble.resizeFrames); + } +]]> + }); + </script> +</macro> + +<macro name="classic_post_date" requires="node"> + <span class="post-date float-left"> + <n.when_created.long_format/> + </span> +</macro> + +<macro name="classic_index_record" requires="servlet"> + <n.get_parameter name="index_record"/> +</macro> + +<macro name="classic_index_record" requires="blog_topic_namespace, servlet"> + <n.int. i="[n.default. to='0'][n.get_parameter name='index_record'/][/n.default.]"> + <n.plus i="1"/> + </n.int.> +</macro> + +<macro name="classic_rows_per_page"> + 20 +</macro> + +<macro name="view_contents" dot_parameter="rows" requires="classic_view_namespace"> + <div id="classic-contents"> + <n.classic_pagination margin="0 .2em .5em" row_count="[n.classic_row_count/]" /> + <n.rows/> + <n.classic_pagination margin="1em .2em 0" row_count="[n.classic_row_count/]" /> + </div> +</macro> + +<macro name="view_contents" dot_parameter="rows" requires="list_view_namespace"> + <div id="list-contents"> + <n.rows/> + </div> +</macro> + +<macro name="view_contents" dot_parameter="rows" requires="threaded_view_namespace"> + <div id="threaded-contents" style="margin-left:0"> + <n.rows/> + </div> +</macro> + +<macro name="threaded_stylesheet"> + <style type="text/css"> + #topic-contents { + overflow:hidden; + cursor: url("/images/hand.png"),w-resize; + } + div.clickable-row { + white-space:nowrap; + right:1em; + padding:.2em 0; + cursor:pointer; + } + div.full-row { + border-width:2px; + border-style:solid; + padding:.3em .8em .5em; + cursor:text; + } + div.full-row-header { + padding-bottom:1em; + cursor:pointer; + } + div.full-row-header > * { + cursor:pointer; + } + div.connect-outer { + background-image:url("/images/connect-line.gif"); + } + div.outer-line { + background-repeat: repeat-y; + } + div.outer-end { + background-repeat: no-repeat; + } + div.connect-inner { + padding-left:1em; + cursor: url("/images/hand.png"),w-resize; + } + div.inner-line { + background:none; + } + div.inner-end { + background:url("/images/connect-end.gif") no-repeat; + } + span.post-snippet { font-size:75%; } + + div.message-text { + cursor:text; + overflow-x:auto; + } + div.right-menu { + float:right; + padding:.3em; + } + img.view-icon { + border:none; + width:18px; + height:18px; + vertical-align:middle; + } + img.close { + width:11px; + height:11px; + } + </style> +</macro> + +<macro name="tree_panning_js"> + <script type="text/javascript"> + $(document).ready(function() { + (function() { + var down = null; + var initialLeft = null; + var $area = $('#threaded-contents'); + function startDrag(e) { + if (e.target == this) { + down = e.pageX; + initialLeft = parseInt($area.css('margin-left')); + return false; + } + }; + function drag(e) { + if (down) { + var m = initialLeft + (e.pageX - down); + $area.css('margin-left',m > 0? '0' : m+'px'); + } + }; + function stopDrag(e){ + down = null; + initialLeft = null; + }; + $('div.connect-inner,#topic-contents') + .mousedown(startDrag) + .mousemove(drag) + .mouseup(stopDrag); + $(document).mouseup(stopDrag); + })(); + }); + </script> +</macro> + +<macro name="ajax_posts_js" parameters="view_name"> + <script type="text/javascript"> + var historyLength = history.length; + var loadedPosts = []; + var allPosts = [<n.compress.all_posts_js_array/>]; + + function setPostHover($e) { + $e.hover( + function(){ $(this).addClass('post-hover'); }, + function(){ $(this).removeClass('post-hover'); }); + }; + + var lastPostId = <n.page_node.last_node.id/>; +<![CDATA[ + Nabble.markUnreadPosts = function(lastVisitedId) { + if (lastVisitedId == null) + $('div.clickable-row').css('font-weight','bold'); + if (lastVisitedId == lastPostId) + return; + else { + for (var i = 0; i < allPosts.length; i++) { + if (allPosts[i] > lastVisitedId) { + $('#clickable-row'+allPosts[i]).css('font-weight','bold'); + } + } + } + }; + + $(document).ready(function() { + var $dummy = $('div.clickable-row'); + setPostHover($dummy); + $dummy.click(function(){ + var postId = $(this).attr('post-id'); + Nabble.loadPost(postId); + }); + + /* Code to open initial post */ + (function() { + var _hash = Nabble.hash(); + var postId = allPosts[0]; + if (_hash && _hash != '#none') + postId = parseInt(_hash.substr(2)); + else if (_hash == '#none') + postId = allPosts.length == 1? allPosts[0] : null; + if (postId) { + if (allPosts.indexOf(postId) >= 0) { + var $dummy = $('#clickable-row'+postId); + $dummy.click(); + } + } + })(); + }); +]]> + + var isFirst = true; + Nabble.loadPost = function(nodeId) { + if (loadedPosts.indexOf(nodeId) == -1) { + $('#loading'+nodeId).show("fast"); + var url = "/"+"template/NamlServlet.jtp?macro=ajax_post&view=<n.view_name/>&node="+nodeId; + $.get(url, function(data) { + $('#clickable-row'+nodeId).replaceWith(data); + + var $dummy = $('#clickable-row'+nodeId); + var $full = $('#full-row'+nodeId); + + /* Click event that collapses the post */ + $full.children('div.full-row-header').click(function(e){ + var t = e.target; + if (t == this || $(t).hasClass('close') || (t.nodeName != 'A' && t.nodeName != 'IMG')) { + $full.slideUp("normal", function() { + $dummy.show(); + Nabble.resizeFrames(); + }); + } + }); + + /* Click event that expands the post */ + $dummy.click(function() { + $dummy.hide(); + $full.slideDown('normal',Nabble.resizeFrames); + }); + setPostHover($dummy); + + var $msg = $('#message'+nodeId); + if (Nabble.isEmbedded) { + $('img',$msg).load(Nabble.resizeFrames); + } + Nabble.searchHighlight($msg); + + <n.ajax_post_custom_scripts/> + + $full.slideDown('normal',function(){ + Nabble.hideQuotes(this); + if (isFirst) { + var isRootPost = nodeId == allPosts[0]; + if (Nabble.isEmbedded) { + if (Nabble.canScroll()) scrollTo(0,0); + var y = isRootPost? 1 : $full.offset().top-30; + Nabble.resizeFrames('', y); + } else { + scrollTo(0,0); + if (!isRootPost) + scrollBy(0,$full.offset().top); + } + isFirst = false; + } + }); + loadedPosts.push(nodeId); + }); + } + }; + </script> + <n.call_later value="[n.page_node.id/]" param="markUnreadPosts"/> +</macro> + +<macro name="ajax_post_custom_scripts"> + <n.comment>To be overridden</n.comment> +</macro> + +<macro name="mark_unread_posts_js"> + <n.if.visitor.is_registered> + <then> + <n.param_loop. param="markUnreadPosts"> + <n.set_var. name='last_id'> + <n.if.visitor.has_visited_node node_id="[n.current_parameter_value/]"> + <then.visitor.last_visited_node. node_id="[n.current_parameter_value/]"> + <n.id/> + </then.visitor.last_visited_node.> + <else>null</else> + </n.if.visitor.has_visited_node> + </n.set_var.> + Nabble.markUnreadPosts(<n.var name='last_id'/>); + </n.param_loop.> + </then> + </n.if.visitor.is_registered> +</macro> + +<subroutine name="threaded_posts" requires="basic,nabble,servlet,node"> + <n.if.call_depth.is_greater_than i="60"> + <then> + <div class="info-message" style="padding:.5em 1em"> + <t>This branch is too big and some posts were omitted. Use the other views to read all posts.</t> + </div> + </then> + <else> + <div> + <n.clickable_post/> + <n.children_list. start="0" length="10000"> + <n.loop.> + <div class="connect-outer outer-[n.connect_class_suffix/]"> + <div class="connect-inner inner-[n.connect_class_suffix/]"> + <n.current_node.threaded_posts/> + </div> + </div> + </n.loop.> + </n.children_list.> + </div> + </else> + </n.if.call_depth.is_greater_than> +</subroutine> + +<macro name="connect_class_suffix" requires="node_list"> + <n.if.is_last_element> + <then>end</then> + <else>line</else> + </n.if.is_last_element> +</macro> + +<macro name="clickable_post" requires="node"> + <div id="clickable-row[n.id/]" class="clickable-row" post-id="[n.id/]"> + <n.post_short_date/> + <n.post_author/> + <n.post_subject separator="–"/> + <n.post_snippet/> + <div id="loading[n.id/]" class="important invisible"><t>Loading...</t></div> + </div> +</macro> + +<macro name="ajax_post" requires="servlet"> + <n.uncache_for.node_changes.get_parameter name="node"/> + <n.ajax. is_cached="true"> + <n.node_page.> + <n.page_node.> + <n.mark_as_visited/> + <div id="clickable-row[n.id/]" class="clickable-row invisible"> + <n.post_short_date/> + <n.post_author/> + <n.post_subject/> + <n.post_snippet/> + </div> + <div id="full-row[n.id/]" class="full-row medium-border-color invisible"> + <div class="full-row-header"> + <div class="right-menu"> + <n.change_view_links/> + + <n.reply_link/> + + <n.post_dropdown/> + + <img src="/images/close.png" class="close" alt="Close"/> + </div> + <n.post_long_date/> + <n.owner.avatar size="small"/> + <n.owner.user_link/> + <n.post_subject/> + </div> + <n.pending_notice/> + <n.updated_notice/> + <n.message_text/> + </div> + </n.page_node.> + </n.node_page.> + </n.ajax.> +</macro> + +<macro name="message_text" requires="node"> + <div id="message[n.id/]" class="message-text adbayes-content"> + <n.message_with_signature/> + </div> +</macro> + +<macro name="change_view_links" requires="node"> + <n.if.equal value1="[n.get_parameter name='view'/]" value2="[n.threaded_view/]"> + <then> + <n.classic_icon_link/> + <n.list_icon_link/> + </then> + <else> + <n.classic_icon_link/> + <n.threaded_icon_link/> + </else> + </n.if.equal> +</macro> + +<macro name="list_stylesheet"> + <style type="text/css"> + #topic-contents { + overflow:hidden; + } + div.clickable-row { + white-space:nowrap; + right:1em; + padding:.2em 0; + cursor:pointer; + } + div.full-row { + border-width:2px; + border-style:solid; + padding:.3em .8em .5em; + cursor:text; + } + div.full-row-header { + padding-bottom:1em; + cursor:pointer; + } + div.full-row-header > * { + cursor:pointer; + } + span.post-snippet { font-size:75%; } + + div.message-text { + cursor:text; + overflow-x:auto; + } + div.right-menu { + float:right; + padding:.3em; + } + img.view-icon { + border:none; + width:18px; + height:18px; + vertical-align:middle; + } + img.close { + width:11px; + height:11px; + } + </style> +</macro> + +<macro name="post_short_date" requires="node"> + <span class="post-date post-date[n.id/]"> + <n.when_created.short_format/> + </span> +</macro> + +<macro name="post_long_date" requires="node"> + <span class="post-date post-date[n.id/]"> + <n.when_created.long_format /> + </span> +</macro> + +<macro name="post_author" requires="node"> + <span class="post-author"> + <n.owner.name/> + </span> +</macro> + +<macro name="post_subject" parameters="separator" requires="node"> + <n.set_var. name='parent_subject'> + <n.if.has_parent> + <then.parent_node.subject/> + </n.if.has_parent> + </n.set_var.> + <n.if.not.ends_with text="[n.subject/]" suffix="[n.var name='parent_subject'/]"> + <then> + <span class="post-subject adbayes-content"><n.subject/> <n.hide_null.separator/></span> + </then> + </n.if.not.ends_with> +</macro> + +<macro name="post_snippet" requires="node"> + <span class="post-snippet adbayes-content"> + <n.truncate. size="150"><n.hide_emails.message.as_text_without_quotes/></n.truncate.> + </span> +</macro> + +<macro name="topic_footer"> + <div id="topic-footer" class="weak-color" style="padding-top:1em"> + <n.page_node.return_to_link/> + | + <n.page_node.views show_text="true"/> + </div> +</macro> + +<macro name="message_count"> + <span style="padding-right:1em"> + <n.one_or_many.page_node.descendant_count> + <one_text><t>message</t></one_text> + <many_text><t>messages</t></many_text> + </n.one_or_many.page_node.descendant_count> + </span> +</macro> + +<macro name="topic_header"> + <div id="topic-search-box" class="search-box float-right" style="padding:.5em 0"> + <n.page_node.search_box/> + </div> + + <h1 id="post-title" class="adbayes-content" style="margin:0.25em 0 .8em"> + <n.break_up.page_node.subject/> + </h1> +</macro> + +<macro name="topic_controls" requires="forum_topic_namespace"> + <div style="margin:1.2em 0 5em"> + <div id="topics-controls-left" class="float-left nowrap"> + <n.topic_controls_left/> + </div> + <div id="topics-controls-right" class="float-right nowrap" style="padding-top:.3em"> + <n.topic_controls_right/> + </div> + </div> +</macro> + +<macro name="topic_controls_left" requires="forum_topic_namespace"> + <n.view_selectors/> +</macro> + +<macro name="topic_controls_right" requires="forum_topic_namespace"> + <n.pin_icon/> + <n.lock_icon/> + <n.message_count/> + <img src="/images/gear.png" class="image16" alt="[t]Options[/t]"/> + <n.page_node.topic_dropdown/> +</macro> + +<macro name="topic_controls" requires="blog_topic_namespace"> + <div class="weak-color float-left" style="font-variant:small-caps"> + <n.topic_left_controls/> + </div> + + <div class="float-right" style="padding:.4em 0"> + <n.topic_right_controls/> + </div> + + <n.root_post_message/> +</macro> + +<macro name="topic_right_controls" requires="blog_topic_namespace"> + <n.root_dropdown/> +</macro> + +<macro name="root_post_message"> + <div class="root-text adbayes-content" style="margin:6em 0 2em;clear:both"> + <n.page_node.node_message_as_html/> + </div> +</macro> + +<macro name="topic_left_controls" requires="blog_topic_namespace"> + <t>Posted by + <t.author> + <n.page_node.owner.avatar size="small"/> + <n.page_node.owner.user_link/> + </t.author></t> + – + <n.page_node.when_created.long_format/> +</macro> + +<macro name="root_dropdown" requires="node_page"> + <img src="/images/gear.png" class="image16" alt="[t]Options[/t]"/> + <n.page_node.root_post_dropdown/> +</macro> + +<macro name="topic_contents" dot_parameter="contents" requires="blog_topic_namespace"> + <div id="comment-section"> + <n.if.page_node.has_replies> + <then> + <h2 class="second-font big-title" style="margin-bottom: .5em"> + <n.one_or_many.page_node.replies> + <one_text><t>Comment</t></one_text> + <many_text><t>Comments</t></many_text> + </n.one_or_many.page_node.replies> + </h2> + <n.view_selectors/> + </then> + </n.if.page_node.has_replies> + + <n.topic_contents_div.contents/> + + <n.add_new_comment_link/> + </div> +</macro> + +<macro name="add_new_comment_link"> + <div class="shaded-bg-color rounded" style="width:25em;margin:1em 0 2em;padding: .5em"> + <div style="float:left;margin-right:.5em"> + <img src="/images/icon_post_message.png" class="image16" alt="[t]Post message[/t]"/> + </div> + <a href="[n.page_node.reply_path/]" rel="nofollow"><t>Add a new comment</t></a> + </div> +</macro> + +<macro name="view_selectors"> + <table> + <tr> + <n.topic_view_option name="[t]Classic[/t]" value="classic" image="view-classic.gif"> + <url><n.page_node.topic_path view="[n.classic_view/]"/></url> + </n.topic_view_option> + + <n.topic_view_option name="[t]List[/t]" value="list" image="view-list.gif"> + <url><n.page_node.topic_path view="[n.list_view/]"/></url> + </n.topic_view_option> + + <n.topic_view_option name="[t]Threaded[/t]" value="threaded" image="view-threaded.gif"> + <url><n.page_node.topic_path view="[n.threaded_view/]"/></url> + </n.topic_view_option> + </tr> + </table> +</macro> + +<macro name="topic_view" requires="servlet"> + <n.get_parameter name="view"/> +</macro> + +<macro name="classic_view"> + classic +</macro> + +<macro name="list_view"> + list +</macro> + +<macro name="threaded_view"> + threaded +</macro> + +<macro name="topic_page_number" requires="servlet"> + <n.paging. + total_rows="0" + current_row="[n.classic_index_record/]" + rows_per_page="[n.classic_rows_per_page/]" + > + <n.current_page_number/> + </n.paging.> +</macro> + +<macro name="topic_path" parameters="view,index_record,selected_id" requires="node"> + <n.set_var. name="index_record"> + <n.to_null_if. equals="0"> + <n.index_record/> + </n.to_null_if.> + </n.set_var.> + <n.remove_spaces.> + /<n.url_encoded_subject/> + -t<n.view_char view="[n.view/]"/><n.id/> + <n.hide_null.prepend. prefix="i"><n.var name="index_record"/></n.hide_null.prepend.> + .html + <n.if> + <condition.both> + <condition1><n.not.is_null.selected_id/></condition1> + <condition2><n.not.equal value1="[n.id/]" value2="[n.selected_id/]"/></condition2> + </condition.both> + <then> + #a<n.selected_id/> + </then> + </n.if> + </n.remove_spaces.> +</macro> + +<macro name="view_char" parameters="view"> + <n.if.equal value1="[n.view/]" value2="[n.classic_view/]"> + <then>d</then> + <else.if.equal value1="[n.view/]" value2="[n.threaded_view/]"> + <then>t</then> + <else>c</else> + </else.if.equal> + </n.if.equal> +</macro> + +<macro name="topic_path_for" dot_parameter="view" requires="node"> + <n.set_var. name='id'><n.id/></n.set_var.> + <n.set_var. name='path'><n.topic_node.topic_path view="[n.view/]" selected_id="[n.var name='id'/]"/></n.set_var.> + <n.var name="path"/> +</macro> + +<macro name="threaded_link" requires="node"> + <a href="javascript:void(0)" onclick="Nabble.setView('threaded', '[n.topic_path_for.threaded_view/]',[n.id/])"><t>Threaded</t></a> + <n.tooltip.> + <t>Open this post in threaded view</t> + </n.tooltip.> +</macro> + +<macro name="classic_icon_link" requires="node"> + <a href="javascript:void(0)" onclick="Nabble.setView('classic', '[n.topic_path_for.classic_view/]',[n.id/])"><img src="/images/view-classic.gif" class="view-icon" alt="Classic"/></a> + <n.tooltip.> + <t>Open this post in classic view</t> + </n.tooltip.> +</macro> + +<macro name="list_icon_link" requires="node"> + <a href="javascript:void(0)" onclick="Nabble.setView('list', '[n.topic_path_for.list_view/]',[n.id/])"><img src="/images/view-list.gif" class="view-icon" alt="List"/></a> + <n.tooltip.> + <t>Open this post in list view</t> + </n.tooltip.> +</macro> + +<macro name="threaded_icon_link" requires="node"> + <a href="javascript:void(0)" onclick="Nabble.setView('threaded', '[n.topic_path_for.threaded_view/]',[n.id/])"><img src="/images/view-threaded.gif" class="view-icon" alt="Threaded"/></a> + <n.tooltip.> + <t>Open this post in threaded view</t> + </n.tooltip.> +</macro> + +<macro name="topic_view_option" parameters="name,value,image,url"> + <n.put_in_head.> + <script type="text/javascript"> + Nabble.setView = function(view,url,post) { + Nabble.setVar("tview",view); + if (url.indexOf('#') == -1) + url += '#none'; + location.replace(url); + }; + </script> + </n.put_in_head.> + + <n.topic_view_option_td value="[n.value/]" url="[n.url/]" style="padding-right:.1em"> + <contents><img src="/images/[n.image/]" width="18" height="18" style="border:none" alt="[n.value/]"/></contents> + </n.topic_view_option_td> + + <n.topic_view_option_td value="[n.value/]" url="[n.url/]" style="padding-right:1.1em"> + <contents><n.name/></contents> + </n.topic_view_option_td> +</macro> + +<macro name="topic_view_option_td" parameters="value,url,contents,style"> + <td style="[n.style/]"> + <n.if.equal value1="[n.topic_view/]" value2="[n.value/]"> + <then><n.contents/></then> + <else><a href="javascript:void(0)" onclick="Nabble.setView('[n.value/]', '[n.url/]',null)"><n.contents/></a></else> + </n.if.equal> + </td> +</macro> + +<macro name="raw_mail" requires="servlet"> + <n.set_response_header name="Content-Type" value="text/plain; charset=iso-8859-1"/> + <n.node_page.> + <n.if.either condition1="[n.visitor.can_edit.page_node/]" condition2="[n.visitor.is_sysadmin/]"> + <then.page_node.message.as_raw/> + </n.if.either> + </n.node_page.> +</macro> + +<macro name="topic_hardcoded_notices" requires="node_page"> + <n.inactive_node_deletion_ui/> +</macro> + +<macro name="page_node_is_scheduled_for_deletion" requires="node_page"> + <n.both> + <condition1><n.page_node.is_root/></condition1> + <condition2><n.site_has_delete_date/></condition2> + </n.both> +</macro> + +<macro name="pin_icon"> + <span style="padding-right:1em;height:21px"> + <img id="pin-icon" src="/images/pin.png" width="20" height="21" title="[t]This topic has been pinned in [t.location.page_node.app_or_root.subject/].[/t]" style="vertical-align:middle;[n.hidden_if.not.page_node.is_pinned/]"/> + <n.tooltip use_title="true"/> + </span> +</macro> + +<macro name="pin_topic_link" requires="node" dot_parameter="text" parameters="title, class"> + <n.put_in_head.> + <script type="text/javascript"> + Nabble.pinTopic = function(id) { + var call = '/' + 'template/NamlServlet.jtp?macro=pin_topic&node=' + id; + $.getScript(call, function() { + $('#pin-icon').show(); + NabbleDropdown.show('unpinTopic'); + NabbleDropdown.hide('pinTopic'); + alert('<t>This topic has been pinned.</t>'); + }); + }; + </script> + </n.put_in_head.> + <a href="javascript: void Nabble.pinTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Pin topic[/t]"><n.text/></n.default.></a> +</macro> + +<macro name="unpin_topic_link" requires="node" dot_parameter="text" parameters="title, class"> + <n.put_in_head.> + <script type="text/javascript"> + Nabble.unpinTopic = function(id) { + var call = '/'+'template/NamlServlet.jtp?macro=unpin_topic&node=' + id; + $.getScript(call, function() { + $('#pin-icon').hide(); + NabbleDropdown.hide('unpinTopic'); + NabbleDropdown.show('pinTopic'); + alert('<t>This topic has been unpinned.</t>'); + }); + }; + </script> + </n.put_in_head.> + <a href="javascript: void Nabble.unpinTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Unpin topic[/t]"><n.text/></n.default.></a> +</macro> + +<macro name="pin_topic" requires="servlet"> + <n.node_page.> + <n.if.both condition1="[n.visitor.can_manage_pinned_topics_in.page_node/]" condition2="[n.not.page_node.is_pinned/]"> + <then><n.page_node.pin/></then> + </n.if.both> + </n.node_page.> +</macro> + +<macro name="unpin_topic" requires="servlet"> + <n.node_page.> + <n.if.both condition1="[n.visitor.can_manage_pinned_topics_in.page_node/]" condition2="[n.page_node.is_pinned/]"> + <then><n.page_node.unpin/></then> + </n.if.both> + </n.node_page.> +</macro> + +<macro name="lock_icon"> + <span id="lock-icon" class="weak-color" style="padding:0 .5em;margin-right:.5em;[n.hidden_if.not.page_node.is_locked_topic/]"> + <img src="/images/lock_sm.png" width="10" height="15" style="vertical-align:middle"/> <t>Locked</t> + </span> +</macro> + +<macro name="lock_topic_link" requires="node" dot_parameter="text" parameters="title, class"> + <n.put_in_head.> + <script type="text/javascript"> + Nabble.lockTopic = function(id) { + var call = '/'+'template/NamlServlet.jtp?macro=lock_topic&node=' + id; + $.getScript(call, function() { + $('#lock-icon').show(); + NabbleDropdown.show('unlockTopic'); + NabbleDropdown.hide('lockTopic'); + alert('<t>This topic has been locked.</t>'); + }); + }; + </script> + </n.put_in_head.> + <a href="javascript: void Nabble.lockTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Lock topic[/t]"><n.text/></n.default.></a> +</macro> + +<macro name="lock_topic" requires="servlet"> + <n.node_page.> + <n.if.both condition1="[n.visitor.can_manage_locked_topics_in.page_node/]" condition2="[n.not.page_node.is_locked_topic/]"> + <then.edit_page_node.> + <n.add_permission permission="[n.reply_permission/]"/> + </then.edit_page_node.> + </n.if.both> + </n.node_page.> +</macro> + +<macro name="unlock_topic_link" requires="node" dot_parameter="text" parameters="title, class"> + <n.put_in_head.> + <script type="text/javascript"> + Nabble.unlockTopic = function(id) { + var call = '/'+'template/NamlServlet.jtp?macro=unlock_topic&node=' + id; + $.getScript(call, function() { + $('#lock-icon').hide(); + NabbleDropdown.hide('unlockTopic'); + NabbleDropdown.show('lockTopic'); + alert('<t>This topic has been unlocked.</t>'); + }); + }; + </script> + </n.put_in_head.> + <a href="javascript: void Nabble.unlockTopic([n.id/])" class="[n.class/]" rel="nofollow" title="[n.title/]"><n.default. to="[t]Unlock topic[/t]"><n.text/></n.default.></a> +</macro> + +<macro name="unlock_topic" requires="servlet"> + <n.node_page.> + <n.if.both condition1="[n.visitor.can_manage_locked_topics_in.page_node/]" condition2="[n.page_node.is_locked_topic/]"> + <then.edit_page_node.> + <n.remove_permission permission="[n.reply_permission/]"/> + </then.edit_page_node.> + </n.if.both> + </n.node_page.> +</macro> + +<macro name="is_locked_topic" requires="node"> + <n.both> + <condition1.node_has_permission.reply_permission /> + <condition2.not.groups_have_permission groups="[n.registered_user_groups/]" permission="[n.reply_permission/]" /> + </n.both> +</macro> + +<macro name="smart_post_link" requires="node" dot_parameter="href" parameters="text, title, class"> + <n.if.is_post> + <then> + <a href="[n.node_href.href/]" title="[n.title/]" class="[n.hide_null.class/] post-link[n.topic_node.id/]" node-id="[n.id/]"><n.node_text.text/></a> + <n.call_later value="[n.topic_node.id/]" param="markUnreadTopics"/> + </then> + <else.node_link text="[n.text/]"/> + </n.if.is_post> +</macro> + +<macro name="mark_unread_topics_js"> + <n.if.visitor.is_registered> + <then> + <![CDATA[ + $('#nabble').append('<a id="not-visited" class="invisible" href="/any-url">x</a> <a id="visited" class="visited-link invisible" href="#">x</a>'); + var notVisitedColor = $('#not-visited').css('color'); + var visitedColor = $('#visited').css('color'); + Nabble.markUnreadTopics = function(topic, lastVisitedId) { + $('a.post-link'+topic).each(function() { + var nodeId = $(this).attr('node-id'); + var isVisited = lastVisitedId && lastVisitedId > 0 && parseInt(nodeId) <= lastVisitedId; + if (isVisited) + $(this).addClass('visited-link'); + else { + var $this = $(this); + $this + .css('color', notVisitedColor) + .click(function() { + $this.css('color',visitedColor); + }); + } + }); + }; + ]]> + <n.param_loop. param="markUnreadTopics"> + <n.set_var. name='last_visited_id'> + <n.if.visitor.has_visited_node node_id="[n.current_parameter_value/]"> + <then.visitor.last_visited_node. node_id="[n.current_parameter_value/]"> + <n.id/> + </then.visitor.last_visited_node.> + <else>null</else> + </n.if.visitor.has_visited_node> + </n.set_var.> + Nabble.markUnreadTopics(<n.current_parameter_value/>, <n.var name='last_visited_id'/>); + </n.param_loop.> + </then> + </n.if.visitor.is_registered> +</macro>