diff --git a/modules/CommentItem.js b/modules/CommentItem.js index b12a12763..c5f76e70c 100644 --- a/modules/CommentItem.js +++ b/modules/CommentItem.js @@ -42,6 +42,17 @@ CommentItem.prototype.getHeading = function () { return parent; }; +/** + * @return {HeadingItem|null} losest heading that can be used for topic subscriptions + */ +CommentItem.prototype.getSubscribableHeading = function () { + var heading = this.getHeading(); + while ( heading && heading.type === 'heading' && !heading.isSubscribable() ) { + heading = heading.parent; + } + return ( heading && heading.type === 'heading' ) ? heading : null; +}; + // TODO: Implement getBodyRange/getBodyHTML/getBodyText/getMentions if required module.exports = CommentItem; diff --git a/modules/HeadingItem.js b/modules/HeadingItem.js index 03aff5a39..d84a95811 100644 --- a/modules/HeadingItem.js +++ b/modules/HeadingItem.js @@ -45,4 +45,22 @@ HeadingItem.prototype.getHeading = function () { return this; }; +/** + * Check whether this heading can be used for topic subscriptions. + * + * @return {boolean} + */ +HeadingItem.prototype.isSubscribable = function () { + return ( + // Placeholder headings have nothing to attach the button to. + !this.placeholderHeading && + // We only allow subscribing to level 2 headings, because the user interface for sub-headings + // would be difficult to present. + this.headingLevel === 2 && + // Check if the name corresponds to a section that contain no comments (only sub-sections). + // They can't be distinguished from each other, so disallow subscribing. + this.name !== 'h-' + ); +}; + module.exports = HeadingItem; diff --git a/modules/controller.js b/modules/controller.js index bc297b5a7..8fd7f8a53 100644 --- a/modules/controller.js +++ b/modules/controller.js @@ -8,7 +8,6 @@ var storage = mw.storage.session, Parser = require( './Parser.js' ), ThreadItem = require( './ThreadItem.js' ), - HeadingItem = require( './HeadingItem.js' ), CommentItem = require( './CommentItem.js' ), CommentDetails = require( './CommentDetails.js' ), ReplyLinksController = require( './ReplyLinksController.js' ), @@ -862,14 +861,13 @@ function init( $container, state ) { } } } - for ( i = 0; i < recentComments.length; i++ ) { - var headingItem = recentComments[ i ].getHeading(); - while ( headingItem instanceof HeadingItem && headingItem.headingLevel !== 2 ) { - headingItem = headingItem.parent; + recentComments.forEach( function ( recentComment ) { + var headingItem = recentComment.getSubscribableHeading(); + if ( headingItem ) { + // Use names as object keys to deduplicate if there are multiple comments in a topic. + headingsToUpdate[ headingItem.name ] = headingItem; } - // Use names as object keys to deduplicate if there are multiple comments in a topic. - headingsToUpdate[ headingItem.name ] = headingItem; - } + } ); updateSubscriptionStates( $container, headingsToUpdate ); } } );