PageSourceSearch

https://cdnn.1prime.ru//js/libs/ria.modal.layer.js

js 1prime.ru collected 2026-10-01 08:34:20 UTC 42,230 bytes, 878 lines download raw bytes

1;"use strict";
2
3/**
4 *  modalLayer v2 12/07/18
5 *
6 * ---------------------------------------------
7 *  Приоритет значений
8 * ---------------------------------------------
9 *
10 *  1. значение из data атрибута на кнопке открытия / закрытия окна
11 *  2. значение переданное через объект в метод открытия/закрытия
12 *  3. значение из data на открываемом / закрываемом прессете
13 *  4. значение по умолчанию или переданное при инициализации для всех окон
14 *
15 * ---------------------------------------------
16 *  Описания data атрибутов
17 * ---------------------------------------------
18 *
19 *  data атрибуты для открытия попапа :
20 *
21 *  data-modal-open             - для открытия попапа, работает только для предустановленных пресетов
22 *  data-modal-max-width        - максимальная ширина попапа
23 *  data-modal-use-full         - для настройки fullscreen слоя установить любое значение
24 *
25 *  data-modal-hide-closing-off - отключение закрытия окна при клике на заменяющий слой
26 *  data-modal-close-hidden     - скрыть крестик закрытия окна
27 *
28 *  data-modal-before-open      - имя функции в window выполняемой до открытия окна
29 *  data-modal-after-open       - имя функции в window выполняемой после открытия окна
30 *
31 *  data-modal-valing           - выравнивание окна [ middle ], top, bottom )
32 *  data-modal-valing-full      - выравнивание окна при fullscreen [ middle ], top, bottom )
33 *
34 *  data-modal-indent           -
35 *  data-modal-indent-top       -
36 *  data-modal-indent-bottom    -
37 *
38 *
39 *  data атрибут для закрытия попапа :
40 *  data-modal-close            - для закрытия попапа установить любое значение
41 *  data-modal-clear-form       - очистка формы в закрываемом пресете или очиста форм во всех пресетах
42 *  data-modal-before-close     - имя функции в window выполняемой до закрытия окна
43 *  data-modal-after-close      - имя функции в window выполняемой после закрытия окна
44 *
45 * ---------------------------------------------
46 *  Описания свойств объекта при открытии / закртыии
47 * ---------------------------------------------
48 *
49 *  Объект свойств передаваемых в open();
50 *  open            - название для предустановленного пересета
51 *  maxWidth        - максимальная ширина окна
52 *  useFull         - использовать full screen если окно не помещается по ширинеx
53 *  hideClosingOff  - отключение закрытия окна при клике на затемняющий слой
54 *  closeHidden     - скрыть крестик закрытия окна
55 *  beforeOpen      - функция или имя функции в window выполняемой до открытия окна
56 *  afterOpen       - функция или имя функции в window выполняемой после открытия окна
57 *  beforeClose     - функция или имя функции в window выполняемой до закрытия окна
58 *  afterClose      - функция или имя функции в window выполняемой после закрытия окна
59 *  customTitle     - текст для кастомного title
60 *  customContent   - текст для кастомного content
61 *
62 *  Объект свойств передаваемых в close();
63 *  clearForm       - очистить формы  [ false ], true, 'all'
64 *  beforeClose     - функция или имя функции в window выполняемой до закрытия окна
65 *  afterClose      - функция или имя функции в window выполняемой после закрытия окна
66 *
67 * ---------------------------------------------
68 *  triggers
69 * ---------------------------------------------
70 *
71 *  initedModalLayer        - инициализирован
72 *  openModalLayer          - окно открыто
73 *  closeModalLayer         - окно закрыто
74 *  hideModalLayer          - контент скрыт при смене
75 *  showModalLayer          - контент показан при смене
76 *  changeModalLayer        - смена контента завершена
77 *
78 *  Содержание объекта data:
79 *  data = {
80 *      eventType   - название эвента
81 *      plugin      - ссылка на плагин
82 *      current     - текущие состояния
83 *  }
84 *
85 *  подписка:
86 *  $( window ).on( 'initedModalLayer openModalLayer closeModalLayer hideModalLayer showModalLayer changeModalLayer', function( event, data ){});
87 *
88 * ---------------------------------------------
89 *  Открыть готовый прессет
90 * ---------------------------------------------
91 *
92 *  data params:
93 *  data-modal-open         - имя пресета
94 *  data-modal-max-width    - ширина открываемомго попапа, только для этой кнопки
95 *  data-modal-use-full     - флаг - делать попап фулскрин как только он не помещается по ширине
96 *
97 *  code:
98 *  modalLayer.open('name_preset');
99 *  modalLayer.open({
100 *      preset: 'name_preset'
101 *  });
102 *
103 *  click:
104 *  <a data-modal-open='name_preset' />
105 *  <a data-modal-open='name_preset' data-modal-max-width='150px' />
106 *  <a data-modal-open='name_preset' data-modal-max-width='150px' data-modal-use-full='true' />
107 *
108 * ---------------------------------------------
109 *  Открыть кастомный попап
110 * ---------------------------------------------
111 *
112 *  modalLayer.open({
113 *      customTitle: 'title text',
114 *      customContent: 'content text'
115 *  })
116 *
117 * ---------------------------------------------
118 *  Закрыть попап
119 * ---------------------------------------------
120 *
121 *  click:
122 *  <a data-modal-close='' />
123 *
124 *  code:
125 *  modalLayer.close();
126 *  modalLayer.close({
127 *      clearForm: true
128 *  });
129 *
130 * ---------------------------------------------
131 * */
132
133var modalLayer = {
134	init: function( options ){
135
136		var _this = this;
137
138		var defaults = {
139	    // used during initialization
140            mainClass : "modal",
141            modifierIsOpen : "m-open",          // попап открыт
142            modifierIsFull : "m-full",          // попап на весь экран
143            modifierIsActive : "m-active",      // активный пресет
144            modifierIsTransform : "m-transform",// container в процессе замены контента трансформацией
145            modifierIsCloseHide : "m-close-hide",// класс скрытого крестика
146            pageSelector : "#page",             // селектор слоя данных
147            modalSelector : "#modalLayer",      // селектор слоя попапа
148
149        // used each size
150            useFull : true,                     // открывать все окна когда упираются в гирину экрана в режиме фуллс крина
151            maxWidth : '480',                   // максимальный размер попапа по умолчанию
152            typeChange : 'resize',              // тип смены контента                                                   [ 'resize' ], 'false'
153            clearForm : false,                  // очистка форм после закрытия окна                                     [ false ], true, 'all'
154            hideClosingOff : false,             // отключить закрытие окна по затемняющиму слою
155            closeHidden : false,                // скрыть крестик закрытия
156
157            beforeOpen : false,                 // функция или имя функции выполняемой до открытия окна
158            afterOpen : false,                  // функция или имя функции выполняемой после открытия окна
159
160            beforeClose : false,                // функция или имя функции выполняемой до закрытия окна
161            afterClose : false,                 // функция или имя функции выполняемой после закрытия окна
162
163            valign: false,                      // выравнивание окна по вертикали                                       [ false ], top, bottom, center = false, full
164            valignFull: false,                  // выравнивание окна по вертикали когда ширина попапа <= ширине экрана  [ false ], top, bottom, center, full = false
165
166            indent : 30,                        // вертикальные отступы до границ окна                                  []
167            indentTop : false,                  // верхний отступ до границ окна                                        []
168            indentBottom : false,               // нижний отступ до границ окна                                         []
169
170            //durationsChangeSize : 200,        // длительсность иземения размеров окна при typeChange : 'resize'
171            //durationsHideContent : 250,       // длительность скрытия контента при typeChange : 'resize'
172            //durationsShowContent : 200,       // длительность показа контента при typeChange : 'resize'
173
174            durationsChangeSize : 250,          // длительсность иземения размеров окна при typeChange : 'resize'
175            durationsHideContent : 250,         // длительность скрытия контента при typeChange : 'resize'
176            durationsShowContent : 250,         // длительность показа контента при typeChange : 'resize'
177
178        // responsive settings
179            responsive : {                      // адаптивные настройки
180                /** 0 : { used each size params },
181                 *  455 : { used each size params },
182                 *  640 : { used each size params },
183                 *  .....
184                 *  853 : { used each size params }
185                 *  1024 : { used each size params }
186                 */
187            }
188        };
189
190        _this.defOptions = defaults;
191        _this.userOptions = options;
192        _this.options = $.extend( true, {}, defaults, options );
193
194        /** used during initialization and delete */
195        _this.$page = $( _this.options.pageSelector );
196        delete _this.options.pageSelector;
197        _this.$modal = $( _this.options.modalSelector );
198        delete _this.options.modalSelector;
199        if (  _this.$page.length <= 0 || _this.$modal.length <= 0) {
200            // если нет стоя контента или стоя попапа выходим
201            console.log(' No layers found for "modalLayer" ');
202            return false;
203        }
204        _this.mc = _this.options.mainClass;
205        delete _this.options.mainClass;
206        _this.mOpen = _this.options.modifierIsOpen;
207        delete _this.options.modifierIsOpen;
208        _this.mFull = _this.options.modifierIsFull;
209        delete _this.options.modifierIsFull;
210        _this.mActive = _this.options.modifierIsActive;
211        delete _this.options.modifierIsActive;
212        _this.mCloseHide = _this.options.modifierIsCloseHide;
213        delete _this.options.modifierIsCloseHide;
214        _this.mTransform = _this.options.modifierIsTransform;
215        delete _this.options.modifierIsTransform;
216
217        /** data attribute */
218        _this.tData = {
219            open : _this.mc + '-open',                      // data-modal-open              название пресета, работает только для предустановленных пресетов
220            close : _this.mc + '-close',                    // data-modal-close             закрытие попапа - любое значение
221            useFull : _this.mc + '-use-full',               // data-modal-use-full          для настройки fullscreen слоя установить любое значение
222            maxWidth : _this.mc + '-max-width',             // data-modal-max-width         максимальная ширина попапа
223            clearForm : _this.mc + '-clear-form',           // data-modal-clear-form        очищать форму(ы) после закрытия
224
225            hideClosingOff : _this.mc + '-hide-closing-off',// data-modal-hide-closing-off  отключить закрытие окна по затемняющиму слою
226            closeHidden : _this.mc + '-close-hidden',       // data-modal-close-hidden      скрыть крестик закрытия
227
228            beforeOpen : _this.mc + '-before-open',         // data-modal-before-open       функция выполняемая до открытия окна
229            afterOpen : _this.mc + '-after-open',           // data-modal-after-open        функция выполняемая после открытия окна
230
231            beforeClose : _this.mc + '-before-close',       // data-modal-before-close      функция выполняемая до закрытия окна
232            afterClose : _this.mc + '-after-close',         // data-modal-after-close       функция выполняемая после закрытия окна
233
234            valign : _this.mc + '-valign',                  // data-modal-valign            выравнивание окна
235            valignFull : _this.mc + '-valign-full',         // data-modal-valign-full       выравнивание окна при fullscreen
236
237            indent : _this.mc + '-indent',                  // data-modal-indent            отступ у окна
238            indentTop : _this.mc + '-indent-top',           // data-modal-indent-top        отступ у окна сверху
239            indentBottom : _this.mc + '-indent-bottom'      // data-modal-indent-bottom     отступ у окна снизу
240        };
241
242        /** main objects */
243        _this.$hide = $( "." + _this.mc + "__hide", _this.$modal );
244        _this.$indents = $( "." + _this.mc + "__indents", _this.$modal );
245        _this.$alignment = $( "." + _this.mc + "__alignment", _this.$modal );
246        _this.$size = $( "." + _this.mc + "__size", _this.$modal );
247        _this.$container = $( "." + _this.mc + "__container", _this.$modal );
248        _this.$presets = $( "." + _this.mc + "__preset", _this.$modal );
249        _this.$contents = $( "." + _this.mc + "__content", _this.$modal );
250        _this.$customTitle = $( "." + _this.mc + "__preset[data-" + _this.mc + "-preset='custom'] ." + _this.mc + "__main-title span", _this.$modal );
251        _this.$customContent = $( "." + _this.mc + "__preset[data-" + _this.mc + "-preset='custom'] ." + _this.mc + "__main-content", _this.$modal );
252        _this.$close = $( "." + _this.mc + "__close", _this.$modal );
253
254        /** Current breakpoint settings */
255        _this._settings = {
256            breakpoints : [ -1, 0 ],            // текущий активный интервал для адаптива
257        };
258
259        /** Current states */
260        _this._current = {
261            preset : false,                     // название открытого пересета
262            $preset : false,                    // объект активного пресета
263            isOpen : false,                     // попап открыт
264            isFull: false,                      // занимает весь экран если упирается в края по ширине
265            pageTop : 0,                        // позиция страницы по вертикали
266            pageLeft : 0,                       // позиция страницы по горизонтали
267            clientHeight: false                 // размер клиента по вертикали
268        };
269
270        /** Queues */
271        _this.queueOpenData = [
272            'maxWidth',
273            'useFull',
274            'clearForm',
275            'closeHidden',
276            'beforeOpen', 'afterOpen',
277            'beforeClose', 'afterClose',
278            'valign', 'valignFull',
279            'indent', 'indentTop', 'indentBottom',
280        ];
281        _this.queueCloseData = [
282            'clearForm',
283            'beforeClose',
284            'afterClose'
285        ];
286
287        /** Первичные стили на слои */
288		_this.$page
289			.css( 'position', 'relative' )
290			.css( 'margin', '0' )
291			.css( 'padding', '0' );
292		_this.$modal
293			.css( 'position', 'absolute' );
294
295		_this.$presets.hide();
296		_this.addHandlers();
297        _this.getSettings();
298        _this.setTrigger( 'inited' );
299
300	},
301
302	addHandlers: function(){
303		var _this = this;
304		// Открываем попап по клику на элемент с атрибутом data-modal-open='название пресета'
305		$( 'body' ).on( 'click', '*[data-' + _this.tData.open + ']', function(){
306		    let tagOpen = $( this ).data( _this.tData.open );
307			if ( tagOpen != '' && typeof tagOpen == 'string' ){
308				let $this = $( this ),
309                    paramsObj = {
310				        preset: tagOpen
311				    };
312				$.each( _this.queueOpenData, function( i, v ){
313                    if ( $this.data( _this.tData[ v ] ) ) {
314                        paramsObj[ v ] = $this.data( _this.tData[ v ] );
315                    }
316                });
317                _this.open( paramsObj );
318			}
319		});
320		/* Закрываем попап по клику на элемент с атрибутом data-modal-close */
321		$( 'body' ).on( 'click', '*[data-' + _this.tData.close + ']', function(){
322            var $this = $( this ),
323                paramsObj = {};
324            $.each( _this.queueCloseData, function( i,v ){
325                if ( $this.data( _this.tData[ v ] ) ) paramsObj[ v ] = $this.data( _this.tData[ v ] );
326            });
327            _this.close( paramsObj );
328		});
329		/* Закрываем попап по клику на крестик */
330		_this.$close.on( 'click', function(){
331			_this.close();
332		});
333		/* Закрываем попап по клику на затемняющий слой */
334		_this.$hide.on( 'click', function(){
335		    if ( !_this._current.hideClosingOff ) _this.close();
336		});
337        $( window ).scroll(function(){
338            _this.onScroll();
339        });
340		$( window ).resize(function(){
341		    _this.onResize();
342		});
343
344	},
345
346    onScroll : function(){
347        var _this = this;
348        if ( _this._current.isOpen ) {
349            _this.checkPageLeft();
350        }
351    },
352
353    onResize : function( force ){
354        var _this = this;
355        if ( force || _this._current.isOpen ) {
356            _this.getSettings();
357            _this.setLayersHeight();
358            _this.checkPageTop();
359            _this.checkFull( );
360            _this.checkVAlign( );
361        }
362    },
363
364    openFull : function( content ){
365	    if ( content ){
366	        $('#modalFullContent').html( content );
367        }
368	    this.open( 'full' );
369    },
370
371	open: function( options ){
372
373	    /* TODO отладка */ //this.testingShowObject( true, 'BEFORE OPEN');
374
375	    // если не переданы опции выходим
376	    if ( !options ) return false;
377	    // если передана строка то это название пресета
378	    if ( typeof options == 'string' ) {
379	        options = {
380	            preset : options
381            }
382        }
383		// если не передан пресет проверяем кастомные данные для открытия кастомного попапа
384		if ( !options.preset ) {
385			if ( ( options.customTitle || options.customContent ) ) {
386				options.preset = 'custom'
387			} else {
388				return false;
389			}
390		}
391		// создаем объект с данными открываемого персета
392		var n = {
393            $preset : this.$container.find( '.' + this.mc + '__preset[data-' + this.mc + '-preset = "' + options.preset + '"]' )
394        };
395
396        // если такой пресет есть в верстке ... иначе выходим
397		if ( n.$preset.length > 0 ) {
398            var _this = this,
399                c = _this._current;
400
401            // Берем настройки и раширяем _current
402            _this.getSettings();
403            $.extend( true, c, _this._settings );
404            _this.setLayersHeight();
405
406            n.preset = options.preset;
407            n.customTitle = options.customTitle;
408            n.customContent = options.customContent;
409
410            // обновляем параметры открываемого пресета с data параметров
411            $.each( _this.queueOpenData, function( i, v ){
412                let presetData = n.$preset.data( _this.tData[ v ] )
413                // TODO testmodalFullHeader
414                //console.log(v, ' : data = ', presetData, ', option = ', options[ v ], ', _current = ', c[ v ]);
415                n[ v ] = presetData || presetData === false ? presetData : options[ v ] || c[ v ] || false;
416            });
417            n.maxWidth = parseInt( n.maxWidth );
418
419            if ( c.isOpen ) {
420
421                _this.change( n );
422
423            } else {
424                $.extend( true, c, n );
425
426                /* TODO remove */ //this.testingShowObject( true, 'modalLayer Open' );
427
428                // сохраняем прокрутку body по вертикали и горизонтали
429                _this.getPageIndents();
430                // выставляем максмальную ширину на контейнер
431                _this.$container.css( 'max-width', c.maxWidth );
432                // если пресет custom заполняем данными
433                if ( c.preset == 'custom' ) _this.pushCustom( c );
434                // выполняем функцию до открытия окна
435                _this.useFunction( c.beforeOpen );
436                // скрываем крестик закрытия
437                if ( c.closeHidden ) _this.$modal.addClass( _this.mCloseHide );
438                // показываем пресет
439                c.$preset.show();
440                // Выставляем контентный слой в fixed с позиционаированием по текущей прокрутке страницы
441                _this.$page
442                    .css( 'position', 'fixed' )
443                    .css( 'top', -c.pageTop )
444                    .css( 'left', -c.pageLeft );
445                /* Показываем попап */
446                _this.setLayersHeight();
447                _this.$modal
448                    .css('position', 'relative')
449                    .show()
450                    .addClass( _this.mOpen )
451                    .attr('data-preset', c.preset );
452                $( 'html' ).scrollTop( 0 );
453                /* выставляем флаг в открыт */
454                c.isOpen = true;
455                _this.checkFull();
456                _this.checkVAlign();
457                // добавляем клас активности
458                c.$preset.addClass( _this.mActive );
459                // выполняем функцию после открытия открытия окна
460                _this.useFunction( c.afterOpen );
461                _this.setTrigger( 'open' );
462            }
463		} else {
464		    console.log('modalLayer: preset "' + options.preset + '" not found to open');
465		    return false;
466        }
467	},
468
469    change : function( n ){
470        var _this = this,
471            c = _this._current;
472
473        /* TODO отладка */ // console.log( 'OPENABLE NEW ', n );
474
475        if ( c.typeChange === 'resize' ) {
476
477            // выполняем функцию до закрытия
478            _this.useFunction( c.beforeClose );
479
480            // собираем размеры текущего положения и размеров окна
481            var sizeWidth = parseInt( _this.$size.outerWidth() ),
482                sizeHeight = parseInt( _this.$size.outerHeight() ),
483                contWidth = parseInt( _this.$container.outerWidth() ),
484                contHeight = parseInt( _this.$container.outerHeight() ),
485                contOffsetTop = _this.$container[0].offsetTop,
486                contOffsetBottom = sizeHeight - contHeight - contOffsetTop;
487
488            // выставляем на попап текущие значения размера
489            _this.$container.css( {
490                'width' : contWidth,
491                'height' : contHeight,
492                'margin-top' : contOffsetTop,
493                'margin-bottom' : contOffsetBottom,
494                'max-width' : ''
495            });
496
497            /* TODO отладка */ //console.log(' === CURRENT --- size ( ', sizeWidth, ' x ', sizeHeight, ' ) --- bg ( ', contWidth, ' x ', contHeight, ' ) --- top ', contOffsetTop, ' bottom ', contOffsetBottom );
498
499            // скрываем текущий контент
500            c.$preset.animate({
501
502                'opacity' : 0
503
504            }, c.durationsHideContent , function(){
505
506                // навешиваем класс m-transform чтобы убрать все растягивания контента
507                _this.$container.addClass( _this.mTransform )
508                // выставляем идентификатор нового пресета чтобы все образмеривания происходили со стилями для этого окна
509                _this.$modal.attr('data-preset', n.preset );
510
511                // скрываем контент текущего и действия после скрытия
512                c.$preset.hide().css( 'opacity', '' );
513                _this.endingClosing();
514                _this.useFunction( c.afterClose );
515                _this.setTrigger( 'hide' );
516
517                // вставляем кастомный контент если есть
518                if ( n.preset == 'custom' ) _this.pushCustom( n );
519
520                // объект свойств для анимации смены
521                var size = {};
522
523                // узнаем размер ширины нового окна для анимации подложки
524                var nWidth = ( sizeWidth <= n.maxWidth ) ? sizeWidth : n.maxWidth;
525                /* TODO отладка */ //console.log( 'OPENABLE sizeWidth = ', sizeWidth ,' n.maxWidth = ', n.maxWidth, ' => ', nWidth )
526
527                // узнаем какое будет новое окно full или нет
528                n.isFull = ( sizeWidth <= n.maxWidth && n.useFull ) ? true : false;
529                /* TODO отладка */ //console.log(' === FULL --- ', c.isFull, ' => ', n.isFull );
530
531                var nValign = n.isFull ? ( n.valignFull || n.valign || '' ) : ( n.valign || '' );
532
533                // выставляем новое значени m-full и data-valign
534                _this.$modal
535                    .toggleClass( _this.mFull, n.isFull )
536                    .attr( 'data-valing', nValign )
537
538                // узнаем высоту нового контента для определения высоты нового окна
539                n.$preset.css({ 'opacity' : 0, 'display': 'block' }).outerWidth( nWidth );
540                var nCH = n.$preset.outerHeight()
541                n.$preset.css({ 'opacity' : '', 'display': 'none', 'width': '' });
542
543                /* TODO отладка */ //console.log( 'OPENABLE new CH = ', nCH ,' new maxWidth = ', n.maxWidth )
544                /* TODO отладка */ //console.log( 'OPENABLE isFull = ', n.isFull, ' valignFull = ', n.valignFull ,' valign = ', n.valign )
545
546                // узнаем высоту нового окна для анимации подложки
547                var nHeight = nCH >= sizeHeight ? nCH
548                                    : ( n.isFull && n.valignFull == 'full' ) ? sizeHeight
549                                    : ( n.isFull && n.valignFull == false && n.valign == false ) ? sizeHeight
550                                    : ( !n.isFull && n.valign == 'full' ) ? sizeHeight
551                                    : nCH;
552
553                size[ 'width' ] = nWidth;
554                size[ 'height' ] = nHeight;
555                size[ 'margin-top' ] = ( n.isFull ? 0 : parseInt( n.indentTop || n.indent || 0 ) ) + 'px';
556                size[ 'margin-bottom' ] = ( n.isFull ? 0 : parseInt( n.indentBottom || n.indent || 0 ) ) + 'px';
557
558                /* TODO отладка */ //console.log( 'OPENABLE width = ',  size[ 'width' ] ,' height = ', size[ 'height' ] )
559                /* TODO отладка */ //console.log( 'OPENABLE indentTop = ', n.indentTop, ' indentBottom = ', n.indentBottom , '  indent = ',  n.indent)
560
561                // крутим страницу вверх с изменением размера подложки окна
562                $( 'html' ).animate( { scrollTop : 0 }, c.durationsChangeSize );
563
564                // изменяем размер окна
565                _this.$container.animate( size, c.durationsChangeSize, function(){
566
567                    _this.$container.removeClass( _this.mTransform )
568
569                    $.extend( true, c, n );
570                    _this.useFunction( c.beforeOpen );
571                    if ( c.closeHidden ) _this.$modal.addClass( _this.mCloseHide );
572                    // показываем новый контент
573                    c.$preset
574                        .css( 'opacity', 0 )
575                        .show()
576                        .addClass( _this.mActive )
577                        .animate({
578                        'opacity': 1
579                    }, c.durationsShowContent, function(){
580                        $( this ).css( 'opacity' , '');
581                        // очищаем стили и выставляем максимальную ширину для окна
582                        _this.$container.css( {
583                            'max-width' : c.maxWidth,
584                            'width' : '',
585                            'height' : ''
586                        });
587
588                        _this.checkFull();
589                        _this.checkVAlign();
590                        _this.useFunction( c.afterOpen );
591                        _this.setTrigger( 'show' );
592                        _this.setTrigger( 'change' );
593                    })
594                })
595            });
596        } else {
597            // закрываем пресет
598            _this.useFunction( c.beforeClose );
599            c.$preset.hide();
600            _this.endingClosing();
601            _this.useFunction( c.afterClose );
602            _this.setTrigger( 'hide' );
603            // обновляем _current
604            $.extend( true, _this._current, n );
605            // открываем новый пресет
606            _this.useFunction( c.beforeOpen );
607            _this.$container.css( 'max-width', c.maxWidth );
608            // скрываем крестик закрытия
609            if ( c.closeHidden ) _this.$modal.addClass( _this.mCloseHide );
610            c.$preset.show();
611            _this.checkFull();
612            _this.checkVAlign();
613            _this.$modal.attr('data-preset', c.preset );
614            _this.useFunction( c.afterOpen );
615            _this.setTrigger( 'show' );
616            _this.setTrigger( 'change' );
617        }
618    },
619
620	close : function( options ){
621		var _this = this,
622            c = _this._current;
623		// если есть открытый попап
624		if ( c.isOpen ) {
625		    if ( options ){
626                $.each( _this.queueCloseData, function( i, v ){
627                    if ( options[ v ] ) c[ v ] = options[ v ]; // записываем в _current опции с кнопки закрытия
628                });
629            }
630            _this.useFunction( c.beforeClose ); // выполняем функцию перед закрытием если есть
631            _this.$modal
632                .removeAttr( 'data-preset' )
633                .removeClass( _this.mOpen )
634                .hide()
635                .css( 'position', 'absolute' );
636            _this.$page
637                .css( 'position','relative' )
638                .css( 'top', 0 )
639                .css( 'left', 0 );
640            _this.setPageIndents();
641            // скрываем все пресеты
642            _this.$presets.hide();
643            // меняем флаг что попап открыт на false
644            c.isOpen = false;
645            // сбрасываем параметры при закрыти окна
646            c.pageTop = 0;
647            c.pageLeft = 0;
648            c.clientHeigth = false;
649            c.isFull = false;
650            _this.$modal.removeClass( _this.mFull );
651            _this.endingClosing( options );
652            // функция после закрытия
653            _this.useFunction( c.afterClose );
654            _this.setTrigger( 'close' );
655		}
656	},
657
658    endingClosing : function(){
659        var _this = this,
660            c = _this._current;
661        // если открыт кастомный обнуляем
662        if ( c.preset == 'custom' ) this.clearCustom();
663        // убираем класс активности
664        // показываем крестик закрытия
665        c.$preset
666            .removeClass( _this.mActive )
667            .removeClass( _this.mCloseHide )
668        // очищаем формы
669        _this.clearForm( c.clearForm );
670        c.clearForm = false;
671        // обнуление данных открытого пресета
672        c.preset = false;
673        c.$preset = false;
674    },
675
676    /**
677     * Full
678     */
679    checkFull: function(){
680        var _this = this,
681            c = _this._current;
682        c.isFull = ( c.useFull && ( _this.$size.outerWidth() <= _this.$container.outerWidth() ) ) ? true : false;
683        _this.$modal.toggleClass( _this.mFull, c.isFull );
684        _this.$container.css({
685            'margin-top' : c.isFull ? 0 : parseInt( c.indentTop || c.indent || 0 ),
686            'margin-bottom' : c.isFull ? 0 : parseInt( c.indentBottom || c.indent || 0 )
687        });
688    },
689
690    /**
691    * VAlign
692    */
693    checkVAlign: function(){
694        var _this = this,
695            c = _this._current;
696        _this.$modal.attr( 'data-valing', ( c.isFull ? ( c.valignFull || c.valign || '' ) : ( c.valign || '' ) ) )
697    },
698
699    /**
700     * Custom content
701     */
702    clearCustom : function(){
703        this.$customTitle.html( '' );
704        this.$customContent.html( '' );
705    },
706    pushCustom : function( obj ){
707        if ( obj.customTitle ) this.$customTitle.html( obj.customTitle );
708        if ( obj.customContent ) this.$customContent.html( obj.customContent );
709    },
710    /**
711     * make function
712     * @param { Object }
713     * */
714    useFunction : function ( func ){
715        if ( typeof func == 'function' ){
716            func();
717        } else if ( typeof func == 'string' && typeof window[ func ] == 'function' ){
718            window[ func ]();
719        }
720    },
721    /**
722     * cleaning the form in the active preset or in all presets
723     * @param { Object }
724     * */
725    clearForm : function( state ){
726	    if ( state == true || state == 'all' ) {
727            var _this = this;
728            if ( state == true ) {
729                $("." + _this.mc + "__preset[data-" + _this.mc + "-preset='" + _this._current.preset + "'] form")[ 0 ].reset();
730            } else if ( state == 'all' ) {
731                $( "form", _this.$container ).each(function(){
732                    $( this )[ 0 ].reset();
733                });
734            }
735	    }
736    },
737    /**
738     * set page indents
739     * */
740    setPageIndents : function(){
741        $( 'html' )
742            .scrollTop( this._current.pageTop )
743            .scrollLeft( this._current.pageLeft );
744    },
745    /**
746     * get page indents
747     * */
748    getPageIndents : function(){
749        this._current.pageTop = $( 'html' ).scrollTop();
750        this._current.pageLeft = $( 'html' ).scrollLeft();
751    },
752    /**
753     * Позиционирование страницы по вертикали при изменении размеров окна
754     * */
755    checkPageTop : function(){
756        var _this = this;
757        if ( _this._current.isOpen ){
758            var indTop = parseInt( _this.$page.css( 'top' ) ),
759                pageH = _this.$page.outerHeight(),
760                wH = _this.getClientHeigth();
761            if ( ( pageH + indTop ) < wH && pageH > wH ){
762                _this.$page.css( 'top', -( pageH - wH ) );
763            }
764        }
765    },
766    /**
767     * Сдвиг контена при горизонтальном скроле попапа
768     * @update {Number} this.pageLeft - horizontal scroll size
769     */
770    checkPageLeft : function(){
771        var _this = this;
772        if ( _this._current.isOpen ){
773            _this.pageLeft = $( 'html' ).scrollLeft();
774            _this.$page.css( 'left', -$( 'html' ).scrollLeft() );
775        }
776    },
777    /**
778     * Установка минимальный высоты слоев
779     * @update {Number} this.clientHeight - client height
780     * */
781    setLayersHeight : function(){
782        var ch = parseInt( this.getClientHeigth() );
783        this.$modal.css( 'height', ch );
784        this._current.clientHeight = ch;
785    },
786    /**
787     * тригер
788     * triggers a public event.
789     * @param {String} event name
790     * @param {Object} data array or object
791     */
792    setTrigger : function( name, data ){
793        if ( typeof name != 'string' ) return false;
794        var _this = this,
795            extObj = {
796                "eventType" : name,
797                "plugin" : _this,
798                "current" : _this._current
799            },
800            data = ( $.isPlainObject( data ) ) ? $.extend( true, data, extOb
800j ) : extObj;
801        $( window ).trigger( name + 'ModalLayer' , data );
802    },
803    /**
804     * Receiving settings based on screen resolution
805     * Получение настроек в зависимости от разрешения экрана
806     * @param {Boolean} forced update
807     * @return {Object} settings
808     */
809    getSettings : function( forced ){
810        var _this = this,
811            viewWidth = _this.getClientWidth(),
812            _s = _this._settings;
813        if ( forced || viewWidth <=  _s.breakpoints[ 0 ] || viewWidth > _s.breakpoints[ 1 ] ){
814            var	overwrites = _this.options.responsive;
815            if ( !overwrites ) {
816                $.extend( true, _s, _this.options );
817                _s.breakpoints = [ 0, Infinity ];
818            } else {
819                var	match = -1,
820                    pointsArray = [],
821                    pointsKey = -1;
822                $.each( overwrites, function( point ) {
823                    pointsArray.push( Number( point ) );
824                    if ( viewWidth >= point && match < point ) {
825                        pointsKey ++;
826                        match = Number( point );
827                    }
828                });
829                _s.breakpoints = [ pointsArray[ pointsKey ] ? pointsArray[ pointsKey ] : 0 , pointsArray[ ( pointsKey + 1 ) ] ? pointsArray[ ( pointsKey + 1 ) ] : Infinity];
830                $.extend( true, _s, _this.options, overwrites[ match ] );
831                delete _s.responsive;
832            }
833        }
834        return _this._settings;
835    },
836    /**
837     * получение ширины окна клиента
838     * @returns {Number} size
839     */
840    getClientWidth : function(){
841        return Math.max( window.innerWidth || 0, ( document.getElementsByTagName( 'html' )[ 0 ] || {} ).clientWidth || 0 )
842    },
843    /**
844     * получение высоты окна клиента
845     * @returns {Number} size
846     */
847    getClientHeigth : function(){
848        return  Math.max( window.innerHeight || 0, ( document.getElementsByTagName( 'html' )[ 0 ] || {} ).clientHeight || 0 )
849    },
850    /**
851     * для отладки - вывод свойств объекта
852     * this.testingShowObject( array|name|true, 'MODAL OPEN - _settings', _this._settings);
853     * @param {String|Array|Boolean} array|name show param(s) or true for show default params
854     * @param {String} text description
855     * @param {Object} params object for show
856     */
857    testingShowObject : function ( a, t, c ) {
858        var c = Object.assign( {}, ( c ? c : this._current )) ,
859            s = [
860                'preset','$preset',
861                'customTitle','customContent',
862                'clientHeight','isOpen','useFull','isFull','maxWidth','typeChange','clearForm',
863                'pageTop', 'pageLeft',
864                'beforeClose','afterClose',
865                'beforeOpen','afterOpen',
866                'valign', 'valignFull',
867                'indent', 'indentTop', 'indentBottom'
868            ],
869            a = a === true ? s : ( typeof a == "string" ) ? [ a ] : a,
870            t = t ? t : '',
871            o = {};
872        $.each( a, function( i, v ){
873            if ( c[ v ] || c[ v ] == false || c[ v ] == 0 ) o[ v ] = c[ v ];
874        });
875        console.log( ">>> " + t, o );
876    },
877
878};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.