// Subtitles parser from https://github.com/bazh/subtitles-parser
// Originally by bazh <interesno@gmail.com> (X11 License: https://github.com/bazh/subtitles-parser/blob/master/LICENSE)
var parser = (function() {
var pItems = {};
pItems.timeMs = function(val) {
var regex = /(\d+):(\d{2}):(\d{2}),(\d{3})/;
var parts = regex.exec(val);
if (parts === null) {
return 0;
}
for (var i = 1; i < 5; i++) {
parts[i] = parseInt(parts[i], 10);
if (isNaN(parts[i])) parts[i] = 0;
}
// hours + minutes + seconds + ms
return parts[1] * 3600000 + parts[2] * 60000 + parts[3] * 1000 + parts[4];
};
pItems.msTime = function(val) {
var measures = [ 3600000, 60000, 1000 ];
var time = [];
for (var i in measures) {
var res = (val / measures[i] >> 0).toString();
if (res.length < 2) res = '0' + res;
val %= measures[i];
time.push(res);
}
var ms = val.toString();
if (ms.length < 3) {
for (i = 0; i <= 3 - ms.length; i++) ms = '0' + ms;
}
return time.join(':') + ',' + ms;
};
/**
* Converts SubRip subtitles into array of objects
* [{
* id: `Number of subtitle`
* startTime: `Start time of subtitle`
* endTime: `End time of subtitle
* text: `Text of subtitle`
* }]
*
* @param {String} data SubRip suntitles string
* @param {Boolean} ms Optional: use milliseconds for startTime and endTime
* @return {Array}
*/
pItems.fromSrt = function(data, ms) {
var useMs = ms ? true : false;
data = data.replace(/\r/g, '');
var regex = /(\d+)\n(\d{2}:\d{2}:\d{2},\d{3}) --> (\d{2}:\d{2}:\d{2},\d{3})/g;
data = data.split(regex);
data.shift();
var items = [];
for (var i = 0; i < data.length; i += 4) {
items.push({
id: data[i].trim(),
startTime: useMs ? pItems.timeMs(data[i + 1].trim()) : data[i + 1].trim(),
endTime: useMs ? pItems.timeMs(data[i + 2].trim()) : data[i + 2].trim(),
text: data[i + 3].trim()
});
}
return items;
};
/**
* Converts Array of objects created by this module to SubRip subtitles
* @param {Array} data
* @return {String} SubRip subtitles string
*/
pItems.toSrt = function(data) {
if (!data instanceof Array) return '';
var res = '';
for (var i = 0; i < data.length; i++) {
var s = data[i];
if (!isNaN(s.startTime) && !isNaN(s.endTime)) {
s.startTime = pItems.msTime(parseInt(s.startTime, 10));
s.endTime = pItems.msTime(parseInt(s.endTime, 10));
}
res += s.id + '\n';
res += s.startTime + ' --> ' + s.endTime + '\n';
res += s.text.replace('\r\n', '\n') + '\n\n';
}
return res;
};
return pItems;
})();
// All the code below is adapted from [[d:MediaWiki:Gadget-labelLister.js/beta.js]]
importStylesheet("User:Mahir256/subtitle-editor.css");
var subtitleEditor = ( function (mw, $){
"use strict";
/**
* Get the ID of the current entity. (if it's not an entity it terminate the script)
*/
var pageName = mw.config.get( 'wgPageName' );
if ( !pageName ) {
return;
}
/**
* Get the user's language
*/
var lang = mw.config.get( 'wgUserLanguage' );
/**
* Write a line on the table
*/
function LlTable (elem){
this.tableElement = elem;
this.diff = {};
this.subs = [];
this.buttons = $("<div class='ll-buttons'><div class='ll-button ll-button-moveup'>đ˘</div><div class='ll-button ll-button-movedown'>đ˘</div><div class='ll-button ll-button-insertbelow'>đ˘</div><div class='ll-button ll-button-insertabove'>đ˘
</div><div class='ll-button ll-button-delete'>đŽ</div></div>");
}
LlTable.prototype = {
addCol: function(lang, type, data){
//Condition
if(typeof lang != "string"){
throw "You've sent the wrong type of data through lang param of LlTable.addCol()";
}
if(typeof type != "string"){
throw "You've sent the wrong type of data through type param of LlTable.addCol()";
}
var ret = '<div class="ll-col ll-col-' + type + '" lang="' + lang + '">';
if(typeof data == "object" && data instanceof Array){
ret += '<ul class="ll-lists ll-' + type + '" lang="' + lang + '">';
for(var key in data){
if(!data.hasOwnProperty(key)){
continue;
}
ret += '<li class="ll-list" lang="' + lang + '">' + mw.html.escape( data[key] ) + '</li>';
}
ret += '<li class="ll-list ll-list-add" lang="' + lang + '">+</li>';
ret += '</ul>';
}
if(typeof data == "string"){
ret += '<div class="ll-single ll-' + type + '" lang="' + lang + '">' + mw.html.escape( data ) + '</div>';
}
ret += "</div>";
return ret;
},
addRow: function(data){
if(typeof data != "object"){
throw "You've sent the wrong type of data through data param of LlTable.addRow()";
}
//First line
var ret = '<div class="ll-row" data-index="' + data.id + '" lang="' + lang + '">';
ret += this.addCol(lang, "index", data.id);
ret += this.addCol(lang, "startTime", data.startTime);
ret += this.addCol(lang, "endTime", data.endTime);
ret += this.addCol(lang, "text", data.text);
ret += '</div>';
return ret;
},
addRows: function(data){
if(typeof data != "object"){
throw "You've sent the wrong type of data through data param of LlTable.addRows()";
}
this.subs = data;
//Reset (no opened language, empty table, close edition)
this.unEditCols();
$(this.tableElement).empty();
var ret = '';
//fetch each line
for(var key in data){
try{
ret = this.addRow(data[key]);
$(this.tableElement).append(ret);
}catch (e){
console.log(e);
}
}
this.setEvent();
},
editCol: function(e){
if(!$(e).hasClass("ll-index") && !$(e).hasClass("ll-pending-edition")){
table.unEditCols();
$(e).removeClass("ll-deleted");
$(e).removeClass("ll-edited");
$(e).addClass("ll-pending-edition");
var inner = e.textContent;
if(typeof $(e).prop("old") == "undefined"){
$(e).prop('old', inner);
}
var old = $(e).prop("old");
if($(e).hasClass("ll-text")){
$(e).html('<textarea id="lli" rows="2" placeholder="' + old + '">' + mw.html.escape( inner ) + '</textarea>');
}
else {
$(e).html('<input id="lli" placeholder="' + old + '" value="' + mw.html.escape( inner ) + '"/>');
}
$('#lli').focus();
}
},
unEditCols: function(){
$(".ll-pending-edition").each(function () {
$(this).removeClass("ll-pending-edition");
//Easter egg (whoops!!)
var rE = new RegExp("whoops!!");
// handle inputs
if($(this).children('input').length != 0){
if(rE.test($(this).children('input').val())){
$(this).children('input').val($(this).prop("old"));
}
var inner = $(this).children('input').val();
var old = $(this).prop("old");
if(!$(this).hasClass("ll-list")) {
$(this).removeClass("ll-deleted");
$(this).removeClass("ll-edited");
if (inner === "" && old !== "") {
$(this).addClass("ll-deleted");
} else if (inner != old) {
$(this).addClass("ll-edited");
}
}else{
$(this).addClass("ll-list-added");
}
$(this).text(inner);
}
// handle textareas
if($(this).children('textarea').length != 0){
if(rE.test($(this).children('textarea').val())){
$(this).children('textarea').val($(this).prop("old"));
}
var inner = $(this).children('textarea').val();
var old = $(this).prop("old");
if(!$(this).hasClass("ll-list")) {
$(this).removeClass("ll-deleted");
$(this).removeClass("ll-edited");
if (inner === "" && old !== "") {
$(this).addClass("ll-deleted");
} else if (inner != old) {
$(this).addClass("ll-edited");
}
}else{
$(this).addClass("ll-list-added");
}
$(this).text(inner);
}
//prevent empty list
if(inner === "" && $(this).hasClass("ll-list")){
table.deleteList(this);
}
});
},
addList: function(e){
table.unEditCols();
var appendice = '<li class="ll-list ll-pending-edition" old="" lang="' + $(e).prop("lang") + '"><input/></li>';
$(e).before(appendice);
},
deleteList: function(e){
table.unEditCols();
$(e).remove();
},
removeList: function(e){
table.unEditCols();
if(!$(e).hasClass("ll-list-removed")) {
$(e).addClass("ll-list-removed");
}else{
$(e).removeClass("ll-list-removed");
}
},
swapRows: function(earlierrow, laterrow){
var findex = $(earlierrow).find(".ll-index").text();
var fstart = parser.timeMs($(earlierrow).find(".ll-startTime").text());
var fend = parser.timeMs($(earlierrow).find(".ll-endTime").text());
var lindex = $(laterrow).find(".ll-index").text();
var lstart = parser.timeMs($(laterrow).find(".ll-startTime").text());
var lend = parser.timeMs($(laterrow).find(".ll-endTime").text());
// adjust the row contents
// todo: make sure original subtitle position is preserved across moves
// todo: if new = old for some part of a row, unset "ll-edited" for that part
$(laterrow).find(".ll-index").prop("old",lindex).text(findex).addClass("ll-edited");
$(laterrow).find(".ll-startTime").text(parser.msTime(fstart));
$(laterrow).find(".ll-endTime").text(parser.msTime(fstart + (lend-lstart)));
$(earlierrow).find(".ll-index").prop("old",findex).text(lindex).addClass("ll-edited");
$(earlierrow).find(".ll-startTime").text(parser.msTime(lend - (fend-fstart)));
$(earlierrow).find(".ll-endTime").text(parser.msTime(lend));
// perform the swap
$(laterrow).after($(earlierrow));
$(laterrow).attr("data-index",findex);
$(earlierrow).attr("data-index",lindex);
},
setEvent: function () {
//add event on data
$(".ll-row").off("click");
$(".ll-col-startTime,.ll-col-endTime,.ll-col-text").each(function () {
var cell = $(this).children('.ll-single');
if(!cell.hasClass("ll-event")) {
cell.addClass("ll-event");
$(this).click(function () {
if(!$(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
table.editCol(cell.get(0));
//update all event
table.setEvent();
}
});
}
});
$(".ll-row").each(function () {
if(!$(this).hasClass("ll-event")) {
$(this).addClass("ll-event");
$(".ll-row").mouseover(function(){
table.buttons.prependTo($(this).find(".ll-col-index"))
}).mouseleave(function(){
$(this).find(".ll-buttons").remove();
});
}
});
//add event on add list button
$(".ll-list-add").each(function () {
if(!$(this).hasClass("ll-event")) {
$(this).addClass("ll-event");
$(this).click(function () {
if(!$(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
table.addList(this);
//update all event
table.setEvent();
}
});
}
});
//add event on add list button
$(".ll-list-added").each(function () {
if(!$(this).hasClass("ll-event")) {
$(this).addClass("ll-event");
$(this).click(function () {
if(!$(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
table.deleteList(this);
//update all event
table.setEvent();
}
});
}
});
//add event on add list button
$(".ll-list").each(function () {
if(!$(this).hasClass("ll-event") && !$(this).hasClass("ll-list-added") && !$(this).hasClass("ll-list-add") && !$(this).hasClass("ll-pending-edition")) {
$(this).addClass("ll-event");
$(this).click(function () {
if(!$(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
table.removeList(this);
//update all event
table.setEvent();
}
});
}
});
$(".ll-index").click(function(){
var startTime = $(this).parents(".ll-row").children('.ll-col-startTime').text();
var endTime = $(this).parents(".ll-row").children('.ll-col-endTime').text();
var pausing_function = function(){
if(this.currentTime < startTime || this.currentTime >= endTime){
this.pause();
this.removeEventListener("timeupdate",pausing_function);
$(".ll-col-index-playing").removeClass("ll-col-index-playing");
}
}
startTime = startTime.replace(',','.').split(':').reduce((acc,time) => (60 * acc) + +time);
endTime = endTime.replace(',','.').split(':').reduce((acc,time) => (60 * acc) + +time);
var editorVideo = $(".ll-videopane video").get(0);
editorVideo.currentTime = startTime;
editorVideo.addEventListener('timeupdate',pausing_function);
$(this).addClass("ll-col-index-playing");
editorVideo.play();
});
//close edition on return
$(".ll-pending-edition input, .ll-pending-edition textarea")
.blur(function () {
table.unEditCols();
table.setEvent();
});
$(".ll-pending-edition input")
.blur(function () {
table.unEditCols();
table.setEvent();
})
.keyup(function (e) {
if(e.which == 13 || e.which == 10) {
table.unEditCols();
table.setEvent();
}
});
$(".ll-pending-edition textarea")
.keyup(function (e) {
if(e.ctrlKey && (e.which == 13 || e.which == 10)) {
table.unEditCols();
table.setEvent();
}
});
//Accept changes
$(".ll-preview-send").each(function () {
if(!$(this).hasClass("ll-event")) {
$(this).addClass("ll-event");
$(this).click(function () {
if($(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
var resume = $(".ll-preview-resume").val();
if(model.sendData(table.diff, resume)){
table.addRows(model.receiveData());
table.unlock();
}
//update all event
table.setEvent();
}
});
}
});
//Cancel changes
$(".ll-preview-return").each(function () {
if(!$(this).hasClass("ll-event")) {
$(this).addClass("ll-event");
$(this).click(function () {
console.log(table.tableElement);
if($(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
table.addRows(model.receiveData());
table.setDiff(table.diff);
table.unlock();
//update all event
table.setEvent();
}
});
}
});
//Cancel changes
$(".ll-preview-cancel").each(function () {
if(!$(this).hasClass("ll-event")) {
$(this).addClass("ll-event");
$(this).click(function () {
if($(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
table.addRows(model.receiveData());
table.unlock();
//update all event
table.setEvent();
}
});
}
});
//Display information
$(".ll-info").each(function () {
if(!$(this).hasClass("ll-event")) {
$(this).addClass("ll-event");
$(this).click(function () {
alert("\n== Label & Description ==\n" +
" * To edit label and description just click on it.\n" +
" * Blue and red ones are those which are changed from the original.\n" +
" * Type \"whoops!!\" without quote anywhere in a field to return to the original value.\n" +
"\n== Aliases ==\n" +
" * To delete an alias from the original click on it, it becomes red. To undo a deletion re-click on it.\n" +
" * To create an alias click on the (+), it creates a new blue one. To cancel a creation from the original just re-click, it will disappear.\n" +
" * To edit an alias. Delete it from the original then create a new one.\n" +
" * Blue ones are those which will be created and red ones are those which woill be deleted from the original.\n" +
"\n== Language ==\n" +
" * If a language doesn't appear in the table, click on (add new language) to add a new one.\n" +
" * You can search for a language in the field (search a language).\n" +
"\n== Other ==\n" +
" * Click on (reload) the re-download data from the server\n" +
" * Click on preview to see your change. You need to preview before saving.\n" +
"\n== Preview ==\n" +
" * Set a summary to explain your change. A summary of what you've changed is automatically added after your summary.");
//update all event
table.setEvent();
});
}
});
$(".ll-row").on("click",".ll-button-moveup",function(){
var currow = $(this).parents(".ll-row");
var prevrow = currow.prev();
if(!$.isEmptyObject(prevrow)){
table.swapRows(prevrow, currow);
}
});
$(".ll-row").on("click",".ll-button-movedown",function(){
var currow = $(this).parents(".ll-row");
var nextrow = currow.next();
if(!$.isEmptyObject(nextrow)){
table.swapRows(currow, nextrow);
}
});
$(".ll-row").on("click",".ll-button-insertbelow",function(){
// get current row details
var currow = $(this).parents(".ll-row");
var fend = parser.timeMs($(currow).find(".ll-endTime").text());
// get next row details
var lindex = parseInt(currow.attr("data-index"))+1;
var lstart = fend + 5000;
var nextrow = currow.next();
if(!$.isEmptyObject(nextrow)){
lstart = parser.timeMs($(nextrow).find(".ll-startTime").text());
}
// create new row
var newrow = $(table.addRow({
id: lindex.toString(),
startTime: parser.msTime(fend+50),
endTime: parser.msTime(lstart-50),
text: ""
}));
$(currow).after($(newrow));
// adjust rest of rows
$(newrow).nextAll().each(function(){
var newindex = (parseInt($(this).attr("data-index"))+1).toString();
$(this).attr("data-index",newindex);
$(this).find(".ll-index").text(newindex);
})
table.setEvent();
});
$(".ll-row").on("click",".ll-button-insertabove",function(){
// get current row details
var currow = $(this).parents(".ll-row");
var lstart = parser.timeMs($(currow).find(".ll-startTime").text());
// get next row details
var findex = parseInt(currow.attr("data-index"));
var fend = lstart - 5000;
var prevrow = currow.prev();
if(!$.isEmptyObject(prevrow)){
fend = parser.timeMs($(prevrow).find(".ll-endTime").text());
}
// create new row
var newrow = $(table.addRow({
id: findex.toString(),
startTime: parser.msTime(fend+50),
endTime: parser.msTime(lstart-50),
text: ""
}));
$(currow).before($(newrow));
// adjust rest of rows
$(newrow).nextAll().each(function(){
var newindex = (parseInt($(this).attr("data-index"))+1).toString();
$(this).attr("data-index",newindex);
$(this).find(".ll-index").text(newindex);
})
table.setEvent();
});
$(".ll-row").on("click",".ll-button-delete",function(){
// get current row details
var currow = $(this).parents(".ll-row");
var nextrow = currow.next();
$(currow).remove();
// adjust rest of rows
if(!$.isEmptyObject(nextrow)){
var newindex = (parseInt($(nextrow).attr("data-index"))-1).toString();
$(nextrow).attr("data-index",newindex);
$(nextrow).find(".ll-index").text(newindex);
$(nextrow).nextAll().each(function(){
var newindex = (parseInt($(this).attr("data-index"))-1).toString();
$(this).attr("data-index",newindex);
$(this).find(".ll-index").text(newindex);
})
}
table.setEvent();
});
},
getDiff: function () {
var ret = {};
$(".ll-row").each( function(){
var row = $(this);
var index = row.attr("data-index");
if(!ret.hasOwnProperty(index)){
ret[index] = {modified: 0};
["index", "startTime", "endTime", "text"].forEach(function(key){
row.find(".ll-col-"+key+" .ll-edited").each(function(){
ret[index][key] = {type: 1};
ret[index][key].new = $(this).text();
ret[index][key].old = $(this).prop("old");
ret[index].modified = 1;
});
row.find(".ll-col-"+key+" .ll-deleted").each(function(){
ret[index][key] = {type: -1};
ret[index][key].new = "[REMOVED]";
ret[index][key].old = $(this).prop("old");
ret[index].modified = 1;
});
row.find(".ll-col-"+key+" :not(.ll-deleted):not(.ll-edited)").each(function(){
ret[index][key] = {type: 0};
ret[index][key].new = $(this).text();
});
});
}
});
table.diff = ret;
return ret;
},
setDiff: function (data) {
for(var index in data){
var row = $(".ll-row[data-index="+index+"]");
["index", "startTime", "endTime", "text"].forEach(function(key){
if(data[index][key].type != 0){
var oldprop = data[index][key].old;
var replacementtext = "";
var newclass = 'll-deleted';
if(data[index][key].type == 1){
replacementtext = data[index][key].new;
newclass = 'll-edited';
}
row.find(".ll-"+key).prop("old",oldprop)
.text(replacementtext)
.addClass(newclass);
}
});
}
},
showDiffs: function () {
var data = this.getDiff();
this.tableElement.empty();
var ret = "";
for(var index in data){
if(data[index].modified != 0){
ret += "<div class='ll-row'>";
["index", "startTime", "endTime", "text"].forEach(function(key){
ret += '<div class="ll-preview-col ll-preview-' + key + '">';
if(data[index][key].type == 0){
ret += data[index][key].new;
}
else if(data[index][key].type == 1){
ret += '<div class="ll-preview-old">' + data[index][key].old + '</div>';
ret += '<div class="ll-preview-new">' + data[index][key].new + '</div>';
}
else if(data[index][key].type == -1){
ret += '<div class="ll-preview-del">' + data[index][key].old + '</div>';
}
ret += '</div>';
});
ret += '</div>';
}
}
this.tableElement.html(ret);
this.initResumeInput();
return ret;
},
lock: function () {
this.unEditCols();
$(table.tableElement).parents(".ll-table").addClass("ll-table-blocked");
},
unlock: function () {
this.unEditCols();
$(table.tableElement).parents(".ll-table").removeClass("ll-table-blocked");
},
head: function ( number ) {
var allHead = [1, 2];
if(allHead.indexOf(number) == -1){
throw "Wrong head number";
}
for(var i in allHead){
if(!allHead.hasOwnProperty(i)){
continue;
}
$(table.tableElement).parents(".ll-table").removeClass("ll-head" + allHead[i] );
$(".ll-form").removeClass("ll-form" + allHead[i] );
}
$(".ll-form").addClass("ll-form" + number );
$(table.tableElement).parents(".ll-table").addClass("ll-head" + number );
},
initResumeInput: function () {
$(".ll-preview-resume").prop("placeholder", "modified subtitles") // todo: reinsert some sort of summary
}
};
/**
* Write a line on the table
*/
function LlModel (Qid){
this.item = Qid;
this.lastrevid = 0;
}
LlModel.prototype = {
api: function (req, data) {
return $.ajax({
type: req,
url: mw.util.wikiScript('api'),
async: false,
data: data
});
},
view2subrip: function (data) {
var modified_subs = [];
for(var index in data){
modified_subs.push({ // todo: better handle deleted rows
id: data[index]["index"].new,
startTime: data[index]["startTime"].new,
endTime: data[index]["endTime"].new,
text: data[index]["text"].new
});
}
return parser.toSrt(modified_subs);
},
subrip2view: function (data) {
return parser.fromSrt(data["query"]["pages"][0]["revisions"][0]["content"]);
},
sendData: function ( data, resume ) {
var newtext = this.view2subrip(data);
if(this.lastrevid == 0){
console.log("Error 418", "Iâm a teapot!", false, true);
return false;
}
var success = false;
this.api("POST", {
action: "edit",
title: this.item,
summary: "modified subtitles", // todo: reinsert some sort of summary
text: newtext,
token: mw.user.tokens.get( 'csrfToken' ),
baserevid: this.lastrevid,
format: 'json'
}).done(function (data) {
if(data.hasOwnProperty("error")){
console.log("Error", "(" + data.error.code + ") " + data.error.info, true, false);
}else if(data.hasOwnProperty("edit")){
if(data["edit"].hasOwnProperty("result")){
if(data.edit.result == "Success"){
console.log("Success", "This edit has been correctly sent to the database", false, true);
success = true;
}
}
}
}).fail(function () {
alert("The request to the API failed.");
});
return success;
},
receiveData: function () {
var ret = {};
table.head(1);
this.api("GET", {
action: "query",
prop: "revisions",
titles: pageName,
rvprop: "content|ids",
formatversion: "2",
format: "json"
}).done(function (data) {
if(data.hasOwnProperty("error")){
console.log("Error", "(" + data.error.code + ") " + data.error.info, true, false);
return {};
}
try {
model.lastrevid = data["query"]["pages"][0]["revisions"][0]["revid"];
} catch (e) {
return;
}
ret = model.subrip2view(data);
}).fail(function () {
alert("The request to the API failed.");
});
return ret;
}
};
/**
* Object size
*/
function objectSize( obj ) {
var size = 0;
for(var key in obj){
if(!obj.hasOwnProperty(key)){
continue;
}
size++
}
return size;
};
/**
* Init instances of Class
*/
var table, model;
/**
* Init portlet and modal on the view
*/
function initCurrentPage () {
//Modal Content
var modalContent =
'<div id="subtitleEditorv0">' +
'<form class="ll-form" onsubmit="return false;">' +
'<div class="ll-twocol">' +
'<div class="ll-tablecontainer">' +
'<div class="ll-table wikitable">' +
'<div class="ll-tablehead">' +
'<div class="ll-head ll-head-lang">Index</div>' +
'<div class="ll-head ll-head-data">Start time</div>' +
'<div class="ll-head ll-head-type">End time</div>' +
'<div class="ll-head ll-head-lang">Text</div>' +
'</div>' +
'<div class="ll-tablecells">' +
'</div>' +
'</div>' +
'</div>' +
'<div class="ll-videopane">' +
'</div>' +
'</div>' +
'<div class="ll-preview-accept">' +
'<div><label for="ll-summary">Summary :</label></div>' +
'<input type="text" id="ll-summary" class="ll-preview-resume"/>' +
'<button class="ll-preview-send">Accept changes</button>' +
'<button class="ll-preview-return">Return to edits</button>' +
'<button class="ll-preview-cancel">Cancel</button>' +
'</div>' +
'</form>' +
'</div>';
//Modal location
var modalExec;
if ( document.getElementById( 'content' ) ) {
modalExec = $( modalContent ).appendTo( '#content' );
} else {
modalExec = $( modalContent ).appendTo( '#mw_content' );
}
//Modal Function
mw.loader.using( ['jquery.ui'], function () {
modalExec.dialog( {
title: '<img id="subtitleEditor-logo" src="//upload.wikimedia.org/wikipedia/commons/d/db/Symbol_list_class.svg" style="width:20px"> Subtitle editor',
autoOpen: false,
modal: true,
width: 1100,
height: 650,
show: 'blind',
hide: 'blind',
buttons: [ {
text: "Preview",
id: 'll-preview',
click: function () {
if(!$(table.tableElement).parents(".ll-table").hasClass("ll-table-blocked")) {
table.unEditCols();
table.lock();
table.head(2);
table.showDiffs();
}
}
},{
text: "Reload",
id: 'll-reload',
click: function () {
table.lock();
table.addRows(model.receiveData());
table.unlock();
}
}, {
text: "Close",
click: function () {
$( this ).dialog( 'close' );
}
} ]
} );
});
//Portlet Link options
if(mw.config.get('wgNamespaceNumber') == 102) {
var portletLinkNextNode = $.uls.data.isRtl( lang ) ? '#ca-view' : '#ca-history';
var portletId = ( mw.config.get( 'skin' ) === 'vector' ) ? 'p-views' : 'p-cactions';
var portletLink = mw.util.addPortletLink( portletId, '#', "Subtitle editor (BETA)", 't-subtitleEditor', "Edit subtitles", 'e', portletLinkNextNode );
}
//Portlet Link Action
$( portletLink ).click( function () {
$( 'div#subtitleEditorv0' ).dialog( 'open' );
$( 'div#subtitleEditorv0' ).dialog({
beforeClose: function(event, ui){
$(".ll-videopane").empty()
}
});
$('.ll-videopane').html($("#mwe_player_0").attr("videopayload"));
$('.ll-videopane video').get(0).pause();
$('.ll-videopane .mediaContainer').css('width',400);
$('.ll-videopane video').css('width',400)
.css('height','');
//On opening
table.addRows(model.receiveData());
table.unlock();
return false;
} );
//Init model Class
model = new LlModel (pageName);
//Init table Class
table = new LlTable ($(".ll-table .ll-tablecells"));
}
/**
* LOADER COMPONENT
*/
function preventLoader(){
var semaphore = false;
var interval = setInterval(function(){
if(!semaphore){
semaphore = true;
initCurrentPage();
window.clearInterval(interval);
}
},100);
}
$( preventLoader );
var ret = new Object();
ret.table = table;
ret.model = model;
return new LlTable();
} ( mediaWiki, jQuery ) );