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);