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

Content deleted Content added
(bot/CD)
(bot/CD)
Line 351:
 
var version = "0.8.0";
var gitAbbrevHash = "1c5f541fa06183";
var gitBranch = "HEADmain";
var gitDate = "TueFri, 287 MayJun 2024 1823:4736:4815 +0800";
var gitVersion = "0.8.0+g1c5f541gfa06183";
 
/**
Line 855:
}
});
}
}
 
/**
* Log errors to the console.
*
* @param {...any} data
*/
function error(...data) {
console.error('[Deputy]', ...data);
}
 
/**
* @param element The element to get the name of
* @return the name of a section from its section heading.
*/
function sectionHeadingName(element) {
var _a;
try {
// Get only the direct text of .mw-headline
// Why? Because DiscussionTools inserts a [subscribe] link in the .mw-headline
// element, which we don't want to include in the section name.
const headlineElement = element.querySelector('.mw-headline');
const headlineDirectText = Array.from((_a = headlineElement === null || headlineElement === void 0 ? void 0 : headlineElement.childNodes) !== null && _a !== void 0 ? _a : [])
.filter(n => n.nodeType === Node.TEXT_NODE)
.reduce((acc, n) => acc + n.textContent, '')
.trim();
return headlineDirectText || (headlineElement === null || headlineElement === void 0 ? void 0 : headlineElement.innerText);
}
catch (e) {
error('Error getting section name', e, element);
throw e;
}
}
Line 977 ⟶ 945:
 
/**
* @paramReturns elementthe Thelast elementitem toof getan the name ofarray.
*
* @return the ID of the section heading.
* @param array The array to get the last element from
* @return The last element of the array
*/
function sectionHeadingIdlast(elementarray) {
tryreturn {array[array.length - 1];
return element.querySelector('.mw-headline')
.getAttribute('id');
}
catch (e) {
error('Error getting section heading ID', e, element);
throw e;
}
}
 
/**
* Each WikiHeadingType implies specific fields in {@link WikiHeading}:
* Check if a given parameter is a wikitext heading parsed into HTML.
*
* - `PARSOID` implies that there is no headline element, and that the `h`
* This is its own function to account for different parse outputs (Legacy, Parsoid,
* element is the root heading element. This means `h.innerText` will be
* DiscussionTools, etc.)
* "Section title".
* - `OLD` implies that there is a headline element and possibly an editsection
* element, and that the `h` is the root heading element. This means that
* `h.innerText` will be "Section title[edit | edit source]" or similar.
* - `NEW` implies that there is a headline element and possibly an editsection
* element, and that a `div` is the root heading element. This means that
* `h.innerText` will be "Section title".
*/
var WikiHeadingType;
(function (WikiHeadingType) {
WikiHeadingType[WikiHeadingType["PARSOID"] = 0] = "PARSOID";
WikiHeadingType[WikiHeadingType["OLD"] = 1] = "OLD";
WikiHeadingType[WikiHeadingType["NEW"] = 2] = "NEW";
})(WikiHeadingType || (WikiHeadingType = {}));
/**
* Get relevant information from an H* element in a section heading.
*
* @param elheadingElement The heading element to check
* @return `true`An ifobject containing the element is arelevant heading,{@link `false`WikiHeading} otherwisefields.
*/
function isWikiHeadinggetHeadingElementInfo(elheadingElement) {
return {
return (el.classList.contains('mw-heading') || /^H\d$/.test(el.tagName));
h: headingElement,
id: headingElement.id,
title: headingElement.innerText,
level: +last(headingElement.tagName)
};
}
 
