User:Bosco/Unsigned helper.js: Difference between revisions

From Test Wiki
Content deleted Content added
findRevisionWhenTextAdded: testFunc: better handling of results of LazyFullRevisionsLoader.loadContent
LazyRevisionIdsLoader#loadIntervalsRecursive: fix logic of checking `response.batchcomplete`. LazyRevisionIdsLoader#loadInterval: fix code of getting `.rvcontinue` from `this.#historyIntervalPromises`
Line 61: Line 61:


#getLastLoadedInterval(upToIndex) {
#getLastLoadedInterval(upToIndex) {
debug(`#getLastLoadedInterval(${upToIndex}): `, this.#historyIntervalPromises.length);
let i = 0;
let i = 0;
while (this.#historyIntervalPromises[i] != undefined && i <= upToIndex) {
while (this.#historyIntervalPromises[i] != undefined && i <= upToIndex) {
i++;
i++;
}
}
debug(`#getLastLoadedInterval(${upToIndex}) = ${i}`);
return [i, this.#historyIntervalPromises[i - 1]];
return [i, this.#historyIntervalPromises[i - 1]];
}
}
Line 72: Line 74:
return undefined;
return undefined;
}
}
return {
const interval = {
rvcontinue: response.continue?.rvcontinue,
rvcontinue: response.continue?.rvcontinue,
revisions: response.query.pages[0].revisions,
revisions: response.query.pages[0].revisions,
};
};
if (response.batchcomplete) {
// remember that MediaWiki has no more revisions to return
interval.batchcomplete = true;
} else {
interval.batchcomplete = false;
}
return interval;
}
}


async #loadIntervalsRecursive(index, upToIndex, rvcontinue) {
async #loadIntervalsRecursive(startIndex, targetIndex, rvcontinue) {
return new Promise(async (resolve, reject) => {
return new Promise(async (resolve, reject) => {
// reference documentation: https://en.wikipedia.org/w/api.php?action=help&modules=query%2Brevisions
// reference documentation: https://en.wikipedia.org/w/api.php?action=help&modules=query%2Brevisions
Line 94: Line 103:
intervalQuery.rvcontinue = rvcontinue;
intervalQuery.rvcontinue = rvcontinue;
}
}
debug('loadIntervalsRecursive Q: index =', index, 'upToIndex =', upToIndex, 'intervalQuery =', intervalQuery);
debug('loadIntervalsRecursive Q: startIndex =', startIndex, 'targetIndex =', targetIndex, 'intervalQuery =', intervalQuery);
this.#api.get(intervalQuery).then(async (response) => {
this.#api.get(intervalQuery).then(async (response) => {
try {
try {
// debug('loadIntervalsRecursive R:', response);
// debug('loadIntervalsRecursive R:', response);
const interval = this.#createIntervalFromResponse(response);
const interval = this.#createIntervalFromResponse(response);
this.#historyIntervalPromises[index] = Promise.resolve(interval);
this.#historyIntervalPromises[startIndex] = Promise.resolve(interval);
if (index == upToIndex) {
if (startIndex == targetIndex) {
// we've hit the limit of what we want to load so far
// we've hit the limit of what we want to load so far
resolve(interval);
resolve(interval);
return;
}
if (response.batchcomplete) {
for (let i = index; i <= upToIndex; i++) {
this.#historyIntervalPromises[i] = Promise.resolve(undefined);
}
// we've asked for an interval of history which doesn't exist
resolve(undefined);
return;
return;
}
}
// recursive call for one more interval
// recursive call for one more interval
const ignored = await this.#loadIntervalsRecursive(index + 1, upToIndex, interval.rvcontinue);
const ignored = await this.#loadIntervalsRecursive(startIndex + 1, targetIndex, interval.rvcontinue);
if (this.#historyIntervalPromises[upToIndex] == undefined) {
if (this.#historyIntervalPromises[targetIndex] == undefined) {
resolve(undefined);
resolve(undefined);
return;
return;
}
}
this.#historyIntervalPromises[upToIndex].then(
this.#historyIntervalPromises[targetIndex].then(
result => resolve(result),
result => resolve(result),
rejection => reject(rejection)
rejection => reject(rejection)
Line 133: Line 134:


async #loadInterval(intervalIndex) {
async #loadInterval(intervalIndex) {
const [firstNotLoadedIntervalIndex, latestLoadedInterval] = this.#getLastLoadedInterval(intervalIndex);
const [firstNotLoadedIntervalIndex, latestLoadedIntervalPromise] = this.#getLastLoadedInterval(intervalIndex);
if (firstNotLoadedIntervalIndex > intervalIndex) {
if (firstNotLoadedIntervalIndex > intervalIndex) {
return this.#historyIntervalPromises[intervalIndex];
return this.#historyIntervalPromises[intervalIndex];
}
}
if (await latestLoadedIntervalPromise?.then(interval => interval.batchcomplete)) {
const rvcontinue = latestLoadedInterval?.rvcontinue;
// latest request returned the last batch in the batch loading of revisions
return Promise.resolve(undefined);
}
const rvcontinue = await latestLoadedIntervalPromise?.then(interval => interval.rvcontinue);
debug(`#loadInterval(${intervalIndex}): ${firstNotLoadedIntervalIndex}, ${rvcontinue}`);
return this.#loadIntervalsRecursive(firstNotLoadedIntervalIndex, intervalIndex, rvcontinue);
return this.#loadIntervalsRecursive(firstNotLoadedIntervalIndex, intervalIndex, rvcontinue);
}
}
Line 147: Line 153:
#indexToIndexInInterval(index) {
#indexToIndexInInterval(index) {
return index % LAZY_REVISION_LOADING_INTERVAL;
return index % LAZY_REVISION_LOADING_INTERVAL;
}

#revisionsToString(revisions) {
if (!revisions) {
return "<undefined revisions>";
}
return Array.from(revisions).map((revision, index) => {
return `[${index}]={revid=${revision.revid} by User:${revision.user}}`
}).join(", ");
}
}


