Skip to content

Commit

Permalink
[partial] cci: section name conflict handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ChlodAlejandro committed Nov 19, 2022
1 parent 57af6cc commit 266f0c8
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 15 deletions.
20 changes: 17 additions & 3 deletions rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,17 @@ function getPlugins() {
].filter( ( v ) => !!v );
}

/**
* Gets global watch options
*
* @return watch options
*/
function getWatch() {
return {
include: [ 'src/**', 'i18n/**', 'package.json', 'rollup.config.js' ]
};
}

/**
* Automatically disable a given component based on environment variables.
*
Expand Down Expand Up @@ -153,7 +164,8 @@ export default [
'\n// <nowiki>',
footer: '// </nowiki>\n// <3'
},
plugins: getPlugins()
plugins: getPlugins(),
watch: getWatch()
} ),
// Standalone Attribution Notice Template Editor
auto( 'ante', {
Expand All @@ -166,7 +178,8 @@ export default [
'\n// <nowiki>',
footer: '// </nowiki>\n// <3'
},
plugins: getPlugins()
plugins: getPlugins(),
watch: getWatch()
} ),
// Standalone Infringement Assistant
auto( 'ia', {
Expand All @@ -179,6 +192,7 @@ export default [
'\n// <nowiki>',
footer: '// </nowiki>\n// <3'
},
plugins: getPlugins()
plugins: getPlugins(),
watch: getWatch()
} )
].filter( ( v ) => !!v );
9 changes: 4 additions & 5 deletions src/session/DeputyRootSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export default class DeputyRootSession {
await mw.loader.using(
[ 'oojs-ui-core', 'oojs-ui.styles.icons-content' ],
() => {
const firstHeading = casePage.findContributionSurveyHeadings()[ 0 ];
const firstHeading = casePage.findFirstContributionSurveyHeading();
if ( firstHeading ) {
const stopButton = new OO.ui.ButtonWidget( {
label: mw.msg( 'deputy.session.otherActive.button' ),
Expand Down Expand Up @@ -117,7 +117,7 @@ export default class DeputyRootSession {
/**
* Shows the interface for continuing a previous session. This includes
* the `[continue CCI session]` notice at the top of each CCI page section heading
* and a single message box showing when the page was last worked on on top of the
* and a single message box showing when the page was last worked on top of the
* first CCI heading found.
*
* @param casePage The case page to continue with
Expand All @@ -128,7 +128,7 @@ export default class DeputyRootSession {
mw.loader.using(
[ 'oojs-ui-core', 'oojs-ui.styles.icons-content' ],
() => {
const firstHeading = casePage.findContributionSurveyHeadings()[ 0 ];
const firstHeading = casePage.findFirstContributionSurveyHeading();
if ( firstHeading ) {
// Insert element directly into widget (not as text, or else event
// handlers will be destroyed).
Expand Down Expand Up @@ -199,7 +199,7 @@ export default class DeputyRootSession {
return mw.loader.using(
[ 'oojs-ui-core', 'oojs-ui.styles.icons-content' ],
() => {
const firstHeading = casePage.findContributionSurveyHeadings()[ 0 ];
const firstHeading = casePage.findFirstContributionSurveyHeading();
if ( firstHeading ) {
const messageBox = DeputyMessageWidget( {
classes: [
Expand Down Expand Up @@ -241,7 +241,6 @@ export default class DeputyRootSession {
const sectionNames = ( Array.isArray( section ) ? section : [ section ] ).map(
( _section ) => sectionHeadingName( _section )
);

// Save session to storage
const casePage = _casePage ?? await DeputyCasePage.build();
const session = await this.setSession( {
Expand Down
8 changes: 6 additions & 2 deletions src/ui/root/DeputyContributionSurveySection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
} from '../../models/ContributionSurveyRowSigningBehavior';
import { generateTrace } from '../../models/DeputyTrace';
import DeputyMessageWidget from '../shared/DeputyMessageWidget';
import sectionHeadingN from '../../wiki/util/sectionHeadingN';

/**
* The contribution survey section UI element. This includes a list of revisions
Expand Down Expand Up @@ -250,15 +251,18 @@ export default class DeputyContributionSurveySection implements DeputyUIElement
( v: HTMLElement ) => v.querySelector( '.mw-collapsible' )
)?.querySelector( '.mw-collapsible' ) ?? null;

const sectionWikitext = await this.casePage.wikitext.getSectionWikitext( this.headingName );
const sectionWikitext = await this.casePage.wikitext.getSectionWikitext(
this.headingName,
sectionHeadingN( this.heading, this.headingName )
);
return this._section ?? (
this._section = new ContributionSurveySection(
this.casePage,
this.headingName,
collapsible != null,
collapsible?.querySelector<HTMLElement>( 'th > div' ).innerText,
wikitext ?? sectionWikitext,
sectionWikitext.revid
wikitext ? wikitext.revid : sectionWikitext.revid
)
);
}
Expand Down
9 changes: 9 additions & 0 deletions src/wiki/DeputyCasePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,15 @@ export default class DeputyCasePage extends DeputyCase {
}
}

/**
* The n-cache stores the `n` of contribution survey headings. In other
* words, it differentiates survey headings by giving it a number if
* another section on the page has a matching heading. The n-cache
* only contains the n of contribution survey headings, but counts all
* HTML headings as part of the n-cache.
*/
nCache: Map<ContributionSurveyHeading, number>;

