/* global moment */ var api, seenAutoTopicSubPopup = !!+mw.user.options.get( 'discussiontools-seenautotopicsubpopup' ), STATE_UNSUBSCRIBED = 0, STATE_SUBSCRIBED = 1, STATE_AUTOSUBSCRIBED = 2, utils = require( './utils.js' ), CommentItem = require( './CommentItem.js' ), ThreadItem = require( './ThreadItem.js' ), linksByName = {}; /** * Update a subscribe link * * @param {HTMLElement} element Subscribe link * @param {number|null} state State constant (STATE_UNSUBSCRIBED, STATE_SUBSCRIBED or STATE_AUTOSUBSCRIBED) */ function updateSubscribeLink( element, state ) { if ( state !== null ) { element.setAttribute( 'data-mw-subscribed', String( state ) ); } if ( state ) { element.textContent = mw.msg( 'discussiontools-topicsubscription-button-unsubscribe' ); element.setAttribute( 'title', mw.msg( 'discussiontools-topicsubscription-button-unsubscribe-tooltip' ) ); } else { element.textContent = mw.msg( 'discussiontools-topicsubscription-button-subscribe' ); element.setAttribute( 'title', mw.msg( 'discussiontools-topicsubscription-button-subscribe-tooltip' ) ); } } function changeSubscription( title, commentName, subscribe ) { var promise = api.postWithToken( 'csrf', { action: 'discussiontoolssubscribe', page: title, commentname: commentName, subscribe: subscribe } ).then( function ( response ) { return OO.getProp( response, 'discussiontoolssubscribe' ) || {}; } ); promise.then( function ( result ) { mw.notify( mw.msg( result.subscribe ? 'discussiontools-topicsubscription-notify-subscribed-body' : 'discussiontools-topicsubscription-notify-unsubscribed-body' ), { title: mw.msg( result.subscribe ? 'discussiontools-topicsubscription-notify-subscribed-title' : 'discussiontools-topicsubscription-notify-unsubscribed-title' ) } ); }, function ( code, data ) { mw.notify( api.getErrorMessage( data ), { type: 'error' } ); } ); return promise; } function getSubscribedStateFromElement( element ) { return element.hasAttribute( 'data-mw-subscribed' ) ? Number( element.getAttribute( 'data-mw-subscribed' ) ) : null; } function getTitleFromHeading( heading ) { var section = utils.getHeadlineNodeAndOffset( heading ).node.id; return mw.config.get( 'wgRelevantPageName' ) + '#' + section; } /** * Get a HeadingItem from a heading element wrapper * * @param {Element} heading Heading element * @return {ThreadItem|null} ThreadItem, null if not found */ function getHeadingItemFromHeading( heading ) { var dataNode = heading.querySelector( '[data-mw-comment]' ); if ( dataNode ) { var hash = JSON.parse( dataNode.getAttribute( 'data-mw-comment' ) ); return ThreadItem.static.newFromJSON( hash ); } return null; } /** * Initialize topic subscriptions feature * * @param {jQuery} $container Page container */ function initTopicSubscriptions( $container ) { linksByName = {}; // Loads later to avoid circular dependency api = require( './controller.js' ).getApi(); // Subscription links (no visual enhancements) $container.find( '.ext-discussiontools-init-section-subscribe-link' ).each( function () { var $link = $( this ); var heading = $link.closest( '.ext-discussiontools-init-section' )[ 0 ]; var headingItem = getHeadingItemFromHeading( heading ); if ( !headingItem ) { // This should never happen return; } var itemName = headingItem.name; if ( !itemName ) { // Cached HTML may not contain item names for a short period. Assume the old // data-mw-comment-name markers are present instead. // This code branch can be removed a week or two after release. itemName = this.getAttribute( 'data-mw-comment-name' ); if ( !itemName ) { // This should never happen return; } } var title = getTitleFromHeading( heading ); linksByName[ itemName ] = this; $link.on( 'click keypress', function ( e ) { if ( e.type === 'keypress' && e.which !== OO.ui.Keys.ENTER && e.which !== OO.ui.Keys.SPACE ) { // Only handle keypresses on the "Enter" or "Space" keys return; } if ( e.type === 'click' && !utils.isUnmodifiedLeftClick( e ) ) { // Only handle unmodified left clicks return; } e.preventDefault(); // Get latest subscribedState var subscribedState = getSubscribedStateFromElement( $link[ 0 ] ); $link.addClass( 'ext-discussiontools-init-section-subscribe-link-pending' ); changeSubscription( title, itemName, !subscribedState ) .then( function ( result ) { updateSubscribeLink( $link[ 0 ], result.subscribe ? STATE_SUBSCRIBED : STATE_UNSUBSCRIBED ); } ) .always( function () { $link.removeClass( 'ext-discussiontools-init-section-subscribe-link-pending' ); } ); } ); } ); } /** * Show the first time popup for auto topic subscriptions, if required */ function maybeShowFirstTimeAutoTopicSubPopup() { var lastHighlightComment = require( './highlighter.js' ).getLastHighlightedPublishedComment(); if ( !lastHighlightComment || seenAutoTopicSubPopup ) { return; } seenAutoTopicSubPopup = true; mw.user.options.set( 'discussiontools-seenautotopicsubpopup', '1' ); api.saveOption( 'discussiontools-seenautotopicsubpopup', '1' ); var $popupContent, popup; function close() { popup.$element.removeClass( 'ext-discussiontools-autotopicsubpopup-fadein' ); setTimeout( function () { popup.$element.detach(); }, 1000 ); } $popupContent = $( '