ꯁꯤꯖꯤꯟꯅꯔꯤꯕ:Nokib Sarkar/Gadget-mayek-bot.js
ꯏꯁꯤꯟꯒꯗꯕ: ꯐꯣꯡꯗꯣꯛꯂꯕ ꯃꯇꯨꯡ, ꯅꯪꯅꯥ ꯑꯍꯣꯡꯕ ꯎꯅꯕ ꯅꯪꯒꯤ ꯕꯔꯥꯎꯁꯔ ꯀꯥꯆꯦ ꯕꯥꯏꯄꯥꯁ ꯇꯧꯔꯣ ꯫
- ꯐꯥꯌꯥꯔꯐꯣꯛꯁ / ꯁꯐꯥꯔꯤ: ꯄꯥꯏꯁꯤꯟꯕꯊꯥꯡꯇꯣꯛꯄ ꯅꯝꯃꯤꯉꯩ ꯃꯅꯨꯡꯗꯑꯃꯨꯛꯍꯟꯅ-ꯆꯤꯡꯉꯣ, ꯅꯠꯇꯔꯒ ꯅꯝꯃꯣ Ctrl-F5 ꯑꯃꯥ ꯍꯦꯛꯇꯥ ꯅꯠꯃꯣ Ctrl-R (⌘-R ꯃꯦꯛ ꯱ ꯇꯥ)
- ꯒꯨꯒꯜ ꯀꯔꯣꯝ: ꯅꯝꯃꯣ Ctrl-Shift-R (⌘-Shift-R ꯃꯦꯛ ꯱ ꯗ)
- ꯏꯟꯇꯔꯅꯦꯠ ꯑꯦꯛꯁꯄ꯭ꯂꯣꯔꯔ/ꯑꯦꯗꯖ: ꯄꯥꯏꯁꯤꯟꯕ Ctrl ꯅꯝꯃꯤꯉꯩ ꯃꯅꯨꯡꯗ ꯇꯦꯈꯠꯍꯟꯂꯨ, ꯅꯠꯇꯔꯒ ꯅꯝꯃꯨ Ctrl-F5
- ꯑꯣꯄꯦꯔꯥ: ꯅꯝꯃꯨ Ctrl-F5 ꯫
class MayekBot {
static MayekMessages = {
'title': 'Transliterate to Bengali',
'title.placeholder': 'Title',
'title.label': 'Title',
'content.label': 'Content',
'content.placeholder': 'The content in Bengali script',
'content.help': 'The content in Bengali script',
'summary.label': 'Summary',
'summary.placeholder': 'A short summary of the changes',
'summary.help': 'A short summary of the changes',
'submit.label': 'Submit',
'cancel.label': 'Cancel',
'error': 'Error:',
'error.titleAlreadyBengali': 'The title is already in Bengali',
'error.notMainNamespace': 'Not running on page because it is not in the main namespace',
'error.notArticle': 'Not running on page because it is not an article',
'error.notEditing': 'Not running on page because it is not being edited',
'prompt': 'Do you want your changes to be transliterated to Bengali as well?',
'success': 'Successfully transliterated to Bengali. The page is at ',
'error.api': 'Error: ',
};
static injectStyle() {
const styleID = 'mayek-bot-style';
const styleClass = 'mayek-bot-dialog';
if (!document.getElementById(styleID)) {
const style = document.createElement('style');
style.id = styleID;
style.innerHTML = `
.${styleClass} {
padding: 10px;
}
`;
document.head.appendChild(style);
}
return styleClass;
}
static showEditDialog({ onCancel, onSubmit }) {
const styleClass = MayekBot.injectStyle();
const transliteratedTitleInput = new OO.ui.TextInputWidget({
placeholder: MayekBot.MayekMessages['title.placeholder'],
disabled: true
});
const contentInput = new OO.ui.MultilineTextInputWidget({
rows: 10,
placeholder: MayekBot.MayekMessages['content.placeholder'],
autosize: true,
help: MayekBot.MayekMessages['content.help'],
disabled: true
});
const summaryInput = new OO.ui.TextInputWidget({
placeholder: MayekBot.MayekMessages['summary.placeholder'],
help: MayekBot.MayekMessages['summary.help'],
disabled: true
});
const submitButton = new OO.ui.ButtonWidget({
label: MayekBot.MayekMessages['submit.label'],
flags: ['primary', 'progressive'],
disabled: true
});
const cancelButton = new OO.ui.ButtonWidget({
label: MayekBot.MayekMessages['cancel.label'],
flags: ['destructive'],
});
const progressBar = new OO.ui.ProgressBarWidget({
progress: false
});
const fields = [
progressBar,
new OO.ui.FieldLayout(transliteratedTitleInput, {
label: MayekBot.MayekMessages['title.label'],
align: 'top',
}),
new OO.ui.FieldLayout(contentInput, {
label: MayekBot.MayekMessages['content.label'],
align: 'top',
}),
new OO.ui.FieldLayout(summaryInput, {
label: MayekBot.MayekMessages['summary.label'],
align: 'top',
}),
new OO.ui.ActionFieldLayout(
cancelButton,
submitButton
)
]
const fieldset = new OO.ui.FieldsetLayout({
items: fields,
label: MayekBot.MayekMessages['title'],
classes: [styleClass]
});
// Creating and opening a simple dialog window.
// Subclass Dialog class. Note that the OOjs inheritClass() method extends the parent constructor's prototype and static methods and properties to the child constructor.
function MyDialog(config) {
MyDialog.super.call(this, config);
}
OO.inheritClass(MyDialog, OO.ui.Dialog);
// Specify a name for .addWindows()
MyDialog.static.name = 'transliterationDialog';
// Specify a title statically (or, alternatively, with data passed to the opening() method).
MyDialog.static.title = MayekBot.MayekMessages['title'];
// Customize the initialize() function: This is where to add content to the dialog body and set up event handlers.
MyDialog.prototype.initialize = function () {
// Call the parent method.
MyDialog.super.prototype.initialize.call(this);
// Create and append a layout and some content.
this.content = fieldset;
// this.content.$element.append('<p>A simple dialog window. Press \'Esc\' to close. </p>');
this.$body.append(this.content.$element);
};
// Override the getBodyHeight() method to specify a custom height (or don't to use the automatically generated height).
MyDialog.prototype.getBodyHeight = function () {
return this.content.$element.outerHeight(true);
};
// Make the window.
var myDialog = new MyDialog({
size: 'large',
styles: {
'padding': '10px',
}
});
// Create and append a window manager, which will open and close the window.
var windowManager = new OO.ui.WindowManager();
$(document.body).append(windowManager.$element);
// Add the window to the window manager using the addWindows() method.
windowManager.addWindows([myDialog]);
// Open the window!
windowManager.openWindow(myDialog);
cancelButton.on('click', function () {
onCancel().then(e => windowManager.closeWindow(myDialog));
});
submitButton.on('click', function () {
progressBar.toggle(true);
submitButton.setDisabled(true);
cancelButton.setDisabled(true);
contentInput.toggle(false);// Disable the content input
summaryInput.setDisabled(true);
transliteratedTitleInput.setDisabled(true);
onSubmit({
title: transliteratedTitleInput.getValue(),
content: contentInput.getValue(),
summary: summaryInput.getValue()
}).then(e => windowManager.closeWindow(myDialog));
});
const loaded = function ({ title, content, summary }) {
// Enable all the inputs
transliteratedTitleInput.setDisabled(false);
contentInput.setDisabled(false);
summaryInput.setDisabled(false);
submitButton.setDisabled(false);
transliteratedTitleInput.setValue(title);
contentInput.setValue(content);
summaryInput.setValue(summary);
progressBar.toggle(false);
}
return loaded;
}
static runMayekBot() {
const namespace = mw.config.get('wgCanonicalNamespace') == '';
// const action = mw.config.get('wgAction') == 'edit';
const isArticle = mw.config.get('wgIsArticle') || true;
if (namespace === false) {
console.log(MayekBot.MayekMessages['error.notMainNamespace']);
return;
}
if (isArticle === false) {
console.log(MayekBot.MayekMessages['error.notArticle']);
return;
}
const submitButton = document.querySelector('button.save.submit.cdx-button,input#wpSave');
const editIcon = document.querySelector('a#ca-edit');
const APIURL = "https://mayek-bot-nokib.toolforge.org/api/transliterate";
async function transliterate(text) {
const f = new FormData();
f.append("text", text);
const response = await fetch(APIURL, {
"credentials": "include",
"method": "POST",
"mode": "cors",
"body": f
});
return await response.text();
}
if (editIcon) {
editIcon.addEventListener('click', function () {
const timer = setInterval(function () {
const submitButton = document.querySelector('button.save.submit.cdx-button,input#wpSave');
if (submitButton) {
submitButton.onclick = onClick();
clearInterval(timer);
};
}, 1000);
});
}
const previousOnclick = submitButton?.onclick;
function onClick() {
let done = false;
return async (e) => {
if (done === false && confirm(MayekBot.MayekMessages['prompt'])) {
try {
e.preventDefault();
e.stopPropagation();
const title = mw.config.get('wgPageName');
const username = mw.config.get('wgUserName');
const contentBox = document.querySelector('textarea#wpTextbox1, textarea#wikitext-editor');
const summaryBox = document.querySelector('input#wpSummary,div.summary > textarea');
const minorEditBox = document.querySelector('input#wpMinoredit');
const currentURL = new URL(window.location.href);
const searchParams = currentURL.searchParams;
let section = searchParams.get('section');
if(!section){
const mobileSectionPattern = /^#\/editor\/(\S+)/
const hash = currentURL.hash;
const match = hash.match(mobileSectionPattern);
if(match){
section = match[1];
}
if(section == "all")
section = null;
}
// const section = mw.config.get('wgAction') === 'edit' ? mw.config.get('wgCurRevisionId') : '';
const resultLoaded = MayekBot.showEditDialog({
onCancel: async () => {
done = true;
return e.target.click();
},
onSubmit: async ({
title,
content,
summary
}) => {
try {
const api = new mw.Api();
const data = {
action: 'edit',
title: title,
text: content,
summary: summary,
minor: minorEditBox?.checked,
}
if (section) {
data.section = section;
if (section == "new") {
// Also grab section title
data.sectiontitle = summary;
}
}
const resp = await api.postWithEditToken(data);
if (resp.error) {
throw new Error(resp.error.info);
}
if (resp.edit && resp.edit.result === 'Success') {
alert(MayekBot.MayekMessages['success'] + title);
}
} catch (e) {
alert(MayekBot.MayekMessages['error.api'] + e.message);
} finally {
done = true;
e.target.click();
}
}
})
const transliteratedTitle = "ꯕꯦꯡꯒꯂꯤ ꯃꯌꯦꯛ:" + await transliterate(title);
if (transliteratedTitle === title) {
throw new Error(MayekBot.MayekMessages['error.titleAlreadyBengali']);
}
const transliteratedContent = await transliterate(contentBox.value);
const summary = summaryBox.value;
const summaryTransliterated = await transliterate(summary);
const minorEdit = minorEditBox?.checked;
resultLoaded({
title: transliteratedTitle,
content: transliteratedContent,
summary: summaryTransliterated,
minorEdit
});
} catch (e) {
alert(MayekBot.MayekMessages['error'] + e.message);
done = true;
e.target.click();
}
}
if (previousOnclick)
await previousOnclick();
}
}
if (submitButton)
submitButton.onclick = onClick();
};
}
mw.loader.using('oojs-ui-windows').done(MayekBot.runMayekBot);