/**
* @param pageId The page ID of the case page.
* @param title The title of the page being accessed
Expand Down
25 changes: 20 additions & 5 deletions src/wiki/DeputyCasePageWikitext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,13 @@ export default class DeputyCasePageWikitext {
* grab the section using API:Query for an up-to-date version.
*
* @param section The section to edit
* @param n If the section heading appears multiple times in the page and n is
* provided, this function extracts the nth occurrence of that section heading.
*/
async getSectionWikitext( section: string | number ): Promise<string & { revid: number }> {
async getSectionWikitext(
section: string | number,
n = 1
): Promise<string & { revid: number }> {
if ( typeof section === 'number' ) {
return getPageContent(
this.casePage.pageId,
Expand All @@ -63,18 +68,28 @@ export default class DeputyCasePageWikitext {

let capturing = false;
let captureLevel = 0;
let currentN = 1;
const sectionLines = [];
for ( let i = 0; i < wikitextLines.length; i++ ) {
const line = wikitextLines[ i ];
const headerCheck = /^(=={1,5})\s*(.+?)\s*=={1,5}$/.exec( line );

if ( !capturing && headerCheck != null && headerCheck[ 2 ] === section ) {
sectionLines.push( line );
capturing = true;
captureLevel = headerCheck[ 1 ].length;
if (
!capturing &&
headerCheck != null &&
headerCheck[ 2 ] === section
) {
if ( currentN < n ) {
currentN++;
} else {
sectionLines.push( line );
capturing = true;
captureLevel = headerCheck[ 1 ].length;
}
} else if ( capturing ) {
if ( headerCheck != null && headerCheck[ 1 ].length <= captureLevel ) {
capturing = false;
break;
} else {
sectionLines.push( line );
}
Expand Down
43 changes: 43 additions & 0 deletions src/wiki/util/sectionHeadingN.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import last from '../../util/last';

/**
* Checks the n of a given element, that is to say the `n`th occurrence of a section
* with this exact heading name in the entire page.
*
* This is purely string- and element-based, with no additional metadata or parsing
* information required.
*
* This function detects the `n` using the following conditions:
* - If the heading ID does not have an n suffix, the n is always 1.
* - If the heading ID does have an n suffix, and the detected heading name does not end
* with a number, the n is always the last number on the ID.
* - If the heading ID and heading name both end with a number,
* - The n is 1 if the ID has an equal number of ending number patterns (sequences of "_n",
* e.g. "_20_30_40" has three) with the heading name.
* - Otherwise, the n is the last number on the ID if the ID than the heading name.
*
* @param heading The heading to check
* @param headingName The name of the heading to check
* @return The n, a number
*/
export default function ( heading: HTMLHeadingElement, headingName: string ): number {
const headingNameEndPattern = /(?:\s|_)*(\d+)$/g;
const headingIdEndPattern = /_(\d+)$/g;

const headingId = heading.getAttribute( 'id' ) ??
heading.querySelector( '.mw-headline' ).getAttribute( 'id' );
const headingIdMatches = headingId.match( headingIdEndPattern );
const headingNameMatches = headingName.match( headingNameEndPattern );

if ( headingIdMatches == null ) {
return 1;
} else if ( headingNameMatches == null ) {
// Last number of the ID
return +( headingIdEndPattern.exec( last( headingIdMatches ) )[ 1 ] );
} else if ( headingIdMatches.length === headingNameMatches.length ) {
return 1;
} else {
// Last number of the ID
return +( headingIdEndPattern.exec( last( headingIdMatches ) )[ 1 ] );
}
}

0 comments on commit 266f0c8

Please sign in to comment.