Refactor Program.cs to use async Run method for improved performance. Update index.html to specify language attribute for accessibility. Enhance BumperTemplateEditor and ScheduleGrid components by replacing divs with buttons for better keyboard accessibility. Improve TemplatePreview sorting logic and optimize episode regex handling. Add close button to ToastItem for better user interaction. Update localization files to include 'close' translations. Refactor CardTitle to ensure screen reader compatibility by explicitly rendering children.
This commit is contained in:
@@ -18,6 +18,20 @@ export function findNumbers(fileName: string): { index: number; start: number; t
|
||||
|
||||
const escapeRegex = (value: string) => value.replace(/[.*+?^${}()|[\]\\/-]/g, '\\$&')
|
||||
|
||||
const isLetter = (char: string) => /\p{L}/u.test(char)
|
||||
const isLetterOrDigit = (char: string) => /[\p{L}\p{N}]/u.test(char)
|
||||
|
||||
/**
|
||||
* Хвост строки из символов, удовлетворяющих условию. Обходим с конца вручную, а не шаблоном вида
|
||||
* `X*$`: такой шаблон движок примеряет с каждой позиции строки и получает квадратичное время
|
||||
* (см. предупреждение анализатора о backtracking), тогда как здесь один линейный проход.
|
||||
*/
|
||||
function trailingRun(value: string, matches: (char: string) => boolean): string {
|
||||
let start = value.length
|
||||
while (start > 0 && matches(value[start - 1])) start--
|
||||
return value.slice(start)
|
||||
}
|
||||
|
||||
/**
|
||||
* Строит regex по указанному пользователем числу в имени файла. Якорем берётся слово перед числом
|
||||
* («Серия 01» → `Серия\s*(\d{1,3})`): позиция числа в разных файлах гуляет, а слово рядом — нет.
|
||||
@@ -36,11 +50,11 @@ export function buildEpisodeRegex(fileName: string, occurrenceIndex: number): st
|
||||
|
||||
// Разделители между якорем и числом описываем классом, а не буквально: в соседних файлах
|
||||
// там встречается то пробел, то точка, то подчёркивание.
|
||||
const gap = /[^\p{L}\p{N}]*$/u.exec(before)?.[0] ?? ''
|
||||
const gap = trailingRun(before, (char) => !isLetterOrDigit(char))
|
||||
const anchorSource = before.slice(0, before.length - gap.length)
|
||||
// Якорь — только буквы: захвати он цифры, «S01E07» дало бы правило `S01E(\d)`, прибитое
|
||||
// к первому сезону, и на «S02E05» оно бы уже не сработало.
|
||||
const anchor = /\p{L}+$/u.exec(anchorSource)?.[0]
|
||||
const anchor = trailingRun(anchorSource, isLetter)
|
||||
|
||||
if (anchor) return `${escapeRegex(anchor)}${gap ? '[\\s._-]*' : ''}${digits}`
|
||||
|
||||
|
||||
Reference in New Issue
Block a user