Расширение API

Библиотека Inputmask строится вокруг расширяемой модели, где ядро отвечает за разбор маски, управление курсором и нормализацию ввода, а все специфические сценарии вынесены в слой расширений. Такой подход позволяет добавлять новые правила форматирования без модификации внутренней логики.

Ключевая особенность API — наличие глобальных реестров и прототипов, через которые подключаются пользовательские определения, алиасы и обработчики событий.

Основные точки расширения:

  • Inputmask.prototype — базовый прототип, через который создаются экземпляры масок
  • Inputmask.extendDefinitions — расширение набора токенов маски
  • Inputmask.extendAliases — добавление новых псевдонимов масок
  • Inputmask.extendDefaults — изменение поведения по умолчанию
  • hooks и callback-интерфейсы — перехват жизненного цикла ввода

Эта структура позволяет формировать как локальные, так и глобальные расширения поведения.


Расширение системы определений символов

В основе маски Inputmask лежит система definitions — словарь токенов, каждый из которых описывает допустимые символы и правила обработки.

Стандартные токены включают:

  • 9 — цифра
  • a — буква
  • * — буквенно-цифровой символ

Однако реальная сила библиотеки проявляется при добавлении собственных определений.

Пример расширения:

Inputmask.extendDefinitions({
  '#': {
    validator: "[0-9]",
    cardinality: 1,
    definitionSymbol: "#"
  }
});

Структура определения

Каждое пользовательское определение может включать:

  • validator — регулярное выражение или функция проверки символа
  • cardinality — количество символов, которые занимает токен
  • prevalidator — предварительная проверка до применения основного валидатора
  • casing — автоматическое приведение регистра
  • definitionSymbol — символ, используемый в маске

Более сложный пример с функцией-валидатором:

Inputmask.extendDefinitions({
  "H": {
    validator: function (ch) {
      return /[0-9A-Fa-f]/.test(ch);
    },
    casing: "upper"
  }
});

Здесь создаётся токен для шестнадцатеричных значений с автоматическим приведением к верхнему регистру.


Расширение алиасов масок

Алиасы (aliases) представляют собой именованные конфигурации масок. Они позволяют переиспользовать сложные настройки без повторного описания структуры.

Добавление нового алиаса:

Inputmask.extendAliases({
  "custom-date": {
    mask: "99-99-9999",
    placeholder: "dd-mm-yyyy",
    alias: "datetime"
  }
});

Возможности алиасов

Алиасы могут содержать практически любые настройки экземпляра Inputmask:

  • mask — строка маски или массив масок
  • regex — регулярное выражение вместо маски
  • placeholder — пользовательский плейсхолдер
  • clearIncomplete — очистка незавершённого ввода
  • showMaskOnHover — отображение маски при наведении
  • onBeforeMask — трансформация входных данных

Пример алиаса с предобработкой:

Inputmask.extendAliases({
  "phone-ru": {
    mask: "+7 (999) 999-99-99",
    onBeforeMask: function (value) {
      return value.replace(/^8/, "7");
    }
  }
});

Хуки жизненного цикла ввода

Одним из наиболее гибких механизмов расширения являются callback-хуки. Они позволяют вмешиваться в процесс обработки данных на разных этапах.

Основные точки перехвата:

  • onBeforeMask — до применения маски
  • onBeforePaste — перед вставкой из буфера
  • onBeforeWrite — перед записью в поле
  • onUnMask — при извлечении «сырого» значения
  • onComplete — при полном заполнении маски

Пример обработки вставки:

Inputmask.extendAliases({
  "serial": {
    mask: "AAA-999",
    onBeforePaste: function (pastedValue) {
      return pastedValue.toUpperCase().replace(/\s/g, "");
    }
  }
});

Управление изменениями через onBeforeWrite

onBeforeWrite позволяет контролировать каждое изменение ввода:

onBeforeWrite: function (event, buffer, caretPos, opts) {
  if (buffer.join("").includes("000")) {
    return false;
  }
}

Возврат false блокирует запись, что позволяет реализовывать сложные ограничения.


Прототипное расширение и низкоуровневый API

Inputmask предоставляет доступ к внутреннему прототипу, что позволяет изменять поведение на уровне экземпляров.

Inputmask.prototype.someExtension = function () {
  // пользовательская логика
};

Хотя такой подход используется реже, он даёт возможность интеграции с нестандартными системами управления формами.

Создание экземпляров с кастомной логикой

const mask = new Inputmask({
  mask: "999-AAA",
  definitions: {
    A: {
      validator: "[A-Z]",
      casing: "upper"
    }
  }
});

mask.mask(document.querySelector("#field"));

Переопределение глобальных настроек

Глобальные настройки влияют на все создаваемые экземпляры масок.

Inputmask.extendDefaults({
  clearMaskOnLostFocus: false,
  showMaskOnHover: false
});

Такой механизм используется для унификации поведения приложения без необходимости повторной настройки каждой маски.


Пользовательские валидаторы и композиция правил

Расширение API часто связано с созданием сложных валидаторов, комбинирующих несколько условий.

Пример комбинированного валидатора:

Inputmask.extendDefinitions({
  "P": {
    validator: function (ch, buffer, pos, strict) {
      const isDigit = /[0-9]/.test(ch);
      const isEven = parseInt(ch, 10) % 2 === 0;
      return isDigit && isEven;
    }
  }
});

Такой подход позволяет внедрять бизнес-правила прямо в слой ввода данных.


Работа с динамическими масками через API

Inputmask поддерживает изменение маски во время выполнения. Это важный элемент расширяемости, позволяющий адаптировать поведение формы в зависимости от состояния данных.

const im = new Inputmask("9999-9999");
im.mask(element);

im.option({
  mask: "+7 (999) 999-99-99"
});

Изменение конфигурации не требует пересоздания экземпляра, что снижает нагрузку на DOM и повышает стабильность интерфейса.


Интеграция пользовательских расширений в цепочку обработки

Внутренний pipeline Inputmask включает несколько этапов:

  1. Парсинг ввода
  2. Применение definitions
  3. Проверка alias-конфигурации
  4. Обработка hooks
  5. Финальная нормализация

Каждый этап может быть расширен через API, что позволяет внедрять дополнительные слои логики без вмешательства в ядро.

Пример вмешательства на уровне преобразования:

Inputmask.extendAliases({
  "trimmed": {
    onBeforeMask: function (value) {
      return value.trim().replace(/\s+/g, "-");
    }
  }
});

Композиция расширений и переиспользование логики

Расширения могут комбинироваться между собой. Алиасы могут включать кастомные definitions, а definitions могут использоваться в разных alias-конфигурациях.

Inputmask.extendDefinitions({
  "X": { validator: "[A-Z]" }
});

Inputmask.extendAliases({
  "code": {
    mask: "XXX-999",
    definitions: {
      X: { validator: "[A-Z]" }
    }
  }
});

Такой подход позволяет создавать библиотеку внутренних стандартов для проекта, сохраняя единый стиль ввода данных.


Расширение поведения маски через событийную модель

Хотя Inputmask не является полноценной event-driven системой, он предоставляет набор событий, которые можно использовать для построения реактивного поведения.

element.addEventListener("complete", function () {
  console.log("Поле заполнено");
});

Событийная модель часто используется в сочетании с хуками для создания сложных сценариев валидации и синхронизации данных между полями формы.