dev

BannerNotification — JavaScript-библиотека, которая создает обертку встроенной библиотеки BannerNotification для UCP.

В дополнение она возвращает функцию автоматического добавления баннеров в верх видимых всплывающих окон. Библиотека совместима с ShowCustomModal, а вот Modal поддерживает ее частично.

Импорт

Чтобы использовать библиотеку в своих скриптах, напишите следующее:

importArticle({
    type: 'script',
    article: 'u:dev:MediaWiki:BannerNotification.js'
});

Конструктор баннера не будет доступен сразу же. Зарегистрируйте хук dev.banners, чтобы отловить момент, когда доступ к нему появится:

mw.hook('dev.banners').add(function(BannerNotification) {
    // `BannerNotification` создает баннер
    new BannerNotification('Hello world', 'notify').show();
    // Также к нему можно обратиться через `window.dev.banners.BannerNotification`, но лучше использовать свою ссылку
});

Usage

Конструктор

После получения доступа к конструктору BannerNotification можно создавать баннер.

new BannerNotification(content, type, $parent, timeout)
content - содержимое баннера. Если дана строка, она будет интерпретироваться как HTML. Если указано что-то кроме строки, оно будет конвертировано в строку. Таким образом экземпляры jQuery или Element будут бесполнезны. Примеры привязки событий после создания баннера с помощью свойства .$element будут приведены далее.
type - тип баннера. Возможные значения: notify, confirm, warn, error
$parent - элемент, в который будет помещен баннер. Это должен быть объект jQuery.
timeout - время, в течение которого будет показываться баннер, в миллисекундах. По умолчанию таймаута нет.

Методы

Вызовы методов экземпляров BannerNotification — самый распространенный способ взаимодействия с ними. В большинстве случаев используется только функция, показывающая баннер.

.show()
Показывает баннер. Если в данный момент активно всплывающее окно, он появится в его верху, но только если в конструкторе не был явно указан параметр $parent.
.hide()
Прячет баннер.
.setType(type)
Устанавливает тип уведомления. При этом иконка открытого баннера не обновится, пока он не будет скрыт и открыт снова. Этот метод не рекомендуется к применению, лучше создать новый баннер.
Возможные значения: notify, confirm, warn, error
.setContent(content)
Изменяет содержимое баннера. У уже открытого уведомления оно не обновится, пока тот не будет скрыт и открыт снова. Использовать метод не рекомендуется, лучше создать новый экземпляр.
.onClose(handler)
Привязывает функцию обратного вызова к событию закрытия баннера. Одновременно можно указать только одну функцию. Вызова не происходит, если баннер закрывается сам по истечении таймаута.

Свойства

У объекта BannerNotification есть несколько свойств. Случаев использования у них мало, однако могут возникнуть специфичные ситуации, требующие это. Обратите внимание: все свойства находятся в режиме "только чтения", и потому прямое присваивание нового значения никак не повлияет на баннер. Некоторые случаи использования свойств будут рассмотрены в разделе с примерами.

.$element
Объект jQuery, представляющий баннер. Если свойство .hidden равно true (метод .show не был вызван или был использован .hide), .$element будет null. Обращение к элементу полезно в случае привязки перехватчиков событий или иного взаимодействия с содержимым баннера.
.$parent
Объект jQuery, указанный в конструкторе в качестве родительского. Если ничего не было указано, свойство будет иметь значение undefined и не будет отражать фактический контейнер баннера.
.content
Строка с содержимым. Может быть изменено с помощью .setContent.
.type
Строка с типом. Можно изменить через метод .setType.
.hidden
Имеет логический тип, указывающий, виден ли баннер или нет. Вызов .show поменяет его значение на false, а вызов .hide — на true.
.onCloseHandler
Содержит фукнцию, которая будет вызвана при закрытии баннера. Если перехватчик события не назначался, будет лежать пустая функция.

Примеры

Это самый простой случай использования BannerNotifications. Зачастую знать показанное ниже достаточно для нормального использования библиотеки.

mw.hook('dev.banners').add(function(BannerNotification) {
    new BannerNotification('Hello', 'notify').show();
});

Если вы используете систему интернационализации и конкретно i18n-js, вы должны вставлять сообщения через .escape() или .parse() во избежание XSS-атак.

// Предположим, что у нас уже есть экземпляр `i18n`
mw.hook('dev.banners').add(function(BannerNotification) {
    new BannerNotification(i18n.msg('banner-content').escape(), 'notify').show();
});

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

mw.hook('dev.banners').add(function(BannerNotification) {
    // Привязываемся к контенту статьи. Выглядит странно, но это же примера ради!
    var $parent = $('#mw-content-text');

    new BannerNotification('Баннер находится внутри статьи. Я уверен, что это все неправильно!', 'notify', $parent).show();
});

Четвертый аргумент конструктора отвечает за таймаут, по истечении которого баннер закроется. Обратите внимание на undefined на месте родителя: мы не заинтересованы в его добавлении, поэтому делаем так. Также можно указать null — ничего не изменится.

mw.hook('dev.banners').add(function(BannerNotification) {
    new BannerNotification('Я закроюсь через 2 секунды.', 'notify', undefined, 2000).show();
});

Для привязки событий неподсредственно к содержимому баннера можно воспользоваться свойством $element. Пример ниже позволяет отменить таймаут, что нельзя сделать через стандартный интерфейс библиотеки.

mw.hook('dev.banners').add(function(BannerNotification) {
    var banner = new BannerNotification('Это уведомление закроется через 5 секунд, если ты по нему не кликнешь!', 'notify').show();
    var $content = banner.$element.find('.wds-banner-notification__text');

    var timeoutId = setTimeout(function() {
        banner.hide();
    }, 5000);

    $content.on('click', function() {
        clearTimeout(timeoutId);
        alert('Поздравляю, катастрофа предотвращена!');
        $content.text('Теперь мы в безопасности');

        // Примечание: это не обновит иконку, а сработает лишь в том случае,
        // когда этот баннер будет быстро скрыт и вновь открыт. Короче, не надо так
        banner.setType('confirm');
    });

    banner.onClose(function() {
        alert('Нет! Зачем ты скрыл его вручную?!');
    });
});