User:Chlod/Scripts/Deputy.js: Difference between revisions

Content deleted Content added
(bot/CD)
(bot/CD)
Line 83:
});
}
 
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
var e = new Error(message);
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};
 
const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);
Line 345 ⟶ 350:
}));
 
var version = "0.5.01";
var gitAbbrevHash = "876b533548da87";
var gitBranch = "mainHEAD";
var gitDate = "TueThu, 1221 SepDec 2023 1314:1631:1747 +0800";
var gitVersion = "0.5.01+g876b533g548da87";
 
/**
Line 1,029 ⟶ 1,034:
*/
isContributionSurveyHeading(el) {
if (!(el instanceof HTMLElement)) {
return false;
}
// All headings (h1, h2, h3, h4, h5, h6)
// TODO: l10n
Line 1,083 ⟶ 1,091:
.filter((h) => this.isContributionSurveyHeading(h));
}
}
/**
* Normalizes a section heading. On some pages, DiscussionTools wraps the heading
* around in a div, which breaks some assumptions with the DOM tree (e.g. that the
* heading is immediately followed by section elements).
*
* This returns the element at the "root" level, i.e. the wrapping <div> when
* DiscussionTools is active, or the <h2> when it is not.
* @param heading
*/
normalizeSectionHeading(heading) {
if (!this.isContributionSurveyHeading(heading)) {
if (!this.isContributionSurveyHeading(heading.parentElement)) {
throw new Error('Provided section heading is not a valid section heading.');
}
else {
heading = heading.parentElement;
}
}
// When DiscussionTools is being used, the header is wrapped in a div.
if (heading.parentElement.classList.contains('mw-heading')) {
heading = heading.parentElement;
}
return heading;
}
/**
Line 1,101 ⟶ 1,133:
getContributionSurveySection(sectionHeading) {
// Normalize "sectionHeading" to use the h* element and not the .mw-heading span.
ifsectionHeading = (!this.isContributionSurveyHeadingnormalizeSectionHeading(sectionHeading)) {;
if (!this.isContributionSurveyHeading(sectionHeading.parentElement)) {
throw new Error('Provided section heading is not a valid section heading.');
}
else {
sectionHeading = sectionHeading.parentElement;
}
}
// When DiscussionTools is being used, the header is wrapped in a div.
if (sectionHeading.parentElement.classList.contains('mw-heading')) {
sectionHeading = sectionHeading.parentElement;
}
const sectionMembers = [];
let nextSibling = sectionHeading.nextElementSiblingnextSibling;
while (nextSibling != null && !this.isContributionSurveyHeading(nextSibling)) {
sectionMembers.push(nextSibling);
nextSibling = nextSibling.nextElementSiblingnextSibling;
}
return sectionMembers;
Line 1,329 ⟶ 1,350:
* @param props.casePage
* @param props.heading
* @param props.height
* @return HTML element
*/
Line 1,339 ⟶ 1,361:
flags: ['primary', 'progressive']
});
const element = h_1("div", { style: { height: props.height + 'px' }, class: "dp-cs-section-add" }, unwrapWidget(startButton));
startButton.on('click', () => {
// This element is automatically appended to the UL of the section, which is a no-no
Line 3,886 ⟶ 3,908:
*/
function decorateEditSummary (editSummary) {
return `${editSummary} ([[UserWikipedia:Chlod/Scripts/Deputy|Deputy]] v${version})`;
}
 
Line 3,979 ⟶ 4,001:
{ tags: config.core.changeTag.get() } :
{};
}
 
/**
* Wraps a set of nodes in a div.dp-cs-extraneous element.
*
* @param children The nodes to wrap
*/
function DeputyExtraneousElement(children) {
const container = document.createElement('div');
container.classList.add('dp-cs-extraneous');
children = Array.isArray(children) ? children : [children];
children.forEach(child => container.appendChild(child.cloneNode(true)));
return container;
}
 
Line 3,996 ⟶ 4,031:
constructor(casePage, heading) {
this.casePage = casePage;
this.heading = casePage.normalizeSectionHeading(heading);
this.sectionElementssectionNodes = casePage.getContributionSurveySection(heading);
}
/**
Line 4,175 ⟶ 4,210:
*
* @param wikitext Internal use only. Used to skip section loading using existing wikitext.
* @return The ContributionSurveySection for this section
*/
getSection(wikitext) {
var _a, _b, _c;
return __awaiter(this, void 0, void 0, function* () {
const collapsible = (_b = (_a = this.sectionElementssectionNodes.find((v) => v instanceof HTMLElement && v.querySelector('.mw-collapsible'))) === null || _a === void 0 ? void 0 : _a.querySelector('.mw-collapsible')) !== null && _b !== void 0 ? _b : null;
const sectionWikitext = yield this.casePage.wikitext.getSectionWikitext(this.headingName, this.headingN);
return (_c = this._section) !== null && _c !== void 0 ? _c : (this._section = new ContributionSurveySection(this.casePage, this.headingName, collapsible != null, collapsible === null || collapsible === void 0 ? void 0 : collapsible.querySelector('th > div').innerText, wikitext !== null && wikitext !== void 0 ? wikitext : sectionWikitext, wikitext ? wikitext.revid : sectionWikitext.revid));
Line 4,192 ⟶ 4,228:
prepare() {
return __awaiter(this, void 0, void 0, function* () {
const firstListlistElements = this.sectionElementssectionNodes.findfilter((el) => el instanceof HTMLElement && el.tagName === 'UL');
if (firstListlistElements.length === null0) {
// Not a valid section! Might be closed already.
return false;
}
this.originalList = firstList;
const rowElements = {};
for (letconst ilistElement =of 0; i < this.originalList.children.length; i++listElements) {
constfor li(let i = this.originalList0; i < listElement.children.item(length; i++); {
if ( const li.tagName !== 'LI'listElement.children.item(i) {;
//if Skip(li.tagName this!== element.'LI') {
continue; // Skip this element.
} continue;
}
const anchor = li.querySelector('a:first-of-type');
// Avoid enlisting if the anchor can't be found (invalid row).
if (anchor) {
rowElements[new mw.Title(anchor.innerText).getPrefixedText()] =
li;
}
}
}
Line 4,217 ⟶ 4,254:
const wikitextLines = sectionWikitext.split('\n');
this.rows = [];
this.rowElements = [];
this.wikitextLines = [];
let rowElement;
for (let i = 0; i < wikitextLines.length; i++) {
const line = wikitextLines[i];
let rowElement;
try {
const csr = new ContributionSurveyRow(this.casePage, line);
Line 4,233 ⟶ 4,271:
}
catch (e) {
// OnlyThis triggeris onnot actuala bulletedcontribution listssurveyor row.
if (/^\*[^*:]+/.test(line)) {
// Only trigger on actual bulleted lists.
console.warn('Could not parse row.', line, e);
// For debugging and tests.
Line 4,241 ⟶ 4,280:
});
}
if (rowElement =instanceof DeputyContributionSurveyRow line;&&
rowElement.originalElement.nextSibling == null &&
rowElement.originalElement.parentNode.nextSibling != null &&
// Just a blank line. Don't try to do anything else.
line !== '') {
// The previous row element was the last in the list. The
// list probably broke somewhere. (comment with wrong
// bullet?)
// In any case, let's try show it anyway. The user might
// miss some context otherwise.
// We'll only begin reading proper section data once we hit
// another bullet. So let's grab all nodes from the erring
// one until the next bullet list.
const extraneousNodes = [];
let lastNode = rowElement.originalElement.parentElement.nextSibling;
while (
// Another node exists next
lastNode != null &&
// The node is part of this section
this.sectionNodes.includes(lastNode) &&
(
// The node is not an element
!(lastNode instanceof HTMLElement) ||
// The element is not a bullet list
lastNode.tagName !== 'UL')) {
extraneousNodes.push(lastNode);
lastNode = lastNode.nextSibling;
}
rowElement = extraneousNodes;
}
else {
rowElement = line;
}
}
if (typeof rowElement !==instanceof 'string'DeputyContributionSurveyRow) {
this.rows.push(rowElement);
this.rowElements.push(rowElement);
this.wikitextLines.push(rowElement);
}
else if (Array.isArray(rowElement)) {
// Array of Nodes
this.wikitextLines.push(line);
this.rowElements.push(DeputyExtraneousElement(rowElement));
}
else if (typeof rowElement === 'string') {
this.wikitextLines.push(rowElement);
}
this.wikitextLines.push(rowElement);
}
// RemoveHide last,all thissection is to preserve as much state as possibleelements
firstListthis.parentElement.removeChildtoggleSectionElements(firstListfalse);
return true;
});
}
/**
* Toggle section elements. Removes the section elements (but preservers them in
* `this.sectionElements`) if `false`, re-appends them to the DOM if `true`.
* @param toggle
*/
toggleSectionElements(toggle) {
var _a;
const bottom = (_a = this.heading.nextSibling) !== null && _a !== void 0 ? _a : null;
for (const sectionElement of this.sectionNodes) {
if (toggle) {
this.heading.parentNode.insertBefore(sectionElement, bottom);
}
else {
removeElement(sectionElement);
}
}
}
/**
Line 4,260 ⟶ 4,357:
*/
close() {
swapElementsremoveElement(this.container, this.originalList);
this.toggleSectionElements(true);
// Detach listeners to stop listening to events.
this.rows.forEach((row) => {
Line 4,295 ⟶ 4,393:
*
* @param sectionId
* @return Save data, or `false` if the save hit an error
*/
save(sectionId) {
Line 4,334 ⟶ 4,433:
return __awaiter(this, void 0, void 0, function* () {
// For debugging and tests.
// noinspection JSUnresolvedReference
if (window.deputy.NO_ROW_LOADING !== true) {
yield Promise.all(this.rows.map(row => row.loadData()));
Line 4,382 ⟶ 4,482:
});
window.deputy.windowManager.addWindows([reviewDialog]);
yield window.deputy.windowManager.openWindow(reviewDialog).opened;
}));
this.saveButton.on('click', () => __awaiter(this, void 0, void 0, function* () {
Line 4,395 ⟶ 4,495:
const { element, wikitext, revid } = yield getSectionHTML(this.casePage.title, sectionId);
removeElement(this.container);
// Remove whatever section elements are still there.
// They may have been greatly modified by the save.
const sectionElements = this.casePage.getContributionSurveySection(this.heading);
sectionElements.forEach((el) => removeElement(el));
// Clear out section elements and re-append new ones to the DOM.
this.sectionElementssectionNodes = [];
// Heading is preserved to avoid messing with IDs.
const heading = this.heading;
for (const childinsertRef of= Array.from(element_a = heading.children)nextSibling) {!== null && _a !== void 0 ? _a : null;
for (const child of Array.from(element.childNodes)) {
if (!this.casePage.isContributionSurveyHeading(child)) {
heading.parentNode.insertBefore((_achild, = last(this.sectionElements)) !== null && _a !== void 0 ? _a : headinginsertRef);
this.insertAdjacentElementsectionNodes.push('afterend', child);
this.sectionElements.push(child);
}
}
this.originalList = element;
if (!this._section.closed) {
this._section = null;
Line 4,425 ⟶ 4,526:
}
}
}), (errorerr) => {
OO.ui.alert(errorerr.message, {
title: mw.msg('deputy.session.section.failed')
});
console.error(errorerr);
saveContainer.classList.remove('active');
this.setDisabled(false);
Line 4,483 ⟶ 4,584:
});
return this.container = h_1("div", { class: "deputy dp-cs-section" },
h_1("div", null, this.rowsrowElements.map((row) => row instanceof HTMLElement ? row : row.render())),
h_1("div", { class: "dp-cs-section-footer" },
h_1("div", { style: { display: 'flex' } },
Line 4,504 ⟶ 4,605:
saveContainer));
}
}
 
/**
*
* @param element
*/
function findNextSiblingElement(element) {
if (element == null) {
return null;
}
let anchor = element.nextSibling;
while (anchor && !(anchor instanceof Element)) {
anchor = anchor.nextSibling;
}
return anchor;
}
 
Line 4,884 ⟶ 5,000:
*/
addSectionOverlay(casePage, heading) {
var _a, _b, _c;
const section = casePage.getContributionSurveySection(heading);
const list = section.find((v) => v instanceof HTMLElement && v.tagName === 'UL');
const headingTop = window.scrollY + heading.getBoundingClientRect().bottom;
const sectionBottom = window.scrollY + ((_c = (_b = (_a = findNextSiblingElement(last(section))) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect()) === null || _b === void 0 ? void 0 : _b.top) !== null && _c !== void 0 ? _c : heading.parentElement.getBoundingClientRect().bottom);
const overlayHeight = sectionBottom - headingTop;
if (list != null) {
list.style.position = 'relative';
list.appendChild(DeputyCCISessionAddSection({
casePage, heading,
height: overlayHeight
}));
}
Line 14,099 ⟶ 14,220:
];
 
var deputyStyles = "/*=============================================================================== GLOBAL DEPUTY CLASSES===============================================================================*/* > .deputy.dp-heading {position: absolute;opacity: 0;pointer-events: none;}*:hover > .deputy.dp-heading:not(.dp-heading--active) {opacity: 1;pointer-events: all;}.dp-loadingDots-1, .dp-loadingDots-2, .dp-loadingDots-3 {display: inline-block;margin: 0.1em 0.6em 0.1em 0.1em;width: 0.8em;height: 0.8em;background-color: rgba(0, 0, 0, 50%);animation: dp-loadingDots linear 3s infinite;border-radius: 50%;}@keyframes dp-loadingDots {0% {background-color: rgba(0, 0, 0, 10%);}16% {background-color: rgba(0, 0, 0, 40%);}32% {background-color: rgba(0, 0, 0, 10%);}100% {background-color: rgba(0, 0, 0, 10%);}}.dp-loadingDots-1 {animation-delay: -1s;}.dp-loadingDots-2 {animation-delay: -0.5s;}#mw-content-text.dp-reloading {opacity: 0.2;pointer-events: none;}p.dp-messageWidget-message {margin: 0 0 0.5em 0;}.dp-messageWidget-actions .oo-ui-buttonElement {margin-top: 0;}/*=============================================================================== DEPUTY REVIEW DIALOG (DeputyReviewDialog)===============================================================================*/.dp-review-progress {flex: 1;width: 60%;min-width: 300px;}/*=============================================================================== DEPUTY ENTRY POINTS (DeputyCCISessionStartLink, etc.)===============================================================================*/.deputy.dp-sessionStarter {font-size: small;font-weight: normal;margin-left: 0.25em;vertical-align: baseline;line-height: 1em;font-family: sans-serif;}.deputy.dp-sessionStarter::before {content: '\\200B';}.mw-content-ltr .deputy.dp-sessionStarter .dp-sessionStarter-bracket:first-of-type,.mw-content-rtl .deputy.dp-sessionStarter .dp-sessionStarter-bracket:not(:first-of-type) {margin-right: 0.25em;color: #54595d;}.client-js .deputy.dp-sessionStarter .dp-sessionStarter-bracket:first-of-type,.client-js .deputy.dp-sessionStarter .dp-sessionStarter-bracket:not(:first-of-type) {margin-left: 0.25em;color: #54595d}.dp-cs-section-add {position: absolute;top: 0;/* -1.6em derived from MediaWiki list margins. */left: -1.6em;width: calc(100% + 1.6em);height: 100%;background-color: rgba(255, 255, 255, 75%);display: flex;justify-content: center;align-items: center;}.dp-cs-section-add .dp-cs-section-addButton {opacity: 0;transition: opacity 0.2s ease-in-out;}.dp-cs-section-add:hover .dp-cs-section-addButton {opacity: 1;}/*=============================================================================== DEPUTY CONTRIBUTION SURVEY SECTION===============================================================================*/.dp-cs-session-notice {margin-top: 8px;position: sticky;top: 8px;z-index: 50;}.skin-vector-2022.vector-sticky-header-visible .dp-cs-session-notice {top: calc(3.125rem + 8px);}.dp-cs-section-footer {position: relative;padding: 8px;}.dp-cs-section-progress {margin-top: 8px;max-height: 0;transition: max-height 0.2s ease-in-out;display: flex;justify-content: center;align-items: center;overflow: hidden;}.dp-cs-section-progress.active {max-height: 50px;}.dp-cs-section-progress .oo-ui-progressBarWidget {flex: 1}.dp-cs-section-closingCommentsField {margin-top: 8px;}.dp-cs-extraneous {border: 1px solid rgba(0, 159, 255, 40%);background-color: rgba(0, 159, 255, 10%);margin-bottom: 8px;padding: 16px;}.dp-cs-extraneous > dl {margin-left: -1.6em;}.dp-cs-extraneous > :first-child {margin-top: 0 !important;}.dp-cs-extraneous > :last-child {margin-bottom: 0 !important;}.dp-cs-row, .dp-cs-extraneous {margin-bottom: 8px;}.dp-cs-row .dp--loadingDots {display: flex;align-items: center;justify-content: center;padding: 0.4em;}.dp-cs-row-status {max-width: 5.4em;}.dp-cs-row-status .oo-ui-dropdownWidget-handle .oo-ui-labelElement-label {width: 0;opacity: 0;}.dp-cs-row-status .dp-cs-row-status--unknown:not(.oo-ui-optionWidget-selected) {display: none;}.dp-cs-row-head > * {vertical-align: middle;}.dp-cs-row-comments {padding: 16px;background-color: rgba(0, 159, 255, 10%);margin: 4px 0;}.dp-cs-row-comments > b {letter-spacing: 0.1em;font-weight: bold;text-transform: uppercase;color: rgba(0, 0, 0, 0.5);}.dp-cs-row-comments hr {border-color: rgb(0, 31, 51);}body.mediawiki.ltr .dp-cs-row-head > :not(:first-child):not(:last-child),body.mediawiki.ltr .dp-cs-row-head > :not(:first-child):not(:last-child) {margin-right: 16px;}body.mediawiki.rtl .dp-cs-row-head > :not(:first-child):not(:last-child),body.mediawiki.rtl .dp-cs-row-head > :not(:first-child):not(:last-child) {margin-left: 16px;}.dp-cs-row-links {margin-right: 0 !important;}.dp-cs-row-links > :not(:last-child) {margin-right: 8px !important;}.dp-cs-row-title {font-weight: bold;font-size: 1.2em;vertical-align: middle;}.dp-cs-row-details {color: #4a5054;font-weight: bold;}.dp-cs-row-toggle .oo-ui-iconElement-icon {background-size: 1em;}.dp-cs-row-toggle .oo-ui-buttonElement-button {border-radius: 50%;}.dp-cs-row .history-user,.dp-cs-row :not(.newpage) + .mw-changeslist-date {margin-left: 0.4em;margin-right: 0.2em;}.dp-cs-row .newpage {margin-left: 0.4em;}.dp-cs-row-content {padding: 16px;background-color: rgba(0, 0, 0, 6%);margin: 4px 0;}.dp-cs-row-content.dp-cs-row-content-empty {display: none !important;}.dp-cs-row-unfinishedWarning {margin-bottom: 8px;}.dp-cs-section-unfinishedWarning {margin-top: 8px;}.dp-cs-row-closeComments {font-family: monospace, monospace;font-size: small;}.dp-cs-row-closeComments:not(:last-child) {margin-bottom: 8px;}.dp-cs-row-finished .oo-ui-fieldLayout:first-child {margin-top: 0;}.dp-cs-row-finished .oo-ui-fieldLayout {margin-top: 8px;}.dp-cs-row-revisions .mw-tag-markers .mw-tag-marker:not(:first-child),.dp-cs-row-detail:not(:first-child) {margin-left: 0.2em;}.dp-cs-rev-checkbox {margin-right: 4px;}.dp-cs-rev-toggleDiff {vertical-align: baseline;margin-right: 4px;}.dp-cs-rev-diff {background-color: white;position: relative;}.dp-cs-rev-diff--loaded {margin: 4px 0;padding: 8px 14px;}.dp-cs-rev-diff--hidden {display: none;}.dp-cs-rev-toggleDiff > .oo-ui-buttonElement-button {padding: 0;min-height: 1em;background-color: unset !important;}.dp-cs-rev-toggleDiff .oo-ui-indicatorElement-indicator {top: -1px;}/*=============================================================================== DEPUTY PAGE TOOLBAR===============================================================================*/.dp-pageToolbar {position: fixed;bottom: 8px;left: 8px;z-index: 100;padding: 8px;background-color: #fff;border: 1px solid gray;font-size: 0.9rem;display: flex;align-items: center;}@media only screen and (max-width: 768px) {.dp-pageToolbar {flex-wrap: wrap;bottom: 0;left: 0;border-left: 0;border-bottom: 0;border-right: 0;width: 100%;}}.dp-pt-section {display: inline-block;white-space: nowrap;}.dp-pt-section + .dp-pt-section {/* TODO: Recheck RTL compatibility */margin-left: 16px;padding-left: 16px;border-left: 1px solid gray;}.dp-pt-section:last-child {/* TODO: Recheck RTL compatibility */margin-right: 8px;}.dp-pt-section-label {font-weight: bold;font-size: 0.6rem;color: #4a5054;text-transform: uppercase;}.dp-pt-section-content .oo-ui-buttonElement:last-child {margin-right: 0;}.dp-pt-caseInfo {font-weight: bold;font-size: 1.3rem;pointer-events: none;}.dp-pt-missingRevision {white-space: normal;}.dp-pageToolbar .dp-cs-row-status {width: 5.4em;}.dp-pt-menu .oo-ui-menuSelectWidget {min-width: 300px;}.dp-pt-menu .oo-ui-menuOptionWidget {padding-top: 8px;padding-bottom: 8px;}";
 
var deputyCoreEnglish = {