Користувач:Sergento/addQuote.js
Увага: Після публікування слід очистити кеш браузера, щоб побачити зміни.
- Firefox / Safari: тримайте Shift, коли натискаєте Оновити, або натисніть Ctrl-F5 чи Ctrl-Shift-R (⌘-R на Apple Mac)
- Google Chrome: натисніть Ctrl-Shift-R (⌘-Shift-R на Apple Mac)
- Internet Explorer / Edge: тримайте Ctrl, коли натискаєте Оновити, або натисніть Ctrl-F5
- Opera: натисніть Ctrl-F5
if( window.AddQuoteToPage === undefined ) {
window.AddQuoteToPage = {
fields: {},
pageid: 0,
pagetitle: '',
pagecontent: '',
pagesections: {},
pagesources: [],
sourcesectionpos: -1,
install: function () {
var aqp = this;
aqp.Caption = 'Додати цитату';
var pLink = mw.util.addPortletLink( 'p-views', '#', aqp.Caption, 'ca-addquote', 'Add quote', '', '#ca-history' );
$( pLink ).click( function ( e ) {
e.preventDefault();
aqp.requestQuote();
});
},
requestQuote: function () {
var aqp = this;
if( $( '#aqp-dialog' ).length === 0 ) {
aqp.createDialog();
}
mw.loader.using( 'jquery.ui', function () {
$( '#aqp-dialog' ).dialog({
width: 400,
buttons: {
'Зберегти': function () {
aqp.saveQuote();
}
}
});
});
},
saveQuote: function() {
var qText = $( '#aqp-quote' ).val();
var qOrig = $( '#aqp-original' ).val();
var qComm = $( '#aqp-comment' ).val();
var qAuth = $( '#aqp-author' ).val();
var qSrce = $( '#aqp-source' ).val().trim();
var newContent = this.pagecontent;
var needRefs = false;
if (qSrce !== '')
{
if (this.pagesources.indexOf(qSrce) > -1)//якщо існуюче джерело
{
// якщо воно уже примітка
if (qSrce.search(/<ref[^>]*(\/>|>[^<]*<\/ref>)/) === 0)
{
var nameMatch = /<ref[^>]*name[ ]*=[ ]*"([^"]*)"[^>]*>/.exec(qSrce);
if (nameMatch !== null) // якщо примітка вже має назву - додаємо її за назвою
{
qSrce = '<ref name="'+ nameMatch[1] +'"/>';
}
// а якщо не має...
else
{
// визначаємо назву
var refName = this.getSourceCaption(qSrce);
if (refName === qSrce || refName.search('"') > -1) // якщо коротку назву не вдається визначити, або якщо вона містить лапки, треба звагранити шось унікальне
{
refName = new Date().getTime(); // напр. так...
}
// тепер треба підставити у тексті цю примітку уже із назвою.
newContent = newContent.replace(qSrce, qSrce.replace('<ref', '<ref name="' + refName + '"'));
// а до нової цитати додається тільки як назва
qSrce = '<ref name="' + refName + '"/>';
}
}
else
// інакше додаємо його ще і як примітку
{
qSrce = '<ref>' + this.getSourceCaption() + '</ref>';
needRefs = true; // переконатися, що є розділ з примітками
}
}
else
{
// якщо нове джерело, треба переконатися, що є розділ для приміток і оформити саме джерело як примітку, якщо треба
needRefs = true;
if (qSrce.search('<ref') !== 0)
qSrce = '<ref>' + qSrce + '</ref>';
}
}
var newQuote = '{{Q\n|Цитата = ' + qText;
newQuote = newQuote + qSrce;
newQuote = newQuote + '\n|Оригінал = ' + qOrig + '\n|Коментар = ' + qComm + '\n|Автор = ';
var aDif = false;
if (qAuth !== '' && qAuth.trim() != this.pagetitle)
{
newQuote = newQuote + qAuth;
aDif = true;
}
newQuote = newQuote + '\n}}\n\n';
// якщо є розділи - треба помістити новий контент у потрібне місце
if (this.pagesections.length > 0)
{
var qFrom = -1;
var hRegex = RegExp('==( )*цитат[^=]*==', 'gi');
for (var i = 0; i<this.pagesections.length; i++)
{
if (hRegex.test(this.pagesections[i]))
{
qFrom = i;
break;
}
}
var qAbout = -1;
hRegex = RegExp('==( )*про[^=]*==', 'gi');
for (i = 0; i<this.pagesections.length; i++)
{
if (hRegex.test(this.pagesections[i]))
{
qAbout = i;
break;
}
}
var isPerson = /{{особа/gi.test(this.pagecontent);
var place = -1;
var header = 'Цитати';
if (!aDif)
{
place = qFrom;
}
else
{
if (isPerson)
{
place = qAbout;
header = 'Про';
}
else
if (qAbout > 0)
{
place = qAbout;
header = 'Про';
}
else
place = qFrom;
}
if (place < 0)
newQuote = '== ' + header + ' ==\n' + newQuote;
newContent = this.addToSection(newQuote, place, newContent);
// якщо потрібно додати розділ приміток
if (needRefs)
{
// якщо його ще нема
if (this.pagecontent.indexOf('{{reflist') < 0 && this.pagecontent.indexOf('<references') < 0)
{
// він має бути наступним за всіма (першими двома?) цитатами
place = Math.max(qFrom, qAbout);
newContent = this.addToSection('== Примітки ==\n{{reflist}}\n', place, newContent);
}
}
}
else
{
// якщо нема розділів - створити потрібні
if (aDif)
{
newContent = this.addToTheEnd('== Про ==\n' + newQuote, newContent);
}
else
{
newContent = this.addToTheEnd('== Цитати ==\n', newContent);
}
if (needRefs)
{
newContent = this.addToTheEnd('== Примітки ==\n{{reflist}}\n', newContent);
}
}
this.writePage(newContent);
},
addToSection: function(textToAdd, sectionNumber, content){
// якщо потрібний розділ останній - додаємо в кінець
if (sectionNumber >= this.pagesections.length)
{
return this.addToTheEnd(textToAdd, content);
}
else
{
// якщо неостанній - додаємо новий вміст в кінець розділу
where = RegExp('\n(?:\n)*' + this.pagesections[sectionNumber+1]).exec(content);
return this.addToTheEnd(textToAdd, content.slice(0, where.index + 1)) + content.slice(where.index + 1);
}
},
addToTheEnd: function(textToAdd, textAddTo){
var templs = textAddTo.match(RegExp('{{([^}|]*)(?:\\|[^}]*?|)}}', 'gi'));
var templPos = textAddTo.length;
var catPos = textAddTo.length;
var qExists = false;
var catMatch = RegExp('\\[\\[Категорія:[^\\]]*?]]').exec(textAddTo);
if (catMatch !== null)
catPos = catMatch.index;
// якщо останнім у розділі є не шаблон цитати - шукаємо його позицію
if (templs.length > 0)
{
for (var i = templs.length - 1; i >= 0; i--)
{
var templMatch = /{{([^}|]*)(?:\\|[^}]*?|)}}/.exec(templs[i]);
if (templMatch[1].trim() !== 'Q')
{
templPos = RegExp(templs[i]).exec(textAddTo).index;
}
else
{
qExists = true;
break;
}
}
}
// якщо є шаблон Q і є категорія, чи шаблон не цитати - додаємо перед ним
if (qExists && (templPos < textAddTo.length || catPos < textAddTo.length))
{
return textAddTo.slice(0, Math.min(templPos, catPos)) + textToAdd + textAddTo.slice(Math.min(templPos, catPos));
}
// інакше - просто в кінець
else
{
return textAddTo.trim() + '\n\n' + textToAdd;
}
},
writePage: function(newPageContent){
var apiParams = {
format: 'json',
action: 'edit',
pageid: this.pageid,
summary: 'adding quote with QuoteAdder (test)',
text: newPageContent,
token: mw.user.tokens.get('csrfToken')
};
$.post(mw.util.wikiScript('api'), apiParams, function() {
location.reload();
});
},
createDialog: function() {
$( '#mw-content-text' ).append('<div id="aqp-dialog" style="display:none;" title="' + this.Caption + '"></div>');
var aqp = this;
mw.util.addCSS( '#aqp-dialog input:not([type="checkbox"]) { width:100%; height: 1.3em; } #aqp-dialog p { margin-bottom: 0; }' );
mw.util.addCSS( '#aqp-srclinks li { cursor:pointer; font-size:90%; }' );
var param = {
action: 'query',
prop: 'revisions',
format: 'json',
rvprop: 'content',
rvlimit: '1',
titles: mw.config.get('wgPageName'),
indexpageids: ''
};
$.get(mw.util.wikiScript('api'), param).done(function(data)
{
aqp.pageid = data.query.pages[data.query.pageids[0]].pageid;
aqp.pagetitle = data.query.pages[data.query.pageids[0]].title;
aqp.pagecontent = data.query.pages[data.query.pageids[0]].revisions[0]['*'];
aqp.addInput('Цитата', 'quote');
aqp.addInput('Оригінал', 'original');
aqp.addInput('Коментар', 'comment');
aqp.addInput('Автор', 'author', aqp.pagetitle, 'text');
aqp.addInput('Джерело', 'source', undefined, 'text');
// пошук виносок
var hRE = RegExp('==[^=]*==', 'gi');
aqp.pagesections = aqp.pagecontent.match(hRE);
hRE = RegExp('<ref[^/>]*?>(?:.|\n)*?<\\/ref>', 'gi');
aqp.pagesources = aqp.pagecontent.match(hRE);
if (aqp.pagesources == null)
{
aqp.pagesources = new Array();
}
// пошук джерел
var section = '';
hRE = RegExp('\\* *((?:[^{}\\*]*)?(?:{{(?:[^{}]*)}})?(?:[^{}\\^\\*]*)?)', 'gi');
var hRegex = RegExp('==( )*джерел[^=]*==', 'gi');
for (var i = 0; i<aqp.pagesections.length; i++)
{
if (hRegex.test(aqp.pagesections[i]))
{
aqp.sourcesectionpos = i;
var section = aqp.pagecontent.slice(aqp.pagecontent.indexOf(aqp.pagesections[i]));
if (i+1 < aqp.pagesections.length)
{
section = section.slice(aqp.pagecontent.indexOf(aqp.pagesections[i+1]))
}
while ((m = hRE.exec(section)) != null)
{
aqp.pagesources.push(m[1]);
}
break;
}
}
aqp.addInput('нова книга', '', '{{книга|автор=|заголовок=|посилання=|місто=|видавництво=|рік=|сторінок=|isbn=|ref=}}', 'srclink');
aqp.addInput('нове посилання', '', '{{Cite web|url=|title=|accessdate=|author=|date=}}', 'srclink');
for (var i = 0; i < aqp.pagesources.length; i++)
{
if (!/<ref[^\/>]*?>( |\n)*<\/ref>/gi.test(aqp.pagesources[i])) // перевірка на порожні теги
aqp.addInput(aqp.getSourceCaption(aqp.pagesources[i]), '', aqp.pagesources[i], 'srclink');
}
});
},
addSource: function(src){
var t = src.currentTarget.title;
var qSrce = $( '#aqp-source' );
qSrce.val(t.replace(/"/g, '"'));
},
getSourceCaption: function(src){
var result = src;
var srcReg = RegExp('{{книга[^}]*\\|заголовок=([^|}]*)[^}]*}}', 'i');
var srcReg1 = RegExp('{{книга[^}]*\\|рік=([^|}]*)[^}]*}}', 'i');
while ((match = srcReg.exec(result)) != null)
{
var bookHeader = match[1];
var year = srcReg1.exec(src);
if (year != null)
{
bookHeader = bookHeader + ', ' + year[1];
}
result = result.replace(match[0], bookHeader.trim());
}
srcReg = RegExp('{{(?:C|c)ite(?:_| )web[^}]*\\|title=([^|}]*)[^}]*}}', 'i');
srcReg1 = RegExp('{{(?:C|c)ite(?:_| )web[^}]*\\|date=([^|}]*)[^}]*}}', 'i');
while ((match = srcReg.exec(result)) != null)
{
var articleHeader = match[1];
var year = srcReg1.exec(src);
if (year != null)
{
articleHeader = articleHeader + ', ' + year[1];
}
result = result.replace(match[0], articleHeader.trim());
}
srcReg = RegExp('\\[(?:http(?:s|):\\/\\/|(?=www\\.))((?:www\\.|)[^\\/ ]*)[^ ]*([^\\]]*)\\]', 'i');
while ((match = srcReg.exec(result)) != null)
{
result = result.replace(match[0], (match[2] + ' (' + match[1] + ')').trim());
}
result = result.replace(/<ref[^>]*>/, '');
result = result.replace(/<\/[ ]*ref[^>]*>/, '');
return result;
},
isBook: function(src){
var srcReg = RegExp('{{книга[^}]*\\|заголовок=([^|}]*)[^}]*}}', 'i');
return srcReg.exec(src) != null;
},
addInput: function (text, id, value, kind) {
this.fields[text] = id;
if (kind === 'srclink')
{
if ($( '#aqp-srclinks' ).length === 0)
{
$( '#aqp-dialog' ).append('<ul id="aqp-srclinks" >');
}
}
else
{
$( '#aqp-dialog' ).append('<div>');
}
switch (kind)
{
case 'text':
$( '#aqp-dialog div' ).last().append('<p>' + text + ':</p><input id="aqp-' + id + '" value="' + (value || '') + '" />');
break;
case 'srclink':
var aqp = this;
$( '#aqp-srclinks' ).last().append('<li class="aqp-sourceitem" title="' + value.replace(/"/g, '"') + '" >' + text + '</li>');
$( '#aqp-srclinks li' ).last().click( function ( e ) {
e.preventDefault();
aqp.addSource(e);
});
break;
default:
$( '#aqp-dialog div' ).last().append('<p>' + text + ':</p><textarea id="aqp-' + id + '" >' + (value || '') + '</textarea>');
break;
}
},
};
}
$( document ).ready(function () {
if(mw.config.get( 'wgNamespaceNumber' ) === 0 && !mw.config.get( 'wgIsMainPage' ))
AddQuoteToPage.install();
});