Skip to content

Commit c87ba35

Browse files
committed
Add flow types to guess-case/modes
1 parent 021aaab commit c87ba35

File tree

2 files changed

+66
-33
lines changed

2 files changed

+66
-33
lines changed

root/static/scripts/guess-case/modes.js

+51-32
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/*
2+
* @flow strict-local
23
* Copyright (C) 2005 Stefan Kestenholz (keschte)
34
* Copyright (C) 2015 MetaBrainz Foundation
45
*
@@ -12,6 +13,7 @@ import * as ReactDOMServer from 'react-dom/server';
1213
import getBooleanCookie from '../common/utility/getBooleanCookie';
1314
import {capitalize} from '../common/utility/strings';
1415

16+
import type {GuessCaseModeT} from './types';
1517
import {
1618
isPrepBracketWord,
1719
isPrepBracketSingleWord,
@@ -95,7 +97,12 @@ const POSTPROCESS_FIXLIST = [
9597
];
9698
/* eslint-enable no-multi-spaces */
9799

98-
function replaceMatch(matches, inputString, regex, replacement) {
100+
function replaceMatch(
101+
matches: RegExp$matchResult,
102+
inputString: string,
103+
regex: RegExp,
104+
replacement: string,
105+
): string {
99106
// get reference to first set of parentheses
100107
const a = matches[1] || '';
101108

@@ -112,29 +119,36 @@ function replaceMatch(matches, inputString, regex, replacement) {
112119
* @param is the input string
113120
* @param fixes the list of fix objects to apply
114121
*/
115-
function runFixes(inputString, fixes) {
122+
function runFixes(
123+
inputString: string,
124+
fixes: $ReadOnlyArray<[RegExp, string]>,
125+
): string {
126+
let output = inputString;
116127
fixes.forEach(function (fix) {
117128
const [regex, replacement] = fix;
118129
let matches;
119130

120131
if (regex.global) {
121-
let oldInputString;
122-
while ((matches = regex.exec(inputString))) {
123-
oldInputString = inputString;
124-
inputString = replaceMatch(matches, inputString, regex, replacement);
125-
if (oldInputString === inputString) {
132+
let previousOutput;
133+
while ((matches = regex.exec(output))) {
134+
previousOutput = output;
135+
output = replaceMatch(matches, output, regex, replacement);
136+
if (previousOutput === output) {
126137
break;
127138
}
128139
}
129-
} else if ((matches = inputString.match(regex)) !== null) {
130-
inputString = replaceMatch(matches, inputString, regex, replacement);
140+
} else {
141+
const matches = output.match(regex);
142+
if (matches !== null) {
143+
output = replaceMatch(matches, output, regex, replacement);
144+
}
131145
}
132146
});
133147

134-
return inputString;
148+
return output;
135149
}
136150

137-
const DefaultMode = {
151+
const DefaultMode: GuessCaseModeT = {
138152
description: '',
139153

140154
/*
@@ -187,21 +201,24 @@ const DefaultMode = {
187201
* My Track 12" remix => My Track (12" remix)
188202
*/
189203
prepExtraTitleInfo(words) {
190-
const lastWord = words.length - 1;
204+
let outputWords = words;
205+
const lastWord = outputWords.length - 1;
191206
let wordIndex = lastWord;
192207
let handlePreProcess = false;
193208

194209
while (wordIndex >= 0 && (
195210
// skip whitespace
196-
(words[wordIndex] === ' ') ||
211+
(outputWords[wordIndex] === ' ') ||
197212

198213
// vinyl (7" or 12")
199-
(words[wordIndex] === '"' &&
200-
(words[wordIndex - 1] === '7' || words[wordIndex - 1] === '12')) ||
201-
((words[wordIndex + 1] || '') === '"' &&
202-
(words[wordIndex] === '7' || words[wordIndex] === '12')) ||
203-
204-
isPrepBracketWord(words[wordIndex])
214+
(outputWords[wordIndex] === '"' &&
215+
(outputWords[wordIndex - 1] === '7' ||
216+
outputWords[wordIndex - 1] === '12')) ||
217+
((outputWords[wordIndex + 1] || '') === '"' &&
218+
(outputWords[wordIndex] === '7' ||
219+
outputWords[wordIndex] === '12')) ||
220+
221+
isPrepBracketWord(outputWords[wordIndex])
205222
)) {
206223
handlePreProcess = true;
207224
wordIndex--;
@@ -221,21 +238,21 @@ const DefaultMode = {
221238
if (wordIndex < lastWord) {
222239
// the word at wi broke out of the loop above, is not extra title info
223240
wordIndex++;
224-
while (words[wordIndex] === ' ' && wordIndex < lastWord) {
241+
while (outputWords[wordIndex] === ' ' && wordIndex < lastWord) {
225242
wordIndex++; // skip whitespace
226243
}
227244

228245
/*
229246
* If we have a single word that needs to be put in parentheses, consult
230247
* the list of words were we don't do that, otherwise continue.
231248
*/
232-
const probe = words[lastWord];
249+
const probe = outputWords[lastWord];
233250
if (wordIndex === lastWord && isPrepBracketSingleWord(probe)) {
234251
handlePreProcess = false;
235252
}
236253

237254
if (handlePreProcess && wordIndex > 0 && wordIndex <= lastWord) {
238-
let newWords = words.slice(0, wordIndex);
255+
let newWords = outputWords.slice(0, wordIndex);
239256

240257
if (newWords[wordIndex - 1] === '(') {
241258
newWords.pop();
@@ -246,13 +263,15 @@ const DefaultMode = {
246263
}
247264

248265
newWords.push('(');
249-
newWords = newWords.concat(words.slice(wordIndex, words.length));
266+
newWords = newWords.concat(
267+
outputWords.slice(wordIndex, outputWords.length),
268+
);
250269
newWords.push(')');
251-
words = newWords;
270+
outputWords = newWords;
252271
}
253272
}
254273

255-
return words;
274+
return outputWords;
256275
},
257276

258277
/*
@@ -284,7 +303,7 @@ const DefaultMode = {
284303
},
285304
};
286305

287-
export const English = {
306+
export const English: GuessCaseModeT = {
288307
...DefaultMode,
289308
description: ReactDOMServer.renderToStaticMarkup(exp.l(
290309
`This mode capitalises almost all words, with some words (mainly articles
@@ -303,25 +322,25 @@ export const English = {
303322
name: 'English',
304323

305324
runPostProcess(inputString) {
306-
inputString = DefaultMode.runPostProcess(inputString);
325+
let output = DefaultMode.runPostProcess(inputString);
307326
/*
308327
* This changes key names in titles to follow
309328
* the English classical music guidelines.
310329
* See https://musicbrainz.org/doc/Style/Classical/Language/English#Keys
311330
*/
312-
inputString = inputString.replace(
331+
output = output.replace(
313332
/\bin ([a-g])(?:[\s-]([Ff]lat|[Ss]harp))?\s(dorian|lydian|major|minor|mixolydian)(?:\b|$)/ig,
314333
function (match, p1, p2, p3) {
315334
return 'in ' + p1.toUpperCase() +
316335
(p2 ? '-' + p2.toLowerCase() : '') +
317336
' ' + p3.toLowerCase();
318337
},
319338
);
320-
return inputString;
339+
return output;
321340
},
322341
};
323342

324-
export const French = {
343+
export const French: GuessCaseModeT = {
325344
...DefaultMode,
326345
description: ReactDOMServer.renderToStaticMarkup(exp.l(
327346
`This mode capitalises titles as sentence mode, but also inserts spaces
@@ -345,7 +364,7 @@ export const French = {
345364
},
346365
};
347366

348-
export const Sentence = {
367+
export const Sentence: GuessCaseModeT = {
349368
...DefaultMode,
350369
description: ReactDOMServer.renderToStaticMarkup(exp.l(
351370
`This mode capitalises the first word of a sentence, most other words
@@ -360,7 +379,7 @@ export const Sentence = {
360379
name: 'Sentence',
361380
};
362381

363-
export const Turkish = {
382+
export const Turkish: GuessCaseModeT = {
364383
...DefaultMode,
365384
description: ReactDOMServer.renderToStaticMarkup(exp.l(
366385
`This mode handles the Turkish capitalisation of 'i' ('İ') and 'ı' ('I').

root/static/scripts/guess-case/types.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,21 @@
1010
import type GuessCaseInput from './MB/GuessCase/Input';
1111
import type GuessCaseOutput from './MB/GuessCase/Output';
1212

13-
declare type GuessCaseModeT = any;
13+
export type GuessCaseModeT = {
14+
+description: string,
15+
+doWord: () => boolean,
16+
+fixVinylSizes: (string) => string,
17+
+isLowerCaseWord: (string) => boolean,
18+
+isRomanNumber: (string) => boolean,
19+
+isSentenceCaps: () => boolean,
20+
+isUpperCaseWord: (string) => boolean,
21+
+name: string,
22+
+prepExtraTitleInfo: (Array<string>) => Array<string>,
23+
+preProcessTitles: (string) => string,
24+
+runPostProcess: (string) => string,
25+
+toLowerCase: (string) => string,
26+
+toUpperCase: (string) => string,
27+
};
1428

1529
export type GuessCaseT = {
1630
CFG_KEEP_UPPERCASED: boolean,

0 commit comments

Comments
 (0)