Merge "rdbms: make transaction rounds apply DBO_TRX to DB_REPLICA connections"
[mediawiki.git] / resources / src / mediawiki.special.preferences.ooui / mobile.js
blobec96c03ec4bb7ba9050b0211fb573b5ad9e75ca5
1 /*!
2  * JavaScript for Special:Preferences: mobileLayout.
3  */
4 ( function () {
5         const nav = require( './nav.js' );
6         nav.insertHints( mw.msg( 'prefs-sections-navigation-hint' ) );
8         // Define a window manager to control the dialogs
9         const dialogFactory = new OO.Factory();
10         const windowManager = new OO.ui.WindowManager( { factory: dialogFactory } );
11         windowManager.on( 'opening', ( win ) => {
12                 if ( !win.$body.data( 'mw-section-infused' ) ) {
13                         win.$body.removeClass( 'mw-htmlform-autoinfuse-lazy' );
14                         mw.hook( 'htmlform.enhance' ).fire( win.$body );
15                         win.$body.data( 'mw-section-infused', true );
16                 }
17         } );
19         // Navigation callback
20         const setSection = function ( sectionName, fieldset ) {
21                 // strip possible prefixes from the section to normalize it
22                 const section = sectionName.replace( 'mw-prefsection-', '' ).replace( 'mw-mobile-prefs-', '' );
23                 const win = windowManager.getCurrentWindow();
24                 if ( win && win.constructor.static.name !== 'mw-mobile-prefs-' + section ) {
25                         windowManager.closeWindow( win );
26                 }
27                 // Work in the window isn't necessarily done when 'then` fires
28                 windowManager.openWindow( 'mw-mobile-prefs-' + section ).opened.then( () => {
29                         // Scroll to a fieldset if provided.
30                         if ( fieldset ) {
31                                 // setTimout is ie11-compatible and queues up tasks for async exec
32                                 setTimeout( () => {
33                                         fieldset.scrollIntoView( { behavior: 'smooth' } );
34                                 } );
35                         }
36                 } );
37                 if ( nav.switchingNoHash ) {
38                         return;
39                 }
40                 location.hash = '#mw-prefsection-' + section;
41         };
43         /*
44          * Configure and register a dialog for a pref section
45          */
46         function createSectionDialog( sectionId, sectionTitle, sectionBody ) {
47                 function PrefDialog() {
48                         const conf = { classes: [ 'overlay-content', 'mw-mobile-pref-window' ] };
49                         PrefDialog.super.call( this, conf );
50                 }
52                 OO.inheritClass( PrefDialog, OO.ui.ProcessDialog );
53                 PrefDialog.static.name = sectionId;
54                 PrefDialog.static.escapable = true;
55                 PrefDialog.static.size = 'larger';
56                 PrefDialog.static.title = sectionTitle;
57                 PrefDialog.static.actions = [
58                         { action: 'cancel', label: mw.msg( 'prefs-back-title' ), flags: [ 'safe', 'close' ] }
59                 ];
60                 PrefDialog.prototype.initialize = function () {
61                         this.name = sectionId;
62                         PrefDialog.super.prototype.initialize.call( this );
63                         this.$body.append( sectionBody );
64                         this.content = new OO.ui.PanelLayout( { padded: true, expanded: true } );
65                         this.$body.addClass( 'mw-mobile-pref-dialog-body' );
66                 };
67                 PrefDialog.prototype.getActionProcess = function ( action ) {
68                         if ( action ) {
69                                 return new OO.ui.Process( () => {
70                                         this.close( { action: action } );
71                                 } );
72                         }
73                         return PrefDialog.super.prototype.getActionProcess.call( this, action );
74                 };
76                 dialogFactory.register( PrefDialog );
77         }
79         /*
80          * Initialize Dialogs for all pref sections
81          */
82         function initDialogs() {
83                 // Query the document once, then query that returned element afterwards.
84                 const preferencesForm = document.getElementById( 'mw-prefs-form' );
85                 const prefButtons = preferencesForm.querySelector( '.mw-htmlform-submit-buttons' );
86                 const sections = preferencesForm.querySelectorAll( '.mw-mobile-prefsection' );
88                 // Move the form buttons (such as save) into the dialog after opening.
89                 windowManager.on( 'opening', ( win, opened ) => {
90                         if ( opened ) {
91                                 win.$foot[ 0 ].appendChild( prefButtons );
92                         }
93                 } );
94                 // Move the form buttons (such as save) back to the main form while closing.
95                 windowManager.on( 'closing', ( _win, closed ) => {
96                         document.getElementById( 'preferences' ).appendChild( prefButtons );
97                         if ( closed ) {
98                                 location.hash = '';
99                         }
100                 } );
101                 // Add the window manager to the form
102                 $( preferencesForm ).append( windowManager.$element );
103                 // Add event listeners and register a dialog for each section
104                 Array.prototype.forEach.call( sections, ( section ) => {
105                         const sectionContent = document.getElementById( section.id + '-content' );
106                         const sectionBody = sectionContent.querySelector( 'div > div.oo-ui-widget' );
107                         const sectionText = sectionContent.querySelector( '.mw-prefs-title' ).textContent;
108                         createSectionDialog( section.id, sectionText, sectionBody );
109                 } );
110                 const prefSelect = OO.ui.infuse( $( '.mw-mobile-prefs-sections' ) );
111                 prefSelect.aggregate( {
112                         click: 'itemClick'
113                 } );
114                 prefSelect.on( 'itemClick', ( button ) => {
115                         setSection( button.getData() );
116                 } );
118         }
119         // DOM-dependant code
120         $( () => {
121                 initDialogs();
122                 nav.onLoad( setSection );
123         } );
124 }() );