Line 158: Line 173:
const promise = new Promise(async (resolve, reject) => {
const promise = new Promise(async (resolve, reject) => {
const intervalIndex = this.#indexToIntervalIndex(index);
const intervalIndex = this.#indexToIntervalIndex(index);
debug(`loadRevision: loading from interval #${intervalIndex}...`);
try {
try {
const interval = await this.#loadInterval(intervalIndex);
const interval = await this.#loadInterval(intervalIndex);
debug(`loadRevision: loaded the interval#${intervalIndex} with revisions: (length=${interval?.revisions?.length})`);
// debug(`loadRevision: loaded the interval#${intervalIndex} with revisions: (length=${interval?.revisions?.length}) ${this.#revisionsToString(interval?.revisions)}`);
if (interval == undefined) {
if (interval == undefined) {
resolve(undefined);
resolve(undefined);
return;
return;
}
}
const theRevision = interval.revisions[this.#indexToIndexInInterval(index)];
const indexInInterval = this.#indexToIndexInInterval(index);
debug(`loadRevision: from the above interval, looking at [${indexInInterval}]`);
const theRevision = interval.revisions[indexInInterval];
debug('loadRevision: loaded revision', index, theRevision);
debug('loadRevision: loaded revision', index, theRevision);
resolve(theRevision);
resolve(theRevision);
Line 326: Line 346:
}
}
const maxIndex = (startIndex === 0) ? null : (await this.#findMaxIndex());
const maxIndex = (startIndex === 0) ? null : (await this.#findMaxIndex());
// const maxIndex = (await this.#findMaxIndex());
info('findRevisionWhenTextAdded: maxIndex =', maxIndex);
const foundIndex = await exponentialSearch(startIndex, maxIndex, startIndex + 10, async (candidateIndex, progressInfo) => {
const foundIndex = await exponentialSearch(startIndex, maxIndex, startIndex + 10, async (candidateIndex, progressInfo) => {
try {
try {
Line 611: Line 633:


window.unsignedHelperAddUnsignedTemplate = function(event) {
window.unsignedHelperAddUnsignedTemplate = function(event) {
mw.loader.using(['mediawiki.util', 'jquery.ui'], doAddUnsignedTemplate);
event.preventDefault();
event.preventDefault();
event.stopPropagation();
event.stopPropagation();
mw.loader.using(['mediawiki.util', 'jquery.ui'], doAddUnsignedTemplate);
return false;
return false;
}
}