User:Nikki/LexemeAddIPA.js
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/* This script adds a link in the header for forms on lexeme pages which opens
a dialog for adding IPA statements to forms which don't have any yet.
More than one pronunciation can be added at the same time - use | (ASCII
vertical bar/pipe character) to separate them.
ASCII ' : and g are automatically converted into the proper IPA characters
before saving.
To use it, add the following line to your common.js:
mw.loader.load("//www.wikidata.org/w/index.php?title=User:Nikki/LexemeAddIPA.js&action=raw&ctype=text/javascript");
By default, the script only shows forms without IPA statements. To always
show all forms, add a line in your common.js before the one which loads this
script like so:
addipa_alwaysshown = true;
The script also supports adding a "pronunciation variety" (P5237) qualifier.
To specify which qualifier to use for which language, add a line in your
common.js before the one which loads this script like so:
addipa_p5237 = { "Q25167": "Q6457972" };
where Q25167 is the ID of the language item (here: Norwegian Bokmål) and
Q6457972 is the value to use as the qualifier (here: urban East Norwegian).
It triggers "addipa-loaded" hooks after loading and "addipa-dialog-opened"
hooks after opening the dialog, which you can use if you would like to extend
the script.
License: CC0
*/
(async function () {
"use strict";
var api = new mw.Api();
api.loadMessages(["cancel"]);
let translations = new mw.Title("User:Nikki/translations.json").getUrl() +
"?action=raw&ctype=application/json";
await $.i18n().load(translations);
function addIPA (e) {
function IpaDialog (config) {
IpaDialog.super.call(this, config);
this.forms = config.forms;
}
OO.inheritClass(IpaDialog, OO.ui.ProcessDialog);
IpaDialog.static.name = 'ipaDialog';
IpaDialog.static.title = $.i18n("add-ipa");
IpaDialog.static.actions = [
{
action: 'save',
label: $.i18n("save-and-reload"),
flags: ['primary', 'progressive'],
},
{
label: mw.msg("cancel"),
flags: ['safe', 'close'],
},
];
IpaDialog.prototype.initialize = function () {
var dialog = this;
IpaDialog.super.prototype.initialize.apply(dialog, arguments);
dialog.fields = [];
for (let form in dialog.forms) {
let input = new OO.ui.TextInputWidget({
data: dialog.forms[form],
classes: ["addipa-ipa-input"],
});
input.on("enter", function () {
return dialog.executeAction("save");
});
let field = new OO.ui.FieldLayout(input, {
label: form,
});
dialog.fields.push(field);
}
this.content = new OO.ui.PanelLayout({
content: [new OO.ui.FieldsetLayout({
items: dialog.fields,
})],
padded: true,
expanded: false,
});
this.$body.append(dialog.content.$element);
};
IpaDialog.prototype.getActionProcess = function (action) {
if (action == 'save') {
var self = this;
return new OO.ui.Process(function () {
let data = [];
for (let field of self.fields) {
let input = field.getField();
if (!input.value) // No IPA was entered for this field
continue;
let forms = input.data;
for (let f of forms) {
let obj = {"id": f, "claims":{"P898":[]}};
for (let ipa of input.value.split("|")) {
ipa = ipa.trim().replace(/ /g, " ").replace(/:/g, "ː").replace(/'/g, "ˈ").replace(/g/g, "ɡ");
let claim = {"mainsnak":{"snaktype":"value","property":"P898","datavalue":{"value": ipa ,"type":"string"}},"type":"statement"};
if (typeof addipa_p5237 !== "undefined" && addipa_p5237.hasOwnProperty(e.language)) {
claim.qualifiers = {
"P5237":[{"snaktype":"value","property":"P5237","datavalue":{"value":{"entity-type":"item","id": addipa_p5237[e.language] },"type":"wikibase-entityid"}}]
};
}
obj.claims.P898.push(claim);
}
data.push(obj);
}
}
var mw_api = new mw.Api();
mw_api.postWithEditToken({
action: "wbeditentity",
id: e.id,
summary: "add IPA",
data: JSON.stringify({"forms": data})
}).then(function (data) {
location.reload();
}).catch(function (err) {
alert("Failed: " + err);
});
});
} else {
return IpaDialog.super.prototype.getActionProcess.call(this, action);
}
};
IpaDialog.prototype.getBodyHeight = function () {
return this.content.$element.outerHeight(true);
};
IpaDialog.prototype.getReadyProcess = function (data) {
return IpaDialog.parent.prototype.getReadyProcess.call(this, data).next(function () {
this.fields[0].getField().focus();
}, this);
};
let forms = {};
for (let f of e.forms) {
// f.claims is an array when empty - T241422
if (typeof f.claims !== "object")
continue;
if (f.claims["P898"] && typeof addipa_alwaysshown === "undefined")
continue;
let form = f.representations[ Object.keys(f.representations)[0] ].value;
if (!forms[form])
forms[form] = [];
forms[form].push(f.id);
}
if (!Object.keys(forms).length) // All forms have IPA
return;
let dialog = new IpaDialog({
forms: forms,
});
OO.ui.getWindowManager().addWindows([dialog]);
$(".wikibase-lexeme-forms-section > h2.wb-section-heading").append("<span style=\"padding-left: 10px; padding-right: 10px; cursor: pointer\" id=\"addipa\" title=\"" + $.i18n("add-ipa") + "\"\>[ə]</span>");
$("#addipa").on("click", function () {
OO.ui.getWindowManager().openWindow(dialog);
mw.hook("addipa-dialog-opened").fire();
});
mw.hook("addipa-loaded").fire();
}
mw.hook('wikibase.entityPage.entityView.rendered').add(function () {
mw.hook("wikibase.entityPage.entityLoaded").add(function (e) {
if (!e.language)
return; // Not on a lexeme page
mw.loader.using([
'oojs',
'oojs-ui-core',
'oojs-ui-widgets',
'oojs-ui-windows',
]).then(function () { addIPA(e); });
});
});
})();