/*! * VisualEditor user interface MWAdvancedSettingsPage class. * * @copyright See AUTHORS.txt * @license The MIT License (MIT); see LICENSE.txt */ /** * MediaWiki meta dialog advanced settings page. * * @class * @extends OO.ui.PageLayout * * @constructor * @param {string} name Unique symbolic name of page * @param {Object} [config] Configuration options * @param {jQuery} [config.$overlay] Overlay to render dropdowns in */ ve.ui.MWAdvancedSettingsPage = function VeUiMWAdvancedSettingsPage( name, config ) { // Parent constructor ve.ui.MWAdvancedSettingsPage.super.apply( this, arguments ); // Properties this.fragment = null; this.indexingOptionTouched = false; this.newSectionEditLinkOptionTouched = false; this.advancedSettingsFieldset = new OO.ui.FieldsetLayout( { label: ve.msg( 'visualeditor-dialog-meta-advancedsettings-label' ), icon: 'settings' } ); // Initialization // Indexing items this.indexing = new OO.ui.FieldLayout( new OO.ui.ButtonSelectWidget() .addItems( [ new OO.ui.ButtonOptionWidget( { data: 'mw:PageProp/index', label: ve.msg( 'visualeditor-dialog-meta-settings-index-force' ) } ), new OO.ui.ButtonOptionWidget( { data: 'default', label: ve.msg( 'visualeditor-dialog-meta-settings-index-default' ) } ), new OO.ui.ButtonOptionWidget( { data: 'mw:PageProp/noindex', label: ve.msg( 'visualeditor-dialog-meta-settings-index-disable' ) } ) ] ) .connect( this, { select: 'onIndexingOptionChange' } ), { $overlay: config.$overlay, align: 'top', label: ve.msg( 'visualeditor-dialog-meta-settings-index-label' ), help: ve.msg( 'visualeditor-dialog-meta-settings-index-help' ) } ); // New edit section link items this.newEditSectionLink = new OO.ui.FieldLayout( new OO.ui.ButtonSelectWidget() .addItems( [ new OO.ui.ButtonOptionWidget( { data: 'mw:PageProp/newsectionlink', label: ve.msg( 'visualeditor-dialog-meta-settings-newsectioneditlink-force' ) } ), new OO.ui.ButtonOptionWidget( { data: 'default', label: ve.msg( 'visualeditor-dialog-meta-settings-newsectioneditlink-default' ) } ), new OO.ui.ButtonOptionWidget( { data: 'mw:PageProp/nonewsectionlink', label: ve.msg( 'visualeditor-dialog-meta-settings-newsectioneditlink-disable' ) } ) ] ) .connect( this, { select: 'onNewSectionEditLinkOptionChange' } ), { $overlay: config.$overlay, align: 'top', label: ve.msg( 'visualeditor-dialog-meta-settings-newsectioneditlink-label' ), // eslint-disable-next-line no-jquery/no-global-selector help: ve.msg( 'visualeditor-dialog-meta-settings-newsectioneditlink-help', $( '#ca-edit' ).text() ) } ); this.displayTitleTouched = false; this.displayTitleInput = new OO.ui.TextInputWidget(); this.displayTitleInput.connect( this, { change: 'onDisplayTitleInputChange' } ); this.displayTitleField = new OO.ui.FieldLayout( this.displayTitleInput, { $overlay: config.$overlay, align: 'top', label: ve.msg( 'visualeditor-dialog-meta-settings-displaytitle' ), help: ve.msg( 'visualeditor-dialog-meta-settings-displaytitle-help' ) } ); this.advancedSettingsFieldset.addItems( [ this.indexing, this.newEditSectionLink, this.displayTitleField ] ); this.metaItemCheckboxes = []; if ( mw.config.get( 'wgVariantArticlePath' ) ) { this.metaItemCheckboxes.push( { metaName: 'mwNoContentConvert', label: ve.msg( 'visualeditor-dialog-meta-settings-nocontentconvert-label' ), help: ve.msg( 'visualeditor-dialog-meta-settings-nocontentconvert-help' ) }, { metaName: 'mwNoTitleConvert', label: ve.msg( 'visualeditor-dialog-meta-settings-notitleconvert-label' ), help: ve.msg( 'visualeditor-dialog-meta-settings-notitleconvert-help' ) } ); } this.metaItemCheckboxes.forEach( ( metaItemCheckbox ) => { metaItemCheckbox.fieldLayout = new OO.ui.FieldLayout( new OO.ui.CheckboxInputWidget(), { $overlay: config.$overlay, align: 'inline', label: metaItemCheckbox.label, help: metaItemCheckbox.help } ); this.advancedSettingsFieldset.addItems( [ metaItemCheckbox.fieldLayout ] ); } ); this.$element.append( this.advancedSettingsFieldset.$element ); }; /* Inheritance */ OO.inheritClass( ve.ui.MWAdvancedSettingsPage, OO.ui.PageLayout ); /* Methods */ /** * Handle display title input change events. * * @param {string} value Current value of input widget */ ve.ui.MWAdvancedSettingsPage.prototype.onDisplayTitleInputChange = function () { this.displayTitleTouched = true; }; /** * @inheritdoc */ ve.ui.MWAdvancedSettingsPage.prototype.setupOutlineItem = function () { this.outlineItem .setIcon( 'settings' ) .setLabel( ve.msg( 'visualeditor-dialog-meta-advancedsettings-section' ) ); }; /* Indexing option methods */ /** * Handle indexing option state change events. */ ve.ui.MWAdvancedSettingsPage.prototype.onIndexingOptionChange = function () { this.indexingOptionTouched = true; }; /** * Get the first meta item of a given name * * @param {string} name Name of the meta item * @return {Object|null} Meta item, if any */ ve.ui.MWAdvancedSettingsPage.prototype.getMetaItem = function ( name ) { return this.fragment.getDocument().getMetaList().getItemsInGroup( name )[ 0 ] || null; }; /* New edit section link option methods */ /** * Handle new edit section link change events. */ ve.ui.MWAdvancedSettingsPage.prototype.onNewSectionEditLinkOptionChange = function () { this.newSectionEditLinkOptionTouched = true; }; /** * Setup settings page. * * @param {ve.dm.SurfaceFragment} fragment Surface fragment * @param {Object} config * @param {Object} [config.data] Dialog setup data * @param {boolean} [config.isReadOnly=false] Dialog is in read-only mode * @return {jQuery.Promise} */ ve.ui.MWAdvancedSettingsPage.prototype.setup = function ( fragment, config ) { this.fragment = fragment; // Indexing items const indexingField = this.indexing.getField(); const indexingOption = this.getMetaItem( 'mwIndex' ); const indexingType = indexingOption && indexingOption.getAttribute( 'property' ) || 'default'; indexingField .selectItemByData( indexingType ) .setDisabled( config.isReadOnly ); this.indexingOptionTouched = false; // New section edit link items const newSectionEditField = this.newEditSectionLink.getField(); const newSectionEditLinkOption = this.getMetaItem( 'mwNewSectionEdit' ); const newSectionEditLinkType = newSectionEditLinkOption && newSectionEditLinkOption.getAttribute( 'property' ) || 'default'; newSectionEditField .selectItemByData( newSectionEditLinkType ) .setDisabled( config.isReadOnly ); this.newSectionEditLinkOptionTouched = false; // Display title items const displayTitleItem = this.getMetaItem( 'mwDisplayTitle' ); let displayTitle = displayTitleItem && displayTitleItem.getAttribute( 'content' ) || ''; if ( !displayTitle ) { displayTitle = mw.Title.newFromText( ve.init.target.getPageName() ).getPrefixedText(); } this.displayTitleInput .setValue( displayTitle ) .setReadOnly( config.isReadOnly ); this.displayTitleTouched = false; // Simple checkbox items this.metaItemCheckboxes.forEach( ( metaItemCheckbox ) => { const isSelected = !!this.getMetaItem( metaItemCheckbox.metaName ); metaItemCheckbox.fieldLayout.getField() .setSelected( isSelected ) .setDisabled( config.isReadOnly ); } ); return ve.createDeferred().resolve().promise(); }; /** * Tear down settings page. * * @param {Object} [data] Dialog tear down data */ ve.ui.MWAdvancedSettingsPage.prototype.teardown = function ( data ) { // Data initialization data = data || {}; if ( data.action !== 'done' ) { return; } // Indexing items const currentIndexingItem = this.getMetaItem( 'mwIndex' ); const newIndexingData = this.indexing.getField().findSelectedItem(); // Alter the indexing option flag iff it's been touched & is actually different if ( this.indexingOptionTouched ) { if ( newIndexingData.data === 'default' ) { if ( currentIndexingItem ) { this.fragment.removeMeta( currentIndexingItem ); } } else { const newIndexingItem = { type: 'mwIndex', attributes: { property: newIndexingData.data } }; if ( !currentIndexingItem ) { this.fragment.insertMeta( newIndexingItem ); } else if ( currentIndexingItem.getAttribute( 'property' ) !== newIndexingData.data ) { this.fragment.replaceMeta( currentIndexingItem, ve.extendObject( true, {}, currentIndexingItem.getElement(), newIndexingItem ) ); } } } // New section edit link items const currentNewSectionEditLinkItem = this.getMetaItem( 'mwNewSectionEdit' ); const newNewSectionEditLinkData = this.newEditSectionLink.getField().findSelectedItem(); // Alter the new section edit option flag iff it's been touched & is actually different if ( this.newSectionEditLinkOptionTouched ) { if ( newNewSectionEditLinkData.data === 'default' ) { if ( currentNewSectionEditLinkItem ) { this.fragment.removeMeta( currentNewSectionEditLinkItem ); } } else { const newNewSectionEditLinkItem = { type: 'mwNewSectionEdit', attributes: { property: newNewSectionEditLinkData.data } }; if ( !currentNewSectionEditLinkItem ) { this.fragment.insertMeta( newNewSectionEditLinkItem ); } else if ( currentNewSectionEditLinkItem.getAttribute( 'property' ) !== newNewSectionEditLinkData.data ) { this.fragment.replaceMeta( currentNewSectionEditLinkItem, ve.extendObject( true, {}, currentNewSectionEditLinkItem.getElement(), newNewSectionEditLinkItem ) ); } } } // Display title items const currentDisplayTitleItem = this.getMetaItem( 'mwDisplayTitle' ); let newDisplayTitle = this.displayTitleInput.getValue(); if ( newDisplayTitle === mw.Title.newFromText( ve.init.target.getPageName() ).getPrefixedText() ) { newDisplayTitle = ''; } const newDisplayTitleItem = { type: 'mwDisplayTitle', attributes: { content: newDisplayTitle } }; // Alter the display title flag iff it's been touched & is actually different if ( this.displayTitleTouched ) { if ( currentDisplayTitleItem ) { if ( newDisplayTitle ) { if ( currentDisplayTitleItem.getAttribute( 'content' ) !== newDisplayTitle ) { // There was a display title and is a new one, but they differ, so replace this.fragment.replaceMeta( currentDisplayTitleItem, ve.extendObject( true, {}, currentDisplayTitleItem.getElement(), newDisplayTitleItem ) ); } } else { // There was a display title and is no new one, so remove this.fragment.removeMeta( currentDisplayTitleItem ); } } else { if ( newDisplayTitle ) { // There's no existing display title but there is a new one, so create // HACK: Putting this at position 0 so that it works – T63862 this.fragment.insertMeta( newDisplayTitleItem, 0 ); } } } this.metaItemCheckboxes.forEach( ( metaItemCheckbox ) => { const currentItem = this.getMetaItem( metaItemCheckbox.metaName ), isSelected = metaItemCheckbox.fieldLayout.getField().isSelected(); if ( currentItem && !isSelected ) { this.fragment.removeMeta( currentItem ); } else if ( !currentItem && isSelected ) { this.fragment.insertMeta( { type: metaItemCheckbox.metaName } ); } } ); this.fragment = null; }; ve.ui.MWAdvancedSettingsPage.prototype.getFieldsets = function () { return [ this.advancedSettingsFieldset ]; };