(mw.config.get('wgNamespaceNumber') || mw.config.get('wgAction') !== 'view') &&
(function consecudiff() {
mw.loader.addStyleTag('.consecudiff::before{content:" ["} .consecudiff::after{content:"]"} .consecudiff-top::before{content:" ⟨"} .consecudiff-top::after{content:"⟩"}');
let isHist = mw.config.get('wgAction') === 'history';
class Consecudiff {
constructor(lis, isContribs) {
this.isContribs = isContribs;
this.isEnhanced = !isHist && !isContribs &&
lis[0].classList.contains('mw-enhanced-rc');
this.threshold = isContribs ? window.consecudiffContribsThreshold || 120
: isHist ? window.consecudiffHistThreshold || 720
: window.consecudiffThreshold || 720;
this.strictMode = !isContribs &&
!!window.consecudiffDetectInterruptions;
this.diffSelector = isHist
? 'a.mw-history-histlinks-previous'
: '.mw-changeslist-diff';
this.permaSelector = this.isEnhanced && '.mw-enhanced-rc-time > a' ||
(isHist || isContribs) && 'a.mw-changeslist-date';
this.hybridSelector = this.diffSelector;
if (this.permaSelector) {
this.hybridSelector = ', ' this.permaSelector;
}
this.topClass = isContribs
? 'mw-contributions-current'
: 'mw-changeslist-last';
let dependencies = ['mediawiki.util'];
if ((isHist || isContribs) && mw.config.get('wgUserLanguage') !== 'en') {
dependencies.push('mediawiki.language.months');
}
mw.loader.using(dependencies, () => {
let chunks;
if (isHist) {
chunks = this.chunkByUser(lis);
} else {
chunks = [];
this.groupByTitle(lis).forEach(group => {
chunks.push(...this.chunkByUser(group));
});
}
let subchunks = [];
chunks.forEach(chunk => {
subchunks.push(...this.divideByDate(chunk));
});
let linkPairs = [];
subchunks.forEach(subchunk => {
linkPairs.push(...this.makeLinks(subchunk));
});
linkPairs.forEach(([$span, parent]) => {
$span.appendTo(parent);
});
});
}
groupByTitle(lis) {
let selector = this.isContribs
? '.mw-contributions-title'
: '.mw-changeslist-title';
let lisByTitle = {};
lis.forEach(li => {
let link = (this.isEnhanced ? li.closest('table') : li)
.querySelector(selector);
if (!link) return;
let title = link.textContent;
if (!lisByTitle.hasOwnProperty(title)) {
lisByTitle[title] = [];
}
lisByTitle[title].push(li);
});
return Object.values(lisByTitle).filter(group => group.length > 1);
}
chunkByUser(lis) {
if (this.isSingleContribs) {
return [lis];
}
let chunks = [], lastSplitAt = 0, prevUser;
this.isSingleContribs = lis.some((li, i) => {
let link = li.querySelector('.mw-userlink');
if (!link && this.isContribs) {
return true;
}
let user = link && link.textContent;
if (!link || i && user !== prevUser) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevUser = user;
});
if (this.isSingleContribs) {
return [lis];
}
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
divideByDate(lis) {
let chunks = [], lastSplitAt = 0, prevDate;
lis.forEach((li, i) => {
let date;
if (isHist || this.isContribs) {
date = this.parseDate(
li.querySelector('.mw-changeslist-date').textContent
);
} else {
date = Date.parse(
li.dataset.mwTs.replace(/(....)(..)(..)(..)(..)(..)/, '$1-$2-$3T$4:$5:$6Z')
);
}
if (date) {
date = date / 60000;
}
if (i && prevDate - date > this.threshold) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
prevDate = date;
if (!this.strictMode || lastSplitAt === i) return;
let prevDiff = lis[i - 1].querySelector(this.diffSelector);
if (prevDiff) {
let prevNext = mw.util.getParamValue('oldid', prevDiff.search);
if (prevNext !== li.dataset.mwRevid) {
chunks.push(lis.slice(lastSplitAt, i));
lastSplitAt = i;
}
}
});
chunks.push(lis.slice(lastSplitAt));
return chunks.filter(chunk => chunk.length > 1);
}
makeLinks(lis) {
let count = lis.length;
let firstPerma;
let start = lis.findIndex(li => (
firstPerma = li.querySelector(this.hybridSelector)
));
if (start === -1 || count - start < 2) return [];
let end, lastDiff;
for (let i = count - 1; i > start; i--) {
if (!isHist && !this.isContribs) {
lastDiff = lis[i].querySelector(this.diffSelector);
if (lastDiff ||
lis[i].classList.contains('mw-changeslist-src-mw-new')
) {
end = i 1;
break;
}
}
if (this.permaSelector && lis[i].querySelector(this.permaSelector)) {
end = i 1;
break;
}
}
if (!end) return [];
count = end - start;
let params = { diff: lis[start].dataset.mwRevid };
if (lastDiff) {
params.oldid = mw.util.getParamValue('oldid', lastDiff.search);
} else {
params.oldid = lis[end - 1].dataset.mwRevid;
if (isHist && lis[end - 1].querySelector(this.diffSelector) ||
this.isContribs && !lis[end - 1].querySelector('.newpage')
) {
params.direction = 'prev';
}
}
let title = !isHist && mw.util.getParamValue('title', firstPerma.search);
let url = mw.util.getUrl(title, params);
let classes = 'consecudiff';
if (!isHist && lis[start].classList.contains(this.topClass)) {
classes = ' consecudiff-top';
}
return lis.slice(start, end).map((li, i) => [
$('<span>').addClass(classes).append(
$('<a>')
.attr('href', url)
.text(this.convertNumber(count - i '/' count))
),
this.isEnhanced
? li.tagName === 'TR'
? li.lastElementChild
: li.querySelector('.mw-changeslist-line-inner')
: li
]);
}
parseDate(s) {
let date = Date.parse(s);
if (date) {
return date;
}
if (s.includes(',')) date = Date.parse(s.replace(',', ''));
if (date) {
return date;
}
if (mw.loader.getState('mediawiki.language.months') !== 'ready') return;
s = s.replace(/\D/g, c => {
let n = mw.language.convertNumber(c, true);
return Number.isNaN(n) ? c : n;
});
let h, m;
s = s.replace(/(\d\d?)[.:h](\d\d?)/, ($0, $1, $2) => {
h = $1;
m = $2;
return ' ';
});
if (!h) return;
let y, dateFirst;
s = s.replace(/^(.*?)(\d{4})(?!\d)/, ($0, $1, $2) => {
y = $2;
dateFirst = /\d/.test($1);
return $1 ' ';
});
if (!y) return;
let mo, d;
if (dateFirst) {
[d, s] = this.getDate(s);
if (!d) return;
[mo, s] = this.getMonth(s);
if (mo === -1) return;
} else {
[mo, s] = this.getMonth(s);
if (mo === -1) return;
[d, s] = this.getDate(s);
if (!d) return;
}
return new Date(y, mo, d, h, m).getTime();
}
getMonth(s) {
if (!this.months) {
this.months = mw.language.months.abbrev
.concat(mw.language.months.names, mw.language.months.genitive)
.reverse();
}
let mo = this.months.findIndex(mn => {
let temp = s.replace(mn, ' ');
if (temp !== s) {
s = temp;
return true;
}
});
if (mo === -1) {
let [numeric, temp] = this.getDate(s);
numeric = parseInt(numeric);
if (numeric > 0 && numeric < 13) {
mo = numeric - 1;
s = temp;
}
} else {
mo = 11 - mo % 12;
}
return [mo, s];
}
getDate(s) {
let d;
s = s.replace(/(^|\D)(\d\d?)(?!\d)/, ($0, $1, $2) => {
d = $2;
return $1 ' ';
});
return [d, s];
}
convertNumber(num) {
try {
return mw.language.convertNumber(num);
} catch (e) {
return num;
}
}
}
mw.hook('wikipage.content').add($content => {
$content.find('.mw-pager-body').each(function () {
let lis = this.querySelectorAll('.mw-contributions-list > li');
if (lis.length > 1) {
new Consecudiff([...lis], !isHist);
}
});
if (isHist) return;
let $lists = $content.filter('.mw-changeslist');
if (!$lists.length) {
$lists = $content.find('.mw-changeslist');
}
$lists.each(function () {
let lis = this.querySelectorAll('.mw-changeslist-edit:not(.mw-changeslist-src-mw-categorize)[data-mw-revid]');
if (lis.length > 1) {
new Consecudiff([...lis]);
}
});
});
}());