Qeyd: Dəyişiklikləri yayımladıqdan sonra etdiyiniz dəyişikliklərin görünməsi üçün brauzerinizin keşinin təmizlənməsi lazım ola bilər.
- Firefox / Safari: Reload düyməsinə basılı tutarkən Shift düyməsinə basın, və ya Ctrl+F5 və ya Ctrl+R (Mac üçün ⌘-R )
- Google Chrome: Ctrl-Shift-R (Mac üçün ⌘-Shift-R)
- Edge: Ctrl düyməsini basılı tutarkən Refresh düyməsinə basın, və ya sadəcə Ctrl+F5.
/* Codex əsaslı SNS qadceti. TWE pəncərəsində yerləşir */
/* <nowiki> */
mw.loader.using(['mediawiki.api', 'mediawiki.util', '@wikimedia/codex'], require => {
const { createMwApp } = require('vue'),
{ CdxDialog, CdxField, CdxTextInput } = require('@wikimedia/codex'),
api = new mw.Api({ userAgent: 'CodexEnhanced/SNS-SNF' }),
ns = mw.config.get('wgNamespaceNumber'),
pageTitle = mw.config.get('wgPageName').replaceAll('_', ' '),
isEligible = [0, 6].includes(ns),
isFile = ns === 6,
venue = isFile ? 'snf' : 'sns',
linkLabel = isFile ? 'Sil (SNF)' : 'Sil (SNS)',
pagePrefix = `Vikipediya:Silinməyə namizəd ${isFile ? 'fayllar' : 'səhifələr'}/`;
if (!isEligible || !mw.config.get('wgUserGroups').includes('autoconfirmed')) return;
const tooltip = 'Silinməyə namizəd göstər';
const portletId = 'p-ap';
const portletLink = mw.util.addPortletLink(
portletId,
'javascript:void(0);',
linkLabel,
't-ap-sns',
tooltip
);
const getNominationTitle = async () => {
const suffixes = {
2: '2-ci', 3: '3-cü', 4: '4-cü', 5: '5-ci',
6: '6-cı', 7: '7-ci', 8: '8-ci', 9: '9-cu', 10: '10-cu'
};
let base = pageTitle;
let suffix = '';
for (let i = 1; i <= 10; i++) {
const tryTitle = `${base}${suffix}`;
const fullTitle = `${pagePrefix}${tryTitle}`;
try {
const exists = await api.get({ action: 'query', titles: fullTitle, format: 'json' })
.then(res => !res.query.pages['-1']);
if (!exists) return { full: fullTitle, short: tryTitle };
} catch (e) {
console.error(e);
}
if (suffixes[i + 1]) {
suffix = ` (${suffixes[i + 1]} namizədlik)`;
} else {
break;
}
}
return null;
};
const getPageCreator = async title => {
const res = await api.get({
action: 'query',
prop: 'revisions',
rvlimit: 1,
rvdir: 'newer',
rvprop: 'user',
titles: title,
format: 'json'
});
const page = Object.values(res.query.pages)[0];
return page && page.revisions && page.revisions[0] && page.revisions[0].user;
};
const app = createMwApp({
data: () => ({
dialogShown: false,
reason: '',
status: 'form',
error: '',
progressText: 'Namizədlik əlavə olunur…',
nominationTarget: null,
countdown: 5,
countdownTimer: null
}),
computed: {
disabled() {
return this.reason.trim().length === 0;
},
isFile() {
return ns === 6;
}
},
methods: {
getUrl(page) {
return mw.util.getUrl(page);
},
toggleDialog() {
this.dialogShown = !this.dialogShown;
},
async onSubmit() {
this.status = 'sending';
this.error = '';
this.progressText = 'Namizədlik səhifəsi yaradılır…';
this.nominationTarget = await getNominationTitle();
if (!this.nominationTarget) {
this.status = 'form';
this.error = '10-dan çox namizədlik mövcuddur. Davam etmək mümkün deyil.';
return;
}
this.progressText = 'Namizədlik səhifəsi yaradılır…';
const cleanReason = this.reason.replace(/\s*(—|–|--)?\s*~{3,4}\s*$/, '').trim();
await api.postWithEditToken({
action: 'edit',
title: this.nominationTarget.full,
appendtext: `== [[:${pageTitle}]] ==\n{{Mənbə axtar|${pageTitle}}}\n* ${cleanReason} — ~~~~`,
summary: 'Səhifə silinməyə namizəd göstərilir.',
format: 'json'
});
this.progressText = 'Səhifəyə silinmə şablonu əlavə olunur…';
await api.postWithEditToken({
action: 'edit',
title: pageTitle,
prependtext: `{{Silinməyə namizəd|${this.nominationTarget.full}}}\n`,
summary: `Səhifə silinməyə namizəd göstərilir. Ətraflı: [[${this.nominationTarget.full}]]`,
format: 'json'
});
this.progressText = 'Silinmə müzakirəsi əlavə edilir…';
await api.postWithEditToken({
action: 'edit',
title: `Vikipediya:Silinməyə namizəd səhifələr`,
appendtext: `\n{{${this.nominationTarget.full}}}`,
summary: `[[${pageTitle}]] əlavə edilir.`,
format: 'json'
});
const creator = await getPageCreator(pageTitle);
if (creator) {
this.progressText = 'Səhifə müəllifinə bildiriş göndərilir…';
const notifyText = `\n{{subst:sns bildirişi|${pageTitle}|${this.nominationTarget.short}}} ~~~~`;
await api.postWithEditToken({
action: 'edit',
title: `İstifadəçi müzakirəsi:${creator}`,
appendtext: notifyText,
summary: `Bildiriş: [[${pageTitle}]] səhifəsi silinməyə namizəd göstərilib.`,
format: 'json'
});
}
this.status = 'done';
this.startCountdown();
},
startCountdown() {
if (this.countdownTimer) clearInterval(this.countdownTimer);
this.countdown = 5;
this.countdownTimer = setInterval(() => {
this.countdown--;
if (this.countdown <= 0) {
clearInterval(this.countdownTimer);
if (this.nominationTarget) {
location.href = this.getUrl(this.nominationTarget.full);
}
}
}, 1000);
},
onDefaultAction() {
if (this.status === 'done' && this.nominationTarget) {
location.href = this.getUrl(this.nominationTarget.full);
} else {
this.toggleDialog();
}
}
},
template: `
<cdx-dialog
v-model:open="dialogShown"
:title="status === 'form' ? 'Silinməyə namizəd göstər' : status === 'sending' ? 'Göndərilir…' : 'Uğurlu!'"
:subtitle="status === 'sending' ? '' : status === 'done' ? 'Namizədlik uğurla əlavə edildi. ' + countdown + ' saniyə sonra müzakirə səhifəsinə keçid ediləcəkdir.' : ''"
use-close-button
close-button-label="Bağla"
:primary-action="status === 'form' ? { label: 'Göndər', actionType: 'progressive', disabled } : undefined"
:default-action="status === 'form' ? { label: 'İmtina' } : { label: 'Müzakirəyə keç' }"
@primary="onSubmit"
@default="onDefaultAction"
>
<template #default>
<template v-if="status === 'form'">
<cdx-field :status="error ? 'error' : 'default'" :messages="{ error }">
<template #description>{{ isFile ? 'Faylın niyə silinməli olduğunu izah edin.' : 'Səhifənin niyə silinməli olduğunu izah edin.' }}</template>
<cdx-text-input v-model="reason" />
</cdx-field>
</template>
<template v-else-if="status === 'sending'">
<div class="cdx-progress-indicator">
<div class="cdx-progress-indicator__indicator">
<progress
class="cdx-progress-indicator__indicator__progress"
id="cdx-sending-progress"
></progress>
</div>
<div class="cdx-label cdx-progress-indicator__label">
<label class="cdx-label__label" for="cdx-sending-progress">
<span class="cdx-label__label__text">{{ progressText }}</span>
</label>
</div>
</div>
</template>
</template>
</cdx-dialog>
`,
mounted() {
portletLink.addEventListener('click', this.toggleDialog);
document.addEventListener('keydown', e => {
if (e.ctrlKey && e.key.toLowerCase() === 'y') {
e.preventDefault();
this.toggleDialog();
}
});
},
unmounted() {
portletLink.removeEventListener('click', this.toggleDialog);
}
});
app
.component('cdx-dialog', CdxDialog)
.component('cdx-field', CdxField)
.component('cdx-text-input', CdxTextInput)
.mount(document.body.appendChild(document.createElement('div')));
});
/* </nowiki> */