/**
* Annoyingly, there are many different ways that a heading can be parsed
* Returns the last item of an array.
* into depending on the version and the parser used for given wikitext.
*
* In order to properly perform such wiki heading checks, we need to identify
* @param array The array to get the last element from
* @returnif Thea lastgiven element is part of thea wiki heading, and perform a arraynormalization
* if so.
*
* Since this function needs to check many things before deciding if a given
* HTML element is part of a section heading or not, this also acts as an
* `isWikiHeading` check.
*
* The layout for a heading differs depending on the MediaWiki version:
*
* <b>On 1.43+ (Parser)</b>
* ```html
* <div class="mw-heading mw-heading2">
* <h2 id="Parsed_wikitext...">Parsed <i>wikitext</i>...</h2>
* <span class="mw-editsection>...</span>
* </div>
* ```
*
* <b>On Parsoid</b>
* ```html
* <h2 id="Parsed_wikitext...">Parsed <i>wikitext</i>...</h2>
* ```
*
* <b>On pre-1.43</b>
* ```html
* <h2>
* <span class="mw-headline" id="Parsed_wikitext...">Parsed <i>wikitext</i>...</span>
* <span class="mw-editsection">...</span>
* </h2>
* ```
*
* <b>Worst case execution time</b> would be if this was run with an element which was
* outside a heading and deeply nested within the page.
*
* Backwards-compatibility support may be removed in the future. This function does not
* support Parsoid specification versions lower than 2.0.
*
* @param node The node to check for
* @param ceiling An element which `node` must be in to be a valid heading.
* This is set to the `.mw-parser-output` element by default.
* @return The root heading element (can be an &lt;h2&gt; or &lt;div&gt;),
* or `null` if it is not a valid heading.
*/
function lastnormalizeWikiHeading(arraynode, ceiling) {
returnvar array[array.length - 1]_a;
if (node == null) {
// Not valid input, obviously.
return null;
}
const rootNode = node.getRootNode();
// Break out of text nodes until we hit an element node.
while (node.nodeType !== node.ELEMENT_NODE) {
node = node.parentNode;
if (node === rootNode) {
// We've gone too far and hit the root. This is not a wiki heading.
return null;
}
}
// node is now surely an element.
let elementNode = node;
// If this node is the 1.43+ heading root, return it immediately.
if (elementNode.classList.contains('mw-heading')) {
return Object.assign({ type: WikiHeadingType.NEW, root: elementNode }, getHeadingElementInfo(Array.from(elementNode.children)
.find(v => /^H[123456]$/.test(v.tagName))));
}
// Otherwise, we're either inside or outside a mw-heading.
// To determine if we are inside or outside, we keep climbing up until
// we either hit an <hN> or a given stop point.
// The stop point is, by default, `.mw-parser-output`, which exists both in a
// Parsoid document and in standard parser output. If such an element doesn't
// exist in this document, we just stop at the root element.
ceiling = (_a = ceiling !== null && ceiling !== void 0 ? ceiling : elementNode.ownerDocument.querySelector('.mw-parser-output')) !== null && _a !== void 0 ? _a : elementNode.ownerDocument.documentElement;
// While we haven't hit a heading, keep going up.
while (elementNode !== ceiling) {
if (/^H[123456]$/.test(elementNode.tagName)) {
// This element is a heading!
// Now determine if this is a MediaWiki heading.
if (elementNode.parentElement.classList.contains('mw-heading')) {
// This element's parent is a `div.mw-heading`!
return Object.assign({ type: WikiHeadingType.NEW, root: elementNode.parentElement }, getHeadingElementInfo(elementNode));
}
else {
const headline = elementNode.querySelector(':scope > .mw-headline');
if (headline != null) {
// This element has a `.mw-headline` child!
return {
type: WikiHeadingType.OLD,
root: elementNode,
h: elementNode,
id: headline.id,
title: headline.innerText,
level: +last(elementNode.tagName)
};
}
else if (elementNode.parentElement.tagName === 'SECTION' &&
elementNode.parentElement.firstElementChild === elementNode) {
// A <section> element is directly above this element, and it is the
// first element of that section!
// This is a specific format followed by the 2.8.0 MediaWiki Parsoid spec.
// https://www.mediawiki.org/wiki/Specs/HTML/2.8.0#Headings_and_Sections
return {
type: WikiHeadingType.PARSOID,
root: elementNode,
h: elementNode,
id: elementNode.id,
title: elementNode.innerText,
level: +last(elementNode.tagName)
};
}
else {
// This is a heading, but we can't figure out how it works.
// This usually means something inserted an <h2> into the DOM, and we
// accidentally picked it up.
// In that case, discard it.
return null;
}
}
}
else if (elementNode.classList.contains('mw-heading')) {
// This element is the `div.mw-heading`!
// This usually happens when we selected an element from inside the
// `span.mw-editsection` span.
return Object.assign({ type: WikiHeadingType.NEW, root: elementNode }, getHeadingElementInfo(Array.from(elementNode.children)
.find(v => /^H[123456]$/.test(v.tagName))));
}
else {
// Haven't reached the top part of a heading yet, or we are not
// in a heading. Keep climbing up the tree until we hit the ceiling.
elementNode = elementNode.parentElement;
}
}
// We hit the ceiling. This is not a wiki heading.
return null;
}
 
