import { registerModule } from '../moduleRegister'; class CreatePageWidget { constructor(dom) { this.baseDom = dom; this.pageUrl = null; this.api = new mw.Api(); this.hasErrors = false; this.hasWarnings = false; this.createButtonEnabled = true; this.initDom(); } initDom() { let namespaces = mw.config.get('wgIsekaiCreatePageTypes'); if (!Array.isArray(namespaces) || namespaces.length === 0) { namespaces = [ { type: 'default', name: 'Main', prefix: '', } ]; } this.selectPageTypeDropdown = new OO.ui.DropdownInputWidget({ options: namespaces.map((nsInfo) => ({ data: JSON.stringify(nsInfo), label: nsInfo.name, })), }); this.selectPageTypeDropdown.on('change', this.onPageTypeChange.bind(this)); this.pageNameInput = new isekai.ui.CreatePageInputWidget({ placeholder: mw.message('isekai-createpage-page-title').parse(), }); this.pageNameInput.on('enter', this.createPage.bind(this)); this.pageNameInput.on('change', this.onPageNameChange.bind(this)); this.createButton = new OO.ui.ButtonWidget({ label: mw.message('isekai-createpage-create-page-button').parse(), flags: [ 'primary', 'progressive' ] }); this.createButton.on('click', this.createPage.bind(this)); this.inputGroup = new OO.ui.ActionFieldLayout(this.pageNameInput, this.createButton, { align: 'center' }); this.formGroup = new OO.ui.HorizontalLayout({ items: [ this.selectPageTypeDropdown, this.inputGroup ] }); this.errorsContainer = $('
'); this.ignoreWarningsCheckbox = new OO.ui.CheckboxInputWidget({ selected: false }); this.ignoreWarningsCheckbox.on('change', this.refreshCreatePageBtnEnabled.bind(this)); this.ignoreWarningsCheckboxField = new OO.ui.FieldLayout(this.ignoreWarningsCheckbox, { align: 'inline', label: mw.message('isekai-createpage-warning-ignore').parse(), helpInline: true, help: mw.message('isekai-createpage-ignore-warnings-help').parse(), }); this.ignoreWarningsCheckboxField.$element .addClass('isekai-createpage-ignore-warnings-field') .hide(); this.cardContent = this.baseDom.find('.card-body .card-content'); this.cardContent.append(this.formGroup.$element); this.cardContent.append(this.errorsContainer); this.cardContent.append(this.ignoreWarningsCheckboxField.$element); } createPage() { let title = this.pageNameInput.getValue(); let pageTypeConfig = this.selectPageTypeDropdown.getValue(); pageTypeConfig = JSON.parse(pageTypeConfig || '{}'); let pageTypeId = pageTypeConfig.id || 'default'; let fullTitle = (pageTypeConfig.prefix || '') + title; if (title.trim().length > 0) { this.createButton.setDisabled(true); if (this.hasWarnings && this.ignoreWarningsCheckbox.isSelected()) { // 已忽略警告 this._doCreatePage(fullTitle); } else { this.validateNewPageTitle(title, pageTypeId).then((valid) => { if (valid) { this._doCreatePage(fullTitle); } }); } } else { this.setErrors([ mw.message('isekai-createpage-title-empty').parse() ]); } } _doCreatePage(fullTitle) { let targetUrl = mw.util.getUrl(fullTitle, { veaction: 'edit' }); window.open(targetUrl, '_blank'); this.pageNameInput.setValue(''); this.clearErrorWarnings(); } onPageNameChange() { this.clearErrorWarnings(); let value = this.pageNameInput.getValue(); if (value.indexOf(':') !== -1 || value.indexOf('`') !== -1) { let range = this.pageNameInput.getRange(); value = value.replace(/:/g, ':').replace(/`/g, '·'); this.pageNameInput.setValue(value); this.pageNameInput.selectRange(range.from, range.to); } } onPageTypeChange() { let pageTypeConfig = this.selectPageTypeDropdown.getValue(); this.pageNameInput.setPagePrefix(pageTypeConfig.prefix); this.clearErrorWarnings(); } makeMessageRaw(kind, html) { let $el = new OO.ui.MessageWidget({ type: kind, inline: true, label: html, }).$element; let $label = $el.find('.oo-ui-labelElement-label'); $label.html(html); return $el; } setErrors(errorMessages) { errorMessages.forEach((errorMessage) => { let $message = this.makeMessageRaw('error', errorMessage); this.errorsContainer.append($message); }); this.hasErrors = true; this.refreshCreatePageBtnEnabled(); this.refreshIgnoreWarningsCheckbox(); } setWarnings(warningMessages) { warningMessages.forEach((warningMessage) => { let $message = this.makeMessageRaw('warning', warningMessage); this.errorsContainer.append($message); }); this.hasWarnings = true; this.refreshCreatePageBtnEnabled(); this.refreshIgnoreWarningsCheckbox(); } clearErrorWarnings() { if (this.hasErrors || this.hasWarnings) { this.errorsContainer.empty(); this.hasErrors = false; this.hasWarnings = false; this.refreshCreatePageBtnEnabled(); this.refreshIgnoreWarningsCheckbox(); } } refreshCreatePageBtnEnabled() { this.createButtonEnabled = (() => { if (this.hasErrors) { return false; } if (this.hasWarnings) { // 检查是否忽略警告 return this.ignoreWarningsCheckbox.isSelected(); } return true; })(); this.createButton.setDisabled(!this.createButtonEnabled); } refreshIgnoreWarningsCheckbox() { if (this.hasWarnings && !this.hasErrors) { this.ignoreWarningsCheckboxField.$element.show(); } else { this.ignoreWarningsCheckboxField.$element.hide(); } if (!this.hasWarnings && !this.hasErrors) { // 没有警告和错误时,重置忽略警告复选框 this.ignoreWarningsCheckbox.setSelected(false); } } validateNewPageTitle(title, pageType = 'default') { return new Promise((resolve, reject) => { this.api.get({ action: 'isekaiwidgets', method: 'createpagevalidatetitle', iwnewpagetitle: title, iwnewpagetype: pageType, }).done((data) => { if (data.isekaiwidget && data.isekaiwidget.createpagevalidatetitle) { let result = data.isekaiwidget.createpagevalidatetitle; if (!result.hasError && !result.hasWarning) { resolve(true); return; } if (result.hasError) { this.setErrors(result.errors.map(error => error.message)); } if (result.hasWarning) { this.setWarnings(result.warnings.map(warning => warning.message)); } resolve(false); } else { resolve(false); } }).fail(reject); }); } } registerModule('ui.CreatePageWidget', CreatePageWidget);