mediawiki-skins-MinervaNeue/resources/skins.minerva.scripts/talk.js

173 lines
5.2 KiB
JavaScript
Raw Normal View History

/**
* @param {Object} mobile mobileFrontend component library
*/
module.exports = function ( mobile ) {
var
toast = mobile.toast,
currentPage = mobile.currentPage(),
loader = mobile.rlModuleLoader,
loadingOverlay = mobile.loadingOverlay,
eventBus = mobile.eventBusSingleton,
PageGateway = mobile.PageGateway,
api = new mw.Api(),
gateway = new PageGateway( api ),
// eslint-disable-next-line no-jquery/no-global-selector
$talk = $( '.talk, [rel="discussion"]' ),
// use the plain return value here - T128273
title = $talk.attr( 'data-title' ),
overlayManager = mobile.OverlayManager.getSingleton(),
// FIXME: This dependency shouldn't exist
skin = mobile.Skin.getSingleton(),
inTalkNamespace = false,
pageTitle, talkTitle, talkNs, pageNs;
// T127190
if ( title ) {
title = decodeURIComponent( title );
}
// sanity check: the talk namespace needs to have the next higher integer
// of the page namespace (the api should add topics only to the talk page of the current
// page)
// (https://www.mediawiki.org/wiki/Manual:Using_custom_namespaces#Creating_a_custom_namespace)
// The method to get associated namespaces will change later (maybe), see T487
pageTitle = mw.Title.newFromText( mw.config.get( 'wgRelevantPageName' ) );
talkTitle = title ? mw.Title.newFromText( title ) : pageTitle.getTalkPage();
// Check that there is a valid page and talk title
if ( !pageTitle || !talkTitle ||
// the talk link points to something other than the current page
// so we chose to leave this as a normal link
pageTitle.getMainText() !== talkTitle.getMainText() ) {
return;
}
talkNs = talkTitle.getNamespaceId();
pageNs = pageTitle.getNamespaceId();
inTalkNamespace = talkNs === pageNs;
if ( pageNs + 1 !== talkNs && !inTalkNamespace ) {
return;
}
/**
* Render a talk overlay for a given section
* @param {string} id (a number e.g. '1' or the string 'new')
* @param {Object} talkOptions
* @return {Overlay}
*/
function talkSectionOverlay( id, talkOptions ) {
// eslint-disable-next-line no-restricted-properties
var M = mw.mobileFrontend;
if ( id === 'new' ) {
return new ( M.require( 'mobile.talk.overlays/TalkSectionAddOverlay' ) )( talkOptions );
}
return new ( M.require( 'mobile.talk.overlays/TalkSectionOverlay' ) )( talkOptions );
}
overlayManager.add( /^\/talk\/?(.*)$/, function ( id ) {
var title = talkTitle.toText(),
talkOptions = {
api: api,
title: title,
onSaveComplete: function () {
gateway.invalidatePage( title );
// navigate back. the overlay is done with so close it
overlayManager.router.back();
try {
overlayManager.replaceCurrent(
mobile.talk.overlay( title, gateway )
);
overlayManager.router.navigateTo( null, {
// This should be defined in Minerva.
path: '#/talk',
useReplaceState: true
} );
} catch ( e ) {
// the user came directly - there is no overlay to replace
// so no overlay to refresh
}
mw.notify( mw.msg( 'mobile-frontend-talk-topic-feedback' ) );
},
Make Minerva use new PageHTMLParser.js and refactored Page.js In I02f8645aac1d7b081eaba8f2ac92a2ef51f78182, Page.js was made into a model and its html parsing responsibilities were moved to PageHTMLParser. Additionally, a singleton for the current page (currentPage.js) and a singleton for the curent page html parser (currentPageHTMLParser.js) were introduced to replace the usage of M.getCurrentPage(). This commit refactors Minerva to make use of these changes. Notable changes: * 🐛 The event bus singleton was added to references.js since it previously relied on an instance of Skin to listen for the `references-loaded` event. However, this event is emitted on the event bus singleton. * Additionally, I didn't see a reason why the `references-loaded` event needed to also pass the current page instance when the only file listening to it is references.js (which already has the current page instance) so I removed that and the convoluted passing of page.js within the file. I assumed this logic was unecessary. * The call to drawer.showReferences in references.js now was made to pass the currentPage instance as well as the currentPageHTMLParser. This is to prepare for I6e858bbe73f83166476b5b2c0fdac1cca7404246 where the getReferences() interface for ReferencesMobileViewGateway.js and ReferencesHtmlScraperGateway.js is refactored to accept both of these instances. Additionally, references.js was refactored to support event delegation which gets rid of some parsing/setup logic. Bug: T193077 Depends-On: I02f8645aac1d7b081eaba8f2ac92a2ef51f78182 Change-Id: I2f32dbcc4ebaa4bebb297cda1ecce3457922b343
2019-07-11 00:56:04 +00:00
// T184273 using `currentPage` because 'wgPageName'
// contains underscores instead of spaces.
currentPageTitle: currentPage.title,
licenseMsg: skin.getLicenseMsg(),
eventBus: eventBus,
id: id
};
// talk case
if ( id ) {
// If the module is already loaded return it instantly and synchronously.
// this avoids a flash of
// content when transitioning from mobile.talk.overlay to this overlay (T221978)
return mw.loader.getState( 'mobile.talk.overlays' ) === 'ready' ?
talkSectionOverlay( id, talkOptions ) :
// otherwise pull it from ResourceLoader async
loader.loadModule( 'mobile.talk.overlays' ).then( function () {
return talkSectionOverlay( id, talkOptions );
} );
} else {
return mobile.talk.overlay( title, gateway );
}
} );
function changeHash() {
// eslint-disable-next-line no-jquery/no-class-state
if ( $talk.hasClass( 'add' ) ) {
window.location.hash = '#/talk/new';
} else {
window.location.hash = '#/talk';
}
}
/**
* @method
* @param {JQuery.Event} ev
* @return {undefined}
*/
function amcTalkClickHandler( ev ) {
var
amcOutreach = mobile.amcOutreach,
amcCampaign = amcOutreach.loadCampaign(),
onDismiss = function () {
changeHash();
toast.show( mw.message( 'mobile-frontend-amc-outreach-dismissed-message' ).text() );
};
// avoiding navigating to original URL
// DO NOT USE stopPropagation or you'll break click tracking in WikimediaEvents
ev.preventDefault();
if ( amcCampaign.showIfEligible( amcOutreach.ACTIONS.onTalkLink, onDismiss, currentPage.title, '#/talk' ) ) {
return;
}
changeHash();
}
/**
* Create route '#/talk'
* @ignore
*/
function init() {
$talk.on( 'click', amcTalkClickHandler );
}
init();
if ( inTalkNamespace ) {
// reload the page after the new discussion was added
eventBus.on( 'talk-added-wo-overlay', function () {
var overlay = loadingOverlay();
window.location.hash = '';
// setTimeout to make sure, that loadingOverlay's overlayenabled class on html doesnt
// get removed by OverlayManager (who closes TalkSectionAddOverlay).
window.setTimeout( function () {
overlay.show();
window.location.reload();
}, 10 );
} );
}
};