Хуки в JavaScript для вызова произвольного кода

Разработка под LiveStreet CMS
В данной статье я расскажу вам о том, как можно наследовать и дополнять JavaScript код в движке ЛС.

Вступление


Механизм делегирования кода JS в ЛС можно осуществлять такими наиболее часто употребляемыми методами в зависимости от поставленной задачи:

  1. Переопределить всю функцию (атата!)
    В своем коде просто переопределить весь метод:
    
    ls.MODULE.METHOD = function (param1, param2) { /* party hard */ }
    

    Желательно не использовать данный подход, он показан для примера.
  2. Механизм хуков
  3. Механизм маркеров

Рассмотрим кратко каждый из приемов.


1. Хуки


Объявление хука (места, где может быть выполнен произвольный код)

Пример кода:
ls.hook.run ('js_hook_super_name', [obj, block], this);


Создает запись для выполнения кода в месте, где хук расположен, вторым параметром передается массив параметров ([obj, block]) и указатель контекста (this). Этот хук можно перехватить с помощью плагина и вызвать свой код:

Использование хука (вызов кода в место, где объявлен хук)

Пример кода:
ls.hook.add ('js_hook_super_name', function (obj, block) { /* code here */ });


Хук на который цепляемся (js_hook_super_name), а также анонимная функция, в которую передаются параметры (obj, block), которые были переданы в объявлении хука. Третий возможный параметр — приоритет. Контекст в этой анонимной функции будет тот, на который указывает третий параметр объявления хука (в данном примере — this)

2. Маркеры


Когда я написал статью, я понял что, возможно, описание раздела про маркеры нужно было начинать с возможности инжекта кода, но, пожалуй, оставлю текст таким как есть. Не останавливайтесь если что-то не совсем понятно — читайте далее. Маркеры и их параметры я расписал очень детально.

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

Объявление маркера (места, где может быть модифицирована оригинальная функция)

Пример кода:
ls.hook.marker ('SomePlace');


Создает дополнительное место в функции (где он объявлен) для выполнения кода. Не обязателен. Маркера может и не быть вовсе, но и в такую функцию код добавить можно — в самое её начало (после открывающей скобки ({). Понятней станет после прочтения вызова метода инжекта кода (см. ниже).

А теперь как этот код может быть модифицирован:

Инжект кода в начало функции или место, где в ней объявлен маркер

Пример кода:
ls.hook.inject ([ls.MODULE, 'METHOD'], function () { /* Im INSIDE of function */ });


Первый параметр вызова:
[ls.MODULE, 'METHOD']

— имя функции куда нужно вставить код. Может быть: строкой ('ls.MODULE.METHOD', полной функцией (ls.MODULE.METHOD) или массивом ([ls.MODULE, 'METHOD']), где первый параметр — модуль, второй — строка, название метода.

Второй параметр вызова — собственно код и третий параметр (строка, не обязательный) — указание имени маркера (в данном примере — 'SomePlace'), куда вставлять свой код в функции (первый параметр вызова). Если не указать третий параметр, то код (2-й параметр вызова) будет вставлен в начало функции (1-й параметр вызова) сразу после открывающей скобки ({), в противном случае код будет помещен на место маркера ('SomePlace') в этой функции (1-й параметр вызова).

Другими словами: код в анонимной функции (2-й параметр вызова) будет перенесен в место маркера или на начало функции как будто он там и был написан с самого начала. Это позволяет управлять ходом обработки функции в т.ч. сделать return false чтобы прервать выполнение метода (если нужно). Хук (см. выше п. 1 вступления) прервать выполнение метода не может, только оперировать с набором параметров, которые переданы в функцию хука.

Итог


В ЛС существует два хороших механизма дополнения JS кода своим функционалом и один плохой метод, который использовать не стоит т.к. исчезает полная совместимость с другими плагинами.

Возможно, это кому-то поможет писать более правильные плагины без делегирования функционала шаблона (я бы вообще запретил в каталоге шаблоны с делегированием, но иногда без делегирования — никак).
0 комментариев
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.