Skip to content

Commit

Permalink
util: add diff URL parser
Browse files Browse the repository at this point in the history
  • Loading branch information
ChlodAlejandro committed Apr 22, 2024
1 parent dc02cda commit 63bcaf3
Show file tree
Hide file tree
Showing 4 changed files with 370 additions and 27 deletions.
34 changes: 7 additions & 27 deletions src/modules/ante/ui/pages/CopiedTemplateRowPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import RevisionDateGetButton from '../components/RevisionDateGetButton';
import SmartTitleInputWidget from '../components/SmartTitleInputWidget';
import PageLatestRevisionGetButton from '../components/PageLatestRevisionGetButton';
import dangerModeConfirm from '../../../../util/dangerModeConfirm';
import parseDiffUrl from '../../../../wiki/util/parseDiffUrl';

export interface CopiedTemplateRowPageData {
/**
Expand Down Expand Up @@ -551,33 +552,12 @@ function initCopiedTemplateRowPage() {
return;
}
}
// From the same wiki, accept deprecation

// Attempt to get values from URL parameters (when using `/w/index.php?action=diff`)
let oldid = url.searchParams.get( 'oldid' );
let diff = url.searchParams.get( 'diff' );
const title = url.searchParams.get( 'title' );

// Attempt to get values from Special:Diff short-link
const diffSpecialPageCheck =
// eslint-disable-next-line security/detect-unsafe-regex
/\/wiki\/Special:Diff\/(prev|next|\d+)(?:\/(prev|next|\d+))?/.exec( url.pathname );
if ( diffSpecialPageCheck != null ) {
if (
diffSpecialPageCheck[ 1 ] != null &&
diffSpecialPageCheck[ 2 ] == null
) {
// Special:Diff/diff
diff = diffSpecialPageCheck[ 1 ];
} else if (
diffSpecialPageCheck[ 1 ] != null &&
diffSpecialPageCheck[ 2 ] != null
) {
// Special:Diff/oldid/diff
oldid = diffSpecialPageCheck[ 1 ];
diff = diffSpecialPageCheck[ 2 ];
}
}
// From the same wiki, accept deprecation immediately.

// Parse out info from this diff URL
const parseInfo = parseDiffUrl( url );
let { diff, oldid } = parseInfo;
const { title } = parseInfo;

// If only an oldid was provided, and no diff
if ( oldid && !diff ) {
Expand Down
1 change: 1 addition & 0 deletions src/wiki/util/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default {
nsId: nsId,
openWindow: openWindow,
pagelinkToTitle: pagelinkToTitle,
parseDiffUrl: parseDiffUrl,
performHacks: performHacks,
purge: purge,
renderWikitext: renderWikitext,
Expand Down
92 changes: 92 additions & 0 deletions src/wiki/util/parseDiffUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
interface DiffInfo {
diff?: number | string;
oldid?: number | string;
title?: string;
}

/**
* What it says on the tin. Attempt to parse out a `title`, `diff`,
* or `oldid` from a URL. This is useful for converting diff URLs into actual
* diff information, and especially useful for {{copied}} templates.
*
* @param url The URL to parse
* @return Parsed info: `diff` or `oldid` revision IDs, and/or the page title.
*/
export default function parseDiffUrl( url: URL | string ): DiffInfo {
if ( typeof url === 'string' ) {
url = new URL( url );
}

// Attempt to get values from URL parameters (when using `/w/index.php?action=diff`)
let oldid: string | number = url.searchParams.get( 'oldid' );
let diff: string | number = url.searchParams.get( 'diff' );
let title = url.searchParams.get( 'title' );

// Attempt to get information from this URL.
tryConvert: {
if ( title && oldid && diff ) {
// Skip if there's nothing else we need to get.
break tryConvert;
}

// Attempt to get values from Special:Diff short-link
const diffSpecialPageCheck =
// eslint-disable-next-line security/detect-unsafe-regex
/\/wiki\/Special:Diff\/(prev|next|\d+)(?:\/(prev|next|\d+))?/i.exec( url.pathname );
if ( diffSpecialPageCheck != null ) {
if (
diffSpecialPageCheck[ 1 ] != null &&
diffSpecialPageCheck[ 2 ] == null
) {
// Special:Diff/diff
diff = diffSpecialPageCheck[ 1 ];
} else if (
diffSpecialPageCheck[ 1 ] != null &&
diffSpecialPageCheck[ 2 ] != null
) {
// Special:Diff/oldid/diff
oldid = diffSpecialPageCheck[ 1 ];
diff = diffSpecialPageCheck[ 2 ];
}
break tryConvert;
}

// Attempt to get values from Special:PermanentLink short-link
const permanentLinkCheck =
/\/wiki\/Special:Perma(nent)?link\/(\d+)/i.exec( url.pathname );
if ( permanentLinkCheck != null ) {
oldid = permanentLinkCheck[ 2 ];
break tryConvert;
}

// Attempt to get values from article path with ?oldid or ?diff
// eslint-disable-next-line security/detect-non-literal-regexp
const articlePathRegex = new RegExp( mw.util.getUrl( '(.*)' ) )
.exec( url.pathname );
if ( articlePathRegex != null ) {
title = articlePathRegex[ 1 ];
break tryConvert;
}
}

// Convert numbers to numbers
if ( oldid != null && !isNaN( +oldid ) ) {
oldid = +oldid;
}
if ( diff != null && !isNaN( +diff ) ) {
diff = +diff;
}

// Try to convert a page title
try {
title = new mw.Title( title ).getPrefixedText();
} catch ( e ) {
console.warn( 'Failed to normalize page title during diff URL conversion.' );
}

return {
diff: diff,
oldid: oldid,
title: title
};
}
Loading

0 comments on commit 63bcaf3

Please sign in to comment.