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

Content deleted Content added
v0.4.1; https://github.com/ChlodAlejandro/deputy/releases/tag/v0.4.1
v0.4.2; https://github.com/ChlodAlejandro/deputy/releases/tag/v0.4.2
Line 1,409:
// {{dif|12345|6789}}
this.eatUntil(/^(?:'''?)?{{dif\|\d+/, true);
let diffsBolded = false;
// At this point, `extras` is either a string or `null`. If it's a string,
// extras exist, and we should add them. If not, there's likely no more
Line 1,429 ⟶ 1,430:
// All diff links removed. Get diff of starting and current to get entire diff part.
diffs = starting.slice(0, starting.length - this.current.length);
// DawkeyeBolded diffs support.
if (diffs.slice(0, 3) === "'''" &&
diffs.slice(-3) === "'''" &&
!diffs.slice(3, -3).includes("'''")) {
diffsBolded = true;
}
// Pre-2014 style support.
if ((diffs !== null && diffs !== void 0 ? diffs : '').includes('{{dif')) {
diffTemplatediffsBolded = '$3{{dif|$1|$2}}$3'true;
diffTemplate = '{{dif|$1|($2)}}';
}
// Comments should be empty, but just in case we do come across comments.
Line 1,461 ⟶ 1,469:
comments,
revids,
diffTemplate,
diffsTemplate: diffsBolded ? "'''$1'''" : '$1'
};
}
Line 2,764 ⟶ 2,773:
}
const unfinishedDiffs = (_d = (_c = (_b = this.revisions) === null || _b === void 0 ? void 0 : _b.filter((v) => !v.completed)) === null || _c === void 0 ? void 0 : _c.sort((a, b) => ContributionSurveyRow.getSorterFunction(this.sortOrder)(a.revision, b.revision))) !== null && _d !== void 0 ? _d : [];
let diffsText = '';
if (unfinishedDiffs.length > 0) {
resultdiffsText += unfinishedDiffs.map((v) => {
return mw.format(this.row.data.diffTemplate, v.revision.revid, v.revision.diffsize > 0 ? '+' + v.revision.diffsize : v.revision.diffsize, Math.abs(v.revision.diffsize) > 500 ? "'''" : '');
}).join('');
result += mw.format(this.row.data.diffsTemplate, diffsText);
if (this.row.data.comments) {
// Comments existed despite not being finished yet. Allow anyway.
Line 3,562 ⟶ 3,573:
}
 
var version = "0.4.12";
var gitAbbrevHash = "a1ccef049388f5";
var gitBranch = "HEAD";
var gitDate = "WedThu, 1823 JanMar 2023 2107:1240:2632 +0800";
var gitVersion = "0.4.12+ga1ccef0g49388f5";
 
/**
Line 3,973 ⟶ 3,984:
catch (e) {
// Only trigger on actual bulleted lists.
if (/^\*[^*:]+/.test(line)) {
console.warn('Could not parse row.', line, e);
// For debugging and tests.
Line 5,381 ⟶ 5,392:
* used instead of the revision-specific toolbar.
* @param title The title of the page to get information for. Defaults to current.
* @param timeout Timeout for the page detail request.
*/
static getPageDetails(revision, title = window.deputy.currentPage, timeout = 500) {
return __awaiter(this, void 0, void 0, function* () {
return window.deputy.comms.sendAndWait({
Line 5,388 ⟶ 5,400:
page: title.getPrefixedText(),
revision: revision
}, timeout);
});
}
Line 5,436 ⟶ 5,448:
// On a "prev" diff page
mw.config.get('wgDiffNewId')) ||
mw.config.get('wgRevisionId'));, window.deputy.currentPage,
// Relatively low-stakes branch, we can handle a bit of a delay.
2000);
const openPromise = this.appendToolbar(Object.assign(Object.assign({}, data), { forceRevision: this.toolbar != null ||
// Is a diff page.
Line 10,818 ⟶ 10,832:
}
}
 
var blockExit$1 = /*#__PURE__*/Object.freeze({
__proto__: null,
blockExit: blockExit,
unblockExit: unblockExit
});
 
/**
Line 12,843 ⟶ 12,863:
lastEdited: new Setting({
defaultValue: 0,
displayOptions: { type: 'number', readOnlyhidden: true },
alwaysSave: true
}),
Line 12,996 ⟶ 13,016:
let configPage;
try {
configPage// =If JSON.parse(`mw.user.optionsstorage.get(WikiConfiguration` returns `false` or `null`, it'll be thrown up.optionKey));
configPage = JSON.parse(mw.storage.get(WikiConfiguration.optionKey));
}
catch (e) {
// Bad local! Switch to non-local.
console.error('Failed to get Deputy wiki configuration', e);
return this.loadFromWiki();
}
Line 13,032 ⟶ 13,053:
// Attempt save of configuration to local options (if not explicitly loaded)
if (sourcePage == null) {
MwApimw.actionstorage.saveOptionset(WikiConfiguration.optionKey, JSON.stringify(configPage)).catch(() => { });
}
return new WikiConfiguration(configPage.title, JSON.parse(configPage.wt), configPage.editable);
Line 13,523 ⟶ 13,544:
];
 
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-row {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;}/*=============================================================================== 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 = {
Line 15,782 ⟶ 15,803:
}
Recents.key = 'mw-userjs-recents';
 
/**
* Runs a clean operation. If `option` is false or null, the operation will not be run.
*
* @param obj
* @param option
* @param callback
*/
function onOption(obj, option, callback) {
if (option == null || option === false) {
return;
}
for (const key of Object.keys(obj)) {
if (option === true ||
option === key ||
(Array.isArray(option) && option.indexOf(key) !== -1)) {
const result = callback(obj[key]);
if (result === undefined) {
delete obj[key];
}
else {
obj[key] = result;
}
}
}
}
/**
* Cleans a parameter list. By default, this performs the following:
* - Removes all undefined, null, or empty values
* - Trims all strings
* - Removes newly undefined, null, or empty values
*
* This mutates the original object and also returns it for chaining.
*
* @param obj
* @param _options
* @return The cleaned parameter list.
*/
function cleanParams(obj, _options = {}) {
const defaultOptions = {
trim: true,
filter: true,
removeYes: false,
removeNo: false,
filter2: true
};
const options = Object.assign({}, defaultOptions, _options);
// First clean pass
onOption(obj, options.filter, (v) => !v || v.length === 0 ? undefined : v);
onOption(obj, options.trim, (v) => v.trim ? v.trim() : v);
onOption(obj, options.removeYes, (v) => yesNo(v, false) ? undefined : v);
onOption(obj, options.removeNo, (v) => yesNo(v, true) ? undefined : v);
// Second clean pass
onOption(obj, options.filter, (v) => !v || v.length === 0 ? undefined : v);
return obj;
}
 
/**
* Iterates over an array and returns an Iterator which checks each element
* of the array sequentially for a given condition (predicated by `condition`)
* and returns another array, containing an element where `true` was returned,
* and every subsequent element where the check returns `false`.
*
* @param arr
* @param condition
* @yield The found sequence
*/
function* pickSequence(arr, condition) {
let currentValues = null;
let shouldReturnValues = false;
for (const val of arr) {
if (condition(val)) {
shouldReturnValues = true;
if (currentValues != null) {
yield currentValues;
}
currentValues = [val];
continue;
}
if (shouldReturnValues) {
currentValues.push(val);
}
}
if (currentValues.length > 0) {
yield currentValues;
}
}
 
var util = {
blockExit: blockExit$1,
classMix: classMix,
cleanParams: cleanParams,
cloneRegex: cloneRegex$1,
copyToClipboard: copyToClipboard,
equalTitle: equalTitle,
fromObjectEntries: fromObjectEntries,
generateId: generateId,
getObjectValues: getObjectValues,
last: last,
matchAll: matchAll,
moveToStart: moveToStart,
pickSequence: pickSequence,
removeElement: removeElement,
Requester: Requester,
sleep: sleep,
swapElements: swapElements,
unwrapWidget: unwrapWidget,
yesNo: yesNo
};
 
/**
* Converts a range-like Object into a native Range object.
*
* @param rangeLike The range to convert
* @param rangeLike.startContainer
* @param rangeLike.startOffset
* @param rangeLike.endContainer
* @param rangeLike.endOffset
* @return A {@link Range} object.
*/
function getNativeRange (rangeLike) {
const doc = rangeLike.startContainer.ownerDocument;
const nativeRange = doc.createRange();
nativeRange.setStart(rangeLike.startContainer, rangeLike.startOffset);
nativeRange.setEnd(rangeLike.endContainer, rangeLike.endOffset);
return nativeRange;
}
 
/**
* Get the content of a revision on-wiki.
*
* @param revision The revision ID of the revision to get the content of
* @param extraOptions Extra options to pass to the request
* @param api The API object to use
* @return A promise resolving to the page content
*/
function getRevisionContent (revision, extraOptions = {}, api = MwApi.action) {
return api.get(Object.assign({ action: 'query', revids: revision, rvprop: 'content', rvslots: 'main', rvlimit: '1' }, extraOptions)).then((data) => {
return Object.assign(data.query.pages[0].revisions[0].slots.main.content, { contentFormat: data.query.pages[0].revisions[0].slots.main.contentformat });
});
}
 
var wikiUtil = {
anchorToTitle: anchorToTitle,
decorateEditSummary: decorateEditSummary,
delink: delink,
errorToOO: errorToOO,
getNativeRange: getNativeRange,
getPageContent: getPageContent,
getPageTitle: getPageTitle,
getRevisionContent: getRevisionContent,
getRevisionDiffURL: getRevisionDiffURL,
getRevisionURL: getRevisionURL,
getSectionHTML: getSectionHTML,
getSectionId: getSectionId,
guessAuthor: guessAuthor,
msgEval: msgEval,
normalizeTitle: normalizeTitle,
nsId: nsId,
openWindow: openWindow,
performHacks: performHacks,
purge: purge,
renderWikitext: renderWikitext,
sectionHeadingId: sectionHeadingId,
sectionHeadingN: sectionHeadingN,
sectionHeadingName: sectionHeadingName,
toRedirectsObject: toRedirectsObject
};
 
/**
Line 15,804 ⟶ 15,993:
ContributionSurveyRow: ContributionSurveyRow
};
this.util = {util;
this.wikiUtil = cloneRegex: cloneRegex$1,wikiUtil;
getPageContent: getPageContent,
normalizeTitle: normalizeTitle,
sectionHeadingName: sectionHeadingName,
msgEval: msgEval
};
this.modules = {
CopiedTemplateEditor: CopiedTemplateEditor,