2019-09-18 23:07:21 +00:00
|
|
|
/**
|
|
|
|
* @param {Object} mobile mobileFrontend component library
|
|
|
|
*/
|
|
|
|
module.exports = function ( mobile ) {
|
2019-02-07 16:34:18 +00:00
|
|
|
var
|
2019-10-17 22:46:07 +00:00
|
|
|
SKIN_MINERVA_TALK_SIMPLIFIED_CLASS = 'skin-minerva--talk-simplified',
|
2019-09-18 03:07:48 +00:00
|
|
|
toast = mobile.toast,
|
|
|
|
currentPage = mobile.currentPage(),
|
2019-02-25 20:52:18 +00:00
|
|
|
api = new mw.Api(),
|
2019-09-05 23:52:27 +00:00
|
|
|
overlayManager = mobile.OverlayManager.getSingleton(),
|
2019-07-02 21:10:10 +00:00
|
|
|
// FIXME: This dependency shouldn't exist
|
2019-07-17 18:14:23 +00:00
|
|
|
skin = mobile.Skin.getSingleton(),
|
2019-11-25 13:08:42 +00:00
|
|
|
talkTitle = currentPage.titleObj.getTalkPage() ?
|
|
|
|
currentPage.titleObj.getTalkPage().getPrefixedText() :
|
|
|
|
undefined;
|
2017-07-12 15:12:40 +00:00
|
|
|
|
2019-10-17 22:46:07 +00:00
|
|
|
/**
|
|
|
|
* Render a type of talk overlay
|
|
|
|
* @param {string} className name of talk overlay to create
|
|
|
|
* @param {Object} talkOptions
|
|
|
|
* @return {Overlay|JQuery.Promise}
|
|
|
|
*/
|
|
|
|
function createOverlay( className, talkOptions ) {
|
|
|
|
// eslint-disable-next-line no-restricted-properties
|
|
|
|
var M = mw.mobileFrontend;
|
2017-07-12 15:12:40 +00:00
|
|
|
|
2019-11-19 17:58:28 +00:00
|
|
|
return new ( M.require( 'mobile.talk.overlays/' + className ) )( talkOptions );
|
2017-09-28 20:06:39 +00:00
|
|
|
}
|
|
|
|
|
2019-11-19 17:58:28 +00:00
|
|
|
/**
|
|
|
|
* Cleanup the listeners previously added in initTalkSection
|
|
|
|
* so that events like clicking on a section) won't cause
|
|
|
|
* scroll changes/things only needed for the simplified view.
|
|
|
|
* Also restore ids for table of contents.
|
|
|
|
*/
|
|
|
|
function restoreSectionHeadings() {
|
2019-10-17 22:46:07 +00:00
|
|
|
// eslint-disable-next-line no-jquery/no-global-selector
|
|
|
|
$( '.section-heading' ).each( function () {
|
2019-11-19 17:58:28 +00:00
|
|
|
var $heading = $( this ),
|
|
|
|
$headline = $heading.find( '.mw-headline' );
|
2019-10-17 22:46:07 +00:00
|
|
|
$heading.off( 'click.talkSectionOverlay' );
|
2019-11-19 17:58:28 +00:00
|
|
|
// restore for table of contents:
|
|
|
|
$headline.attr( 'id', $headline.data( 'id' ) );
|
2019-10-17 22:46:07 +00:00
|
|
|
} );
|
2017-07-12 15:12:40 +00:00
|
|
|
}
|
|
|
|
|
2019-07-24 22:05:35 +00:00
|
|
|
/**
|
2019-10-17 22:46:07 +00:00
|
|
|
* @param {JQuery.Element} $heading
|
|
|
|
* @param {JQuery.Element} $headline
|
|
|
|
* @param {string} sectionId
|
|
|
|
* @return {JQuery.Promise} A promise that rejects if simplified mode is off.
|
|
|
|
* A promise that resolves to the TalkSectionOverlay otherwise (unless a
|
|
|
|
* network error occurs).
|
2019-07-24 22:05:35 +00:00
|
|
|
*/
|
2019-10-17 22:46:07 +00:00
|
|
|
function createTalkSectionOverlay( $heading, $headline, sectionId ) {
|
|
|
|
if ( !isSimplifiedViewEnabled() ) {
|
|
|
|
// If the simplified view is not enabled, we don't want to show the
|
|
|
|
// talk section overlay (e.g. when user clicks on a link in TOC)
|
|
|
|
return mobile.util.Deferred().reject();
|
2019-07-24 22:05:35 +00:00
|
|
|
}
|
2019-10-17 22:46:07 +00:00
|
|
|
|
2019-11-19 17:58:28 +00:00
|
|
|
return createOverlay( 'TalkSectionOverlay', {
|
|
|
|
id: sectionId,
|
|
|
|
section: new mobile.Section( {
|
2019-12-13 00:51:53 +00:00
|
|
|
line: $headline.html(),
|
2019-11-19 17:58:28 +00:00
|
|
|
text: $heading.next().html()
|
|
|
|
} ),
|
|
|
|
// FIXME: Replace this api param with onSaveComplete
|
|
|
|
api: api,
|
|
|
|
title: talkTitle,
|
|
|
|
// T184273 using `currentPage` because 'wgPageName'
|
|
|
|
// contains underscores instead of spaces.
|
|
|
|
licenseMsg: skin.getLicenseMsg(),
|
|
|
|
onSaveComplete: function () {
|
|
|
|
toast.showOnPageReload( mw.message( 'minerva-talk-reply-success' ).text() );
|
|
|
|
window.location.reload();
|
|
|
|
}
|
|
|
|
} );
|
2019-10-17 22:46:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes code needed to display the TalkSectionOverlay
|
|
|
|
*/
|
|
|
|
function initTalkSection() {
|
|
|
|
// register route for each of the sub-headings
|
|
|
|
// eslint-disable-next-line no-jquery/no-global-selector
|
|
|
|
$( '.section-heading' ).each( function () {
|
|
|
|
var
|
|
|
|
sectionId,
|
|
|
|
$heading = $( this ),
|
|
|
|
$headline = $heading.find( '.mw-headline' ),
|
|
|
|
sectionIdMatch = $heading.next().attr( 'class' ).match( /mf-section-(\d+)/ ),
|
2020-01-15 00:06:17 +00:00
|
|
|
headlineId = $headline.attr( 'id' ),
|
|
|
|
// T238364: Before registering a route with OverlayManager, we need to
|
|
|
|
// encode the id first to ensure it forms a valid URI in case the id
|
|
|
|
// contains illegal URI characters as defined by RFC3986. This avoids
|
|
|
|
// inconsistencies with how different browsers encode illegal URI
|
|
|
|
// characters.
|
|
|
|
encodedHeadlineId = encodeURIComponent( headlineId );
|
2019-10-17 22:46:07 +00:00
|
|
|
|
|
|
|
if ( sectionIdMatch === null || sectionIdMatch.length !== 2 ) {
|
|
|
|
// If section id couldn't be parsed, there is no point in continuing
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
sectionId = sectionIdMatch[ 1 ];
|
|
|
|
|
|
|
|
$heading.on( 'click.talkSectionOverlay', function ( ev ) {
|
|
|
|
ev.preventDefault();
|
2020-01-15 00:06:17 +00:00
|
|
|
window.location.hash = '#' + encodedHeadlineId;
|
2019-10-17 22:46:07 +00:00
|
|
|
|
|
|
|
} );
|
|
|
|
|
2019-11-19 17:58:28 +00:00
|
|
|
// remove the `id` to avoid conflicts with the overlay route.
|
|
|
|
// Without JS the id will still be present. With JS the overlay will open.
|
|
|
|
$headline.removeAttr( 'id' );
|
|
|
|
// however cache it to data for cooperation with the 'read as wiki page' button.
|
|
|
|
$headline.data( 'id', headlineId );
|
|
|
|
|
2020-01-15 00:06:17 +00:00
|
|
|
overlayManager.add( encodedHeadlineId, function () {
|
2019-10-17 22:46:07 +00:00
|
|
|
return createTalkSectionOverlay( $heading, $headline, sectionId );
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes code needed to display the TalkSectionAddOverlay
|
|
|
|
*/
|
|
|
|
function initTalkSectionAdd() {
|
|
|
|
overlayManager.add( /^\/talk\/new$/, function () {
|
|
|
|
return createOverlay( 'TalkSectionAddOverlay', {
|
2019-02-21 23:20:45 +00:00
|
|
|
api: api,
|
2019-10-17 22:46:07 +00:00
|
|
|
title: talkTitle,
|
2019-07-11 00:56:04 +00:00
|
|
|
// T184273 using `currentPage` because 'wgPageName'
|
2019-02-21 23:20:45 +00:00
|
|
|
// contains underscores instead of spaces.
|
|
|
|
licenseMsg: skin.getLicenseMsg(),
|
2019-10-17 22:46:07 +00:00
|
|
|
|
|
|
|
currentPageTitle: currentPage.title,
|
|
|
|
onSaveComplete: function () {
|
2019-10-24 21:17:18 +00:00
|
|
|
toast.showOnPageReload( mw.message( 'minerva-talk-topic-feedback' ).text() );
|
|
|
|
window.location = currentPage.titleObj.getTalkPage().getUrl();
|
2019-10-17 22:46:07 +00:00
|
|
|
}
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* T230695: In the simplified view, we need to display a "Read as wikipage"
|
|
|
|
* button which enables the user to switch from simplified mode to the regular
|
|
|
|
* version of the mobile talk page (with TOC and sections that you can
|
|
|
|
* expand/collapse).
|
|
|
|
*/
|
|
|
|
function renderReadAsWikiPageButton() {
|
|
|
|
$( '<button>' )
|
|
|
|
.addClass( 'minerva-talk-full-page-button' )
|
|
|
|
.text( mw.message( 'minerva-talk-full-page' ).text() )
|
|
|
|
.on( 'click', function () {
|
2019-11-19 17:58:28 +00:00
|
|
|
restoreSectionHeadings();
|
2020-01-06 13:03:52 +00:00
|
|
|
$( document.body ).removeClass( 'skin-minerva--talk-simplified' );
|
2019-10-17 22:46:07 +00:00
|
|
|
$( this ).remove();
|
|
|
|
// send user back up to top of page so they don't land awkwardly in
|
|
|
|
// middle of page when it expands
|
|
|
|
window.scrollTo( 0, 0 );
|
|
|
|
} )
|
|
|
|
.appendTo( '#content' );
|
2019-09-18 03:07:48 +00:00
|
|
|
}
|
|
|
|
|
2017-07-12 15:12:40 +00:00
|
|
|
/**
|
2019-10-17 22:46:07 +00:00
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
function isSimplifiedViewEnabled() {
|
2020-01-06 13:03:52 +00:00
|
|
|
// eslint-disable-next-line no-jquery/no-class-state
|
|
|
|
return $( document.body ).hasClass( SKIN_MINERVA_TALK_SIMPLIFIED_CLASS );
|
2019-10-17 22:46:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets up necessary event handlers related to the talk page and talk buttons.
|
|
|
|
* Also renders the "Read as wikipage" button for the simplified mode
|
|
|
|
* (T230695).
|
2017-07-12 15:12:40 +00:00
|
|
|
*/
|
|
|
|
function init() {
|
2019-11-19 17:58:28 +00:00
|
|
|
var promise,
|
2019-10-17 22:46:07 +00:00
|
|
|
// eslint-disable-next-line no-jquery/no-global-selector
|
|
|
|
$addTalk = $( '.minerva-talk-add-button' );
|
|
|
|
|
2020-01-14 18:49:58 +00:00
|
|
|
$addTalk.on( 'click', function ( ev ) {
|
|
|
|
// avoid navigating to original URL in anchor element
|
|
|
|
ev.preventDefault();
|
|
|
|
window.location.hash = '#/talk/new';
|
|
|
|
} );
|
2019-10-17 22:46:07 +00:00
|
|
|
|
|
|
|
// We only want the talk section add overlay to show when the user is on the
|
|
|
|
// view action (default action) of the talk page and not when the user is on
|
|
|
|
// other actions of the talk page (e.g. like the history action)
|
|
|
|
if ( currentPage.titleObj.isTalkPage() && mw.config.get( 'wgAction' ) === 'view' ) {
|
2019-11-19 17:58:28 +00:00
|
|
|
promise = mw.loader.using( 'mobile.talk.overlays' )
|
|
|
|
.then( initTalkSectionAdd );
|
|
|
|
} else {
|
|
|
|
return;
|
2019-10-17 22:46:07 +00:00
|
|
|
}
|
2019-11-19 17:58:28 +00:00
|
|
|
|
2019-10-17 22:46:07 +00:00
|
|
|
// SkinMinerva sets a class on the body which effectively controls when this
|
|
|
|
// mode is on
|
|
|
|
if ( isSimplifiedViewEnabled() ) {
|
2019-11-19 17:58:28 +00:00
|
|
|
promise.then( initTalkSection )
|
|
|
|
.then( renderReadAsWikiPageButton );
|
2019-10-17 22:46:07 +00:00
|
|
|
}
|
2017-07-12 15:12:40 +00:00
|
|
|
}
|
|
|
|
|
2019-11-25 13:08:42 +00:00
|
|
|
if ( talkTitle ) {
|
|
|
|
init();
|
|
|
|
}
|
2019-09-18 23:07:21 +00:00
|
|
|
};
|