/**
* GetCheck theif levela (1given toparameter 6)is ofa anywikitext heading parsed wikitextinto headingHTML.
*
* Alias for `normalizeWikiHeading( el ) != null`.
* This is its own function to account for different parse outputs (Legacy, Parsoid,
* DiscussionTools, etc.)
*
* @param el The element to check. This MUST be a wikitext heading.
* @return The`true` level ofif the headingelement (1is a heading, to`false` 6)otherwise
*/
function getWikiHeadingLevelisWikiHeading(el) {
return normalizeWikiHeading(el) != null;
const h = el.classList.contains('mw-heading') ?
el.querySelector('h1, h2, h3, h4, h5, h6') :
el;
// Check if this is a valid header
if (!/^H\d+$/.test(h.tagName)) {
throw new Error('Heading element does not contain a valid <h*> element');
}
return +last(h.tagName);
}
 
Line 1,123 ⟶ 1,227:
return false;
}
//const Allheading headings= normalizeWikiHeading(h1, h2, h3, h4, h5, h6el);
constreturn headlineElementheading != this.parsoidnull ?&&
el :=== heading.h &&
el.querySelector('.mw-headline');
// Handle DiscussionTools case (.mw-heading)
return isWikiHeading(el) &&
headlineElement != null &&
// eslint-disable-next-line security/detect-non-literal-regexp
new RegExp(window.deputy.wikiConfig.cci.headingMatch.get()).test(headlineElementheading.innerTexttitle);
}
/**
Line 1,139 ⟶ 1,239:
* @return The <h*> element of the heading.
*/
findFirstContributionSurveyHeadingfindFirstContributionSurveyHeadingElement() {
return this.findContributionSurveyHeadings()[0];
}
Line 1,151 ⟶ 1,251:
*/
findContributionSurveyHeading(sectionIdentifier, useId = false) {
// No need to perform .mw-headline existence check here, already
// done by `findContributionSurveyHeadings`
return this.findContributionSurveyHeadings()
.find((v) => normalizeWikiHeading(v)[useId ? 'id' : 'title'] === sectionIdentifier);
sectionHeadingId(v) === sectionIdentifier :
sectionHeadingName(v) === sectionIdentifier);
}
/**
Line 1,177 ⟶ 1,273:
.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,218 ⟶ 1,290:
*/
getContributionSurveySection(sectionHeading) {
//const Normalizeheading "= normalizeWikiHeading(sectionHeading" to use the h* element and not the .mw-heading span.);
sectionHeadingconst ceiling = thisheading.root.normalizeSectionHeading(sectionHeading)parentElement;
return getSectionElements(heading.root, (el) => { var _a, _b; return heading.level >= ((_b = (_a = normalizeWikiHeading(el, ceiling)) === null || _a === void 0 ? void 0 : _a.level) !== null && _b !== void 0 ? _b : Infinity); });
const sectionHeadingLevel = getWikiHeadingLevel(sectionHeading);
return getSectionElements(this.normalizeSectionHeading(sectionHeading), (el) => isWikiHeading(el) &&
sectionHeadingLevel >= getWikiHeadingLevel(el));
}
/**
Line 1,379 ⟶ 1,449:
h_1("a", { onClick: () => __awaiter(this, void 0, void 0, function* () {
if (casePage && casePage.lastActiveSections.length > 0) {
const headingId = sectionHeadingId(heading).id;
if (window.deputy.config.cci.openOldOnContinue.get()) {
if (casePage.lastActiveSections.indexOf(headingId) === -1) {
Line 1,391 ⟶ 1,461:
}
else {
yield window.deputy.session.DeputyRootSession.startSession(heading.h);
}
}) }, mw.message(casePage && casePage.lastActiveSections.length > 0 ?
Line 1,408 ⟶ 1,478:
var _a;
return (_a = element === null || element === void 0 ? void 0 : element.parentElement) === null || _a === void 0 ? void 0 : _a.removeChild(element);
}
 
/**
* Log errors to the console.
*
* @param {...any} data
*/
function error(...data) {
console.error('[Deputy]', ...data);
}
 
