مستخدم:لوقا/PendingEditsChecker.js
يمكن توفير توثيق لسكربت المستخدم هذا في الصفحة : مستخدم:لوقا/PendingEditsChecker. |
ملاحظة: بعد الحفظ، قد يلزمك إفراغ الكاش لرؤية التغييرات ( ).
/**
* PendingEditsChecker is a singleton class that checks for pending edits
* on a Wikipedia page and displays a message box with details about the pending edits
* and the last review date.
*/
class PendingEditsChecker {
constructor() {
// If an instance already exists, return it to maintain the singleton pattern
if (PendingEditsChecker.instance) {
return PendingEditsChecker.instance;
}
// Initialize the page title and API instance
this.pageTitle = mw.config.get('wgPageName');
this.api = new mw.Api();
PendingEditsChecker.instance = this;
// Initialize the checker
this.init();
}
/**
* Gets the singleton instance of the PendingEditsChecker class.
* @returns {PendingEditsChecker} The singleton instance.
*/
static getInstance() {
if (!PendingEditsChecker.instance) {
PendingEditsChecker.instance = new PendingEditsChecker();
}
return PendingEditsChecker.instance;
}
/**
* Initializes the checker by setting up an event listener
* that triggers the check for pending edits when the page is in view mode.
*/
init() {
// Check if the page is in view mode
if (mw.config.get('wgAction') === 'view') {
document.addEventListener('DOMContentLoaded', this.checkPendingEdits.bind(this));
}
}
/**
* Checks for pending edits by comparing the latest revision with the last reviewed revision.
* If there are pending edits, it calls the method to display the message box.
*/
checkPendingEdits() {
this.api.get({
action: 'query',
prop: 'revisions',
titles: this.pageTitle,
rvprop: 'ids|timestamp',
rvlimit: 'max',
formatversion: 2,
}).then((data) => {
const page = data.query.pages[0];
const revisions = page.revisions;
const latestRevisionId = revisions[0].revid;
const latestRevisionTimestamp = this.formatTimestamp(revisions[0].timestamp);
// Fetch the latest reviewed revision (if available)
this.api.get({
action: 'query',
prop: 'flagged',
titles: this.pageTitle,
formatversion: 2,
}).then((flaggedData) => {
const flaggedPage = flaggedData.query.pages[0];
const reviewedRevisionId = flaggedPage.flagged.stable_revid;
// Fetch and format the last review date
this.getFormattedLastReviewDate().then((reviewedRevisionTimestamp) => {
// Count the number of pending edits
const pendingEdits = revisions.filter(revision => revision.revid > reviewedRevisionId).length;
if (pendingEdits > 0) {
this.displayMessageBox(latestRevisionId, reviewedRevisionId, latestRevisionTimestamp, reviewedRevisionTimestamp, pendingEdits);
}
});
});
});
}
/**
* Fetches the last review log data from the MediaWiki API.
* @returns {Promise<Object|null>} A promise that resolves to the last review log entry or null if not found.
*/
fetchLastReviewLog() {
return this.api.get({
action: 'query',
list: 'logevents',
letype: 'review',
letitle: this.pageTitle,
lelimit: 1,
leprop: 'user|timestamp|comment|details',
formatversion: 2,
}).then((data) => {
if (data.query.logevents && data.query.logevents.length > 0) {
return data.query.logevents[0];
} else {
return null;
}
}).catch((error) => {
console.error("Error fetching review log data:", error);
return null;
});
}
/**
* Returns the Arabic name of a month given its numeric value.
* @param {string} month - The numeric month value (e.g., '01' for January).
* @returns {string} The Arabic name of the month.
*/
getArabicMonth(month) {
switch (month) {
case '01': return 'يناير';
case '02': return 'فبراير';
case '03': return 'مارس';
case '04': return 'أبريل';
case '05': return 'مايو';
case '06': return 'يونيو';
case '07': return 'يوليو';
case '08': return 'أغسطس';
case '09': return 'سبتمبر';
case '10': return 'أكتوبر';
case '11': return 'نوفمبر';
case '12': return 'ديسمبر';
default: return 'غير معروف';
}
}
/**
* Formats a given timestamp into a readable date string in Arabic.
* @param {string} timestamp - The timestamp to format.
* @returns {string} The formatted date string in the format "day month year".
*/
formatTimestamp(timestamp) {
try {
const date = new Date(timestamp);
const day = date.getDate();
const month = this.getArabicMonth(String(date.getMonth() + 1).padStart(2, '0'));
const year = date.getFullYear();
return `${day} ${month} ${year}`;
} catch (error) {
console.error('Error formatting timestamp:', error);
return 'تاريخ غير متوفر';
}
}
/**
* Fetches the last review log data and formats the timestamp of the last review.
* @returns {Promise<string>} A promise that resolves to the formatted last review date string.
*/
async getFormattedLastReviewDate() {
const lastReview = await this.fetchLastReviewLog();
if (lastReview) {
return this.formatTimestamp(lastReview.timestamp);
} else {
return 'تاريخ غير متوفر';
}
}
/**
* Displays a message box with details about the pending edits and the last review date.
* @param {number} latestRevisionId - The ID of the latest revision.
* @param {number} reviewedRevisionId - The ID of the last reviewed revision.
* @param {string} latestRevisionTimestamp - The timestamp of the latest revision.
* @param {string} reviewedRevisionTimestamp - The timestamp of the last reviewed revision.
* @param {number} pendingEdits - The number of pending edits.
*/
displayMessageBox(latestRevisionId, reviewedRevisionId, latestRevisionTimestamp, reviewedRevisionTimestamp, pendingEdits) {
// Create a box to display the message with a link
const messageBox = document.createElement('div');
messageBox.style.marginBottom = '10px';
messageBox.style.marginTop = '10px';
messageBox.classList.add(
'mw-message-box',
'cdx-message',
'cdx-message--block',
);
// Determine the correct text based on the number of pending edits
let pendingEditsText = '';
if (pendingEdits === 1) {
pendingEditsText += 'تعديل واحد';
} else if (pendingEdits === 2) {
pendingEditsText += 'تعديلان';
} else if (pendingEdits > 2) {
pendingEditsText += `${pendingEdits} تعديلات`;
}
// Create the message text with the stable version link embedded in the "فحصت" part
const messageText = document.createElement('span');
messageText.innerHTML = `${pendingEditsText} في هذه النسخه <a href="https://ar.wikipedia.org/wiki/%D8%AA%D8%B9%D8%AF%D9%8A%D9%84%D8%A7%D8%AA_%D9%85%D8%B9%D9%84%D9%82%D8%A9">معلق للمراجعة</a>.<a href="${mw.util.getUrl(this.pageTitle, { oldid: reviewedRevisionId })}"> فحصت النسخة المستقرة</a> في ${reviewedRevisionTimestamp}.`;
// Create a link with the diff URL
const diffLink = document.createElement('a');
diffLink.href = mw.util.getUrl(this.pageTitle, {
diff: latestRevisionId,
oldid: reviewedRevisionId
});
diffLink.textContent = ' [اظهر الفرق] ';
// Create a new span element for the icon
const spanElement = document.createElement('span');
spanElement.className = 'cdx-message__icon';
// Append elements to the message box
messageBox.appendChild(spanElement);
messageBox.appendChild(diffLink);
messageBox.appendChild(messageText);
messageBox.appendChild(document.createElement('br')); // Add line break
// Insert the box before the content
const content = document.getElementById('mw-content-text');
if (content) {
content.parentNode.insertBefore(messageBox, content);
}
}
}
// Instantiate the singleton
PendingEditsChecker.getInstance().checkPendingEdits();