Line 6,375 ⟶ 6,454:
*
* @param heading The heading to check
* @param headingName The name of the heading to check
* @return The n, a number
*/
function sectionHeadingN (heading, headingName) {
try {
const headingNameEndPattern = /(?:\s|_)(\d+)/g;
const headingIdEndPattern = /_(\d+)/g;
const headingId = sectionHeadingId(heading).id;
const headingIdMatches = headingId.match(headingIdEndPattern);
const headingNameMatches = headingNameheading.title.match(headingNameEndPattern);
if (headingIdMatches == null) {
return 1;
Line 6,434 ⟶ 6,512:
constructor(casePage, heading) {
this.casePage = casePage;
this.heading = casePage.normalizeSectionHeadingnormalizeWikiHeading(heading);
this.sectionNodes = casePage.getContributionSurveySection(heading);
}
Line 6,609 ⟶ 6,687:
*/
get headingName() {
return sectionHeadingName(this.heading).title;
}
/**
Line 6,615 ⟶ 6,693:
*/
get headingN() {
return sectionHeadingN(this.heading, this.headingName);
}
/**
Line 6,770 ⟶ 6,848:
toggleSectionElements(toggle) {
var _a;
const bottom = (_a = this.heading.root.nextSibling) !== null && _a !== void 0 ? _a : null;
for (const sectionElement of this.sectionNodes) {
if (toggle) {
this.heading.root.parentNode.insertBefore(sectionElement, bottom);
}
else {
Line 6,938 ⟶ 7,016:
// Remove whatever section elements are still there.
// They may have been greatly modified by the save.
const sectionElements = this.casePage.getContributionSurveySection(this.heading.root);
sectionElements.forEach((el) => removeElement(el));
// Clear out section elements and re-append new ones to the DOM.
this.sectionNodes = [];
// Heading is preserved to avoid messing with IDs.
const heading = this.heading.root;
const insertRef = (_a = heading.nextSibling) !== null && _a !== void 0 ? _a : null;
for (const child of Array.from(element.childNodes)) {
Line 6,957 ⟶ 7,035:
yield this.getSection(Object.assign(wikitext, { revid }));
yield this.prepare();
if (heading.parentElement.classList.containsinsertAdjacentElement('mw-headingafterend', this.render()) {;
// Intentional recursive call
heading.parentElement.insertAdjacentElement('afterend', this.render());
}
else {
// Intentional recursive call
heading.insertAdjacentElement('afterend', this.render());
}
// Run this asynchronously.
setTimeout(this.loadData.bind(this), 0);
Line 7,166 ⟶ 7,237:
casePage.findContributionSurveyHeadings()
.forEach((heading) => {
const linknormalizedHeading = DeputyCCISessionStartLinknormalizeWikiHeading(heading, casePage);
const link = DeputyCCISessionStartLink(normalizedHeading, casePage);
startLink.push(link);
headingnormalizedHeading.root.appendChild(link);
});
window.deputy.comms.addEventListener('sessionStarted', () => {
Line 7,189 ⟶ 7,261:
return __awaiter(this, void 0, void 0, function* () {
yield mw.loader.using(['oojs-ui-core', 'oojs-ui.styles.icons-content'], () => {
const firstHeading = casePage.findFirstContributionSurveyHeadingfindFirstContributionSurveyHeadingElement();
if (firstHeading) {
const stopButton = new OO.ui.ButtonWidget({
Line 7,223 ⟶ 7,295:
window.deputy.session.init();
});
casePage.normalizeSectionHeadingnormalizeWikiHeading(firstHeading).root.insertAdjacentElement('beforebegin', unwrapWidget(messageBox));
}
});
Line 7,242 ⟶ 7,314:
mw.loader.using(['oojs-ui-core', 'oojs-ui.styles.icons-content'], () => {
const lastActiveSection = DeputyRootSession.findFirstLastActiveSection(casePage);
const firstSection = casePage.normalizeSectionHeadingnormalizeWikiHeading(casePage.findFirstContributionSurveyHeadingfindFirstContributionSurveyHeadingElement());
// Insert element directly into widget (not as text, or else event
// handlers will be destroyed).
Line 7,259 ⟶ 7,331:
'deputy.session.continue.help' :
'deputy.session.continue.help.fromStart', lastActiveSection ?
sectionHeadingNamenormalizeWikiHeading(lastActiveSection).title :
casePage.lastActiveSections[0]
.replace(/_/g, ' '), sectionHeadingName(firstSection).title),
actions: [continueButton],
closable: true
Line 7,276 ⟶ 7,348:
else {
DeputyRootSession.continueSession(casePage, [
sectionHeadingId(firstSection).id
]);
}
window.deputy.comms.removeEventListener('sessionStarted', sessionStartListener);
});
firstSection.root.insertAdjacentElement('beforebegin', unwrapWidget(messageBox));
window.deputy.comms.addEventListener('sessionStarted', sessionStartListener, { once: true });
})
Line 7,298 ⟶ 7,370:
const casePage = _casePage !== null && _casePage !== void 0 ? _casePage : yield DeputyCasePage.build();
return mw.loader.using(['oojs-ui-core', 'oojs-ui.styles.icons-content'], () => {
const firstHeading = casePage.findFirstContributionSurveyHeadingfindFirstContributionSurveyHeadingElement();
if (firstHeading) {
const messageBox = DeputyMessageWidget({
Line 7,309 ⟶ 7,381:
closable: true
});
casePage.normalizeSectionHeadingnormalizeWikiHeading(firstHeading).root.insertAdjacentElement('beforebegin', unwrapWidget(messageBox));
window.deputy.comms.addEventListener('sessionClosed', () => __awaiter(this, void 0, void 0, function* () {
removeElement(unwrapWidget(messageBox));
Line 7,330 ⟶ 7,402:
for (const lastActiveSection of casePage.lastActiveSections) {
for (const heading of csHeadings) {
if (sectionHeadingIdnormalizeWikiHeading(heading).id === lastActiveSection) {
return heading;
}
Line 7,345 ⟶ 7,417:
static startSession(section, _casePage) {
return __awaiter(this, void 0, void 0, function* () {
const sectionIds = (Array.isArray(section) ? section : [section]).map((_section) => sectionHeadingIdnormalizeWikiHeading(_section).id);
// Save session to storage
const casePage = _casePage !== null && _casePage !== void 0 ? _casePage : yield DeputyCasePage.build();
Line 7,445 ⟶ 7,517:
const activeSectionPromises = [];
for (const heading of this.casePage.findContributionSurveyHeadings()) {
const headingId = sectionHeadingIdnormalizeWikiHeading(heading).id;
if (this.session.caseSections.indexOf(headingId) !== -1) {
activeSectionPromises.push(this.activateSection(this.casePage, heading)
Line 7,504 ⟶ 7,576:
addSectionOverlay(casePage, heading) {
var _a, _b, _c;
const normalizedHeading = casePage.normalizeSectionHeadingnormalizeWikiHeading(heading).root;
const section = casePage.getContributionSurveySection(normalizedHeading);
const list = section.find((v) => v instanceof HTMLElement && v.tagName === 'UL');
Line 7,562 ⟶ 7,634:
return false;
}
const sectionId = sectionHeadingIdnormalizeWikiHeading(heading).id;
this.sections.push(el);
const lastActiveSession = this.session.caseSections.indexOf(sectionId);
Line 7,570 ⟶ 7,642:
}
yield casePage.addActiveSection(sectionId);
if normalizeWikiHeading(heading).parentElementroot.classList.containsinsertAdjacentElement('mw-headingafterend', el.render()) {;
heading.parentElement.insertAdjacentElement('afterend', el.render());
}
else {
heading.insertAdjacentElement('afterend', el.render());
}
yield el.loadData();
mw.hook('deputy.load.cci.session').fire();
Line 7,595 ⟶ 7,662:
e0.casePage : e0;
const heading = e0 instanceof DeputyContributionSurveySection ?
e0.heading : normalizeWikiHeading(e1);
const sectionId = sectionHeadingId(heading).id;
const sectionListIndex = this.sections.indexOf(el);
if (el != null && sectionListIndex !== -1) {
Line 7,613 ⟶ 7,680:
yield DeputyRootSession.setSession(this.session);
yield casePage.removeActiveSection(sectionId);
this.addSectionOverlay(casePage, heading.h);
}
}
Line 15,277 ⟶ 15,344:
*/
static getListingHeader(el) {
var _a;
let listingPage = null;
let previousPivot = (
// Target the ol/ul element itself if a list, target the <p> if not a list.
el.parentElement.tagName === 'LI' ? el.parentElement.parentElement : el.parentElement).previousElementSibling;
let heading;
while (previousPivot != null && previousPivot.tagName !== 'H4') {
// Search for a level 4 heading backwards.
while (previousPivot != null &&
// Set the ceiling to be immediately above for efficiency.
((_a = (heading = normalizeWikiHeading(previousPivot, previousPivot.parentElement))) === null || _a === void 0 ? void 0 : _a.level) !== 4) {
previousPivot = previousPivot.previousElementSibling;
}
Line 15,287 ⟶ 15,359:
return false;
}
if// At this point, (previousPivot.querySelector('.mw-headline') !=is null)likely {a MediaWiki level 4 heading.
const h4Anchor = heading.h.querySelector('a');
// At this point, previousPivot is likely a MediaWiki level 4 heading.
if const (h4Anchor) = previousPivot.querySelector('.mw-headline a');{
listingPage = pagelinkToTitle(h4Anchor);
// Identify if the page is a proper listing page (within the root page's
Line 16,724 ⟶ 16,796:
}
/**
* Adds a panel containing the "new listing" buttons (single and multiple)
*
* and the panel container (when filing a multiple-page listing) to the proper
* ___location: either at the end of the copyright problems section or replacing
* the redlink to the blank copyright problems page.
*/
addNewListingsPanel() {
document.querySelectorAll('.mw-headline >a, .mw-heading a, a.external, a.redlink').forEach((el) => {
const href = el.getAttribute('href');
const url = new URL(href, window.___location.href);
if (equalTitle(url.searchParams.get('title'), CopyrightProblemsPage.getCurrentListingPage()) ||
url.pathname === mw.util.getUrl(CopyrightProblemsPage.getCurrentListingPage().getPrefixedText())) {
if (el.classList.contains('external') || el.classList.contains('redlink')) {
// Crawl backwards, avoiding common inline elements, to see if this is a standalone
// lineKeep withincrawling up and find the renderedparent of this element that is text.directly
let currentPivot = el // below the parser root or the current section.parentElement;
while ( let currentPivot !== null &&el;
['I',while 'B', 'SPAN', 'EM', 'STRONG'].indexOf(currentPivot.tagName) !== -1)null {&&
currentPivot = !currentPivot.parentElement;classList.contains('mw-parser-output') &&
} ['A', 'I', 'B', 'SPAN', 'EM', 'STRONG']
// By this point, current pivot will be a <div>, <p>, or other.indexOf(currentPivot.tagName) usable!== element.-1) {
if (!el currentPivot = currentPivot.parentElement.classList.contains('mw-headline') &&;
(currentPivot == null ||
currentPivot.children.length > 1)) {
return;
}
else if (el.parentElement.classList.contains('mw-headline')) {
// "Edit source" button of an existing section heading.
let headingBottom = el.parentElement.parentElement.nextElementSibling;
let pos = 'beforebegin';
while (headingBottom != null &&
!/^H[123456]$/.test(headingBottom.tagName)) {
headingBottom = headingBottom.nextElementSibling;
}
if// (headingBottomWe're ==now null)at {the <p> or <div> or whatever.
// Check if it headingBottomonly =has el.parentElement.parentElement.parentElement;one child (the tree that contains this element)
// and if so, posreplace =the 'beforeend';links.
if (currentPivot.children.length > 1) {
return;
}
// Add below today's section header.
mw.loader.using([
'oojs-ui-core',
Line 16,764 ⟶ 16,829:
'mediawiki.widgets.TitlesMultiselectWidget'
], () => {
//swapElements(currentPivot, H4NewCopyrightProblemsListing());
headingBottom.insertAdjacentElement(pos, NewCopyrightProblemsListing());
});
}
else {
// This is in a heading. Let's place it after the section heading.
const heading = normalizeWikiHeading(el);
if (heading.root.classList.contains('dp-ia-upgraded')) {
return;
}
heading.root.classList.add('dp-ia-upgraded');
mw.loader.using([
'oojs-ui-core',
Line 16,775 ⟶ 16,845:
'mediawiki.widgets.TitlesMultiselectWidget'
], () => {
swapElementsheading.root.insertAdjacentElement(el'afterend', NewCopyrightProblemsListing());
});
}
Line 17,185 ⟶ 17,255:
function findSectionHeading(sectionHeadingName, n = 1) {
let currentN = 1;
const headlines = Array.from(document.querySelectorAll('h2 > .mw-headline'));
// Old style headings
[1, 2, 3, 4, 5, 6].map(v => `h${v} > .mw-headline`).join(',') +
',' +
// New style headings
[1, 2, 3, 4, 5, 6].map(v => `mw-heading > h${v}`).join(',')));
for (const el of headlines) {
if (el instanceof HTMLElement && el.innerText === sectionHeadingName) {
Line 17,281 ⟶ 17,356:
getSectionHTML: getSectionHTML,
getSectionId: getSectionId,
getWikiHeadingLevel: getWikiHeadingLevel,
guessAuthor: guessAuthor,
isWikiHeading: isWikiHeading,
msgEval: msgEval,
normalizeTitle: normalizeTitle,
normalizeWikiHeading: normalizeWikiHeading,
nsId: nsId,
openWindow: openWindow,
Line 17,293 ⟶ 17,368:
purge: purge,
renderWikitext: renderWikitext,
sectionHeadingId: sectionHeadingId,
sectionHeadingN: sectionHeadingN,
sectionHeadingName: sectionHeadingName,
toRedirectsObject: toRedirectsObject
};