3 * Full featured mobile HTML framework for building iOS & Android apps
4 * http://framework7.io/
6 * Copyright 2014-2019 Vladimir Kharlampidi
8 * Released under the MIT License
10 * Released on: July 19, 2019
13 (function (global
, factory
) {
14 typeof exports
=== 'object' && typeof module
!== 'undefined' ? module
.exports
= factory() :
15 typeof define
=== 'function' && define
.amd
? define(factory
) :
16 (global
= global
|| self
, global
.Framework7
= factory());
17 }(this, function () { 'use strict';
21 * Mobile-first HTML template engine
23 * http://www.idangero.us/template7/
25 * Copyright 2019, Vladimir Kharlampidi
27 * http://www.idangero.us/
31 * Released on: June 14, 2019
35 if (typeof window
!== 'undefined') {
37 } else if (typeof global
!== 'undefined') {
43 var Template7Context
= t7ctx
;
45 var Template7Utils
= {
46 quoteSingleRexExp
: new RegExp('\'', 'g'),
47 quoteDoubleRexExp
: new RegExp('"', 'g'),
48 isFunction
: function isFunction(func
) {
49 return typeof func
=== 'function';
51 escape
: function escape(string
) {
52 if ( string
=== void 0 ) string
= '';
55 .replace(/&/g
, '&')
56 .replace(/</g
, '<')
57 .replace(/>/g
, '>')
58 .replace(/"/g, '"')
59 .replace(/'/g, ''');
61 helperToSlices: function helperToSlices(string) {
62 var quoteDoubleRexExp = Template7Utils.quoteDoubleRexExp;
63 var quoteSingleRexExp = Template7Utils.quoteSingleRexExp;
64 var helperParts = string.replace(/[{}#}]/g, '').trim().split(' ');
69 for (i = 0; i < helperParts.length; i += 1) {
70 var part = helperParts[i];
71 var blockQuoteRegExp = (void 0);
72 var openingQuote = (void 0);
73 if (i === 0) { slices.push(part); }
74 else if (part.indexOf('"') === 0 || part.indexOf('\'') === 0) {
75 blockQuoteRegExp = part.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp;
76 openingQuote = part.indexOf('"') === 0 ? '"' : '\'';
78 if (part.match(blockQuoteRegExp).length === 2) {
84 for (j = i + 1; j < helperParts.length; j += 1) {
85 part += " " + (helperParts[j]);
86 if (helperParts[j].indexOf(openingQuote) >= 0) {
92 if (shiftIndex) { i = shiftIndex; }
94 } else if (part.indexOf('=') > 0) {
96 var hashParts = part.split('=');
97 var hashName = hashParts[0];
98 var hashContent = hashParts[1];
99 if (!blockQuoteRegExp) {
100 blockQuoteRegExp = hashContent.indexOf('"') === 0 ? quoteDoubleRexExp : quoteSingleRexExp;
101 openingQuote = hashContent.indexOf('"') === 0 ? '"' : '\'';
103 if (hashContent.match(blockQuoteRegExp).length !== 2) {
105 for (j = i + 1; j < helperParts.length; j += 1) {
106 hashContent += " " + (helperParts[j]);
107 if (helperParts[j].indexOf(openingQuote) >= 0) {
112 if (shiftIndex) { i = shiftIndex; }
114 var hash = [hashName, hashContent.replace(blockQuoteRegExp, '')];
123 stringToBlocks: function stringToBlocks(string) {
127 if (!string) { return []; }
128 var stringBlocks = string.split(/({{[^{^}]*}})/);
129 for (i = 0; i < stringBlocks.length; i += 1) {
130 var block = stringBlocks[i];
131 if (block === '') { continue; }
132 if (block.indexOf('{{') < 0) {
138 if (block.indexOf('{/') >= 0) {
142 .replace(/{{([#/])*([ ])*/, '{{$1')
143 .replace(/([ ])*}}/, '}}');
144 if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) {
148 contextName: block.replace(/[{}]/g, ''),
153 var helperSlices = Template7Utils.helperToSlices(block);
154 var helperName = helperSlices[0];
155 var isPartial = helperName === '>';
156 var helperContext = [];
158 for (j = 1; j < helperSlices.length; j += 1) {
159 var slice = helperSlices[j];
160 if (Array.isArray(slice)) {
162 helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1];
164 helperContext.push(slice);
168 if (block.indexOf('{#') >= 0) {
170 var helperContent = '';
171 var elseContent = '';
173 var shiftIndex = (void 0);
174 var foundClosed = false;
175 var foundElse = false;
177 for (j = i + 1; j < stringBlocks.length; j += 1) {
178 if (stringBlocks[j].indexOf('{{#') >= 0) {
181 if (stringBlocks[j].indexOf('{{/') >= 0) {
184 if (stringBlocks[j].indexOf(("{{#" + helperName)) >= 0) {
185 helperContent += stringBlocks[j];
186 if (foundElse) { elseContent += stringBlocks[j]; }
188 } else if (stringBlocks[j].indexOf(("{{/" + helperName)) >= 0) {
191 helperContent += stringBlocks[j];
192 if (foundElse) { elseContent += stringBlocks[j]; }
198 } else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) {
201 if (!foundElse) { helperContent += stringBlocks[j]; }
202 if (foundElse) { elseContent += stringBlocks[j]; }
206 if (shiftIndex) { i = shiftIndex; }
207 if (helperName === 'raw
') {
210 content: helperContent,
215 helperName: helperName,
216 contextName: helperContext,
217 content: helperContent,
218 inverseContent: elseContent,
223 } else if (block.indexOf(' ') > 0) {
225 helperName = '_partial
';
226 if (helperContext[0]) {
227 if (helperContext[0].indexOf('[') === 0) { helperContext[0] = helperContext[0].replace(/[[\]]/g, ''); }
228 else { helperContext[0] = "\"" + (helperContext[0].replace(/"|'/g
, '')) + "\""; }
233 helperName
: helperName
,
234 contextName
: helperContext
,
242 parseJsVariable
: function parseJsVariable(expression
, replace
, object
) {
243 return expression
.split(/([+ \-*/^()&=|<>!%:?])/g
).reduce(function (arr
, part
) {
247 if (part
.indexOf(replace
) < 0) {
252 arr
.push(JSON
.stringify(''));
256 var variable
= object
;
257 if (part
.indexOf((replace
+ ".")) >= 0) {
258 part
.split((replace
+ "."))[1].split('.').forEach(function (partName
) {
259 if (partName
in variable
) { variable
= variable
[partName
]; }
260 else { variable
= undefined; }
264 (typeof variable
=== 'string')
265 || Array
.isArray(variable
)
266 || (variable
.constructor && variable
.constructor === Object
)
268 variable
= JSON
.stringify(variable
);
270 if (variable
=== undefined) { variable
= 'undefined'; }
277 parseJsParents
: function parseJsParents(expression
, parents
) {
278 return expression
.split(/([+ \-*^()&=|<>!%:?])/g).reduce(function (arr
, part
) {
283 if (part
.indexOf('../') < 0) {
288 if (!parents
|| parents
.length
=== 0) {
289 arr
.push(JSON
.stringify(''));
293 var levelsUp
= part
.split('../').length
- 1;
294 var parentData
= levelsUp
> parents
.length
? parents
[parents
.length
- 1] : parents
[levelsUp
- 1];
296 var variable
= parentData
;
297 var parentPart
= part
.replace(/..\//g, '');
298 parentPart
.split('.').forEach(function (partName
) {
299 if (typeof variable
[partName
] !== 'undefined') { variable
= variable
[partName
]; }
300 else { variable
= 'undefined'; }
302 if (variable
=== false || variable
=== true) {
303 arr
.push(JSON
.stringify(variable
));
306 if (variable
=== null || variable
=== 'undefined') {
307 arr
.push(JSON
.stringify(''));
310 arr
.push(JSON
.stringify(variable
));
314 getCompileVar
: function getCompileVar(name
, ctx
, data
) {
315 if ( data
=== void 0 ) data
= 'data_1';
321 if (name
.indexOf('../') === 0) {
322 levelsUp
= name
.split('../').length
- 1;
323 newDepth
= variable
.split('_')[1] - levelsUp
;
324 variable
= "ctx_" + (newDepth
>= 1 ? newDepth
: 1);
325 parts
= name
.split('../')[levelsUp
].split('.');
326 } else if (name
.indexOf('@global') === 0) {
327 variable
= 'Template7.global';
328 parts
= name
.split('@global.')[1].split('.');
329 } else if (name
.indexOf('@root') === 0) {
331 parts
= name
.split('@root.')[1].split('.');
333 parts
= name
.split('.');
335 for (var i
= 0; i
< parts
.length
; i
+= 1) {
337 if (part
.indexOf('@') === 0) {
338 var dataLevel
= data
.split('_')[1];
340 dataLevel
= newDepth
;
343 variable
+= "[(data_" + dataLevel
+ " && data_" + dataLevel
+ "." + (part
.replace('@', '')) + ")]";
345 variable
= "(data_" + dataLevel
+ " && data_" + dataLevel
+ "." + (part
.replace('@', '')) + ")";
347 } else if (Number
.isFinite
? Number
.isFinite(part
) : Template7Context
.isFinite(part
)) {
348 variable
+= "[" + part
+ "]";
349 } else if (part
=== 'this' || part
.indexOf('this.') >= 0 || part
.indexOf('this[') >= 0 || part
.indexOf('this(') >= 0) {
350 variable
= part
.replace('this', ctx
);
352 variable
+= "." + part
;
357 getCompiledArguments
: function getCompiledArguments(contextArray
, ctx
, data
) {
359 for (var i
= 0; i
< contextArray
.length
; i
+= 1) {
360 if (/^['"]/.test(contextArray
[i
])) { arr
.push(contextArray
[i
]); }
361 else if (/^(true|false|\d+)$/.test(contextArray
[i
])) { arr
.push(contextArray
[i
]); }
363 arr
.push(Template7Utils
.getCompileVar(contextArray
[i
], ctx
, data
));
367 return arr
.join(', ');
371 /* eslint no-eval: "off" */
373 var Template7Helpers
= {
374 _partial
: function _partial(partialName
, options
) {
376 var p
= Template7Class
.partials
[partialName
];
377 if (!p
|| (p
&& !p
.template
)) { return ''; }
379 p
.compiled
= new Template7Class(p
.template
).compile();
381 Object
.keys(options
.hash
).forEach(function (hashName
) {
382 ctx
[hashName
] = options
.hash
[hashName
];
384 return p
.compiled(ctx
, options
.data
, options
.root
);
386 escape
: function escape(context
) {
387 if (typeof context
=== 'undefined' || context
=== null) { return ''; }
388 if (typeof context
!== 'string') {
389 throw new Error('Template7: Passed context to "escape" helper should be a string');
391 return Template7Utils
.escape(context
);
393 if: function if$1(context
, options
) {
395 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
397 return options
.fn(this, options
.data
);
400 return options
.inverse(this, options
.data
);
402 unless
: function unless(context
, options
) {
404 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
406 return options
.fn(this, options
.data
);
409 return options
.inverse(this, options
.data
);
411 each
: function each(context
, options
) {
415 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
416 if (Array
.isArray(ctx
)) {
417 if (options
.hash
.reverse
) {
420 for (i
= 0; i
< ctx
.length
; i
+= 1) {
421 ret
+= options
.fn(ctx
[i
], { first
: i
=== 0, last
: i
=== ctx
.length
- 1, index
: i
});
423 if (options
.hash
.reverse
) {
427 // eslint-disable-next-line
428 for (var key
in ctx
) {
430 ret
+= options
.fn(ctx
[key
], { key
: key
});
433 if (i
> 0) { return ret
; }
434 return options
.inverse(this);
436 with: function with$1(context
, options
) {
438 if (Template7Utils
.isFunction(ctx
)) { ctx
= context
.call(this); }
439 return options
.fn(ctx
);
441 join
: function join(context
, options
) {
443 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
444 return ctx
.join(options
.hash
.delimiter
|| options
.hash
.delimeter
);
446 js
: function js(expression
, options
) {
447 var data
= options
.data
;
449 var execute
= expression
;
450 ('index first last key').split(' ').forEach(function (prop
) {
451 if (typeof data
[prop
] !== 'undefined') {
452 var re1
= new RegExp(("this.@" + prop
), 'g');
453 var re2
= new RegExp(("@" + prop
), 'g');
455 .replace(re1
, JSON
.stringify(data
[prop
]))
456 .replace(re2
, JSON
.stringify(data
[prop
]));
459 if (options
.root
&& execute
.indexOf('@root') >= 0) {
460 execute
= Template7Utils
.parseJsVariable(execute
, '@root', options
.root
);
462 if (execute
.indexOf('@global') >= 0) {
463 execute
= Template7Utils
.parseJsVariable(execute
, '@global', Template7Context
.Template7
.global
);
465 if (execute
.indexOf('../') >= 0) {
466 execute
= Template7Utils
.parseJsParents(execute
, options
.parents
);
468 if (execute
.indexOf('return') >= 0) {
469 func
= "(function(){" + execute
+ "})";
471 func
= "(function(){return (" + execute
+ ")})";
473 return eval(func
).call(this);
475 js_if
: function js_if(expression
, options
) {
476 var data
= options
.data
;
478 var execute
= expression
;
479 ('index first last key').split(' ').forEach(function (prop
) {
480 if (typeof data
[prop
] !== 'undefined') {
481 var re1
= new RegExp(("this.@" + prop
), 'g');
482 var re2
= new RegExp(("@" + prop
), 'g');
484 .replace(re1
, JSON
.stringify(data
[prop
]))
485 .replace(re2
, JSON
.stringify(data
[prop
]));
488 if (options
.root
&& execute
.indexOf('@root') >= 0) {
489 execute
= Template7Utils
.parseJsVariable(execute
, '@root', options
.root
);
491 if (execute
.indexOf('@global') >= 0) {
492 execute
= Template7Utils
.parseJsVariable(execute
, '@global', Template7Context
.Template7
.global
);
494 if (execute
.indexOf('../') >= 0) {
495 execute
= Template7Utils
.parseJsParents(execute
, options
.parents
);
497 if (execute
.indexOf('return') >= 0) {
498 func
= "(function(){" + execute
+ "})";
500 func
= "(function(){return (" + execute
+ ")})";
502 var condition
= eval(func
).call(this);
504 return options
.fn(this, options
.data
);
507 return options
.inverse(this, options
.data
);
510 Template7Helpers
.js_compare
= Template7Helpers
.js_if
;
512 var Template7Options
= {};
513 var Template7Partials
= {};
515 var Template7Class
= function Template7Class(template
) {
517 t
.template
= template
;
520 var staticAccessors
= { options
: { configurable
: true },partials
: { configurable
: true },helpers
: { configurable
: true } };
521 Template7Class
.prototype.compile
= function compile (template
, depth
) {
522 if ( template
=== void 0 ) template
= this.template
;
523 if ( depth
=== void 0 ) depth
= 1;
526 if (t
.compiled
) { return t
.compiled
; }
528 if (typeof template
!== 'string') {
529 throw new Error('Template7: Template must be a string');
531 var stringToBlocks
= Template7Utils
.stringToBlocks
;
532 var getCompileVar
= Template7Utils
.getCompileVar
;
533 var getCompiledArguments
= Template7Utils
.getCompiledArguments
;
535 var blocks
= stringToBlocks(template
);
536 var ctx
= "ctx_" + depth
;
537 var data
= "data_" + depth
;
538 if (blocks
.length
=== 0) {
539 return function empty() { return ''; };
542 function getCompileFn(block
, newDepth
) {
543 if (block
.content
) { return t
.compile(block
.content
, newDepth
); }
544 return function empty() { return ''; };
546 function getCompileInverse(block
, newDepth
) {
547 if (block
.inverseContent
) { return t
.compile(block
.inverseContent
, newDepth
); }
548 return function empty() { return ''; };
551 var resultString
= '';
553 resultString
+= "(function (" + ctx
+ ", " + data
+ ", root) {\n";
555 resultString
+= "(function (" + ctx
+ ", " + data
+ ") {\n";
558 resultString
+= 'function isArray(arr){return Array.isArray(arr);}\n';
559 resultString
+= 'function isFunction(func){return (typeof func === \'function\');}\n';
560 resultString
+= 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n';
561 resultString
+= 'root = root || ctx_1 || {};\n';
563 resultString
+= 'var r = \'\';\n';
565 for (i
= 0; i
< blocks
.length
; i
+= 1) {
566 var block
= blocks
[i
];
568 if (block
.type
=== 'plain') {
569 // eslint-disable-next-line
570 resultString
+= "r +='" + ((block
.content
).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')) + "';";
573 var variable = (void 0);
574 var compiledArguments = (void 0);
576 if (block.type === 'variable') {
577 variable = getCompileVar(block.contextName, ctx, data);
578 resultString += "r
+= c(" + variable + ", " + ctx + ");";
581 if (block.type === 'helper') {
582 var parents = (void 0);
583 if (ctx !== 'ctx_1') {
584 var level = ctx.split('_')[1];
585 var parentsString = "ctx_
" + (level - 1);
586 for (var j = level - 2; j >= 1; j -= 1) {
587 parentsString += ", ctx_
" + j;
589 parents = "[" + parentsString + "]";
591 parents = "[" + ctx + "]";
593 var dynamicHelper = (void 0);
594 if (block.helperName.indexOf('[') === 0) {
595 block.helperName = getCompileVar(block.helperName.replace(/[[\]]/g, ''), ctx, data);
596 dynamicHelper = true;
598 if (dynamicHelper || block.helperName in Template7Helpers) {
599 compiledArguments = getCompiledArguments(block.contextName, ctx, data);
600 resultString += "r
+= (Template7Helpers
" + (dynamicHelper ? ("[" + (block.helperName) + "]") : ("." + (block.helperName))) + ").call(" + ctx + ", " + (compiledArguments && ((compiledArguments + ", "))) + "{hash
:" + (JSON.stringify(block.hash)) + ", data
: " + data + " || {}, fn
: " + (getCompileFn(block, depth + 1)) + ", inverse
: " + (getCompileInverse(block, depth + 1)) + ", root
: root
, parents
: " + parents + "});";
601 } else if (block.contextName.length > 0) {
602 throw new Error(("Template7
: Missing helper
: \"" + (block.helperName) + "\""));
604 variable = getCompileVar(block.helperName, ctx, data);
605 resultString += "if (" + variable + ") {";
606 resultString += "if (isArray(" + variable + ")) {";
607 resultString += "r
+= (Template7Helpers
.each
).call(" + ctx + ", " + variable + ", {hash
:" + (JSON.stringify(block.hash)) + ", data
: " + data + " || {}, fn
: " + (getCompileFn(block, depth + 1)) + ", inverse
: " + (getCompileInverse(block, depth + 1)) + ", root
: root
, parents
: " + parents + "});";
608 resultString += '}else {';
609 resultString += "r
+= (Template7Helpers
.with).call(" + ctx + ", " + variable + ", {hash
:" + (JSON.stringify(block.hash)) + ", data
: " + data + " || {}, fn
: " + (getCompileFn(block, depth + 1)) + ", inverse
: " + (getCompileInverse(block, depth + 1)) + ", root
: root
, parents
: " + parents + "});";
610 resultString += '}}';
614 resultString += '\nreturn r;})';
617 // eslint-disable-next-line
618 t.compiled = eval(resultString);
623 staticAccessors.options.get = function () {
624 return Template7Options;
626 staticAccessors.partials.get = function () {
627 return Template7Partials;
629 staticAccessors.helpers.get = function () {
630 return Template7Helpers;
633 Object.defineProperties( Template7Class, staticAccessors );
635 function Template7() {
636 var args = [], len = arguments.length;
637 while ( len-- ) args[ len ] = arguments[ len ];
639 var template = args[0];
641 if (args.length === 2) {
642 var instance = new Template7Class(template);
643 var rendered = instance.compile()(data);
647 return new Template7Class(template);
649 Template7.registerHelper = function registerHelper(name, fn) {
650 Template7Class.helpers[name] = fn;
652 Template7.unregisterHelper = function unregisterHelper(name) {
653 Template7Class.helpers[name] = undefined;
654 delete Template7Class.helpers[name];
656 Template7.registerPartial = function registerPartial(name, template) {
657 Template7Class.partials[name] = { template: template };
659 Template7.unregisterPartial = function unregisterPartial(name) {
660 if (Template7Class.partials[name]) {
661 Template7Class.partials[name] = undefined;
662 delete Template7Class.partials[name];
665 Template7.compile = function compile(template, options) {
666 var instance = new Template7Class(template, options);
667 return instance.compile();
670 Template7.options = Template7Class.options;
671 Template7.helpers = Template7Class.helpers;
672 Template7.partials = Template7Class.partials;
676 * Better handling for window object in SSR environment
677 * https://github.com/nolimits4web/ssr-window
679 * Copyright 2018, Vladimir Kharlampidi
683 * Released on: July 18, 2018
685 var doc = (typeof document === 'undefined') ? {
687 addEventListener: function addEventListener() {},
688 removeEventListener: function removeEventListener() {},
690 blur: function blur() {},
693 querySelector: function querySelector() {
696 querySelectorAll: function querySelectorAll() {
699 getElementById: function getElementById() {
702 createEvent: function createEvent() {
704 initEvent: function initEvent() {},
707 createElement: function createElement() {
712 setAttribute: function setAttribute() {},
713 getElementsByTagName: function getElementsByTagName() {
718 location: { hash: '' },
719 } : document; // eslint-disable-line
721 var win = (typeof window === 'undefined') ? {
728 CustomEvent: function CustomEvent() {
731 addEventListener: function addEventListener() {},
732 removeEventListener: function removeEventListener() {},
733 getComputedStyle: function getComputedStyle() {
735 getPropertyValue: function getPropertyValue() {
740 Image: function Image() {},
741 Date: function Date() {},
743 setTimeout: function setTimeout() {},
744 clearTimeout: function clearTimeout() {},
745 } : window; // eslint-disable-line
749 * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API
750 * http://framework7.io/docs/dom.html
752 * Copyright 2019, Vladimir Kharlampidi
754 * http://www.idangero.us/
758 * Released on: February 11, 2019
761 var Dom7 = function Dom7(arr) {
763 // Create array-like object
764 for (var i = 0; i < arr.length; i += 1) {
767 self.length = arr.length;
768 // Return collection with methods
772 function $(selector, context) {
775 if (selector && !context) {
776 if (selector instanceof Dom7) {
782 if (typeof selector === 'string') {
785 var html = selector.trim();
786 if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
787 var toCreate = 'div';
788 if (html.indexOf('<li') === 0) { toCreate = 'ul'; }
789 if (html.indexOf('<tr') === 0) { toCreate = 'tbody'; }
790 if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) { toCreate = 'tr'; }
791 if (html.indexOf('<tbody') === 0) { toCreate = 'table'; }
792 if (html.indexOf('<option') === 0) { toCreate = 'select'; }
793 tempParent = doc.createElement(toCreate);
794 tempParent.innerHTML = html;
795 for (i = 0; i < tempParent.childNodes.length; i += 1) {
796 arr.push(tempParent.childNodes[i]);
799 if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
801 els = [doc.getElementById(selector.trim().split('#')[1])];
804 els = (context || doc).querySelectorAll(selector.trim());
806 for (i = 0; i < els.length; i += 1) {
807 if (els[i]) { arr.push(els[i]); }
810 } else if (selector.nodeType || selector === win || selector === doc) {
813 } else if (selector.length > 0 && selector[0].nodeType) {
814 // Array of elements or instance of Dom
815 for (i = 0; i < selector.length; i += 1) {
816 arr.push(selector[i]);
820 return new Dom7(arr);
823 $.fn = Dom7.prototype;
827 function unique(arr) {
828 var uniqueArray = [];
829 for (var i = 0; i < arr.length; i += 1) {
830 if (uniqueArray.indexOf(arr[i]) === -1) { uniqueArray.push(arr[i]); }
834 function toCamelCase(string) {
835 return string.toLowerCase().replace(/-(.)/g, function (match, group1) { return group1.toUpperCase(); });
838 function requestAnimationFrame(callback) {
839 if (win.requestAnimationFrame) { return win.requestAnimationFrame(callback); }
840 else if (win.webkitRequestAnimationFrame) { return win.webkitRequestAnimationFrame(callback); }
841 return win.setTimeout(callback, 1000 / 60);
843 function cancelAnimationFrame(id) {
844 if (win.cancelAnimationFrame) { return win.cancelAnimationFrame(id); }
845 else if (win.webkitCancelAnimationFrame) { return win.webkitCancelAnimationFrame(id); }
846 return win.clearTimeout(id);
849 // Classes and attributes
850 function addClass(className) {
851 if (typeof className === 'undefined') {
854 var classes = className.split(' ');
855 for (var i = 0; i < classes.length; i += 1) {
856 for (var j = 0; j < this.length; j += 1) {
857 if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.add(classes[i]); }
862 function removeClass(className) {
863 var classes = className.split(' ');
864 for (var i = 0; i < classes.length; i += 1) {
865 for (var j = 0; j < this.length; j += 1) {
866 if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.remove(classes[i]); }
871 function hasClass(className) {
872 if (!this[0]) { return false; }
873 return this[0].classList.contains(className);
875 function toggleClass(className) {
876 var classes = className.split(' ');
877 for (var i = 0; i < classes.length; i += 1) {
878 for (var j = 0; j < this.length; j += 1) {
879 if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.toggle(classes[i]); }
884 function attr(attrs, value) {
885 var arguments$1 = arguments;
887 if (arguments.length === 1 && typeof attrs === 'string') {
889 if (this[0]) { return this[0].getAttribute(attrs); }
894 for (var i = 0; i < this.length; i += 1) {
895 if (arguments$1.length === 2) {
897 this[i].setAttribute(attrs, value);
900 // eslint-disable-next-line
901 for (var attrName in attrs) {
902 this[i][attrName] = attrs[attrName];
903 this[i].setAttribute(attrName, attrs[attrName]);
909 // eslint-disable-next-line
910 function removeAttr(attr) {
911 for (var i = 0; i < this.length; i += 1) {
912 this[i].removeAttribute(attr);
916 // eslint-disable-next-line
917 function prop(props, value) {
918 var arguments$1 = arguments;
920 if (arguments.length === 1 && typeof props === 'string') {
922 if (this[0]) { return this[0][props]; }
925 for (var i = 0; i < this.length; i += 1) {
926 if (arguments$1.length === 2) {
928 this[i][props] = value;
931 // eslint-disable-next-line
932 for (var propName in props) {
933 this[i][propName] = props[propName];
940 function data(key, value) {
942 if (typeof value === 'undefined') {
946 if (el.dom7ElementDataStorage && (key in el.dom7ElementDataStorage)) {
947 return el.dom7ElementDataStorage[key];
950 var dataKey = el.getAttribute(("data
-" + key));
960 for (var i = 0; i < this.length; i += 1) {
962 if (!el.dom7ElementDataStorage) { el.dom7ElementDataStorage = {}; }
963 el.dom7ElementDataStorage[key] = value;
967 function removeData(key) {
968 for (var i = 0; i < this.length; i += 1) {
970 if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) {
971 el.dom7ElementDataStorage[key] = null;
972 delete el.dom7ElementDataStorage[key];
978 if (!el) { return undefined; }
979 var dataset = {}; // eslint-disable-line
981 // eslint-disable-next-line
982 for (var dataKey in el.dataset) {
983 dataset[dataKey] = el.dataset[dataKey];
986 for (var i = 0; i < el.attributes.length; i += 1) {
987 // eslint-disable-next-line
988 var attr = el.attributes[i];
989 if (attr.name.indexOf('data-') >= 0) {
990 dataset[toCamelCase(attr.name.split('data-')[1])] = attr.value;
994 // eslint-disable-next-line
995 for (var key in dataset) {
996 if (dataset[key] === 'false') { dataset[key] = false; }
997 else if (dataset[key] === 'true') { dataset[key] = true; }
998 else if (parseFloat(dataset[key]) === dataset[key] * 1) { dataset[key] *= 1; }
1002 function val(value) {
1004 if (typeof value === 'undefined') {
1006 if (dom[0].multiple && dom[0].nodeName.toLowerCase() === 'select') {
1008 for (var i = 0; i < dom[0].selectedOptions.length; i += 1) {
1009 values.push(dom[0].selectedOptions[i].value);
1013 return dom[0].value;
1018 for (var i$1 = 0; i$1 < dom.length; i$1 += 1) {
1020 if (Array.isArray(value) && el.multiple && el.nodeName.toLowerCase() === 'select') {
1021 for (var j = 0; j < el.options.length; j += 1) {
1022 el.options[j].selected = value.indexOf(el.options[j].value) >= 0;
1031 // eslint-disable-next-line
1032 function transform(transform) {
1033 for (var i = 0; i < this.length; i += 1) {
1034 var elStyle = this[i].style;
1035 elStyle.webkitTransform = transform;
1036 elStyle.transform = transform;
1040 function transition(duration) {
1041 if (typeof duration !== 'string') {
1042 duration = duration + "ms
"; // eslint-disable-line
1044 for (var i = 0; i < this.length; i += 1) {
1045 var elStyle = this[i].style;
1046 elStyle.webkitTransitionDuration = duration;
1047 elStyle.transitionDuration = duration;
1055 var args = [], len = arguments.length;
1056 while ( len-- ) args[ len ] = arguments[ len ];
1057 var eventType = args[0];
1058 var targetSelector = args[1];
1059 var listener = args[2];
1060 var capture = args[3];
1061 if (typeof args[1] === 'function') {
1062 (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]);
1063 targetSelector = undefined;
1065 if (!capture) { capture = false; }
1067 function handleLiveEvent(e) {
1068 var target = e.target;
1069 if (!target) { return; }
1070 var eventData = e.target.dom7EventData || [];
1071 if (eventData.indexOf(e) < 0) {
1072 eventData.unshift(e);
1074 if ($(target).is(targetSelector)) { listener.apply(target, eventData); }
1076 var parents = $(target).parents(); // eslint-disable-line
1077 for (var k = 0; k < parents.length; k += 1) {
1078 if ($(parents[k]).is(targetSelector)) { listener.apply(parents[k], eventData); }
1082 function handleEvent(e) {
1083 var eventData = e && e.target ? e.target.dom7EventData || [] : [];
1084 if (eventData.indexOf(e) < 0) {
1085 eventData.unshift(e);
1087 listener.apply(this, eventData);
1089 var events = eventType.split(' ');
1091 for (var i = 0; i < this.length; i += 1) {
1093 if (!targetSelector) {
1094 for (j = 0; j < events.length; j += 1) {
1095 var event = events[j];
1096 if (!el.dom7Listeners) { el.dom7Listeners = {}; }
1097 if (!el.dom7Listeners[event]) { el.dom7Listeners[event] = []; }
1098 el.dom7Listeners[event].push({
1100 proxyListener: handleEvent,
1102 el.addEventListener(event, handleEvent, capture);
1106 for (j = 0; j < events.length; j += 1) {
1107 var event$1 = events[j];
1108 if (!el.dom7LiveListeners) { el.dom7LiveListeners = {}; }
1109 if (!el.dom7LiveListeners[event$1]) { el.dom7LiveListeners[event$1] = []; }
1110 el.dom7LiveListeners[event$1].push({
1112 proxyListener: handleLiveEvent,
1114 el.addEventListener(event$1, handleLiveEvent, capture);
1123 var args = [], len = arguments.length;
1124 while ( len-- ) args[ len ] = arguments[ len ];
1125 var eventType = args[0];
1126 var targetSelector = args[1];
1127 var listener = args[2];
1128 var capture = args[3];
1129 if (typeof args[1] === 'function') {
1130 (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]);
1131 targetSelector = undefined;
1133 if (!capture) { capture = false; }
1135 var events = eventType.split(' ');
1136 for (var i = 0; i < events.length; i += 1) {
1137 var event = events[i];
1138 for (var j = 0; j < this.length; j += 1) {
1140 var handlers = (void 0);
1141 if (!targetSelector && el.dom7Listeners) {
1142 handlers = el.dom7Listeners[event];
1143 } else if (targetSelector && el.dom7LiveListeners) {
1144 handlers = el.dom7LiveListeners[event];
1146 if (handlers && handlers.length) {
1147 for (var k = handlers.length - 1; k >= 0; k -= 1) {
1148 var handler = handlers[k];
1149 if (listener && handler.listener === listener) {
1150 el.removeEventListener(event, handler.proxyListener, capture);
1151 handlers.splice(k, 1);
1152 } else if (listener && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {
1153 el.removeEventListener(event, handler.proxyListener, capture);
1154 handlers.splice(k, 1);
1155 } else if (!listener) {
1156 el.removeEventListener(event, handler.proxyListener, capture);
1157 handlers.splice(k, 1);
1168 var args = [], len = arguments.length;
1169 while ( len-- ) args[ len ] = arguments[ len ];
1171 var eventName = args[0];
1172 var targetSelector = args[1];
1173 var listener = args[2];
1174 var capture = args[3];
1175 if (typeof args[1] === 'function') {
1176 (assign = args, eventName = assign[0], listener = assign[1], capture = assign[2]);
1177 targetSelector = undefined;
1179 function onceHandler() {
1180 var eventArgs = [], len = arguments.length;
1181 while ( len-- ) eventArgs[ len ] = arguments[ len ];
1183 listener.apply(this, eventArgs);
1184 dom.off(eventName, targetSelector, onceHandler, capture);
1185 if (onceHandler.dom7proxy) {
1186 delete onceHandler.dom7proxy;
1189 onceHandler.dom7proxy = listener;
1190 return dom.on(eventName, targetSelector, onceHandler, capture);
1192 function trigger() {
1193 var args = [], len = arguments.length;
1194 while ( len-- ) args[ len ] = arguments[ len ];
1196 var events = args[0].split(' ');
1197 var eventData = args[1];
1198 for (var i = 0; i < events.length; i += 1) {
1199 var event = events[i];
1200 for (var j = 0; j < this.length; j += 1) {
1204 evt = new win.CustomEvent(event, {
1210 evt = doc.createEvent('Event');
1211 evt.initEvent(event, true, true);
1212 evt.detail = eventData;
1214 // eslint-disable-next-line
1215 el.dom7EventData = args.filter(function (data, dataIndex) { return dataIndex > 0; });
1216 el.dispatchEvent(evt);
1217 el.dom7EventData = [];
1218 delete el.dom7EventData;
1223 function transitionEnd(callback) {
1224 var events = ['webkitTransitionEnd', 'transitionend'];
1227 function fireCallBack(e) {
1228 /* jshint validthis:true */
1229 if (e.target !== this) { return; }
1230 callback.call(this, e);
1231 for (i = 0; i < events.length; i += 1) {
1232 dom.off(events[i], fireCallBack);
1236 for (i = 0; i < events.length; i += 1) {
1237 dom.on(events[i], fireCallBack);
1242 function animationEnd(callback) {
1243 var events = ['webkitAnimationEnd', 'animationend'];
1246 function fireCallBack(e) {
1247 if (e.target !== this) { return; }
1248 callback.call(this, e);
1249 for (i = 0; i < events.length; i += 1) {
1250 dom.off(events[i], fireCallBack);
1254 for (i = 0; i < events.length; i += 1) {
1255 dom.on(events[i], fireCallBack);
1262 if (this[0] === win) {
1263 return win.innerWidth;
1266 if (this.length > 0) {
1267 return parseFloat(this.css('width'));
1272 function outerWidth(includeMargins) {
1273 if (this.length > 0) {
1274 if (includeMargins) {
1275 // eslint-disable-next-line
1276 var styles = this.styles();
1277 return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left'));
1279 return this[0].offsetWidth;
1284 if (this[0] === win) {
1285 return win.innerHeight;
1288 if (this.length > 0) {
1289 return parseFloat(this.css('height'));
1294 function outerHeight(includeMargins) {
1295 if (this.length > 0) {
1296 if (includeMargins) {
1297 // eslint-disable-next-line
1298 var styles = this.styles();
1299 return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom'));
1301 return this[0].offsetHeight;
1306 if (this.length > 0) {
1308 var box = el.getBoundingClientRect();
1309 var body = doc.body;
1310 var clientTop = el.clientTop || body.clientTop || 0;
1311 var clientLeft = el.clientLeft || body.clientLeft || 0;
1312 var scrollTop = el === win ? win.scrollY : el.scrollTop;
1313 var scrollLeft = el === win ? win.scrollX : el.scrollLeft;
1315 top: (box.top + scrollTop) - clientTop,
1316 left: (box.left + scrollLeft) - clientLeft,
1323 for (var i = 0; i < this.length; i += 1) {
1324 this[i].style.display = 'none';
1329 for (var i = 0; i < this.length; i += 1) {
1331 if (el.style.display === 'none') {
1332 el.style.display = '';
1334 if (win.getComputedStyle(el, null).getPropertyValue('display') === 'none') {
1335 // Still not visible
1336 el.style.display = 'block';
1342 if (this[0]) { return win.getComputedStyle(this[0], null); }
1345 function css(props, value) {
1347 if (arguments.length === 1) {
1348 if (typeof props === 'string') {
1349 if (this[0]) { return win.getComputedStyle(this[0], null).getPropertyValue(props); }
1351 for (i = 0; i < this.length; i += 1) {
1352 // eslint-disable-next-line
1353 for (var prop in props) {
1354 this[i].style[prop] = props[prop];
1360 if (arguments.length === 2 && typeof props === 'string') {
1361 for (i = 0; i < this.length; i += 1) {
1362 this[i].style[props] = value;
1370 function toArray() {
1372 for (var i = 0; i < this.length; i += 1) {
1377 // Iterate over the collection passing elements to `callback`
1378 function each(callback) {
1379 // Don't bother continuing without a callback
1380 if (!callback) { return this; }
1381 // Iterate over the current collection
1382 for (var i = 0; i < this.length; i += 1) {
1383 // If the callback returns false
1384 if (callback.call(this[i], i, this[i]) === false) {
1385 // End the loop early
1389 // Return `this` to allow chained DOM operations
1392 function forEach(callback) {
1393 // Don't bother continuing without a callback
1394 if (!callback) { return this; }
1395 // Iterate over the current collection
1396 for (var i = 0; i < this.length; i += 1) {
1397 // If the callback returns false
1398 if (callback.call(this[i], this[i], i) === false) {
1399 // End the loop early
1403 // Return `this` to allow chained DOM operations
1406 function filter(callback) {
1407 var matchedItems = [];
1409 for (var i = 0; i < dom.length; i += 1) {
1410 if (callback.call(dom[i], i, dom[i])) { matchedItems.push(dom[i]); }
1412 return new Dom7(matchedItems);
1414 function map(callback) {
1415 var modifiedItems = [];
1417 for (var i = 0; i < dom.length; i += 1) {
1418 modifiedItems.push(callback.call(dom[i], i, dom[i]));
1420 return new Dom7(modifiedItems);
1422 // eslint-disable-next-line
1423 function html(html) {
1424 if (typeof html === 'undefined') {
1425 return this[0] ? this[0].innerHTML : undefined;
1428 for (var i = 0; i < this.length; i += 1) {
1429 this[i].innerHTML = html;
1433 // eslint-disable-next-line
1434 function text(text) {
1435 if (typeof text === 'undefined') {
1437 return this[0].textContent.trim();
1442 for (var i = 0; i < this.length; i += 1) {
1443 this[i].textContent = text;
1447 function is(selector) {
1451 if (!el || typeof selector === 'undefined') { return false; }
1452 if (typeof selector === 'string') {
1453 if (el.matches) { return el.matches(selector); }
1454 else if (el.webkitMatchesSelector) { return el.webkitMatchesSelector(selector); }
1455 else if (el.msMatchesSelector) { return el.msMatchesSelector(selector); }
1457 compareWith = $(selector);
1458 for (i = 0; i < compareWith.length; i += 1) {
1459 if (compareWith[i] === el) { return true; }
1462 } else if (selector === doc) { return el === doc; }
1463 else if (selector === win) { return el === win; }
1465 if (selector.nodeType || selector instanceof Dom7) {
1466 compareWith = selector.nodeType ? [selector] : selector;
1467 for (i = 0; i < compareWith.length; i += 1) {
1468 if (compareWith[i] === el) { return true; }
1474 function indexOf(el) {
1475 for (var i = 0; i < this.length; i += 1) {
1476 if (this[i] === el) { return i; }
1481 var child = this[0];
1485 // eslint-disable-next-line
1486 while ((child = child.previousSibling) !== null) {
1487 if (child.nodeType === 1) { i += 1; }
1493 // eslint-disable-next-line
1494 function eq(index) {
1495 if (typeof index === 'undefined') { return this; }
1496 var length = this.length;
1498 if (index > length - 1) {
1499 return new Dom7([]);
1502 returnIndex = length + index;
1503 if (returnIndex < 0) { return new Dom7([]); }
1504 return new Dom7([this[returnIndex]]);
1506 return new Dom7([this[index]]);
1509 var args = [], len = arguments.length;
1510 while ( len-- ) args[ len ] = arguments[ len ];
1514 for (var k = 0; k < args.length; k += 1) {
1516 for (var i = 0; i < this.length; i += 1) {
1517 if (typeof newChild === 'string') {
1518 var tempDiv = doc.createElement('div');
1519 tempDiv.innerHTML = newChild;
1520 while (tempDiv.firstChild) {
1521 this[i].appendChild(tempDiv.firstChild);
1523 } else if (newChild instanceof Dom7) {
1524 for (var j = 0; j < newChild.length; j += 1) {
1525 this[i].appendChild(newChild[j]);
1528 this[i].appendChild(newChild);
1535 // eslint-disable-next-line
1536 function appendTo(parent) {
1537 $(parent).append(this);
1540 function prepend(newChild) {
1543 for (i = 0; i < this.length; i += 1) {
1544 if (typeof newChild === 'string') {
1545 var tempDiv = doc.createElement('div');
1546 tempDiv.innerHTML = newChild;
1547 for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {
1548 this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
1550 } else if (newChild instanceof Dom7) {
1551 for (j = 0; j < newChild.length; j += 1) {
1552 this[i].insertBefore(newChild[j], this[i].childNodes[0]);
1555 this[i].insertBefore(newChild, this[i].childNodes[0]);
1560 // eslint-disable-next-line
1561 function prependTo(parent) {
1562 $(parent).prepend(this);
1565 function insertBefore(selector) {
1566 var before = $(selector);
1567 for (var i = 0; i < this.length; i += 1) {
1568 if (before.length === 1) {
1569 before[0].parentNode.insertBefore(this[i], before[0]);
1570 } else if (before.length > 1) {
1571 for (var j = 0; j < before.length; j += 1) {
1572 before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
1577 function insertAfter(selector) {
1578 var after = $(selector);
1579 for (var i = 0; i < this.length; i += 1) {
1580 if (after.length === 1) {
1581 after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
1582 } else if (after.length > 1) {
1583 for (var j = 0; j < after.length; j += 1) {
1584 after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
1589 function next(selector) {
1590 if (this.length > 0) {
1592 if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {
1593 return new Dom7([this[0].nextElementSibling]);
1595 return new Dom7([]);
1598 if (this[0].nextElementSibling) { return new Dom7([this[0].nextElementSibling]); }
1599 return new Dom7([]);
1601 return new Dom7([]);
1603 function nextAll(selector) {
1606 if (!el) { return new Dom7([]); }
1607 while (el.nextElementSibling) {
1608 var next = el.nextElementSibling; // eslint-disable-line
1610 if ($(next).is(selector)) { nextEls.push(next); }
1611 } else { nextEls.push(next); }
1614 return new Dom7(nextEls);
1616 function prev(selector) {
1617 if (this.length > 0) {
1620 if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {
1621 return new Dom7([el.previousElementSibling]);
1623 return new Dom7([]);
1626 if (el.previousElementSibling) { return new Dom7([el.previousElementSibling]); }
1627 return new Dom7([]);
1629 return new Dom7([]);
1631 function prevAll(selector) {
1634 if (!el) { return new Dom7([]); }
1635 while (el.previousElementSibling) {
1636 var prev = el.previousElementSibling; // eslint-disable-line
1638 if ($(prev).is(selector)) { prevEls.push(prev); }
1639 } else { prevEls.push(prev); }
1642 return new Dom7(prevEls);
1644 function siblings(selector) {
1645 return this.nextAll(selector).add(this.prevAll(selector));
1647 function parent(selector) {
1648 var parents = []; // eslint-disable-line
1649 for (var i = 0; i < this.length; i += 1) {
1650 if (this[i].parentNode !== null) {
1652 if ($(this[i].parentNode).is(selector)) { parents.push(this[i].parentNode); }
1654 parents.push(this[i].parentNode);
1658 return $(unique(parents));
1660 function parents(selector) {
1661 var parents = []; // eslint-disable-line
1662 for (var i = 0; i < this.length; i += 1) {
1663 var parent = this[i].parentNode; // eslint-disable-line
1666 if ($(parent).is(selector)) { parents.push(parent); }
1668 parents.push(parent);
1670 parent = parent.parentNode;
1673 return $(unique(parents));
1675 function closest(selector) {
1676 var closest = this; // eslint-disable-line
1677 if (typeof selector === 'undefined') {
1678 return new Dom7([]);
1680 if (!closest.is(selector)) {
1681 closest = closest.parents(selector).eq(0);
1685 function find(selector) {
1686 var foundElements = [];
1687 for (var i = 0; i < this.length; i += 1) {
1688 var found = this[i].querySelectorAll(selector);
1689 for (var j = 0; j < found.length; j += 1) {
1690 foundElements.push(found[j]);
1693 return new Dom7(foundElements);
1695 function children(selector) {
1696 var children = []; // eslint-disable-line
1697 for (var i = 0; i < this.length; i += 1) {
1698 var childNodes = this[i].childNodes;
1700 for (var j = 0; j < childNodes.length; j += 1) {
1702 if (childNodes[j].nodeType === 1) { children.push(childNodes[j]); }
1703 } else if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) {
1704 children.push(childNodes[j]);
1708 return new Dom7(unique(children));
1711 for (var i = 0; i < this.length; i += 1) {
1712 if (this[i].parentNode) { this[i].parentNode.removeChild(this[i]); }
1717 return this.remove();
1720 var args = [], len = arguments.length;
1721 while ( len-- ) args[ len ] = arguments[ len ];
1726 for (i = 0; i < args.length; i += 1) {
1727 var toAdd = $(args[i]);
1728 for (j = 0; j < toAdd.length; j += 1) {
1729 dom[dom.length] = toAdd[j];
1736 for (var i = 0; i < this.length; i += 1) {
1738 if (el.nodeType === 1) {
1739 for (var j = 0; j < el.childNodes.length; j += 1) {
1740 if (el.childNodes[j].parentNode) {
1741 el.childNodes[j].parentNode.removeChild(el.childNodes[j]);
1744 el.textContent = '';
1750 var Methods = /*#__PURE__*/Object.freeze({
1752 removeClass: removeClass,
1754 toggleClass: toggleClass,
1756 removeAttr: removeAttr,
1759 removeData: removeData,
1762 transform: transform,
1763 transition: transition,
1768 transitionEnd: transitionEnd,
1769 animationEnd: animationEnd,
1771 outerWidth: outerWidth,
1773 outerHeight: outerHeight,
1793 prependTo: prependTo,
1794 insertBefore: insertBefore,
1795 insertAfter: insertAfter,
1812 function scrollTo() {
1815 var args = [], len = arguments.length;
1816 while ( len-- ) args[ len ] = arguments[ len ];
1819 var duration = args[2];
1820 var easing = args[3];
1821 var callback = args[4];
1822 if (args.length === 4 && typeof easing === 'function') {
1824 (assign = args, left = assign[0], top = assign[1], duration = assign[2], callback = assign[3], easing = assign[4]);
1826 if (typeof easing === 'undefined') { easing = 'swing'; }
1828 return this.each(function animate() {
1836 var scrollTop; // eslint-disable-line
1837 var scrollLeft; // eslint-disable-line
1838 var animateTop = top > 0 || top === 0;
1839 var animateLeft = left > 0 || left === 0;
1840 if (typeof easing === 'undefined') {
1844 currentTop = el.scrollTop;
1850 currentLeft = el.scrollLeft;
1852 el.scrollLeft = left;
1855 if (!duration) { return; }
1857 maxTop = el.scrollHeight - el.offsetHeight;
1858 newTop = Math.max(Math.min(top, maxTop), 0);
1861 maxLeft = el.scrollWidth - el.offsetWidth;
1862 newLeft = Math.max(Math.min(left, maxLeft), 0);
1864 var startTime = null;
1865 if (animateTop && newTop === currentTop) { animateTop = false; }
1866 if (animateLeft && newLeft === currentLeft) { animateLeft = false; }
1867 function render(time) {
1868 if ( time === void 0 ) time = new Date().getTime();
1870 if (startTime === null) {
1873 var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
1874 var easeProgress = easing === 'linear' ? progress : (0.5 - (Math.cos(progress * Math.PI) / 2));
1876 if (animateTop) { scrollTop = currentTop + (easeProgress * (newTop - currentTop)); }
1877 if (animateLeft) { scrollLeft = currentLeft + (easeProgress * (newLeft - currentLeft)); }
1878 if (animateTop && newTop > currentTop && scrollTop >= newTop) {
1879 el.scrollTop = newTop;
1882 if (animateTop && newTop < currentTop && scrollTop <= newTop) {
1883 el.scrollTop = newTop;
1886 if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {
1887 el.scrollLeft = newLeft;
1890 if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {
1891 el.scrollLeft = newLeft;
1896 if (callback) { callback(); }
1899 if (animateTop) { el.scrollTop = scrollTop; }
1900 if (animateLeft) { el.scrollLeft = scrollLeft; }
1901 requestAnimationFrame(render);
1903 requestAnimationFrame(render);
1906 // scrollTop(top, duration, easing, callback) {
1907 function scrollTop() {
1910 var args = [], len = arguments.length;
1911 while ( len-- ) args[ len ] = arguments[ len ];
1913 var duration = args[1];
1914 var easing = args[2];
1915 var callback = args[3];
1916 if (args.length === 3 && typeof easing === 'function') {
1917 (assign = args, top = assign[0], duration = assign[1], callback = assign[2], easing = assign[3]);
1920 if (typeof top === 'undefined') {
1921 if (dom.length > 0) { return dom[0].scrollTop; }
1924 return dom.scrollTo(undefined, top, duration, easing, callback);
1926 function scrollLeft() {
1929 var args = [], len = arguments.length;
1930 while ( len-- ) args[ len ] = arguments[ len ];
1932 var duration = args[1];
1933 var easing = args[2];
1934 var callback = args[3];
1935 if (args.length === 3 && typeof easing === 'function') {
1936 (assign = args, left = assign[0], duration = assign[1], callback = assign[2], easing = assign[3]);
1939 if (typeof left === 'undefined') {
1940 if (dom.length > 0) { return dom[0].scrollLeft; }
1943 return dom.scrollTo(left, undefined, duration, easing, callback);
1946 var Scroll = /*#__PURE__*/Object.freeze({
1948 scrollTop: scrollTop,
1949 scrollLeft: scrollLeft
1952 function animate(initialProps, initialParams) {
1955 props: Object.assign({}, initialProps),
1956 params: Object.assign({
1958 easing: 'swing', // or 'linear'
1962 progress(elements, complete, remaining, start, tweenValue)
1970 easingProgress: function easingProgress(easing, progress) {
1971 if (easing === 'swing') {
1972 return 0.5 - (Math.cos(progress * Math.PI) / 2);
1974 if (typeof easing === 'function') {
1975 return easing(progress);
1979 stop: function stop() {
1981 cancelAnimationFrame(a.frameId);
1983 a.animating = false;
1984 a.elements.each(function (index, el) {
1986 delete element.dom7AnimateInstance;
1990 done: function done(complete) {
1991 a.animating = false;
1992 a.elements.each(function (index, el) {
1994 delete element.dom7AnimateInstance;
1996 if (complete) { complete(els); }
1997 if (a.que.length > 0) {
1998 var que = a.que.shift();
1999 a.animate(que[0], que[1]);
2002 animate: function animate(props, params) {
2004 a.que.push([props, params]);
2009 // Define & Cache Initials & Units
2010 a.elements.each(function (index, el) {
2011 var initialFullValue;
2017 if (!el.dom7AnimateInstance) { a.elements[index].dom7AnimateInstance = a; }
2022 Object.keys(props).forEach(function (prop) {
2023 initialFullValue = win.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');
2024 initialValue = parseFloat(initialFullValue);
2025 unit = initialFullValue.replace(initialValue, '');
2026 finalValue = parseFloat(props[prop]);
2027 finalFullValue = props[prop] + unit;
2028 elements[index][prop] = {
2029 initialFullValue: initialFullValue,
2030 initialValue: initialValue,
2032 finalValue: finalValue,
2033 finalFullValue: finalFullValue,
2034 currentValue: initialValue,
2039 var startTime = null;
2041 var elementsDone = 0;
2049 time = new Date().getTime();
2055 if (params.begin) { params.begin(els); }
2057 if (startTime === null) {
2060 if (params.progress) {
2061 // eslint-disable-next-line
2062 params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), ((startTime + params.duration) - time < 0 ? 0 : (startTime + params.duration) - time), startTime);
2065 elements.forEach(function (element) {
2067 if (done || el.done) { return; }
2068 Object.keys(props).forEach(function (prop) {
2069 if (done || el.done) { return; }
2070 progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);
2071 easeProgress = a.easingProgress(params.easing, progress);
2073 var initialValue = ref.initialValue;
2074 var finalValue = ref.finalValue;
2075 var unit = ref.unit;
2076 el[prop].currentValue = initialValue + (easeProgress * (finalValue - initialValue));
2077 var currentValue = el[prop].currentValue;
2080 (finalValue > initialValue && currentValue >= finalValue) ||
2081 (finalValue < initialValue && currentValue <= finalValue)) {
2082 el.container.style[prop] = finalValue + unit;
2084 if (propsDone === Object.keys(props).length) {
2088 if (elementsDone === elements.length) {
2093 a.done(params.complete);
2096 el.container.style[prop] = currentValue + unit;
2099 if (done) { return; }
2101 a.frameId = requestAnimationFrame(render);
2103 a.frameId = requestAnimationFrame(render);
2108 if (a.elements.length === 0) {
2112 var animateInstance;
2113 for (var i = 0; i < a.elements.length; i += 1) {
2114 if (a.elements[i].dom7AnimateInstance) {
2115 animateInstance = a.elements[i].dom7AnimateInstance;
2116 } else { a.elements[i].dom7AnimateInstance = a; }
2118 if (!animateInstance) {
2119 animateInstance = a;
2122 if (initialProps === 'stop') {
2123 animateInstance.stop();
2125 animateInstance.animate(a.props, a.params);
2133 for (var i = 0; i < els.length; i += 1) {
2134 if (els[i].dom7AnimateInstance) {
2135 els[i].dom7AnimateInstance.stop();
2140 var Animate = /*#__PURE__*/Object.freeze({
2145 var noTrigger = ('resize scroll').split(' ');
2146 function eventShortcut(name) {
2149 var args = [], len = arguments.length - 1;
2150 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
2151 if (typeof args[0] === 'undefined') {
2152 for (var i = 0; i < this.length; i += 1) {
2153 if (noTrigger.indexOf(name) < 0) {
2154 if (name in this[i]) { this[i][name](); }
2156 $(this[i]).trigger(name);
2162 return (ref = this).on.apply(ref, [ name ].concat( args ));
2166 var args = [], len = arguments.length;
2167 while ( len-- ) args[ len ] = arguments[ len ];
2169 return eventShortcut.bind(this).apply(void 0, [ 'click' ].concat( args ));
2172 var args = [], len = arguments.length;
2173 while ( len-- ) args[ len ] = arguments[ len ];
2175 return eventShortcut.bind(this).apply(void 0, [ 'blur' ].concat( args ));
2178 var args = [], len = arguments.length;
2179 while ( len-- ) args[ len ] = arguments[ len ];
2181 return eventShortcut.bind(this).apply(void 0, [ 'focus' ].concat( args ));
2183 function focusin() {
2184 var args = [], len = arguments.length;
2185 while ( len-- ) args[ len ] = arguments[ len ];
2187 return eventShortcut.bind(this).apply(void 0, [ 'focusin' ].concat( args ));
2189 function focusout() {
2190 var args = [], len = arguments.length;
2191 while ( len-- ) args[ len ] = arguments[ len ];
2193 return eventShortcut.bind(this).apply(void 0, [ 'focusout' ].concat( args ));
2196 var args = [], len = arguments.length;
2197 while ( len-- ) args[ len ] = arguments[ len ];
2199 return eventShortcut.bind(this).apply(void 0, [ 'keyup' ].concat( args ));
2201 function keydown() {
2202 var args = [], len = arguments.length;
2203 while ( len-- ) args[ len ] = arguments[ len ];
2205 return eventShortcut.bind(this).apply(void 0, [ 'keydown' ].concat( args ));
2207 function keypress() {
2208 var args = [], len = arguments.length;
2209 while ( len-- ) args[ len ] = arguments[ len ];
2211 return eventShortcut.bind(this).apply(void 0, [ 'keypress' ].concat( args ));
2214 var args = [], len = arguments.length;
2215 while ( len-- ) args[ len ] = arguments[ len ];
2217 return eventShortcut.bind(this).apply(void 0, [ 'submit' ].concat( args ));
2220 var args = [], len = arguments.length;
2221 while ( len-- ) args[ len ] = arguments[ len ];
2223 return eventShortcut.bind(this).apply(void 0, [ 'change' ].concat( args ));
2225 function mousedown() {
2226 var args = [], len = arguments.length;
2227 while ( len-- ) args[ len ] = arguments[ len ];
2229 return eventShortcut.bind(this).apply(void 0, [ 'mousedown' ].concat( args ));
2231 function mousemove() {
2232 var args = [], len = arguments.length;
2233 while ( len-- ) args[ len ] = arguments[ len ];
2235 return eventShortcut.bind(this).apply(void 0, [ 'mousemove' ].concat( args ));
2237 function mouseup() {
2238 var args = [], len = arguments.length;
2239 while ( len-- ) args[ len ] = arguments[ len ];
2241 return eventShortcut.bind(this).apply(void 0, [ 'mouseup' ].concat( args ));
2243 function mouseenter() {
2244 var args = [], len = arguments.length;
2245 while ( len-- ) args[ len ] = arguments[ len ];
2247 return eventShortcut.bind(this).apply(void 0, [ 'mouseenter' ].concat( args ));
2249 function mouseleave() {
2250 var args = [], len = arguments.length;
2251 while ( len-- ) args[ len ] = arguments[ len ];
2253 return eventShortcut.bind(this).apply(void 0, [ 'mouseleave' ].concat( args ));
2255 function mouseout() {
2256 var args = [], len = arguments.length;
2257 while ( len-- ) args[ len ] = arguments[ len ];
2259 return eventShortcut.bind(this).apply(void 0, [ 'mouseout' ].concat( args ));
2261 function mouseover() {
2262 var args = [], len = arguments.length;
2263 while ( len-- ) args[ len ] = arguments[ len ];
2265 return eventShortcut.bind(this).apply(void 0, [ 'mouseover' ].concat( args ));
2267 function touchstart() {
2268 var args = [], len = arguments.length;
2269 while ( len-- ) args[ len ] = arguments[ len ];
2271 return eventShortcut.bind(this).apply(void 0, [ 'touchstart' ].concat( args ));
2273 function touchend() {
2274 var args = [], len = arguments.length;
2275 while ( len-- ) args[ len ] = arguments[ len ];
2277 return eventShortcut.bind(this).apply(void 0, [ 'touchend' ].concat( args ));
2279 function touchmove() {
2280 var args = [], len = arguments.length;
2281 while ( len-- ) args[ len ] = arguments[ len ];
2283 return eventShortcut.bind(this).apply(void 0, [ 'touchmove' ].concat( args ));
2286 var args = [], len = arguments.length;
2287 while ( len-- ) args[ len ] = arguments[ len ];
2289 return eventShortcut.bind(this).apply(void 0, [ 'resize' ].concat( args ));
2292 var args = [], len = arguments.length;
2293 while ( len-- ) args[ len ] = arguments[ len ];
2295 return eventShortcut.bind(this).apply(void 0, [ 'scroll' ].concat( args ));
2298 var eventShortcuts = /*#__PURE__*/Object.freeze({
2309 mousedown: mousedown,
2310 mousemove: mousemove,
2312 mouseenter: mouseenter,
2313 mouseleave: mouseleave,
2315 mouseover: mouseover,
2316 touchstart: touchstart,
2318 touchmove: touchmove,
2323 [Methods, Scroll, Animate, eventShortcuts].forEach(function (group) {
2324 Object.keys(group).forEach(function (methodName) {
2325 $.fn[methodName] = group[methodName];
2330 * https://github.com/gre/bezier-easing
2331 * BezierEasing - use bezier curve for transition easing function
2332 * by Gaëtan Renaudeau 2014 - 2015 – MIT License
2335 /* eslint-disable */
2337 // These values are established by empiricism with tests (tradeoff: performance VS precision)
2338 var NEWTON_ITERATIONS = 4;
2339 var NEWTON_MIN_SLOPE = 0.001;
2340 var SUBDIVISION_PRECISION = 0.0000001;
2341 var SUBDIVISION_MAX_ITERATIONS = 10;
2343 var kSplineTableSize = 11;
2344 var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
2346 var float32ArraySupported = typeof Float32Array === 'function';
2348 function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
2349 function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
2350 function C (aA1) { return 3.0 * aA1; }
2352 // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
2353 function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
2355 // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
2356 function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
2358 function binarySubdivide (aX, aA, aB, mX1, mX2) {
2359 var currentX, currentT, i = 0;
2361 currentT = aA + (aB - aA) / 2.0;
2362 currentX = calcBezier(currentT, mX1, mX2) - aX;
2363 if (currentX > 0.0) {
2368 } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
2372 function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
2373 for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
2374 var currentSlope = getSlope(aGuessT, mX1, mX2);
2375 if (currentSlope === 0.0) {
2378 var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
2379 aGuessT -= currentX / currentSlope;
2384 function bezier (mX1, mY1, mX2, mY2) {
2385 if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
2386 throw new Error('bezier x values must be in [0, 1] range');
2389 // Precompute samples table
2390 var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
2391 if (mX1 !== mY1 || mX2 !== mY2) {
2392 for (var i = 0; i < kSplineTableSize; ++i) {
2393 sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
2397 function getTForX (aX) {
2398 var intervalStart = 0.0;
2399 var currentSample = 1;
2400 var lastSample = kSplineTableSize - 1;
2402 for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
2403 intervalStart += kSampleStepSize;
2407 // Interpolate to provide an initial guess for t
2408 var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
2409 var guessForT = intervalStart + dist * kSampleStepSize;
2411 var initialSlope = getSlope(guessForT, mX1, mX2);
2412 if (initialSlope >= NEWTON_MIN_SLOPE) {
2413 return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
2414 } else if (initialSlope === 0.0) {
2417 return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
2421 return function BezierEasing (x) {
2422 if (mX1 === mY1 && mX2 === mY2) {
2425 // Because JavaScript number are imprecise, we should guarantee the extremes are right.
2432 return calcBezier(getTForX(x), mY1, mY2);
2436 /* eslint no-control-regex: "off
" */
2438 // Remove Diacritics
2439 var defaultDiacriticsRemovalap = [
2440 { base: 'A', letters: '\u0041\u24B6\uFF21\u00C0\u00C1\u00C2\u1EA6\u1EA4\u1EAA\u1EA8\u00C3\u0100\u0102\u1EB0\u1EAE\u1EB4\u1EB2\u0226\u01E0\u00C4\u01DE\u1EA2\u00C5\u01FA\u01CD\u0200\u0202\u1EA0\u1EAC\u1EB6\u1E00\u0104\u023A\u2C6F' },
2441 { base: 'AA', letters: '\uA732' },
2442 { base: 'AE', letters: '\u00C6\u01FC\u01E2' },
2443 { base: 'AO', letters: '\uA734' },
2444 { base: 'AU', letters: '\uA736' },
2445 { base: 'AV', letters: '\uA738\uA73A' },
2446 { base: 'AY', letters: '\uA73C' },
2447 { base: 'B', letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181' },
2448 { base: 'C', letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E' },
2449 { base: 'D', letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779' },
2450 { base: 'DZ', letters: '\u01F1\u01C4' },
2451 { base: 'Dz', letters: '\u01F2\u01C5' },
2452 { base: 'E', letters: '\u0045\u24BA\uFF25\u00C8\u00C9\u00CA\u1EC0\u1EBE\u1EC4\u1EC2\u1EBC\u0112\u1E14\u1E16\u0114\u0116\u00CB\u1EBA\u011A\u0204\u0206\u1EB8\u1EC6\u0228\u1E1C\u0118\u1E18\u1E1A\u0190\u018E' },
2453 { base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
2454 { base: 'G', letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E' },
2455 { base: 'H', letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D' },
2456 { base: 'I', letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197' },
2457 { base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
2458 { base: 'K', letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2' },
2459 { base: 'L', letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780' },
2460 { base: 'LJ', letters: '\u01C7' },
2461 { base: 'Lj', letters: '\u01C8' },
2462 { base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
2463 { base: 'N', letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4' },
2464 { base: 'NJ', letters: '\u01CA' },
2465 { base: 'Nj', letters: '\u01CB' },
2466 { base: 'O', letters: '\u004F\u24C4\uFF2F\u00D2\u00D3\u00D4\u1ED2\u1ED0\u1ED6\u1ED4\u00D5\u1E4C\u022C\u1E4E\u014C\u1E50\u1E52\u014E\u022E\u0230\u00D6\u022A\u1ECE\u0150\u01D1\u020C\u020E\u01A0\u1EDC\u1EDA\u1EE0\u1EDE\u1EE2\u1ECC\u1ED8\u01EA\u01EC\u00D8\u01FE\u0186\u019F\uA74A\uA74C' },
2467 { base: 'OI', letters: '\u01A2' },
2468 { base: 'OO', letters: '\uA74E' },
2469 { base: 'OU', letters: '\u0222' },
2470 { base: 'OE', letters: '\u008C\u0152' },
2471 { base: 'oe', letters: '\u009C\u0153' },
2472 { base: 'P', letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754' },
2473 { base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
2474 { base: 'R', letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782' },
2475 { base: 'S', letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784' },
2476 { base: 'T', letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786' },
2477 { base: 'TZ', letters: '\uA728' },
2478 { base: 'U', letters: '\u0055\u24CA\uFF35\u00D9\u00DA\u00DB\u0168\u1E78\u016A\u1E7A\u016C\u00DC\u01DB\u01D7\u01D5\u01D9\u1EE6\u016E\u0170\u01D3\u0214\u0216\u01AF\u1EEA\u1EE8\u1EEE\u1EEC\u1EF0\u1EE4\u1E72\u0172\u1E76\u1E74\u0244' },
2479 { base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
2480 { base: 'VY', letters: '\uA760' },
2481 { base: 'W', letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72' },
2482 { base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
2483 { base: 'Y', letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE' },
2484 { base: 'Z', letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762' },
2485 { base: 'a', letters: '\u0061\u24D0\uFF41\u1E9A\u00E0\u00E1\u00E2\u1EA7\u1EA5\u1EAB\u1EA9\u00E3\u0101\u0103\u1EB1\u1EAF\u1EB5\u1EB3\u0227\u01E1\u00E4\u01DF\u1EA3\u00E5\u01FB\u01CE\u0201\u0203\u1EA1\u1EAD\u1EB7\u1E01\u0105\u2C65\u0250' },
2486 { base: 'aa', letters: '\uA733' },
2487 { base: 'ae', letters: '\u00E6\u01FD\u01E3' },
2488 { base: 'ao', letters: '\uA735' },
2489 { base: 'au', letters: '\uA737' },
2490 { base: 'av', letters: '\uA739\uA73B' },
2491 { base: 'ay', letters: '\uA73D' },
2492 { base: 'b', letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253' },
2493 { base: 'c', letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184' },
2494 { base: 'd', letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A' },
2495 { base: 'dz', letters: '\u01F3\u01C6' },
2496 { base: 'e', letters: '\u0065\u24D4\uFF45\u00E8\u00E9\u00EA\u1EC1\u1EBF\u1EC5\u1EC3\u1EBD\u0113\u1E15\u1E17\u0115\u0117\u00EB\u1EBB\u011B\u0205\u0207\u1EB9\u1EC7\u0229\u1E1D\u0119\u1E19\u1E1B\u0247\u025B\u01DD' },
2497 { base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
2498 { base: 'g', letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F' },
2499 { base: 'h', letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265' },
2500 { base: 'hv', letters: '\u0195' },
2501 { base: 'i', letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131' },
2502 { base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
2503 { base: 'k', letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3' },
2504 { base: 'l', letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747' },
2505 { base: 'lj', letters: '\u01C9' },
2506 { base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
2507 { base: 'n', letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5' },
2508 { base: 'nj', letters: '\u01CC' },
2509 { base: 'o', letters: '\u006F\u24DE\uFF4F\u00F2\u00F3\u00F4\u1ED3\u1ED1\u1ED7\u1ED5\u00F5\u1E4D\u022D\u1E4F\u014D\u1E51\u1E53\u014F\u022F\u0231\u00F6\u022B\u1ECF\u0151\u01D2\u020D\u020F\u01A1\u1EDD\u1EDB\u1EE1\u1EDF\u1EE3\u1ECD\u1ED9\u01EB\u01ED\u00F8\u01FF\u0254\uA74B\uA74D\u0275' },
2510 { base: 'oi', letters: '\u01A3' },
2511 { base: 'ou', letters: '\u0223' },
2512 { base: 'oo', letters: '\uA74F' },
2513 { base: 'p', letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755' },
2514 { base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
2515 { base: 'r', letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783' },
2516 { base: 's', letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B' },
2517 { base: 't', letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787' },
2518 { base: 'tz', letters: '\uA729' },
2519 { base: 'u', letters: '\u0075\u24E4\uFF55\u00F9\u00FA\u00FB\u0169\u1E79\u016B\u1E7B\u016D\u00FC\u01DC\u01D8\u01D6\u01DA\u1EE7\u016F\u0171\u01D4\u0215\u0217\u01B0\u1EEB\u1EE9\u1EEF\u1EED\u1EF1\u1EE5\u1E73\u0173\u1E77\u1E75\u0289' },
2520 { base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
2521 { base: 'vy', letters: '\uA761' },
2522 { base: 'w', letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73' },
2523 { base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
2524 { base: 'y', letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF' },
2525 { base: 'z', letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' } ];
2527 var diacriticsMap = {};
2528 for (var i = 0; i < defaultDiacriticsRemovalap.length; i += 1) {
2529 var letters = defaultDiacriticsRemovalap[i].letters;
2530 for (var j = 0; j < letters.length; j += 1) {
2531 diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base;
2535 var uniqueNumber = 1;
2538 uniqueNumber: function uniqueNumber$1() {
2540 return uniqueNumber;
2542 id: function id(mask, map) {
2543 if ( mask === void 0 ) mask = 'xxxxxxxxxx';
2544 if ( map === void 0 ) map = '0123456789abcdef';
2546 var length = map.length;
2547 return mask.replace(/x/g, function () { return map[Math.floor((Math.random() * length))]; });
2549 mdPreloaderContent: "\n <span
class=\"preloader
-inner
\">\n <span
class=\"preloader
-inner
-gap
\"></span>\n <span class=\"preloader-inner-left\">\n <span class=\"preloader-inner-half-circle\"></span>\n </span>\n <span class=\"preloader-inner-right\">\n <span class=\"preloader-inner-half-circle\"></span>\n </span>\n </span>\n ".trim(),
2550 iosPreloaderContent: ("\n <span
class=\"preloader
-inner
\">\n " + ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map(function () { return '<span class="preloader
-inner
-line
"></span>'; }).join('')) + "\n </span
>\n ").trim(),
2551 auroraPreloaderContent: "\n <span
class=\"preloader
-inner
\">\n <span
class=\"preloader
-inner
-circle
\"></span>\n </span>\n ",
2552 eventNameToColonCase: function eventNameToColonCase(eventName) {
2554 return eventName.split('').map(function (char, index) {
2555 if (char.match(/[A-Z]/) && index !== 0 && !hasColon) {
2557 return (":" + (char.toLowerCase()));
2559 return char.toLowerCase();
2562 deleteProps: function deleteProps(obj) {
2564 Object.keys(object).forEach(function (key) {
2568 // no setter for object
2573 // something got wrong
2577 bezier: function bezier$1() {
2578 var args = [], len = arguments.length;
2579 while ( len-- ) args[ len ] = arguments[ len ];
2581 return bezier.apply(void 0, args);
2583 nextTick: function nextTick(callback, delay) {
2584 if ( delay === void 0 ) delay = 0;
2586 return setTimeout(callback, delay);
2588 nextFrame: function nextFrame(callback) {
2589 return Utils.requestAnimationFrame(function () {
2590 Utils.requestAnimationFrame(callback);
2593 now: function now() {
2596 requestAnimationFrame: function requestAnimationFrame(callback) {
2597 return win.requestAnimationFrame(callback);
2599 cancelAnimationFrame: function cancelAnimationFrame(id) {
2600 return win.cancelAnimationFrame(id);
2602 removeDiacritics: function removeDiacritics(str) {
2603 return str.replace(/[^\u0000-\u007E]/g, function (a) { return diacriticsMap[a] || a; });
2605 parseUrlQuery: function parseUrlQuery(url) {
2607 var urlToParse = url || win.location.href;
2612 if (typeof urlToParse === 'string' && urlToParse.length) {
2613 urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\S*\?/, '') : '';
2614 params = urlToParse.split('&').filter(function (paramsPart) { return paramsPart !== ''; });
2615 length = params.length;
2617 for (i = 0; i < length; i += 1) {
2618 param = params[i].replace(/#\S+/g, '').split('=');
2619 query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param.slice(1).join('=')) || '';
2624 getTranslate: function getTranslate(el, axis) {
2625 if ( axis === void 0 ) axis = 'x';
2629 var transformMatrix;
2631 var curStyle = win.getComputedStyle(el, null);
2633 if (win.WebKitCSSMatrix) {
2634 curTransform = curStyle.transform || curStyle.webkitTransform;
2635 if (curTransform.split(',').length > 6) {
2636 curTransform = curTransform.split(', ').map(function (a) { return a.replace(',', '.'); }).join(', ');
2638 // Some old versions of Webkit choke when 'none' is passed; pass
2639 // empty string instead in this case
2640 transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
2642 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
2643 matrix = transformMatrix.toString().split(',');
2647 // Latest Chrome and webkits Fix
2648 if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m41; }
2649 // Crazy IE10 Matrix
2650 else if (matrix.length === 16) { curTransform = parseFloat(matrix[12]); }
2652 else { curTransform = parseFloat(matrix[4]); }
2655 // Latest Chrome and webkits Fix
2656 if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m42; }
2657 // Crazy IE10 Matrix
2658 else if (matrix.length === 16) { curTransform = parseFloat(matrix[13]); }
2660 else { curTransform = parseFloat(matrix[5]); }
2662 return curTransform || 0;
2664 serializeObject: function serializeObject(obj, parents) {
2665 if ( parents === void 0 ) parents = [];
2667 if (typeof obj === 'string') { return obj; }
2668 var resultArray = [];
2669 var separator = '&';
2671 function varName(name) {
2672 if (parents.length > 0) {
2673 var parentParts = '';
2674 for (var j = 0; j < parents.length; j += 1) {
2675 if (j === 0) { parentParts += parents[j]; }
2676 else { parentParts += "[" + (encodeURIComponent(parents[j])) + "]"; }
2678 return (parentParts + "[" + (encodeURIComponent(name)) + "]");
2680 return encodeURIComponent(name);
2682 function varValue(value) {
2683 return encodeURIComponent(value);
2685 Object.keys(obj).forEach(function (prop) {
2687 if (Array.isArray(obj[prop])) {
2689 for (var i = 0; i < obj[prop].length; i += 1) {
2690 if (!Array.isArray(obj[prop][i]) && typeof obj[prop][i] === 'object') {
2691 newParents = parents.slice();
2692 newParents.push(prop);
2693 newParents.push(String(i));
2694 toPush.push(Utils.serializeObject(obj[prop][i], newParents));
2696 toPush.push(((varName(prop)) + "[]=" + (varValue(obj[prop][i]))));
2699 if (toPush.length > 0) { resultArray.push(toPush.join(separator)); }
2700 } else if (obj[prop] === null || obj[prop] === '') {
2701 resultArray.push(((varName(prop)) + "="));
2702 } else if (typeof obj[prop] === 'object') {
2703 // Object, convert to named array
2704 newParents = parents.slice();
2705 newParents.push(prop);
2706 toPush = Utils.serializeObject(obj[prop], newParents);
2707 if (toPush !== '') { resultArray.push(toPush); }
2708 } else if (typeof obj[prop] !== 'undefined' && obj[prop] !== '') {
2709 // Should be string or plain value
2710 resultArray.push(((varName(prop)) + "=" + (varValue(obj[prop]))));
2711 } else if (obj[prop] === '') { resultArray.push(varName(prop)); }
2713 return resultArray.join(separator);
2715 isObject: function isObject(o) {
2716 return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object;
2718 merge: function merge() {
2719 var args = [], len$1 = arguments.length;
2720 while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];
2726 for (var i = 0; i < from.length; i += 1) {
2727 var nextSource = args[i];
2728 if (nextSource !== undefined && nextSource !== null) {
2729 var keysArray = Object.keys(Object(nextSource));
2730 for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
2731 var nextKey = keysArray[nextIndex];
2732 var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
2733 if (desc !== undefined && desc.enumerable) {
2734 to[nextKey] = nextSource[nextKey];
2741 extend: function extend() {
2742 var args = [], len$1 = arguments.length;
2743 while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];
2748 if (typeof args[0] === 'boolean') {
2758 for (var i = 0; i < from.length; i += 1) {
2759 var nextSource = args[i];
2760 if (nextSource !== undefined && nextSource !== null) {
2761 var keysArray = Object.keys(Object(nextSource));
2762 for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
2763 var nextKey = keysArray[nextIndex];
2764 var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
2765 if (desc !== undefined && desc.enumerable) {
2767 to[nextKey] = nextSource[nextKey];
2768 } else if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
2769 Utils.extend(to[nextKey], nextSource[nextKey]);
2770 } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
2772 Utils.extend(to[nextKey], nextSource[nextKey]);
2774 to[nextKey] = nextSource[nextKey];
2782 colorHexToRgb: function colorHexToRgb(hex) {
2783 var h = hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, function (m, r, g, b) { return r + r + g + g + b + b; });
2784 var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(h);
2786 ? result.slice(1).map(function (n) { return parseInt(n, 16); })
2789 colorRgbToHex: function colorRgbToHex(r, g, b) {
2790 var result = [r, g, b].map(function (n) {
2791 var hex = n.toString(16);
2792 return hex.length === 1 ? ("0" + hex) : hex;
2794 return ("#" + result);
2796 colorRgbToHsl: function colorRgbToHsl(r, g, b) {
2797 r /= 255; // eslint-disable-line
2798 g /= 255; // eslint-disable-line
2799 b /= 255; // eslint-disable-line
2800 var max = Math.max(r, g, b);
2801 var min = Math.min(r, g, b);
2804 if (d === 0) { h = 0; }
2805 else if (max === r) { h = ((g - b) / d) % 6; }
2806 else if (max === g) { h = (b - r) / d + 2; }
2807 else if (max === b) { h = (r - g) / d + 4; }
2808 var l = (min + max) / 2;
2809 var s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
2810 if (h < 0) { h = 360 / 60 + h; }
2811 return [h * 60, s, l];
2813 colorHslToRgb: function colorHslToRgb(h, s, l) {
2814 var c = (1 - Math.abs(2 * l - 1)) * s;
2816 var x = c * (1 - Math.abs((hp % 2) - 1));
2818 if (Number.isNaN(h) || typeof h === 'undefined') {
2820 } else if (hp <= 1) { rgb1 = [c, x, 0]; }
2821 else if (hp <= 2) { rgb1 = [x, c, 0]; }
2822 else if (hp <= 3) { rgb1 = [0, c, x]; }
2823 else if (hp <= 4) { rgb1 = [0, x, c]; }
2824 else if (hp <= 5) { rgb1 = [x, 0, c]; }
2825 else if (hp <= 6) { rgb1 = [c, 0, x]; }
2826 var m = l - (c / 2);
2827 return rgb1.map(function (n) { return Math.max(0, Math.min(255, Math.round(255 * (n + m)))); });
2829 colorHsbToHsl: function colorHsbToHsl(h, s, b) {
2835 var HSB = { h: h, s: s, b: b };
2837 HSL.l = (2 - HSB.s) * HSB.b / 2;
2838 HSL.s = HSL.l && HSL.l < 1 ? HSB.s * HSB.b / (HSL.l < 0.5 ? HSL.l * 2 : 2 - HSL.l * 2) : HSL.s;
2840 return [HSL.h, HSL.s, HSL.l];
2842 colorHslToHsb: function colorHslToHsb(h, s, l) {
2848 var HSL = { h: h, s: s, l: l };
2850 var t = HSL.s * (HSL.l < 0.5 ? HSL.l : 1 - HSL.l);
2852 HSB.s = HSL.l > 0 ? 2 * t / HSB.b : HSB.s;
2854 return [HSB.h, HSB.s, HSB.b];
2856 colorThemeCSSProperties: function colorThemeCSSProperties() {
2857 var args = [], len = arguments.length;
2858 while ( len-- ) args[ len ] = arguments[ len ];
2862 if (args.length === 1) {
2864 rgb = Utils.colorHexToRgb(hex);
2865 } else if (args.length === 3) {
2867 hex = Utils.colorRgbToHex.apply(Utils, rgb);
2869 if (!rgb) { return {}; }
2870 var hsl = Utils.colorRgbToHsl.apply(Utils, rgb);
2871 var hslShade = [hsl[0], hsl[1], Math.max(0, (hsl[2] - 0.08))];
2872 var hslTint = [hsl[0], hsl[1], Math.max(0, (hsl[2] + 0.08))];
2873 var shade = Utils.colorRgbToHex.apply(Utils, Utils.colorHslToRgb.apply(Utils, hslShade));
2874 var tint = Utils.colorRgbToHex.apply(Utils, Utils.colorHslToRgb.apply(Utils, hslTint));
2876 '--f7-theme-color': hex,
2877 '--f7-theme-color-rgb': rgb.join(', '),
2878 '--f7-theme-color-shade': shade,
2879 '--f7-theme-color-tint': tint,
2884 var Support = (function Support() {
2885 var testDiv = doc.createElement('div');
2888 touch: (function checkTouch() {
2889 return !!((win.navigator.maxTouchPoints > 0) || ('ontouchstart' in win) || (win.DocumentTouch && doc instanceof win.DocumentTouch));
2892 pointerEvents: !!(win.navigator.pointerEnabled || win.PointerEvent || ('maxTouchPoints' in win.navigator && win.navigator.maxTouchPoints > 0)),
2893 prefixedPointerEvents: !!win.navigator.msPointerEnabled,
2895 transition: (function checkTransition() {
2896 var style = testDiv.style;
2897 return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style);
2899 transforms3d: (win.Modernizr && win.Modernizr.csstransforms3d === true) || (function checkTransforms3d() {
2900 var style = testDiv.style;
2901 return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style);
2904 flexbox: (function checkFlexbox() {
2905 var div = doc.createElement('div').style;
2906 var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
2907 for (var i = 0; i < styles.length; i += 1) {
2908 if (styles[i] in div) { return true; }
2913 observer: (function checkObserver() {
2914 return ('MutationObserver' in win || 'WebkitMutationObserver' in win);
2917 passiveListener: (function checkPassiveListener() {
2918 var supportsPassive = false;
2920 var opts = Object.defineProperty({}, 'passive', {
2921 // eslint-disable-next-line
2922 get: function get() {
2923 supportsPassive = true;
2926 win.addEventListener('testPassiveListener', null, opts);
2930 return supportsPassive;
2933 gestures: (function checkGestures() {
2934 return 'ongesturestart' in win;
2937 intersectionObserver: (function checkObserver() {
2938 return ('IntersectionObserver' in win);
2943 var Device = (function Device() {
2944 var platform = win.navigator.platform;
2945 var ua = win.navigator.userAgent;
2950 androidChrome: false,
2952 windowsPhone: false,
2962 cordova: !!(win.cordova || win.phonegap),
2963 phonegap: !!(win.cordova || win.phonegap),
2967 var screenWidth = win.screen.width;
2968 var screenHeight = win.screen.height;
2970 var windowsPhone = ua.match(/(Windows Phone);?[\s\/]+([\d.]+)?/); // eslint-disable-line
2971 var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
2972 var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
2973 var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
2974 var iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
2975 var iphoneX = iphone && (
2976 (screenWidth === 375 && screenHeight === 812) // X/XS
2977 || (screenWidth === 414 && screenHeight === 896) // XR / XS Max
2979 var ie = ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;
2980 var edge = ua.indexOf('Edge/') >= 0;
2981 var firefox = ua.indexOf('Gecko/') >= 0 && ua.indexOf('Firefox/') >= 0;
2982 var windows = platform === 'Win32';
2983 var electron = ua.toLowerCase().indexOf('electron') >= 0;
2984 var macos = platform === 'MacIntel';
2991 (screenWidth === 1024 && screenHeight === 1366) // Pro 12.9
2992 || (screenWidth === 834 && screenHeight === 1194) // Pro 11
2993 || (screenWidth === 834 && screenHeight === 1112) // Pro 10.5
2994 || (screenWidth === 768 && screenHeight === 1024) // other
2997 ipad = ua.match(/(Version)\/([\d.]+)/);
3003 device.firefox = firefox;
3007 device.os = 'windowsPhone';
3008 device.osVersion = windowsPhone[2];
3009 device.windowsPhone = true;
3012 if (android && !windows) {
3013 device.os = 'android';
3014 device.osVersion = android[2];
3015 device.android = true;
3016 device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;
3018 if (ipad || iphone || ipod) {
3023 if (iphone && !ipod) {
3024 device.osVersion = iphone[2].replace(/_/g, '.');
3025 device.iphone = true;
3026 device.iphoneX = iphoneX;
3029 device.osVersion = ipad[2].replace(/_/g, '.');
3033 device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
3036 // iOS 8+ changed UA
3037 if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {
3038 if (device.osVersion.split('.')[0] === '10') {
3039 device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];
3044 device.webView = !!((iphone || ipad || ipod) && (ua.match(/.*AppleWebKit(?!.*Safari)/i) || win.navigator.standalone))
3045 || (win.matchMedia && win.matchMedia('(display-mode: standalone)').matches);
3046 device.webview = device.webView;
3047 device.standalone = device.webView;
3050 device.desktop = !(device.ios || device.android || device.windowsPhone) || electron;
3051 if (device.desktop) {
3052 device.electron = electron;
3053 device.macos = macos;
3054 device.windows = windows;
3058 var metaStatusbar = doc.querySelector('meta[name="apple
-mobile
-web
-app
-status
-bar
-style
"]');
3060 // Check for status bar and fullscreen app mode
3061 device.needsStatusbarOverlay = function needsStatusbarOverlay() {
3062 if (device.desktop) { return false; }
3063 if (device.standalone && device.ios && metaStatusbar && metaStatusbar.content === 'black-translucent') {
3066 if ((device.webView || (device.android && device.cordova)) && (win.innerWidth * win.innerHeight === win.screen.width * win.screen.height)) {
3067 if (device.iphoneX && (win.orientation === 90 || win.orientation === -90)) {
3074 device.statusbar = device.needsStatusbarOverlay();
3077 device.pixelRatio = win.devicePixelRatio || 1;
3080 var DARK = '(prefers-color-scheme: dark)';
3081 var LIGHT = '(prefers-color-scheme: light)';
3082 device.prefersColorScheme = function prefersColorTheme() {
3084 if (win.matchMedia && win.matchMedia(LIGHT).matches) {
3087 if (win.matchMedia && win.matchMedia(DARK).matches) {
3097 var EventsClass = function EventsClass(parents) {
3098 if ( parents === void 0 ) parents = [];
3101 self.eventsParents = parents;
3102 self.eventsListeners = {};
3105 EventsClass.prototype.on = function on (events, handler, priority) {
3107 if (typeof handler !== 'function') { return self; }
3108 var method = priority ? 'unshift' : 'push';
3109 events.split(' ').forEach(function (event) {
3110 if (!self.eventsListeners[event]) { self.eventsListeners[event] = []; }
3111 self.eventsListeners[event][method](handler);
3116 EventsClass.prototype.once = function once (events, handler, priority) {
3118 if (typeof handler !== 'function') { return self; }
3119 function onceHandler() {
3120 var args = [], len = arguments.length;
3121 while ( len-- ) args[ len ] = arguments[ len ];
3123 handler.apply(self, args);
3124 self.off(events, onceHandler);
3125 if (onceHandler.f7proxy) {
3126 delete onceHandler.f7proxy;
3129 onceHandler.f7proxy = handler;
3130 return self.on(events, onceHandler, priority);
3133 EventsClass.prototype.off = function off (events, handler) {
3135 if (!self.eventsListeners) { return self; }
3136 events.split(' ').forEach(function (event) {
3137 if (typeof handler === 'undefined') {
3138 self.eventsListeners[event] = [];
3139 } else if (self.eventsListeners[event]) {
3140 self.eventsListeners[event].forEach(function (eventHandler, index) {
3141 if (eventHandler === handler || (eventHandler.f7proxy && eventHandler.f7proxy === handler)) {
3142 self.eventsListeners[event].splice(index, 1);
3150 EventsClass.prototype.emit = function emit () {
3151 var args = [], len = arguments.length;
3152 while ( len-- ) args[ len ] = arguments[ len ];
3155 if (!self.eventsListeners) { return self; }
3160 if (typeof args[0] === 'string' || Array.isArray(args[0])) {
3162 data = args.slice(1, args.length);
3164 eventsParents = self.eventsParents;
3166 events = args[0].events;
3167 data = args[0].data;
3168 context = args[0].context || self;
3169 eventsParents = args[0].local ? [] : args[0].parents || self.eventsParents;
3171 var eventsArray = Array.isArray(events) ? events : events.split(' ');
3172 var localEvents = eventsArray.map(function (eventName) { return eventName.replace('local::', ''); });
3173 var parentEvents = eventsArray.filter(function (eventName) { return eventName.indexOf('local::') < 0; });
3175 localEvents.forEach(function (event) {
3176 if (self.eventsListeners && self.eventsListeners[event]) {
3178 self.eventsListeners[event].forEach(function (eventHandler) {
3179 handlers.push(eventHandler);
3181 handlers.forEach(function (eventHandler) {
3182 eventHandler.apply(context, data);
3186 if (eventsParents && eventsParents.length > 0) {
3187 eventsParents.forEach(function (eventsParent) {
3188 eventsParent.emit.apply(eventsParent, [ parentEvents ].concat( data ));
3194 var Framework7Class = /*@__PURE__*/(function (EventsClass) {
3195 function Framework7Class(params, parents) {
3196 if ( params === void 0 ) params = {};
3197 if ( parents === void 0 ) parents = [];
3199 EventsClass.call(this, parents);
3201 self.params = params;
3203 if (self.params && self.params.on) {
3204 Object.keys(self.params.on).forEach(function (eventName) {
3205 self.on(eventName, self.params.on[eventName]);
3210 if ( EventsClass ) Framework7Class.__proto__ = EventsClass;
3211 Framework7Class.prototype = Object.create( EventsClass && EventsClass.prototype );
3212 Framework7Class.prototype.constructor = Framework7Class;
3214 var staticAccessors = { components: { configurable: true } };
3216 // eslint-disable-next-line
3217 Framework7Class.prototype.useModuleParams = function useModuleParams (module, instanceParams) {
3218 if (module.params) {
3219 var originalParams = {};
3220 Object.keys(module.params).forEach(function (paramKey) {
3221 if (typeof instanceParams[paramKey] === 'undefined') { return; }
3222 originalParams[paramKey] = Utils.extend({}, instanceParams[paramKey]);
3224 Utils.extend(instanceParams, module.params);
3225 Object.keys(originalParams).forEach(function (paramKey) {
3226 Utils.extend(instanceParams[paramKey], originalParams[paramKey]);
3231 Framework7Class.prototype.useModulesParams = function useModulesParams (instanceParams) {
3232 var instance = this;
3233 if (!instance.modules) { return; }
3234 Object.keys(instance.modules).forEach(function (moduleName) {
3235 var module = instance.modules[moduleName];
3237 if (module.params) {
3238 Utils.extend(instanceParams, module.params);
3243 Framework7Class.prototype.useModule = function useModule (moduleName, moduleParams) {
3244 if ( moduleName === void 0 ) moduleName = '';
3245 if ( moduleParams === void 0 ) moduleParams = {};
3247 var instance = this;
3248 if (!instance.modules) { return; }
3249 var module = typeof moduleName === 'string' ? instance.modules[moduleName] : moduleName;
3250 if (!module) { return; }
3252 // Extend instance methods and props
3253 if (module.instance) {
3254 Object.keys(module.instance).forEach(function (modulePropName) {
3255 var moduleProp = module.instance[modulePropName];
3256 if (typeof moduleProp === 'function') {
3257 instance[modulePropName] = moduleProp.bind(instance);
3259 instance[modulePropName] = moduleProp;
3263 // Add event listeners
3264 if (module.on && instance.on) {
3265 Object.keys(module.on).forEach(function (moduleEventName) {
3266 instance.on(moduleEventName, module.on[moduleEventName]);
3271 if (!instance.vnodeHooks) { instance.vnodeHooks = {}; }
3272 Object.keys(module.vnode).forEach(function (vnodeId) {
3273 Object.keys(module.vnode[vnodeId]).forEach(function (hookName) {
3274 var handler = module.vnode[vnodeId][hookName];
3275 if (!instance.vnodeHooks[hookName]) { instance.vnodeHooks[hookName] = {}; }
3276 if (!instance.vnodeHooks[hookName][vnodeId]) { instance.vnodeHooks[hookName][vnodeId] = []; }
3277 instance.vnodeHooks[hookName][vnodeId].push(handler.bind(instance));
3281 // Module create callback
3282 if (module.create) {
3283 module.create.bind(instance)(moduleParams);
3287 Framework7Class.prototype.useModules = function useModules (modulesParams) {
3288 if ( modulesParams === void 0 ) modulesParams = {};
3290 var instance = this;
3291 if (!instance.modules) { return; }
3292 Object.keys(instance.modules).forEach(function (moduleName) {
3293 var moduleParams = modulesParams[moduleName] || {};
3294 instance.useModule(moduleName, moduleParams);
3298 staticAccessors.components.set = function (components) {
3300 if (!Class.use) { return; }
3301 Class.use(components);
3304 Framework7Class.installModule = function installModule (module) {
3305 var params = [], len = arguments.length - 1;
3306 while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];
3309 if (!Class.prototype.modules) { Class.prototype.modules = {}; }
3310 var name = module.name || (((Object.keys(Class.prototype.modules).length) + "_
" + (Utils.now())));
3311 Class.prototype.modules[name] = module;
3314 Object.keys(module.proto).forEach(function (key) {
3315 Class.prototype[key] = module.proto[key];
3319 if (module.static) {
3320 Object.keys(module.static).forEach(function (key) {
3321 Class[key] = module.static[key];
3325 if (module.install) {
3326 module.install.apply(Class, params);
3331 Framework7Class.use = function use (module) {
3332 var params = [], len = arguments.length - 1;
3333 while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];
3336 if (Array.isArray(module)) {
3337 module.forEach(function (m) { return Class.installModule(m); });
3340 return Class.installModule.apply(Class, [ module ].concat( params ));
3343 Object.defineProperties( Framework7Class, staticAccessors );
3345 return Framework7Class;
3348 function ConstructorMethods (parameters) {
3349 if ( parameters === void 0 ) parameters = {};
3351 var defaultSelector = parameters.defaultSelector;
3352 var constructor = parameters.constructor;
3353 var domProp = parameters.domProp;
3354 var app = parameters.app;
3355 var addMethods = parameters.addMethods;
3357 create: function create() {
3358 var args = [], len = arguments.length;
3359 while ( len-- ) args[ len ] = arguments[ len ];
3361 if (app) { return new (Function.prototype.bind.apply( constructor, [ null ].concat( [app], args) )); }
3362 return new (Function.prototype.bind.apply( constructor, [ null ].concat( args) ));
3364 get: function get(el) {
3365 if ( el === void 0 ) el = defaultSelector;
3367 if (el instanceof constructor) { return el; }
3369 if ($el.length === 0) { return undefined; }
3370 return $el[0][domProp];
3372 destroy: function destroy(el) {
3373 var instance = methods.get(el);
3374 if (instance && instance.destroy) { return instance.destroy(); }
3378 if (addMethods && Array.isArray(addMethods)) {
3379 addMethods.forEach(function (methodName) {
3380 methods[methodName] = function (el) {
3381 if ( el === void 0 ) el = defaultSelector;
3382 var args = [], len = arguments.length - 1;
3383 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
3385 var instance = methods.get(el);
3386 if (instance && instance[methodName]) { return instance[methodName].apply(instance, args); }
3394 function ModalMethods (parameters) {
3395 if ( parameters === void 0 ) parameters = {};
3397 var defaultSelector = parameters.defaultSelector;
3398 var constructor = parameters.constructor;
3399 var app = parameters.app;
3400 var methods = Utils.extend(
3401 ConstructorMethods({
3402 defaultSelector: defaultSelector,
3403 constructor: constructor,
3408 open: function open(el, animate) {
3410 var instance = $el[0].f7Modal;
3411 if (!instance) { instance = new constructor(app, { el: $el }); }
3412 return instance.open(animate);
3414 close: function close(el, animate) {
3415 if ( el === void 0 ) el = defaultSelector;
3418 if ($el.length === 0) { return undefined; }
3419 var instance = $el[0].f7Modal;
3420 if (!instance) { instance = new constructor(app, { el: $el }); }
3421 return instance.close(animate);
3428 var fetchedModules = [];
3429 function loadModule(moduleToLoad) {
3430 var Framework7 = this;
3431 return new Promise(function (resolve, reject) {
3432 var app = Framework7.instance;
3436 if (!moduleToLoad) {
3437 reject(new Error('Framework7: Lazy module must be specified'));
3441 function install(module) {
3442 Framework7.use(module);
3445 app.useModuleParams(module, app.params);
3446 app.useModule(module);
3450 if (typeof moduleToLoad === 'string') {
3451 var matchNamePattern = moduleToLoad.match(/([a-z0-9-]*)/i);
3452 if (moduleToLoad.indexOf('.') < 0 && matchNamePattern && matchNamePattern[0].length === moduleToLoad.length) {
3453 if (!app || (app && !app.params.lazyModulesPath)) {
3454 reject(new Error('Framework7: "lazyModulesPath
" app parameter must be specified to fetch module by name'));
3457 modulePath = (app.params.lazyModulesPath) + "/" + moduleToLoad + ".js
";
3459 modulePath = moduleToLoad;
3461 } else if (typeof moduleToLoad === 'function') {
3462 moduleFunc = moduleToLoad;
3464 // considering F7-Plugin object
3465 moduleObj = moduleToLoad;
3469 var module = moduleFunc(Framework7, false);
3471 reject(new Error('Framework7: Can\'t find Framework7 component in specified component function'));
3474 // Check if it was added
3475 if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
3485 var module$1 = moduleObj;
3487 reject(new Error('Framework7: Can\'t find Framework7 component in specified component'));
3490 // Check if it was added
3491 if (Framework7.prototype.modules && Framework7.prototype.modules[module$1.name]) {
3501 if (fetchedModules.indexOf(modulePath) >= 0) {
3505 fetchedModules.push(modulePath);
3506 var scriptLoad = new Promise(function (resolveScript, rejectScript) {
3507 Framework7.request.get(
3509 function (scriptContent) {
3510 var id = Utils.id();
3511 var callbackLoadName = "f7_component_loader_callback_
" + id;
3513 var scriptEl = document.createElement('script');
3514 scriptEl.innerHTML = "window
." + callbackLoadName + " = function (Framework7
, Framework7AutoInstallComponent
) {return " + (scriptContent.trim()) + "}";
3515 $('head').append(scriptEl);
3517 var componentLoader = window[callbackLoadName];
3518 delete window[callbackLoadName];
3519 $(scriptEl).remove();
3521 var module = componentLoader(Framework7, false);
3524 rejectScript(new Error(("Framework7
: Can
't find Framework7 component in " + modulePath + " file")));
3528 // Check if it was added
3529 if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
3539 function (xhr, status) {
3540 rejectScript(xhr, status);
3544 var styleLoad = new Promise(function (resolveStyle) {
3545 Framework7.request.get(
3546 modulePath.replace('.js
', app.rtl ? '.rtl
.css
' : '.css
'),
3547 function (styleContent) {
3548 var styleEl = document.createElement('style
');
3549 styleEl.innerHTML = styleContent;
3550 $('head
').append(styleEl);
3560 Promise.all([scriptLoad, styleLoad]).then(function () {
3562 }).catch(function (err) {
3569 var Framework7 = /*@__PURE__*/(function (Framework7Class) {
3570 function Framework7(params) {
3571 Framework7Class.call(this, params);
3572 if (Framework7.instance) {
3573 throw new Error('Framework7 is already initialized and can
\'t be initialized more than once
');
3576 var passedParams = Utils.extend({}, params);
3581 Framework7.instance = app;
3586 id: 'io
.framework7
.testapp
',
3589 language: win.navigator.language,
3592 lazyModulesPath: null,
3593 initOnDeviceReady: true,
3595 autoDarkTheme: false,
3598 // Extend defaults with modules params
3599 app.useModulesParams(defaults);
3601 // Extend defaults with passed params
3602 app.params = Utils.extend(defaults, params);
3604 var $rootEl = $(app.params.root);
3610 name: app.params.name,
3612 version: app.params.version,
3614 routes: app.params.routes,
3616 language: app.params.language,
3620 rtl: $rootEl.css('direction
') === 'rtl
',
3622 theme: (function getTheme() {
3623 if (app.params.theme === 'auto
') {
3624 if (Device.ios) { return 'ios
'; }
3625 if (Device.desktop && Device.electron) { return 'aurora
'; }
3628 return app.params.theme;
3630 // Initially passed parameters
3631 passedParams: passedParams,
3635 if (app.root && app.root[0]) {
3636 app.root[0].f7 = app;
3642 // Init Data & Methods
3646 var DARK = '(prefers
-color
-scheme
: dark
)';
3647 var LIGHT = '(prefers
-color
-scheme
: light
)';
3649 if (win.matchMedia) {
3650 app.mq.dark = win.matchMedia(DARK);
3651 app.mq.light = win.matchMedia(LIGHT);
3653 app.colorSchemeListener = function colorSchemeListener(ref) {
3654 var matches = ref.matches;
3655 var media = ref.media;
3660 var html = doc.querySelector('html
');
3661 if (media === DARK) {
3662 html.classList.add('theme
-dark
');
3663 } else if (media === LIGHT) {
3664 html.classList.remove('theme
-dark
');
3668 if (app.params.init) {
3669 if (Device.cordova && app.params.initOnDeviceReady) {
3670 $(doc).on('deviceready
', function () {
3677 // Return app instance
3681 if ( Framework7Class ) Framework7.__proto__ = Framework7Class;
3682 Framework7.prototype = Object.create( Framework7Class && Framework7Class.prototype );
3683 Framework7.prototype.constructor = Framework7;
3685 var prototypeAccessors = { $: { configurable: true },t7: { configurable: true } };
3686 var staticAccessors = { Dom7: { configurable: true },$: { configurable: true },Template7: { configurable: true },Class: { configurable: true },Events: { configurable: true } };
3688 Framework7.prototype.initData = function initData () {
3693 if (app.params.data && typeof app.params.data === 'function') {
3694 Utils.extend(app.data, app.params.data.bind(app)());
3695 } else if (app.params.data) {
3696 Utils.extend(app.data, app.params.data);
3700 if (app.params.methods) {
3701 Object.keys(app.params.methods).forEach(function (methodName) {
3702 if (typeof app.params.methods[methodName] === 'function') {
3703 app.methods[methodName] = app.params.methods[methodName].bind(app);
3705 app.methods[methodName] = app.params.methods[methodName];
3711 Framework7.prototype.enableAutoDarkTheme = function enableAutoDarkTheme () {
3712 if (!win.matchMedia) { return; }
3714 var html = doc.querySelector('html
');
3715 if (app.mq.dark && app.mq.light) {
3716 app.mq.dark.addListener(app.colorSchemeListener);
3717 app.mq.light.addListener(app.colorSchemeListener);
3719 if (app.mq.dark && app.mq.dark.matches) {
3720 html.classList.add('theme
-dark
');
3721 } else if (app.mq.light && app.mq.light.matches) {
3722 html.classList.remove('theme
-dark
');
3726 Framework7.prototype.disableAutoDarkTheme = function disableAutoDarkTheme () {
3727 if (!win.matchMedia) { return; }
3729 if (app.mq.dark) { app.mq.dark.removeListener(app.colorSchemeListener); }
3730 if (app.mq.light) { app.mq.light.removeListener(app.colorSchemeListener); }
3733 Framework7.prototype.init = function init () {
3735 if (app.initialized) { return app; }
3737 app.root.addClass('framework7
-initializing
');
3741 $('html
').attr('dir
', 'rtl
');
3745 if (app.params.autoDarkTheme) {
3746 app.enableAutoDarkTheme();
3750 app.root.addClass('framework7
-root
');
3753 $('html
').removeClass('ios md
').addClass(app.theme);
3756 Utils.nextFrame(function () {
3757 app.root.removeClass('framework7
-initializing
');
3759 // Emit, init other modules
3760 app.initialized = true;
3766 // eslint-disable-next-line
3767 Framework7.prototype.loadModule = function loadModule () {
3768 var args = [], len = arguments.length;
3769 while ( len-- ) args[ len ] = arguments[ len ];
3771 return Framework7.loadModule.apply(Framework7, args);
3774 // eslint-disable-next-line
3775 Framework7.prototype.loadModules = function loadModules () {
3776 var args = [], len = arguments.length;
3777 while ( len-- ) args[ len ] = arguments[ len ];
3779 return Framework7.loadModules.apply(Framework7, args);
3782 Framework7.prototype.getVnodeHooks = function getVnodeHooks (hook, id) {
3784 if (!app.vnodeHooks || !app.vnodeHooks[hook]) { return []; }
3785 return app.vnodeHooks[hook][id] || [];
3788 // eslint-disable-next-line
3789 prototypeAccessors.$.get = function () {
3792 // eslint-disable-next-line
3793 prototypeAccessors.t7.get = function () {
3797 staticAccessors.Dom7.get = function () {
3801 staticAccessors.$.get = function () {
3805 staticAccessors.Template7.get = function () {
3809 staticAccessors.Class.get = function () {
3810 return Framework7Class;
3813 staticAccessors.Events.get = function () {
3817 Object.defineProperties( Framework7.prototype, prototypeAccessors );
3818 Object.defineProperties( Framework7, staticAccessors );
3821 }(Framework7Class));
3823 Framework7.ModalMethods = ModalMethods;
3824 Framework7.ConstructorMethods = ConstructorMethods;
3826 Framework7.loadModule = loadModule;
3827 Framework7.loadModules = function loadModules(modules) {
3828 return Promise.all(modules.map(function (module) { return Framework7.loadModule(module); }));
3831 var DeviceModule = {
3840 init: function init() {
3841 var classNames = [];
3842 var html = doc.querySelector('html
');
3843 var metaStatusbar = doc.querySelector('meta
[name
="apple-mobile-web-app-status-bar-style"]');
3844 if (!html) { return; }
3845 if (Device.standalone && Device.ios && metaStatusbar && metaStatusbar.content === 'black
-translucent
') {
3846 classNames.push('device
-full
-viewport
');
3850 classNames.push(("device-pixel-ratio-" + (Math.floor(Device.pixelRatio))));
3851 if (Device.pixelRatio >= 2) {
3852 classNames.push('device
-retina
');
3857 ("device-" + (Device.os)),
3858 ("device-" + (Device.os) + "-" + (Device.osVersion.split('.')[0])),
3859 ("device-" + (Device.os) + "-" + (Device.osVersion.replace(/\./g, '-')))
3861 if (Device.os === 'ios
') {
3862 var major = parseInt(Device.osVersion.split('.')[0], 10);
3863 for (var i = major - 1; i >= 6; i -= 1) {
3864 classNames.push(("device-ios-gt-" + i));
3866 if (Device.iphoneX) {
3867 classNames.push('device
-iphone
-x
');
3870 } else if (Device.desktop) {
3871 classNames.push('device
-desktop
');
3872 if (Device.macos) { classNames.push('device
-macos
'); }
3873 else if (Device.windows) { classNames.push('device
-windows
'); }
3875 if (Device.cordova || Device.phonegap) {
3876 classNames.push('device
-cordova
');
3880 classNames.forEach(function (className) {
3881 html.classList.add(className);
3887 var SupportModule = {
3896 init: function init() {
3897 var html = doc.querySelector('html
');
3898 if (!html) { return; }
3899 var classNames = [];
3901 classNames.forEach(function (className) {
3902 html.classList.add(className);
3918 var ResizeModule = {
3921 getSize: function getSize() {
3923 if (!app.root[0]) { return { width: 0, height: 0, left: 0, top: 0 }; }
3924 var offset = app.root.offset();
3925 var ref = [app.root[0].offsetWidth, app.root[0].offsetHeight, offset.left, offset.top];
3927 var height = ref[1];
3931 app.height = height;
3934 return { width: width, height: height, left: left, top: top };
3938 init: function init() {
3945 win.addEventListener('resize
', function () {
3949 // Emit orientationchange
3950 win.addEventListener('orientationchange
', function () {
3951 app.emit('orientationchange
');
3954 orientationchange: function orientationchange() {
3956 // Fix iPad weird body scroll
3957 if (app.device.ipad) {
3958 doc.body.scrollLeft = 0;
3959 setTimeout(function () {
3960 doc.body.scrollLeft = 0;
3964 resize: function resize() {
3972 var jsonpRequests = 0;
3974 function Request(requestOptions) {
3975 var globalsNoCallbacks = Utils.extend({}, globals);
3976 ('beforeCreate beforeOpen beforeSend error complete success statusCode
').split(' ').forEach(function (callbackName) {
3977 delete globalsNoCallbacks[callbackName];
3979 var defaults = Utils.extend({
3980 url: win.location.toString(),
3992 contentType: 'application
/x
-www
-form
-urlencoded
',
3994 }, globalsNoCallbacks);
3996 var options = Utils.extend({}, defaults, requestOptions);
3999 // Function to run XHR callbacks and events
4000 function fireCallback(callbackName) {
4001 var data = [], len = arguments.length - 1;
4002 while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ];
4006 beforeCreate (options),
4007 beforeOpen (xhr, options),
4008 beforeSend (xhr, options),
4009 error (xhr, status),
4010 complete (xhr, stautus),
4011 success (response, status, xhr),
4014 var globalCallbackValue;
4015 var optionCallbackValue;
4016 if (globals[callbackName]) {
4017 globalCallbackValue = globals[callbackName].apply(globals, data);
4019 if (options[callbackName]) {
4020 optionCallbackValue = options[callbackName].apply(options, data);
4022 if (typeof globalCallbackValue !== 'boolean') { globalCallbackValue = true; }
4023 if (typeof optionCallbackValue !== 'boolean') { optionCallbackValue = true; }
4024 return (globalCallbackValue && optionCallbackValue);
4027 // Before create callback
4028 proceedRequest = fireCallback('beforeCreate
', options);
4029 if (proceedRequest === false) { return undefined; }
4032 if (options.type) { options.method = options.type; }
4034 // Parameters Prefix
4035 var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';
4038 var method = options.method.toUpperCase();
4040 // Data to modify GET URL
4041 if ((method === 'GET
' || method === 'HEAD
' || method === 'OPTIONS
' || method === 'DELETE
') && options.data) {
4043 if (typeof options.data === 'string
') {
4044 // Should be key=value string
4045 if (options.data.indexOf('?') >= 0) { stringData = options.data.split('?')[1]; }
4046 else { stringData = options.data; }
4048 // Should be key=value object
4049 stringData = Utils.serializeObject(options.data);
4051 if (stringData.length) {
4052 options.url += paramsPrefix + stringData;
4053 if (paramsPrefix === '?') { paramsPrefix = '&'; }
4058 if (options.dataType === 'json
' && options.url.indexOf('callback
=') >= 0) {
4059 var callbackName = "f7jsonp_" + (Date.now() + ((jsonpRequests += 1)));
4061 var callbackSplit = options.url.split('callback
=');
4062 var requestUrl = (callbackSplit[0]) + "callback=" + callbackName;
4063 if (callbackSplit[1].indexOf('&') >= 0) {
4064 var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');
4065 if (addVars.length > 0) { requestUrl += "&" + addVars; }
4069 var script = doc.createElement('script
');
4070 script.type = 'text
/javascript
';
4071 script.onerror = function onerror() {
4072 clearTimeout(abortTimeout);
4073 fireCallback('error
', null, 'scripterror
');
4074 fireCallback('complete
', null, 'scripterror
');
4076 script.src = requestUrl;
4079 win[callbackName] = function jsonpCallback(data) {
4080 clearTimeout(abortTimeout);
4081 fireCallback('success
', data);
4082 script.parentNode.removeChild(script);
4084 delete win[callbackName];
4086 doc.querySelector('head
').appendChild(script);
4088 if (options.timeout > 0) {
4089 abortTimeout = setTimeout(function () {
4090 script.parentNode.removeChild(script);
4092 fireCallback('error
', null, 'timeout
');
4093 }, options.timeout);
4099 // Cache for GET/HEAD requests
4100 if (method === 'GET
' || method === 'HEAD
' || method === 'OPTIONS
' || method === 'DELETE
') {
4101 if (options.cache === false) {
4102 options.url += paramsPrefix + "_nocache" + (Date.now());
4107 var xhr = new XMLHttpRequest();
4110 xhr.requestUrl = options.url;
4111 xhr.requestParameters = options;
4113 // Before open callback
4114 proceedRequest = fireCallback('beforeOpen
', xhr, options);
4115 if (proceedRequest === false) { return xhr; }
4118 xhr.open(method, options.url, options.async, options.user, options.password);
4121 var postData = null;
4123 if ((method === 'POST
' || method === 'PUT
' || method === 'PATCH
') && options.data) {
4124 if (options.processData) {
4125 var postDataInstances = [ArrayBuffer, Blob, Document, FormData];
4127 if (postDataInstances.indexOf(options.data.constructor) >= 0) {
4128 postData = options.data;
4131 var boundary = "---------------------------" + (Date.now().toString(16));
4133 if (options.contentType === 'multipart
/form
-data
') {
4134 xhr.setRequestHeader('Content
-Type
', ("multipart/form-data; boundary=" + boundary));
4136 xhr.setRequestHeader('Content
-Type
', options.contentType);
4139 var data$1 = Utils.serializeObject(options.data);
4140 if (options.contentType === 'multipart
/form
-data
') {
4141 data$1 = data$1.split('&');
4143 for (var i = 0; i < data$1.length; i += 1) {
4144 newData.push(("Content-Disposition: form-data; name=\"" + (data$1[i].split('=')[0]) + "\"\r\n\r\n" + (data$1[i].split('=')[1]) + "\r\n"));
4146 postData = "--" + boundary + "\r\n" + (newData.join(("--" + boundary + "\r\n"))) + "--" + boundary + "--\r\n";
4147 } else if (options.contentType === 'application
/json
') {
4148 postData = JSON.stringify(options.data);
4154 postData = options.data;
4155 xhr.setRequestHeader('Content
-Type
', options.contentType);
4158 if (options.dataType === 'json
' && (!options.headers || !options.headers.Accept)) {
4159 xhr.setRequestHeader('Accept
', 'application
/json
');
4162 // Additional headers
4163 if (options.headers) {
4164 Object.keys(options.headers).forEach(function (headerName) {
4165 xhr.setRequestHeader(headerName, options.headers[headerName]);
4169 // Check for crossDomain
4170 if (typeof options.crossDomain === 'undefined') {
4171 // eslint-disable-next-line
4172 options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== win.location.host;
4175 if (!options.crossDomain) {
4176 xhr.setRequestHeader('X
-Requested
-With
', 'XMLHttpRequest
');
4179 if (options.xhrFields) {
4180 Utils.extend(xhr, options.xhrFields);
4186 xhr.onload = function onload() {
4187 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4188 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
4190 if (options.dataType === 'json
') {
4193 responseData = JSON.parse(xhr.responseText);
4198 fireCallback('success
', responseData, xhr.status, xhr);
4200 fireCallback('error
', xhr, 'parseerror
');
4203 responseData = xhr.responseType === 'text
' || xhr.responseType === '' ? xhr.responseText : xhr.response;
4204 fireCallback('success
', responseData, xhr.status, xhr);
4207 fireCallback('error
', xhr, xhr.status);
4209 if (options.statusCode) {
4210 if (globals.statusCode && globals.statusCode[xhr.status]) { globals.statusCode[xhr.status](xhr); }
4211 if (options.statusCode[xhr.status]) { options.statusCode[xhr.status](xhr); }
4213 fireCallback('complete
', xhr, xhr.status);
4216 xhr.onerror = function onerror() {
4217 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4218 fireCallback('error
', xhr, xhr.status);
4219 fireCallback('complete
', xhr, 'error
');
4223 if (options.timeout > 0) {
4224 xhr.onabort = function onabort() {
4225 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4227 xhrTimeout = setTimeout(function () {
4229 fireCallback('error
', xhr, 'timeout
');
4230 fireCallback('complete
', xhr, 'timeout
');
4231 }, options.timeout);
4234 // Ajax start callback
4235 proceedRequest = fireCallback('beforeSend
', xhr, options);
4236 if (proceedRequest === false) { return xhr; }
4241 // Return XHR object
4244 function RequestShortcut(method) {
4245 var assign, assign$1;
4247 var args = [], len = arguments.length - 1;
4248 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
4252 var success = ref[2];
4254 var dataType = ref[4];
4255 if (typeof args[1] === 'function') {
4256 (assign = args, url = assign[0], success = assign[1], error = assign[2], dataType = assign[3]);
4258 (assign$1 = args, url = assign$1[0], data = assign$1[1], success = assign$1[2], error = assign$1[3], dataType = assign$1[4]);
4260 [success, error].forEach(function (callback) {
4261 if (typeof callback === 'string
') {
4262 dataType = callback;
4263 if (callback === success) { success = undefined; }
4264 else { error = undefined; }
4267 dataType = dataType || (method === 'json
' || method === 'postJSON
' ? 'json
' : undefined);
4268 var requestOptions = {
4270 method: method === 'post
' || method === 'postJSON
' ? 'POST
' : 'GET
',
4276 if (method === 'postJSON
') {
4277 Utils.extend(requestOptions, {
4278 contentType: 'application
/json
',
4281 data: typeof data === 'string
' ? data : JSON.stringify(data),
4284 return Request(requestOptions);
4286 function RequestShortcutPromise(method) {
4287 var args = [], len = arguments.length - 1;
4288 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
4292 var dataType = args[2];
4293 return new Promise(function (resolve, reject) {
4298 function (response) {
4301 function (xhr, status) {
4308 Object.assign(Request, {
4310 var args = [], len = arguments.length;
4311 while ( len-- ) args[ len ] = arguments[ len ];
4313 return RequestShortcut.apply(void 0, [ 'get' ].concat( args ));
4316 var args = [], len = arguments.length;
4317 while ( len-- ) args[ len ] = arguments[ len ];
4319 return RequestShortcut.apply(void 0, [ 'post
' ].concat( args ));
4322 var args = [], len = arguments.length;
4323 while ( len-- ) args[ len ] = arguments[ len ];
4325 return RequestShortcut.apply(void 0, [ 'json
' ].concat( args ));
4327 getJSON: function () {
4328 var args = [], len = arguments.length;
4329 while ( len-- ) args[ len ] = arguments[ len ];
4331 return RequestShortcut.apply(void 0, [ 'json
' ].concat( args ));
4333 postJSON: function () {
4334 var args = [], len = arguments.length;
4335 while ( len-- ) args[ len ] = arguments[ len ];
4337 return RequestShortcut.apply(void 0, [ 'postJSON
' ].concat( args ));
4341 Request.promise = function requestPromise(requestOptions) {
4342 return new Promise(function (resolve, reject) {
4343 Request(Object.assign(requestOptions, {
4344 success: function success(data) {
4347 error: function error(xhr, status) {
4353 Object.assign(Request.promise, {
4355 var args = [], len = arguments.length;
4356 while ( len-- ) args[ len ] = arguments[ len ];
4358 return RequestShortcutPromise.apply(void 0, [ 'get' ].concat( args ));
4361 var args = [], len = arguments.length;
4362 while ( len-- ) args[ len ] = arguments[ len ];
4364 return RequestShortcutPromise.apply(void 0, [ 'post
' ].concat( args ));
4367 var args = [], len = arguments.length;
4368 while ( len-- ) args[ len ] = arguments[ len ];
4370 return RequestShortcutPromise.apply(void 0, [ 'json
' ].concat( args ));
4372 getJSON: function () {
4373 var args = [], len = arguments.length;
4374 while ( len-- ) args[ len ] = arguments[ len ];
4376 return RequestShortcutPromise.apply(void 0, [ 'json
' ].concat( args ));
4378 postJSON: function () {
4379 var args = [], len = arguments.length;
4380 while ( len-- ) args[ len ] = arguments[ len ];
4382 return RequestShortcutPromise.apply(void 0, [ 'postJSON
' ].concat( args ));
4386 Request.setup = function setup(options) {
4387 if (options.type && !options.method) {
4388 Utils.extend(options, { method: options.type });
4390 Utils.extend(globals, options);
4393 /* eslint no-param-reassign: "off" */
4395 var RequestModule = {
4405 function initTouch() {
4407 var params = app.params.touch;
4408 var useRipple = params[((app.theme) + "TouchRipple")];
4410 if (Device.ios && Device.webView) {
4411 // Strange hack required for iOS 8 webview to work on inputs
4412 win.addEventListener('touchstart
', function () {});
4420 var activeSelection;
4428 var activableElement;
4432 var needsFastClickTimeOut;
4438 function findActivableElement(el) {
4440 var parents = target.parents(params.activeStateElements);
4442 if (target.is(params.activeStateElements)) {
4445 if (parents.length > 0) {
4446 activable = activable ? activable.add(parents) : parents;
4448 if (activable && activable.length > 1) {
4449 var newActivable = [];
4450 var preventPropagation;
4451 for (var i = 0; i < activable.length; i += 1) {
4452 if (!preventPropagation) {
4453 newActivable.push(activable[i]);
4454 if (activable.eq(i).hasClass('prevent
-active
-state
-propagation
')
4455 || activable.eq(i).hasClass('no
-active
-state
-propagation
')
4457 preventPropagation = true;
4461 activable = $(newActivable);
4463 return activable || target;
4466 function isInsideScrollableViewLight(el) {
4467 var pageContent = el.parents('.page
-content
');
4468 return pageContent.length > 0;
4470 function isInsideScrollableView(el) {
4471 var pageContent = el.parents('.page
-content
');
4473 if (pageContent.length === 0) {
4477 // This event handler covers the "tap to stop scrolling".
4478 if (pageContent.prop('scrollHandlerSet
') !== 'yes
') {
4479 pageContent.on('scroll
', function () {
4480 clearTimeout(activeTimeout);
4481 clearTimeout(rippleTimeout);
4483 pageContent.prop('scrollHandlerSet
', 'yes
');
4488 function addActive() {
4489 if (!activableElement) { return; }
4490 activableElement.addClass('active
-state
');
4492 function removeActive() {
4493 if (!activableElement) { return; }
4494 activableElement.removeClass('active
-state
');
4495 activableElement = null;
4497 function isFormElement(el) {
4498 var nodes = ('input select textarea label
').split(' ');
4499 if (el.nodeName && nodes.indexOf(el.nodeName.toLowerCase()) >= 0) { return true; }
4502 function androidNeedsBlur(el) {
4503 var noBlur = ('button input textarea select
').split(' ');
4504 if (doc.activeElement && el !== doc.activeElement && doc.activeElement !== doc.body) {
4505 if (noBlur.indexOf(el.nodeName.toLowerCase()) >= 0) {
4512 function targetNeedsFastClick(el) {
4518 Device.osVersion.split('.')[0] > 9
4520 (Device.osVersion.split('.')[0] * 1 === 9 && Device.osVersion.split('.')[1] >= 1)
4527 if (el.nodeName.toLowerCase() === 'input
' && (el.type === 'file
' || el.type === 'range
')) { return false; }
4528 if (el.nodeName.toLowerCase() === 'select
' && Device.android) { return false; }
4529 if ($el.hasClass('no
-fastclick
') || $el.parents('.no
-fastclick
').length > 0) { return false; }
4530 if (params.fastClicksExclude && $el.closest(params.fastClicksExclude).length > 0) { return false; }
4534 function targetNeedsFocus(el) {
4535 if (doc.activeElement === el) {
4538 var tag = el.nodeName.toLowerCase();
4539 var skipInputs = ('button checkbox file image radio submit
').split(' ');
4540 if (el.disabled || el.readOnly) { return false; }
4541 if (tag === 'textarea
') { return true; }
4542 if (tag === 'select
') {
4543 if (Device.android) { return false; }
4546 if (tag === 'input
' && skipInputs.indexOf(el.type) < 0) { return true; }
4549 function targetNeedsPrevent(el) {
4552 if ($el.is('label
') || $el.parents('label
').length > 0) {
4553 if (Device.android) {
4555 } else if (Device.ios && $el.is('input
')) {
4557 } else { prevent = false; }
4563 function findRippleElement(el) {
4564 var rippleElements = params.touchRippleElements;
4566 if ($el.is(rippleElements)) {
4567 if ($el.hasClass('no
-ripple
')) {
4572 if ($el.parents(rippleElements).length > 0) {
4573 var rippleParent = $el.parents(rippleElements).eq(0);
4574 if (rippleParent.hasClass('no
-ripple
')) {
4577 return rippleParent;
4581 function createRipple($el, x, y) {
4582 if (!$el) { return; }
4583 rippleWave = app.touchRipple.create($el, x, y);
4586 function removeRipple() {
4587 if (!rippleWave) { return; }
4588 rippleWave.remove();
4589 rippleWave = undefined;
4590 rippleTarget = undefined;
4592 function rippleTouchStart(el) {
4593 rippleTarget = findRippleElement(el);
4594 if (!rippleTarget || rippleTarget.length === 0) {
4595 rippleTarget = undefined;
4598 var inScrollable = params.fastClicks
4599 ? isInsideScrollableView(rippleTarget)
4600 : isInsideScrollableViewLight(rippleTarget);
4602 if (!inScrollable) {
4604 createRipple(rippleTarget, touchStartX, touchStartY);
4606 clearTimeout(rippleTimeout);
4607 rippleTimeout = setTimeout(function () {
4609 createRipple(rippleTarget, touchStartX, touchStartY);
4613 function rippleTouchMove() {
4614 clearTimeout(rippleTimeout);
4617 function rippleTouchEnd() {
4618 if (!rippleWave && rippleTarget && !isMoved) {
4619 clearTimeout(rippleTimeout);
4620 createRipple(rippleTarget, touchStartX, touchStartY);
4621 setTimeout(removeRipple, 0);
4628 function handleMouseDown(e) {
4629 findActivableElement(e.target).addClass('active
-state
');
4630 if ('which
' in e && e.which === 3) {
4631 setTimeout(function () {
4632 $('.active
-state
').removeClass('active
-state
');
4636 touchStartX = e.pageX;
4637 touchStartY = e.pageY;
4638 rippleTouchStart(e.target, e.pageX, e.pageY);
4641 function handleMouseMove() {
4642 $('.active
-state
').removeClass('active
-state
');
4647 function handleMouseUp() {
4648 $('.active
-state
').removeClass('active
-state
');
4655 function sendClick(e) {
4656 var touch = e.changedTouches[0];
4657 var evt = doc.createEvent('MouseEvents
');
4658 var eventType = 'click
';
4659 if (Device.android && targetElement.nodeName.toLowerCase() === 'select
') {
4660 eventType = 'mousedown
';
4662 evt.initMouseEvent(eventType, true, true, win, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
4663 evt.forwardedTouchEvent = true;
4665 if (app.device.ios && win.navigator.standalone) {
4666 // Fix the issue happens in iOS home screen apps where the wrong element is selected during a momentum scroll.
4667 // Upon tapping, we give the scrolling time to stop, then we grab the element based where the user tapped.
4668 setTimeout(function () {
4669 targetElement = doc.elementFromPoint(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
4670 if (targetElement) {
4671 targetElement.dispatchEvent(evt);
4675 targetElement.dispatchEvent(evt);
4680 function handleTouchStart(e) {
4684 tapHoldFired = false;
4685 if (e.targetTouches.length > 1) {
4686 if (activableElement) { removeActive(); }
4689 if (e.touches.length > 1 && activableElement) {
4692 if (params.tapHold) {
4693 if (tapHoldTimeout) { clearTimeout(tapHoldTimeout); }
4694 tapHoldTimeout = setTimeout(function () {
4695 if (e && e.touches && e.touches.length > 1) { return; }
4696 tapHoldFired = true;
4698 $(e.target).trigger('taphold
');
4699 }, params.tapHoldDelay);
4701 if (needsFastClickTimeOut) { clearTimeout(needsFastClickTimeOut); }
4702 needsFastClick = targetNeedsFastClick(e.target);
4704 if (!needsFastClick) {
4708 if (Device.ios || (Device.android && 'getSelection
' in win)) {
4709 var selection = win.getSelection();
4711 selection.rangeCount
4712 && selection.focusNode !== doc.body
4713 && (!selection.isCollapsed || doc.activeElement === selection.focusNode)
4715 activeSelection = true;
4719 activeSelection = false;
4721 if (Device.android) {
4722 if (androidNeedsBlur(e.target)) {
4723 doc.activeElement.blur();
4728 targetElement = e.target;
4729 touchStartTime = (new Date()).getTime();
4730 touchStartX = e.targetTouches[0].pageX;
4731 touchStartY = e.targetTouches[0].pageY;
4733 // Detect scroll parent
4735 scrollParent = undefined;
4736 $(targetElement).parents().each(function () {
4737 var parent = this$1;
4738 if (parent.scrollHeight > parent.offsetHeight && !scrollParent) {
4739 scrollParent = parent;
4740 scrollParent.f7ScrollTop = scrollParent.scrollTop;
4744 if ((touchStartTime - lastClickTime) < params.fastClicksDelayBetweenClicks) {
4748 if (params.activeState) {
4749 activableElement = findActivableElement(targetElement);
4750 activeTimeout = setTimeout(addActive, 0);
4753 rippleTouchStart(targetElement);
4757 function handleTouchMove(e) {
4758 if (!trackClick) { return; }
4759 var distance = params.fastClicksDistanceThreshold;
4761 var pageX = e.targetTouches[0].pageX;
4762 var pageY = e.targetTouches[0].pageY;
4763 if (Math.abs(pageX - touchStartX) > distance || Math.abs(pageY - touchStartY) > distance) {
4771 targetElement = null;
4773 if (params.tapHold) {
4774 clearTimeout(tapHoldTimeout);
4776 if (params.activeState) {
4777 clearTimeout(activeTimeout);
4785 function handleTouchEnd(e) {
4786 clearTimeout(activeTimeout);
4787 clearTimeout(tapHoldTimeout);
4789 var touchEndTime = (new Date()).getTime();
4792 if (!activeSelection && needsFastClick) {
4793 if (!(Device.android && !e.cancelable) && e.cancelable) {
4797 if (params.activeState) { removeActive(); }
4804 if (doc.activeElement === e.target) {
4805 if (params.activeState) { removeActive(); }
4812 if (!activeSelection) {
4816 if ((touchEndTime - lastClickTime) < params.fastClicksDelayBetweenClicks) {
4817 setTimeout(removeActive, 0);
4824 lastClickTime = touchEndTime;
4828 if (Device.ios && scrollParent) {
4829 if (scrollParent.scrollTop !== scrollParent.f7ScrollTop) {
4834 // Add active-state here because, in a very fast tap, the timeout didn't
4835 // have the chance to execute. Removing active-state in a timeout gives
4836 // the chance to the animation execute.
4837 if (params
.activeState
) {
4839 setTimeout(removeActive
, 0);
4846 // Trigger focus when required
4847 if (targetNeedsFocus(targetElement
)) {
4848 if (Device
.ios
&& Device
.webView
) {
4849 targetElement
.focus();
4853 targetElement
.focus();
4856 // Blur active elements
4857 if (doc
.activeElement
&& targetElement
!== doc
.activeElement
&& doc
.activeElement
!== doc
.body
&& targetElement
.nodeName
.toLowerCase() !== 'label') {
4858 doc
.activeElement
.blur();
4863 if (params
.tapHoldPreventClicks
&& tapHoldFired
) {
4869 function handleTouchCancel() {
4871 targetElement
= null;
4873 // Remove Active State
4874 clearTimeout(activeTimeout
);
4875 clearTimeout(tapHoldTimeout
);
4876 if (params
.activeState
) {
4886 function handleClick(e
) {
4887 var allowClick
= false;
4889 targetElement
= null;
4893 if ((e
.target
.type
=== 'submit' && e
.detail
=== 0) || e
.target
.type
=== 'file') {
4896 if (!targetElement
) {
4897 if (!isFormElement(e
.target
)) {
4901 if (!needsFastClick
) {
4904 if (doc
.activeElement
=== targetElement
) {
4907 if (e
.forwardedTouchEvent
) {
4910 if (!e
.cancelable
) {
4913 if (params
.tapHold
&& params
.tapHoldPreventClicks
&& tapHoldFired
) {
4917 e
.stopImmediatePropagation();
4918 e
.stopPropagation();
4919 if (targetElement
) {
4920 if (targetNeedsPrevent(targetElement
) || isMoved
) {
4926 targetElement
= null;
4928 needsFastClickTimeOut
= setTimeout(function () {
4929 needsFastClick
= false;
4930 }, (Device
.ios
|| Device
.androidChrome
? 100 : 400));
4932 if (params
.tapHold
) {
4933 tapHoldTimeout
= setTimeout(function () {
4934 tapHoldFired
= false;
4935 }, (Device
.ios
|| Device
.androidChrome
? 100 : 400));
4941 function handleTouchStartLight(e
) {
4943 tapHoldFired
= false;
4944 preventClick
= false;
4945 if (e
.targetTouches
.length
> 1) {
4946 if (activableElement
) { removeActive(); }
4949 if (e
.touches
.length
> 1 && activableElement
) {
4952 if (params
.tapHold
) {
4953 if (tapHoldTimeout
) { clearTimeout(tapHoldTimeout
); }
4954 tapHoldTimeout
= setTimeout(function () {
4955 if (e
&& e
.touches
&& e
.touches
.length
> 1) { return; }
4956 tapHoldFired
= true;
4958 preventClick
= true;
4959 $(e
.target
).trigger('taphold');
4960 }, params
.tapHoldDelay
);
4962 targetElement
= e
.target
;
4963 touchStartX
= e
.targetTouches
[0].pageX
;
4964 touchStartY
= e
.targetTouches
[0].pageY
;
4966 if (params
.activeState
) {
4967 activableElement
= findActivableElement(targetElement
);
4968 if (!isInsideScrollableViewLight(activableElement
)) {
4971 activeTimeout
= setTimeout(addActive
, 80);
4975 rippleTouchStart(targetElement
);
4979 function handleTouchMoveLight(e
) {
4982 if (e
.type
=== 'touchmove') {
4983 touch
= e
.targetTouches
[0];
4984 distance
= params
.touchClicksDistanceThreshold
;
4985 // if (touch && touch.touchType === 'stylus') {
4992 if (distance
&& touch
) {
4993 var pageX
= touch
.pageX
;
4994 var pageY
= touch
.pageY
;
4995 if (Math
.abs(pageX
- touchStartX
) > distance
|| Math
.abs(pageY
- touchStartY
) > distance
) {
5002 preventClick
= true;
5003 if (params
.tapHold
) {
5004 clearTimeout(tapHoldTimeout
);
5006 if (params
.activeState
) {
5007 clearTimeout(activeTimeout
);
5015 function handleTouchEndLight(e
) {
5016 clearTimeout(activeTimeout
);
5017 clearTimeout(tapHoldTimeout
);
5018 if (doc
.activeElement
=== e
.target
) {
5019 if (params
.activeState
) { removeActive(); }
5025 if (params
.activeState
) {
5027 setTimeout(removeActive
, 0);
5032 if ((params
.tapHoldPreventClicks
&& tapHoldFired
) || preventClick
) {
5033 if (e
.cancelable
) { e
.preventDefault(); }
5034 preventClick
= true;
5039 function handleClickLight(e
) {
5040 var localPreventClick
= preventClick
;
5041 if (targetElement
&& e
.target
!== targetElement
) {
5042 localPreventClick
= true;
5044 if (params
.tapHold
&& params
.tapHoldPreventClicks
&& tapHoldFired
) {
5045 localPreventClick
= true;
5047 if (localPreventClick
) {
5048 e
.stopImmediatePropagation();
5049 e
.stopPropagation();
5053 if (params
.tapHold
) {
5054 tapHoldTimeout
= setTimeout(
5056 tapHoldFired
= false;
5058 (Device
.ios
|| Device
.androidChrome
? 100 : 400)
5061 preventClick
= false;
5062 targetElement
= null;
5064 return !localPreventClick
;
5067 function emitAppTouchEvent(name
, e
) {
5073 function appClick(e
) {
5074 emitAppTouchEvent('click', e
);
5076 function appTouchStartActive(e
) {
5077 emitAppTouchEvent('touchstart touchstart:active', e
);
5079 function appTouchMoveActive(e
) {
5080 emitAppTouchEvent('touchmove touchmove:active', e
);
5082 function appTouchEndActive(e
) {
5083 emitAppTouchEvent('touchend touchend:active', e
);
5085 function appTouchStartPassive(e
) {
5086 emitAppTouchEvent('touchstart:passive', e
);
5088 function appTouchMovePassive(e
) {
5089 emitAppTouchEvent('touchmove:passive', e
);
5091 function appTouchEndPassive(e
) {
5092 emitAppTouchEvent('touchend:passive', e
);
5095 var passiveListener
= Support
.passiveListener
? { passive
: true } : false;
5096 var activeListener
= Support
.passiveListener
? { passive
: false } : false;
5098 doc
.addEventListener('click', appClick
, true);
5100 if (Support
.passiveListener
) {
5101 doc
.addEventListener(app
.touchEvents
.start
, appTouchStartActive
, activeListener
);
5102 doc
.addEventListener(app
.touchEvents
.move, appTouchMoveActive
, activeListener
);
5103 doc
.addEventListener(app
.touchEvents
.end
, appTouchEndActive
, activeListener
);
5105 doc
.addEventListener(app
.touchEvents
.start
, appTouchStartPassive
, passiveListener
);
5106 doc
.addEventListener(app
.touchEvents
.move, appTouchMovePassive
, passiveListener
);
5107 doc
.addEventListener(app
.touchEvents
.end
, appTouchEndPassive
, passiveListener
);
5109 doc
.addEventListener(app
.touchEvents
.start
, function (e
) {
5110 appTouchStartActive(e
);
5111 appTouchStartPassive(e
);
5113 doc
.addEventListener(app
.touchEvents
.move, function (e
) {
5114 appTouchMoveActive(e
);
5115 appTouchMovePassive(e
);
5117 doc
.addEventListener(app
.touchEvents
.end
, function (e
) {
5118 appTouchEndActive(e
);
5119 appTouchEndPassive(e
);
5123 if (Support
.touch
) {
5124 if (params
.fastClicks
) {
5125 app
.on('click', handleClick
);
5126 app
.on('touchstart', handleTouchStart
);
5127 app
.on('touchmove', handleTouchMove
);
5128 app
.on('touchend', handleTouchEnd
);
5130 app
.on('click', handleClickLight
);
5131 app
.on('touchstart', handleTouchStartLight
);
5132 app
.on('touchmove', handleTouchMoveLight
);
5133 app
.on('touchend', handleTouchEndLight
);
5136 doc
.addEventListener('touchcancel', handleTouchCancel
, { passive
: true });
5137 } else if (params
.activeState
) {
5138 app
.on('touchstart', handleMouseDown
);
5139 app
.on('touchmove', handleMouseMove
);
5140 app
.on('touchend', handleMouseUp
);
5142 doc
.addEventListener('contextmenu', function (e
) {
5143 if (params
.disableContextMenu
&& (Device
.ios
|| Device
.android
|| Device
.cordova
)) {
5147 if (activableElement
) { removeActive(); }
5159 fastClicksDistanceThreshold
: 10,
5160 fastClicksDelayBetweenClicks
: 50,
5161 fastClicksExclude
: '', // CSS selector
5163 touchClicksDistanceThreshold
: 5,
5165 disableContextMenu
: false,
5169 tapHoldPreventClicks
: true,
5172 activeStateElements
: 'a, button, label, span, .actions-button, .stepper-button, .stepper-button-plus, .stepper-button-minus, .card-expandable, .menu-item, .link, .item-link',
5173 mdTouchRipple
: true,
5174 iosTouchRipple
: false,
5175 auroraTouchRipple
: false,
5176 touchRippleElements
: '.ripple, .link, .item-link, .list-button, .links-list a, .button, button, .input-clear-button, .dialog-button, .tab-link, .item-radio, .item-checkbox, .actions-button, .searchbar-disable-button, .fab a, .checkbox, .radio, .data-table .sortable-cell:not(.input-cell), .notification-close-button, .stepper-button, .stepper-button-minus, .stepper-button-plus, .menu-item-content',
5181 start
: Support
.touch
? 'touchstart' : 'mousedown',
5182 move: Support
.touch
? 'touchmove' : 'mousemove',
5183 end
: Support
.touch
? 'touchend' : 'mouseup',
5192 * Expose `pathToRegexp`.
5194 var pathToRegexp_1
= pathToRegexp
;
5195 var parse_1
= parse
;
5196 var compile_1
= compile
;
5197 var tokensToFunction_1
= tokensToFunction
;
5198 var tokensToRegExp_1
= tokensToRegExp
;
5203 var DEFAULT_DELIMITER
= '/';
5206 * The main path matching regexp utility.
5210 var PATH_REGEXP
= new RegExp([
5211 // Match escaped characters that would otherwise appear in future matches.
5212 // This allows the user to escape special characters that won't transform.
5214 // Match Express-style parameters and un-named parameters with a prefix
5215 // and optional suffixes. Matches appear as:
5217 // ":test(\\d+)?" => ["test", "\d+", undefined, "?"]
5218 // "(\\d+)" => [undefined, undefined, "\d+", undefined]
5219 '(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?'
5223 * Parse a string for the raw tokens.
5225 * @param {string} str
5226 * @param {Object=} options
5229 function parse (str
, options
) {
5234 var defaultDelimiter
= (options
&& options
.delimiter
) || DEFAULT_DELIMITER
;
5235 var whitelist
= (options
&& options
.whitelist
) || undefined;
5236 var pathEscaped
= false;
5239 while ((res
= PATH_REGEXP
.exec(str
)) !== null) {
5241 var escaped
= res
[1];
5242 var offset
= res
.index
;
5243 path
+= str
.slice(index
, offset
);
5244 index
= offset
+ m
.length
;
5246 // Ignore already escaped sequences.
5255 var capture
= res
[3];
5257 var modifier
= res
[5];
5259 if (!pathEscaped
&& path
.length
) {
5260 var k
= path
.length
- 1;
5262 var matches
= whitelist
? whitelist
.indexOf(c
) > -1 : true;
5266 path
= path
.slice(0, k
);
5270 // Push the current path onto the tokens.
5274 pathEscaped
= false;
5277 var repeat
= modifier
=== '+' || modifier
=== '*';
5278 var optional
= modifier
=== '?' || modifier
=== '*';
5279 var pattern
= capture
|| group
;
5280 var delimiter
= prev
|| defaultDelimiter
;
5283 name
: name
|| key
++,
5285 delimiter
: delimiter
,
5289 ? escapeGroup(pattern
)
5290 : '[^' + escapeString(delimiter
=== defaultDelimiter
? delimiter
: (delimiter
+ defaultDelimiter
)) + ']+?'
5294 // Push any remaining characters.
5295 if (path
|| index
< str
.length
) {
5296 tokens
.push(path
+ str
.substr(index
));
5303 * Compile a string to a template function for the path.
5305 * @param {string} str
5306 * @param {Object=} options
5307 * @return {!function(Object=, Object=)}
5309 function compile (str
, options
) {
5310 return tokensToFunction(parse(str
, options
))
5314 * Expose a method for transforming tokens into the path function.
5316 function tokensToFunction (tokens
) {
5317 // Compile all the tokens into regexps.
5318 var matches
= new Array(tokens
.length
);
5320 // Compile all the patterns before compilation.
5321 for (var i
= 0; i
< tokens
.length
; i
++) {
5322 if (typeof tokens
[i
] === 'object') {
5323 matches
[i
] = new RegExp('^(?:' + tokens
[i
].pattern
+ ')$');
5327 return function (data
, options
) {
5329 var encode
= (options
&& options
.encode
) || encodeURIComponent
;
5331 for (var i
= 0; i
< tokens
.length
; i
++) {
5332 var token
= tokens
[i
];
5334 if (typeof token
=== 'string') {
5339 var value
= data
? data
[token
.name
] : undefined;
5342 if (Array
.isArray(value
)) {
5343 if (!token
.repeat
) {
5344 throw new TypeError('Expected "' + token
.name
+ '" to not repeat, but got array')
5347 if (value
.length
=== 0) {
5348 if (token
.optional
) { continue }
5350 throw new TypeError('Expected "' + token
.name
+ '" to not be empty')
5353 for (var j
= 0; j
< value
.length
; j
++) {
5354 segment
= encode(value
[j
], token
);
5356 if (!matches
[i
].test(segment
)) {
5357 throw new TypeError('Expected all "' + token
.name
+ '" to match "' + token
.pattern
+ '"')
5360 path
+= (j
=== 0 ? token
.prefix
: token
.delimiter
) + segment
;
5366 if (typeof value
=== 'string' || typeof value
=== 'number' || typeof value
=== 'boolean') {
5367 segment
= encode(String(value
), token
);
5369 if (!matches
[i
].test(segment
)) {
5370 throw new TypeError('Expected "' + token
.name
+ '" to match "' + token
.pattern
+ '", but got "' + segment
+ '"')
5373 path
+= token
.prefix
+ segment
;
5377 if (token
.optional
) { continue }
5379 throw new TypeError('Expected "' + token
.name
+ '" to be ' + (token
.repeat
? 'an array' : 'a string'))
5387 * Escape a regular expression string.
5389 * @param {string} str
5392 function escapeString (str
) {
5393 return str
.replace(/([.+*?=^!:${}()[\]|/\\])/g
, '\\$1')
5397 * Escape the capturing group by escaping special characters and meaning.
5399 * @param {string} group
5402 function escapeGroup (group
) {
5403 return group
.replace(/([=!:$/()])/g
, '\\$1')
5407 * Get the flags for a regexp from the options.
5409 * @param {Object} options
5412 function flags (options
) {
5413 return options
&& options
.sensitive
? '' : 'i'
5417 * Pull out keys from a regexp.
5419 * @param {!RegExp} path
5420 * @param {Array=} keys
5423 function regexpToRegexp (path
, keys
) {
5424 if (!keys
) { return path
}
5426 // Use a negative lookahead to match only capturing groups.
5427 var groups
= path
.source
.match(/\((?!\?)/g);
5430 for (var i
= 0; i
< groups
.length
; i
++) {
5446 * Transform an array into a regexp.
5448 * @param {!Array} path
5449 * @param {Array=} keys
5450 * @param {Object=} options
5453 function arrayToRegexp (path
, keys
, options
) {
5456 for (var i
= 0; i
< path
.length
; i
++) {
5457 parts
.push(pathToRegexp(path
[i
], keys
, options
).source
);
5460 return new RegExp('(?:' + parts
.join('|') + ')', flags(options
))
5464 * Create a path regexp from string input.
5466 * @param {string} path
5467 * @param {Array=} keys
5468 * @param {Object=} options
5471 function stringToRegexp (path
, keys
, options
) {
5472 return tokensToRegExp(parse(path
, options
), keys
, options
)
5476 * Expose a function for taking tokens and returning a RegExp.
5478 * @param {!Array} tokens
5479 * @param {Array=} keys
5480 * @param {Object=} options
5483 function tokensToRegExp (tokens
, keys
, options
) {
5484 options
= options
|| {};
5486 var strict
= options
.strict
;
5487 var start
= options
.start
!== false;
5488 var end
= options
.end
!== false;
5489 var delimiter
= options
.delimiter
|| DEFAULT_DELIMITER
;
5490 var endsWith
= [].concat(options
.endsWith
|| []).map(escapeString
).concat('$').join('|');
5491 var route
= start
? '^' : '';
5493 // Iterate over the tokens and create our regexp string.
5494 for (var i
= 0; i
< tokens
.length
; i
++) {
5495 var token
= tokens
[i
];
5497 if (typeof token
=== 'string') {
5498 route
+= escapeString(token
);
5500 var capture
= token
.repeat
5501 ? '(?:' + token
.pattern
+ ')(?:' + escapeString(token
.delimiter
) + '(?:' + token
.pattern
+ '))*'
5504 if (keys
) { keys
.push(token
); }
5506 if (token
.optional
) {
5507 if (!token
.prefix
) {
5508 route
+= '(' + capture
+ ')?';
5510 route
+= '(?:' + escapeString(token
.prefix
) + '(' + capture
+ '))?';
5513 route
+= escapeString(token
.prefix
) + '(' + capture
+ ')';
5519 if (!strict
) { route
+= '(?:' + escapeString(delimiter
) + ')?'; }
5521 route
+= endsWith
=== '$' ? '$' : '(?=' + endsWith
+ ')';
5523 var endToken
= tokens
[tokens
.length
- 1];
5524 var isEndDelimited
= typeof endToken
=== 'string'
5525 ? endToken
[endToken
.length
- 1] === delimiter
5526 : endToken
=== undefined;
5528 if (!strict
) { route
+= '(?:' + escapeString(delimiter
) + '(?=' + endsWith
+ '))?'; }
5529 if (!isEndDelimited
) { route
+= '(?=' + escapeString(delimiter
) + '|' + endsWith
+ ')'; }
5532 return new RegExp(route
, flags(options
))
5536 * Normalize the given path string, returning a regular expression.
5538 * An empty array can be passed in for the keys, which will hold the
5539 * placeholder key descriptions. For example, using `/user/:id`, `keys` will
5540 * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
5542 * @param {(string|RegExp|Array)} path
5543 * @param {Array=} keys
5544 * @param {Object=} options
5547 function pathToRegexp (path
, keys
, options
) {
5548 if (path
instanceof RegExp
) {
5549 return regexpToRegexp(path
, keys
)
5552 if (Array
.isArray(path
)) {
5553 return arrayToRegexp(/** @type {!Array} */ (path
), keys
, options
)
5556 return stringToRegexp(/** @type {string} */ (path
), keys
, options
)
5558 pathToRegexp_1
.parse
= parse_1
;
5559 pathToRegexp_1
.compile
= compile_1
;
5560 pathToRegexp_1
.tokensToFunction
= tokensToFunction_1
;
5561 pathToRegexp_1
.tokensToRegExp
= tokensToRegExp_1
;
5565 clearQueue
: function clearQueue() {
5566 if (History
.queue
.length
=== 0) { return; }
5567 var currentQueue
= History
.queue
.shift();
5571 clearRouterQueue
: function clearRouterQueue() {
5572 if (History
.routerQueue
.length
=== 0) { return; }
5573 var currentQueue
= History
.routerQueue
.pop();
5574 var router
= currentQueue
.router
;
5575 var stateUrl
= currentQueue
.stateUrl
;
5576 var action
= currentQueue
.action
;
5578 var animate
= router
.params
.animate
;
5579 if (router
.params
.pushStateAnimate
=== false) { animate
= false; }
5581 if (action
=== 'back') {
5582 router
.back({ animate
: animate
, pushState
: false });
5584 if (action
=== 'load') {
5585 router
.navigate(stateUrl
, { animate
: animate
, pushState
: false });
5588 handle
: function handle(e
) {
5589 if (History
.blockPopstate
) { return; }
5591 // const mainView = app.views.main;
5592 var state
= e
.state
;
5593 History
.previousState
= History
.state
;
5594 History
.state
= state
;
5596 History
.allowChange
= true;
5597 History
.clearQueue();
5599 state
= History
.state
;
5600 if (!state
) { state
= {}; }
5602 app
.views
.forEach(function (view
) {
5603 var router
= view
.router
;
5604 var viewState
= state
[view
.id
];
5605 if (!viewState
&& view
.params
.pushState
) {
5607 url
: view
.router
.history
[0],
5610 if (!viewState
) { return; }
5611 var stateUrl
= viewState
.url
|| undefined;
5613 var animate
= router
.params
.animate
;
5614 if (router
.params
.pushStateAnimate
=== false) { animate
= false; }
5616 if (stateUrl
!== router
.url
) {
5617 if (router
.history
.indexOf(stateUrl
) >= 0) {
5619 if (router
.allowPageChange
) {
5620 router
.back({ animate
: animate
, pushState
: false });
5622 History
.routerQueue
.push({
5627 } else if (router
.allowPageChange
) {
5629 router
.navigate(stateUrl
, { animate
: animate
, pushState
: false });
5631 History
.routerQueue
.unshift({
5640 initViewState
: function initViewState(viewId
, viewState
) {
5643 var newState
= Utils
.extend({}, (History
.state
|| {}), ( obj
= {}, obj
[viewId
] = viewState
, obj
));
5644 History
.state
= newState
;
5645 win
.history
.replaceState(newState
, '');
5647 push
: function push(viewId
, viewState
, url
) {
5650 if (!History
.allowChange
) {
5651 History
.queue
.push(function () {
5652 History
.push(viewId
, viewState
, url
);
5656 History
.previousState
= History
.state
;
5657 var newState
= Utils
.extend({}, (History
.previousState
|| {}), ( obj
= {}, obj
[viewId
] = viewState
, obj
));
5658 History
.state
= newState
;
5659 win
.history
.pushState(newState
, '', url
);
5661 replace
: function replace(viewId
, viewState
, url
) {
5664 if (!History
.allowChange
) {
5665 History
.queue
.push(function () {
5666 History
.replace(viewId
, viewState
, url
);
5670 History
.previousState
= History
.state
;
5671 var newState
= Utils
.extend({}, (History
.previousState
|| {}), ( obj
= {}, obj
[viewId
] = viewState
, obj
));
5672 History
.state
= newState
;
5673 win
.history
.replaceState(newState
, '', url
);
5675 go
: function go(index
) {
5676 History
.allowChange
= false;
5677 win
.history
.go(index
);
5679 back
: function back() {
5680 History
.allowChange
= false;
5685 state
: win
.history
.state
,
5686 blockPopstate
: true,
5687 init
: function init(app
) {
5688 $(win
).on('load', function () {
5689 setTimeout(function () {
5690 History
.blockPopstate
= false;
5694 if (doc
.readyState
&& doc
.readyState
=== 'complete') {
5695 History
.blockPopstate
= false;
5698 $(win
).on('popstate', History
.handle
.bind(app
));
5702 function SwipeBack(r
) {
5704 var $el
= router
.$el
;
5705 var $navbarEl
= router
.$navbarEl
;
5706 var app
= router
.app
;
5707 var params
= router
.params
;
5708 var isTouched
= false;
5709 var isMoved
= false;
5710 var touchesStart
= {};
5712 var $currentPageEl
= [];
5713 var $previousPageEl
= [];
5714 var viewContainerWidth
;
5716 var allowViewTouchMove
= true;
5718 var $currentNavbarInnerEl
= [];
5719 var $previousNavbarInnerEl
= [];
5725 var animatableNavEls
;
5727 var paramsSwipeBackAnimateShadow
= params
[((app
.theme
) + "SwipeBackAnimateShadow")];
5728 var paramsSwipeBackAnimateOpacity
= params
[((app
.theme
) + "SwipeBackAnimateOpacity")];
5729 var paramsSwipeBackActiveArea
= params
[((app
.theme
) + "SwipeBackActiveArea")];
5730 var paramsSwipeBackThreshold
= params
[((app
.theme
) + "SwipeBackThreshold")];
5732 var transformOrigin
= app
.rtl
? 'right center' : 'left center';
5734 function animatableNavElements() {
5736 var inverter
= app
.rtl
? -1 : 1;
5737 var currentNavIsLarge
= $currentNavbarInnerEl
.hasClass('navbar-inner-large');
5738 var previousNavIsLarge
= $previousNavbarInnerEl
.hasClass('navbar-inner-large');
5739 var fromLarge
= currentNavIsLarge
&& !$currentNavbarInnerEl
.hasClass('navbar-inner-large-collapsed');
5740 var toLarge
= previousNavIsLarge
&& !$previousNavbarInnerEl
.hasClass('navbar-inner-large-collapsed');
5741 var $currentNavElements
= $currentNavbarInnerEl
.children('.left, .title, .right, .subnavbar, .fading, .title-large');
5742 var $previousNavElements
= $previousNavbarInnerEl
.children('.left, .title, .right, .subnavbar, .fading, .title-large');
5743 var activeNavBackIconText
;
5744 var previousNavBackIconText
;
5746 if (params
.iosAnimateNavbarBackIcon
) {
5747 if ($currentNavbarInnerEl
.hasClass('sliding')) {
5748 activeNavBackIconText
= $currentNavbarInnerEl
.children('.left').find('.back .icon + span').eq(0);
5750 activeNavBackIconText
= $currentNavbarInnerEl
.children('.left.sliding').find('.back .icon + span').eq(0);
5752 if ($previousNavbarInnerEl
.hasClass('sliding')) {
5753 previousNavBackIconText
= $previousNavbarInnerEl
.children('.left').find('.back .icon + span').eq(0);
5755 previousNavBackIconText
= $previousNavbarInnerEl
.children('.left.sliding').find('.back .icon + span').eq(0);
5757 if (activeNavBackIconText
.length
) {
5758 $previousNavElements
.each(function (index
, el
) {
5759 if (!$(el
).hasClass('title')) { return; }
5760 el
.f7NavbarLeftOffset
+= activeNavBackIconText
.prev('.icon')[0].offsetWidth
;
5765 .each(function (index
, navEl
) {
5766 var $navEl
= $(navEl
);
5767 var isSubnavbar
= $navEl
.hasClass('subnavbar');
5768 var isLeft
= $navEl
.hasClass('left');
5769 var isTitle
= $navEl
.hasClass('title');
5770 if (!fromLarge
&& $navEl
.hasClass('.title-large')) { return; }
5775 if (isTitle
) { return; }
5776 if ($navEl
.hasClass('title-large')) {
5777 if (!separateNavbar
) { return; }
5779 if (els
.indexOf(el
) < 0) { els
.push(el
); }
5780 el
.overflow
= 'visible';
5781 el
.transform
= 'translateX(100%)';
5782 $navEl
.find('.title-large-text, .title-large-inner').each(function (subIndex
, subNavEl
) {
5785 transform: function (progress
) { return ("translateX(" + (-100 + progress
* 100 * inverter
) + "%)"); },
5789 if (els
.indexOf(el
) < 0) { els
.push(el
); }
5790 el
.overflow
= 'hidden';
5791 el
.transform = function (progress
) { return ("translateY(calc(" + (-progress
) + " * var(--f7-navbar-large-title-height)))"); };
5792 $navEl
.find('.title-large-text, .title-large-inner').each(function (subIndex
, subNavEl
) {
5795 transform: function (progress
) { return ("translateX(" + (progress
* 100 * inverter
) + "%) translateY(calc(" + progress
+ " * var(--f7-navbar-large-title-height)))"); },
5804 if ($navEl
.hasClass('title-large')) {
5805 if (!separateNavbar
) { return; }
5806 if (els
.indexOf(el
) < 0) { els
.push(el
); }
5810 if (isLeft
&& separateNavbar
) {
5811 if (els
.indexOf(el
) < 0) { els
.push(el
); }
5812 el
.opacity = function (progress
) { return (1 - (Math
.pow( progress
, 0.33 ))); };
5813 $navEl
.find('.back span').each(function (subIndex
, subNavEl
) {
5816 'transform-origin': transformOrigin
,
5817 transform: function (progress
) { return ("translateY(calc(var(--f7-navbar-height) * " + progress
+ ")) scale(" + (1 + (1 * progress
)) + ")"); },
5823 if ($navEl
.hasClass('title-large')) { return; }
5824 var isSliding
= $navEl
.hasClass('sliding') || $currentNavbarInnerEl
.hasClass('sliding');
5825 if (els
.indexOf(el
) < 0) { els
.push(el
); }
5826 if (!isSubnavbar
|| (isSubnavbar
&& !isSliding
)) {
5827 el
.opacity = function (progress
) { return (1 - (Math
.pow( progress
, 0.33 ))); };
5830 var transformTarget
= el
;
5831 if (isLeft
&& activeNavBackIconText
.length
&& params
.iosAnimateNavbarBackIcon
) {
5832 var textEl
= { el
: activeNavBackIconText
[0] };
5833 transformTarget
= textEl
;
5836 transformTarget
.transform = function (progress
) {
5837 var activeNavTranslate
= progress
* transformTarget
.el
.f7NavbarRightOffset
;
5838 if (Device
.pixelRatio
=== 1) { activeNavTranslate
= Math
.round(activeNavTranslate
); }
5839 if (isSubnavbar
&& currentNavIsLarge
&& separateNavbar
) {
5840 return ("translate3d(" + activeNavTranslate
+ "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)");
5842 return ("translate3d(" + activeNavTranslate
+ "px,0,0)");
5846 $previousNavElements
5847 .each(function (index
, navEl
) {
5848 var $navEl
= $(navEl
);
5849 var isSubnavbar
= $navEl
.hasClass('subnavbar');
5850 var isLeft
= $navEl
.hasClass('left');
5851 var isTitle
= $navEl
.hasClass('title');
5856 if (isTitle
) { return; }
5857 if (els
.indexOf(el
) < 0) { els
.push(el
); }
5859 if ($navEl
.hasClass('title-large')) {
5860 if (!separateNavbar
) { return; }
5863 el
.overflow
= 'visible';
5864 el
.transform
= 'translateY(0)';
5865 $navEl
.find('.title-large-text').each(function (subIndex
, subNavEl
) {
5868 'transform-origin': transformOrigin
,
5869 opacity: function (progress
) { return (Math
.pow( progress
, 3 )); },
5870 transform: function (progress
) { return ("translateY(calc(" + (-1 + progress
* 1) + " * var(--f7-navbar-large-title-height))) scale(" + (0.5 + progress
* 0.5) + ")"); },
5874 el
.transform = function (progress
) { return ("translateY(calc(" + (progress
- 1) + " * var(--f7-navbar-large-title-height)))"); };
5876 el
.overflow
= 'hidden';
5877 $navEl
.find('.title-large-text').each(function (subIndex
, subNavEl
) {
5880 'transform-origin': transformOrigin
,
5881 opacity: function (progress
) { return (Math
.pow( progress
, 3 )); },
5882 transform: function (progress
) { return ("scale(" + (0.5 + progress
* 0.5) + ")"); },
5886 $navEl
.find('.title-large-inner').each(function (subIndex
, subNavEl
) {
5889 'transform-origin': transformOrigin
,
5890 opacity: function (progress
) { return (Math
.pow( progress
, 3 )); },
5891 transform: function (progress
) { return ("translateX(" + (-100 * (1 - progress
) * inverter
) + "%)"); },
5897 if ($navEl
.hasClass('title-large')) { return; }
5898 var isSliding
= $navEl
.hasClass('sliding') || $previousNavbarInnerEl
.hasClass('sliding');
5899 if (els
.indexOf(el
) < 0) { els
.push(el
); }
5900 if (!isSubnavbar
|| (isSubnavbar
&& !isSliding
)) {
5901 el
.opacity = function (progress
) { return (Math
.pow( progress
, 3 )); };
5904 var transformTarget
= el
;
5905 if (isLeft
&& previousNavBackIconText
.length
&& params
.iosAnimateNavbarBackIcon
) {
5906 var textEl
= { el
: previousNavBackIconText
[0] };
5907 transformTarget
= textEl
;
5910 transformTarget
.transform = function (progress
) {
5911 var previousNavTranslate
= transformTarget
.el
.f7NavbarLeftOffset
* (1 - progress
);
5912 if (Device
.pixelRatio
=== 1) { previousNavTranslate
= Math
.round(previousNavTranslate
); }
5913 if (isSubnavbar
&& previousNavIsLarge
&& separateNavbar
) {
5914 return ("translate3d(" + previousNavTranslate
+ "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)");
5916 return ("translate3d(" + previousNavTranslate
+ "px,0,0)");
5923 function setAnimatableNavElements(ref
) {
5924 if ( ref
=== void 0 ) ref
= {};
5925 var progress
= ref
.progress
;
5926 var reset
= ref
.reset
;
5927 var transition
= ref
.transition
;
5929 var styles
= ['overflow', 'transform', 'transform-origin', 'opacity'];
5930 for (var i
= 0; i
< animatableNavEls
.length
; i
+= 1) {
5931 var el
= animatableNavEls
[i
];
5933 if (transition
=== true) { el
.el
.classList
.add('navbar-page-transitioning'); }
5934 if (transition
=== false) { el
.el
.classList
.remove('navbar-page-transitioning'); }
5935 for (var j
= 0; j
< styles
.length
; j
+= 1) {
5936 var styleProp
= styles
[j
];
5937 if (el
[styleProp
]) {
5939 el
.el
.style
[styleProp
] = '';
5940 } else if (typeof el
[styleProp
] === 'function') {
5941 el
.el
.style
[styleProp
] = el
[styleProp
](progress
);
5943 el
.el
.style
[styleProp
] = el
[styleProp
];
5951 function handleTouchStart(e
) {
5952 var swipeBackEnabled
= params
[((app
.theme
) + "SwipeBack")];
5953 if (!allowViewTouchMove
|| !swipeBackEnabled
|| isTouched
|| (app
.swipeout
&& app
.swipeout
.el
) || !router
.allowPageChange
) { return; }
5954 if ($(e
.target
).closest('.range-slider, .calendar-months').length
> 0) { return; }
5955 if ($(e
.target
).closest('.page-master, .page-master-detail').length
> 0 && params
.masterDetailBreakpoint
> 0 && app
.width
>= params
.masterDetailBreakpoint
) { return; }
5958 isScrolling
= undefined;
5959 touchesStart
.x
= e
.type
=== 'touchstart' ? e
.targetTouches
[0].pageX
: e
.pageX
;
5960 touchesStart
.y
= e
.type
=== 'touchstart' ? e
.targetTouches
[0].pageY
: e
.pageY
;
5961 touchStartTime
= Utils
.now();
5962 dynamicNavbar
= router
.dynamicNavbar
;
5963 separateNavbar
= router
.separateNavbar
;
5965 function handleTouchMove(e
) {
5966 if (!isTouched
) { return; }
5967 var pageX
= e
.type
=== 'touchmove' ? e
.targetTouches
[0].pageX
: e
.pageX
;
5968 var pageY
= e
.type
=== 'touchmove' ? e
.targetTouches
[0].pageY
: e
.pageY
;
5969 if (typeof isScrolling
=== 'undefined') {
5970 isScrolling
= !!(isScrolling
|| Math
.abs(pageY
- touchesStart
.y
) > Math
.abs(pageX
- touchesStart
.x
)) || (pageX
< touchesStart
.x
&& !app
.rtl
) || (pageX
> touchesStart
.x
&& app
.rtl
);
5972 if (isScrolling
|| e
.f7PreventSwipeBack
|| app
.preventSwipeBack
) {
5977 // Calc values during first move fired
5979 var target
= $(e
.target
);
5981 var swipeout
= target
.closest('.swipeout');
5982 if (swipeout
.length
> 0) {
5983 if (!app
.rtl
&& swipeout
.find('.swipeout-actions-left').length
> 0) { cancel
= true; }
5984 if (app
.rtl
&& swipeout
.find('.swipeout-actions-right').length
> 0) { cancel
= true; }
5987 $currentPageEl
= target
.closest('.page');
5988 if ($currentPageEl
.hasClass('no-swipeback') || target
.closest('.no-swipeback, .card-opened').length
> 0) { cancel
= true; }
5989 $previousPageEl
= $el
.find('.page-previous:not(.stacked)');
5990 if ($previousPageEl
.length
> 1) {
5991 $previousPageEl
= $previousPageEl
.eq($previousPageEl
.length
- 1);
5993 var notFromBorder
= touchesStart
.x
- $el
.offset().left
> paramsSwipeBackActiveArea
;
5994 viewContainerWidth
= $el
.width();
5996 notFromBorder
= touchesStart
.x
< ($el
.offset().left
- $el
[0].scrollLeft
) + (viewContainerWidth
- paramsSwipeBackActiveArea
);
5998 notFromBorder
= touchesStart
.x
- $el
.offset().left
> paramsSwipeBackActiveArea
;
6000 if (notFromBorder
) { cancel
= true; }
6001 if ($previousPageEl
.length
=== 0 || $currentPageEl
.length
=== 0) { cancel
= true; }
6007 if (paramsSwipeBackAnimateShadow
) {
6008 $pageShadowEl
= $currentPageEl
.find('.page-shadow-effect');
6009 if ($pageShadowEl
.length
=== 0) {
6010 $pageShadowEl
= $('<div class="page-shadow-effect"></div>');
6011 $currentPageEl
.append($pageShadowEl
);
6014 if (paramsSwipeBackAnimateOpacity
) {
6015 $pageOpacityEl
= $previousPageEl
.find('.page-opacity-effect');
6016 if ($pageOpacityEl
.length
=== 0) {
6017 $pageOpacityEl
= $('<div class="page-opacity-effect"></div>');
6018 $previousPageEl
.append($pageOpacityEl
);
6022 if (dynamicNavbar
) {
6023 if (separateNavbar
) {
6024 $currentNavbarInnerEl
= $navbarEl
.find('.navbar-current:not(.stacked)');
6025 $previousNavbarInnerEl
= $navbarEl
.find('.navbar-previous:not(.stacked)');
6027 $currentNavbarInnerEl
= $currentPageEl
.children('.navbar').children('.navbar-inner');
6028 $previousNavbarInnerEl
= $previousPageEl
.children('.navbar').children('.navbar-inner');
6030 if ($previousNavbarInnerEl
.length
> 1) {
6031 $previousNavbarInnerEl
= $previousNavbarInnerEl
.eq($previousNavbarInnerEl
.length
- 1);
6034 animatableNavEls
= animatableNavElements();
6037 // Close/Hide Any Picker
6038 if ($('.sheet.modal-in').length
> 0 && app
.sheet
) {
6039 app
.sheet
.close($('.sheet.modal-in'));
6042 e
.f7PreventPanelSwipe
= true;
6044 app
.preventSwipePanelBySwipeBack
= true;
6048 var inverter
= app
.rtl
? -1 : 1;
6051 touchesDiff
= (pageX
- touchesStart
.x
- paramsSwipeBackThreshold
) * inverter
;
6052 if (touchesDiff
< 0) { touchesDiff
= 0; }
6053 var percentage
= Math
.min(Math
.max(touchesDiff
/ viewContainerWidth
, 0), 1);
6055 // Swipe Back Callback
6056 var callbackData
= {
6057 percentage
: percentage
,
6058 progress
: percentage
,
6059 currentPageEl
: $currentPageEl
[0],
6060 previousPageEl
: $previousPageEl
[0],
6061 currentNavbarEl
: $currentNavbarInnerEl
[0],
6062 previousNavbarEl
: $previousNavbarInnerEl
[0],
6064 $el
.trigger('swipeback:move', callbackData
);
6065 router
.emit('swipebackMove', callbackData
);
6068 var currentPageTranslate
= touchesDiff
* inverter
;
6069 var previousPageTranslate
= ((touchesDiff
/ 5) - (viewContainerWidth
/ 5)) * inverter
;
6071 currentPageTranslate
= Math
.min(currentPageTranslate
, viewContainerWidth
);
6072 previousPageTranslate
= Math
.min(previousPageTranslate
, 0);
6074 currentPageTranslate
= Math
.max(currentPageTranslate
, -viewContainerWidth
);
6075 previousPageTranslate
= Math
.max(previousPageTranslate
, 0);
6077 if (Device
.pixelRatio
=== 1) {
6078 currentPageTranslate
= Math
.round(currentPageTranslate
);
6079 previousPageTranslate
= Math
.round(previousPageTranslate
);
6082 router
.swipeBackActive
= true;
6083 $([$currentPageEl
[0], $previousPageEl
[0]]).addClass('page-swipeback-active');
6085 $currentPageEl
.transform(("translate3d(" + currentPageTranslate
+ "px,0,0)"));
6086 if (paramsSwipeBackAnimateShadow
) { $pageShadowEl
[0].style
.opacity
= 1 - (1 * percentage
); }
6088 if (app
.theme
=== 'ios') {
6089 $previousPageEl
.transform(("translate3d(" + previousPageTranslate
+ "px,0,0)"));
6091 if (paramsSwipeBackAnimateOpacity
) { $pageShadowEl
[0].style
.opacity
= 1 - (1 * percentage
); }
6093 // Dynamic Navbars Animation
6094 if (!dynamicNavbar
) { return; }
6096 setAnimatableNavElements({ progress
: percentage
});
6098 function handleTouchEnd() {
6099 app
.preventSwipePanelBySwipeBack
= false;
6100 if (!isTouched
|| !isMoved
) {
6107 router
.swipeBackActive
= false;
6108 $([$currentPageEl
[0], $previousPageEl
[0]]).removeClass('page-swipeback-active');
6109 if (touchesDiff
=== 0) {
6110 $([$currentPageEl
[0], $previousPageEl
[0]]).transform('');
6111 if ($pageShadowEl
&& $pageShadowEl
.length
> 0) { $pageShadowEl
.remove(); }
6112 if ($pageOpacityEl
&& $pageOpacityEl
.length
> 0) { $pageOpacityEl
.remove(); }
6113 if (dynamicNavbar
) {
6114 setAnimatableNavElements({ reset
: true });
6118 var timeDiff
= Utils
.now() - touchStartTime
;
6119 var pageChanged
= false;
6120 // Swipe back to previous page
6122 (timeDiff
< 300 && touchesDiff
> 10)
6123 || (timeDiff
>= 300 && touchesDiff
> viewContainerWidth
/ 2)
6125 $currentPageEl
.removeClass('page-current').addClass(("page-next" + (app
.theme
!== 'ios' ? ' page-next-on-right' : '')));
6126 $previousPageEl
.removeClass('page-previous').addClass('page-current').removeAttr('aria-hidden');
6127 if ($pageShadowEl
) { $pageShadowEl
[0].style
.opacity
= ''; }
6128 if ($pageOpacityEl
) { $pageOpacityEl
[0].style
.opacity
= ''; }
6129 if (dynamicNavbar
) {
6130 $currentNavbarInnerEl
.removeClass('navbar-current').addClass('navbar-next');
6131 $previousNavbarInnerEl
.removeClass('navbar-previous').addClass('navbar-current').removeAttr('aria-hidden');
6135 // Reset custom styles
6136 // Add transitioning class for transition-duration
6137 $([$currentPageEl
[0], $previousPageEl
[0]]).addClass('page-transitioning page-transitioning-swipeback').transform('');
6139 if (dynamicNavbar
) {
6140 setAnimatableNavElements({ progress
: pageChanged
? 1 : 0, transition
: true });
6142 allowViewTouchMove
= false;
6143 router
.allowPageChange
= false;
6145 // Swipe Back Callback
6146 var callbackData
= {
6147 currentPageEl
: $currentPageEl
[0],
6148 previousPageEl
: $previousPageEl
[0],
6149 currentNavbarEl
: $currentNavbarInnerEl
[0],
6150 previousNavbarEl
: $previousNavbarInnerEl
[0],
6155 router
.currentRoute
= $previousPageEl
[0].f7Page
.route
;
6156 router
.currentPage
= $previousPageEl
[0];
6158 // Page before animation callback
6159 router
.pageCallback('beforeOut', $currentPageEl
, $currentNavbarInnerEl
, 'current', 'next', { route
: $currentPageEl
[0].f7Page
.route
, swipeBack
: true });
6160 router
.pageCallback('beforeIn', $previousPageEl
, $previousNavbarInnerEl
, 'previous', 'current', { route
: $previousPageEl
[0].f7Page
.route
, swipeBack
: true }, $currentPageEl
[0]);
6162 $el
.trigger('swipeback:beforechange', callbackData
);
6163 router
.emit('swipebackBeforeChange', callbackData
);
6165 $el
.trigger('swipeback:beforereset', callbackData
);
6166 router
.emit('swipebackBeforeReset', callbackData
);
6169 $currentPageEl
.transitionEnd(function () {
6170 $([$currentPageEl
[0], $previousPageEl
[0]]).removeClass('page-transitioning page-transitioning-swipeback');
6171 if (dynamicNavbar
) {
6172 setAnimatableNavElements({ reset
: true, transition
: false });
6174 allowViewTouchMove
= true;
6175 router
.allowPageChange
= true;
6178 if (router
.history
.length
=== 1) {
6179 router
.history
.unshift(router
.url
);
6181 router
.history
.pop();
6182 router
.saveHistory();
6184 // Update push state
6185 if (params
.pushState
) {
6189 // Page after animation callback
6190 router
.pageCallback('afterOut', $currentPageEl
, $currentNavbarInnerEl
, 'current', 'next', { route
: $currentPageEl
[0].f7Page
.route
, swipeBack
: true });
6191 router
.pageCallback('afterIn', $previousPageEl
, $previousNavbarInnerEl
, 'previous', 'current', { route
: $previousPageEl
[0].f7Page
.route
, swipeBack
: true });
6194 if (params
.stackPages
&& router
.initialPages
.indexOf($currentPageEl
[0]) >= 0) {
6195 $currentPageEl
.addClass('stacked');
6196 if (separateNavbar
) {
6197 $currentNavbarInnerEl
.addClass('stacked');
6200 router
.pageCallback('beforeRemove', $currentPageEl
, $currentNavbarInnerEl
, 'next', { swipeBack
: true });
6201 router
.removePage($currentPageEl
);
6202 if (separateNavbar
) {
6203 router
.removeNavbar($currentNavbarInnerEl
);
6207 $el
.trigger('swipeback:afterchange', callbackData
);
6208 router
.emit('swipebackAfterChange', callbackData
);
6210 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
6212 if (params
.preloadPreviousPage
) {
6213 router
.back(router
.history
[router
.history
.length
- 2], { preload
: true });
6216 $el
.trigger('swipeback:afterreset', callbackData
);
6217 router
.emit('swipebackAfterReset', callbackData
);
6219 if ($pageShadowEl
&& $pageShadowEl
.length
> 0) { $pageShadowEl
.remove(); }
6220 if ($pageOpacityEl
&& $pageOpacityEl
.length
> 0) { $pageOpacityEl
.remove(); }
6224 function attachEvents() {
6225 var passiveListener
= (app
.touchEvents
.start
=== 'touchstart' && Support
.passiveListener
) ? { passive
: true, capture
: false } : false;
6226 $el
.on(app
.touchEvents
.start
, handleTouchStart
, passiveListener
);
6227 app
.on('touchmove:active', handleTouchMove
);
6228 app
.on('touchend:passive', handleTouchEnd
);
6230 function detachEvents() {
6231 var passiveListener
= (app
.touchEvents
.start
=== 'touchstart' && Support
.passiveListener
) ? { passive
: true, capture
: false } : false;
6232 $el
.off(app
.touchEvents
.start
, handleTouchStart
, passiveListener
);
6233 app
.off('touchmove:active', handleTouchMove
);
6234 app
.off('touchend:passive', handleTouchEnd
);
6239 router
.on('routerDestroy', detachEvents
);
6242 function redirect (direction
, route
, options
) {
6244 var redirect
= route
.route
.redirect
;
6245 if (options
.initial
&& router
.params
.pushState
) {
6246 options
.replaceState
= true; // eslint-disable-line
6247 options
.history
= true; // eslint-disable-line
6249 function redirectResolve(redirectUrl
, redirectOptions
) {
6250 if ( redirectOptions
=== void 0 ) redirectOptions
= {};
6252 router
.allowPageChange
= true;
6253 router
[direction
](redirectUrl
, Utils
.extend({}, options
, redirectOptions
));
6255 function redirectReject() {
6256 router
.allowPageChange
= true;
6258 if (typeof redirect
=== 'function') {
6259 router
.allowPageChange
= false;
6260 var redirectUrl
= redirect
.call(router
, route
, redirectResolve
, redirectReject
);
6261 if (redirectUrl
&& typeof redirectUrl
=== 'string') {
6262 router
.allowPageChange
= true;
6263 return router
[direction
](redirectUrl
, options
);
6267 return router
[direction
](redirect
, options
);
6270 function processQueue(router
, routerQueue
, routeQueue
, to
, from, resolve
, reject
) {
6273 if (Array
.isArray(routeQueue
)) {
6274 queue
.push
.apply(queue
, routeQueue
);
6275 } else if (routeQueue
&& typeof routeQueue
=== 'function') {
6276 queue
.push(routeQueue
);
6279 if (Array
.isArray(routerQueue
)) {
6280 queue
.push
.apply(queue
, routerQueue
);
6282 queue
.push(routerQueue
);
6287 if (queue
.length
=== 0) {
6291 var queueItem
= queue
.shift();
6308 function processRouteQueue (to
, from, resolve
, reject
) {
6310 function enterNextRoute() {
6311 if (to
&& to
.route
&& (router
.params
.routesBeforeEnter
|| to
.route
.beforeEnter
)) {
6312 router
.allowPageChange
= false;
6315 router
.params
.routesBeforeEnter
,
6316 to
.route
.beforeEnter
,
6320 router
.allowPageChange
= true;
6331 function leaveCurrentRoute() {
6332 if (from && from.route
&& (router
.params
.routesBeforeLeave
|| from.route
.beforeLeave
)) {
6333 router
.allowPageChange
= false;
6336 router
.params
.routesBeforeLeave
,
6337 from.route
.beforeLeave
,
6341 router
.allowPageChange
= true;
6352 leaveCurrentRoute();
6355 function appRouterCheck (router
, method
) {
6357 throw new Error(("Framework7: it is not allowed to use router methods on global app router. Use router methods only on related View, e.g. app.views.main.router." + method
+ "(...)"));
6361 function refreshPage() {
6363 appRouterCheck(router
, 'refreshPage');
6364 return router
.navigate(router
.currentRoute
.url
, {
6366 reloadCurrent
: true,
6370 function forward(el
, forwardOptions
) {
6371 if ( forwardOptions
=== void 0 ) forwardOptions
= {};
6375 var app
= router
.app
;
6376 var view
= router
.view
;
6377 var options
= Utils
.extend(false, {
6378 animate
: router
.params
.animate
,
6380 replaceState
: false,
6382 reloadCurrent
: router
.params
.reloadPages
,
6383 reloadPrevious
: false,
6385 clearPreviousHistory
: false,
6386 reloadDetail
: router
.params
.reloadDetail
,
6390 var masterDetailEnabled
= router
.params
.masterDetailBreakpoint
> 0;
6391 var isMaster
= masterDetailEnabled
&& options
.route
&& options
.route
.route
&& options
.route
.route
.master
=== true;
6393 var otherDetailPageEl
;
6395 var currentRouteIsModal
= router
.currentRoute
.modal
;
6397 if (!currentRouteIsModal
) {
6398 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
6399 if (router
.currentRoute
&& router
.currentRoute
.route
&& router
.currentRoute
.route
[modalLoadProp
]) {
6400 currentRouteIsModal
= true;
6401 modalType
= modalLoadProp
;
6406 if (currentRouteIsModal
) {
6407 var modalToClose
= router
.currentRoute
.modal
6408 || router
.currentRoute
.route
.modalInstance
6409 || app
[modalType
].get();
6410 var previousUrl
= router
.history
[router
.history
.length
- 2];
6411 var previousRoute
= router
.findMatchingRoute(previousUrl
);
6412 if (!previousRoute
&& previousUrl
) {
6415 path
: previousUrl
.split('?')[0],
6416 query
: Utils
.parseUrlQuery(previousUrl
),
6418 path
: previousUrl
.split('?')[0],
6424 router
.modalRemove(modalToClose
);
6427 var dynamicNavbar
= router
.dynamicNavbar
;
6428 var separateNavbar
= router
.separateNavbar
;
6430 var $viewEl
= router
.$el
;
6432 var reload
= options
.reloadPrevious
|| options
.reloadCurrent
|| options
.reloadAll
;
6436 var $newNavbarInner
;
6437 var $oldNavbarInner
;
6439 router
.allowPageChange
= false;
6440 if ($newPage
.length
=== 0) {
6441 router
.allowPageChange
= true;
6445 if ($newPage
.length
) {
6446 // Remove theme elements
6447 router
.removeThemeElements($newPage
);
6450 if (dynamicNavbar
) {
6451 $newNavbarInner
= $newPage
.children('.navbar').children('.navbar-inner');
6452 if (separateNavbar
) {
6453 $navbarEl
= router
.$navbarEl
;
6454 if ($newNavbarInner
.length
> 0) {
6455 $newPage
.children('.navbar').remove();
6457 if ($newNavbarInner
.length
=== 0 && $newPage
[0] && $newPage
[0].f7Page
) {
6458 // Try from pageData
6459 $newNavbarInner
= $newPage
[0].f7Page
.$navbarEl
;
6464 // Save Keep Alive Cache
6465 if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !options
.route
.route
.keepAliveData
) {
6466 options
.route
.route
.keepAliveData
= {
6472 var $pagesInView
= $viewEl
6473 .children('.page:not(.stacked)')
6474 .filter(function (index
, pageInView
) { return pageInView
!== $newPage
[0]; });
6478 if (separateNavbar
) {
6479 $navbarsInView
= $navbarEl
6480 .children('.navbar-inner:not(.stacked)')
6481 .filter(function (index
, navbarInView
) { return navbarInView
!== $newNavbarInner
[0]; });
6484 // Exit when reload previous and only 1 page in view so nothing ro reload
6485 if (options
.reloadPrevious
&& $pagesInView
.length
< 2) {
6486 router
.allowPageChange
= true;
6490 // Find Detail' master page
6493 if (masterDetailEnabled
&& !options
.reloadAll
) {
6494 for (var i
= 0; i
< $pagesInView
.length
; i
+= 1) {
6496 && $pagesInView
[i
].classList
.contains('page-master')
6498 masterPageEl
= $pagesInView
[i
];
6499 continue; // eslint-disable-line
6502 isDetail
= !isMaster
&& masterPageEl
;
6505 // Find Other Detail
6507 for (var i
$1 = 0; i
$1 < $pagesInView
.length
; i
$1 += 1) {
6508 if ($pagesInView
[i
$1].classList
.contains('page-master-detail')
6510 otherDetailPageEl
= $pagesInView
[i
$1];
6511 continue; // eslint-disable-line
6516 reloadDetail
= isDetail
&& options
.reloadDetail
&& app
.width
>= router
.params
.masterDetailBreakpoint
&& masterPageEl
;
6520 var newPagePosition
= 'next';
6521 if (options
.reloadCurrent
|| options
.reloadAll
|| reloadDetail
) {
6522 newPagePosition
= 'current';
6523 } else if (options
.reloadPrevious
) {
6524 newPagePosition
= 'previous';
6527 .removeClass('page-previous page-current page-next')
6528 .addClass(("page-" + newPagePosition
+ (isMaster
? ' page-master' : '') + (isDetail
? ' page-master-detail' : '')))
6529 .removeClass('stacked')
6530 .trigger('page:unstack')
6531 .trigger('page:position', { position
: newPagePosition
});
6532 router
.emit('pageUnstack', $newPage
[0]);
6533 router
.emit('pagePosition', $newPage
[0], newPagePosition
);
6535 if (isMaster
|| isDetail
) {
6536 $newPage
.trigger('page:role', { role
: isMaster
? 'master' : 'detail' });
6540 if (dynamicNavbar
&& $newNavbarInner
.length
) {
6542 .removeClass('navbar-previous navbar-current navbar-next')
6543 .addClass(("navbar-" + newPagePosition
+ (isMaster
? ' navbar-master' : '') + (isDetail
? ' navbar-master-detail' : '')))
6544 .removeClass('stacked');
6548 if (options
.reloadCurrent
|| reloadDetail
) {
6549 $oldPage
= $pagesInView
.eq($pagesInView
.length
- 1);
6550 if (separateNavbar
) {
6551 // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 1);
6552 $oldNavbarInner
= $(app
.navbar
.getElByPage($oldPage
));
6554 } else if (options
.reloadPrevious
) {
6555 $oldPage
= $pagesInView
.eq($pagesInView
.length
- 2);
6556 if (separateNavbar
) {
6557 // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 2);
6558 $oldNavbarInner
= $(app
.navbar
.getElByPage($oldPage
));
6560 } else if (options
.reloadAll
) {
6561 $oldPage
= $pagesInView
.filter(function (index
, pageEl
) { return pageEl
!== $newPage
[0]; });
6562 if (separateNavbar
) {
6563 $oldNavbarInner
= $navbarsInView
.filter(function (index
, navbarEl
) { return navbarEl
!== $newNavbarInner
[0]; });
6566 if ($pagesInView
.length
> 1) {
6568 for (i
$2 = 0; i
$2 < $pagesInView
.length
- 1; i
$2 += 1) {
6570 && $pagesInView
[i
$2] === masterPageEl
6572 $pagesInView
.eq(i
$2).addClass('page-master-stacked');
6573 $pagesInView
.eq(i
$2).trigger('page:masterstack');
6574 router
.emit('pageMasterStack', $pagesInView
[i
$2]);
6575 if (separateNavbar
) {
6576 $(app
.navbar
.getElByPage(masterPageEl
)).addClass('navbar-master-stacked');
6578 continue; // eslint-disable-line
6580 var oldNavbarInnerEl
= app
.navbar
.getElByPage($pagesInView
.eq(i
$2));
6581 if (router
.params
.stackPages
) {
6582 $pagesInView
.eq(i
$2).addClass('stacked');
6583 $pagesInView
.eq(i
$2).trigger('page:stack');
6584 router
.emit('pageStack', $pagesInView
[i
$2]);
6585 if (separateNavbar
) {
6586 $(oldNavbarInnerEl
).addClass('stacked');
6589 // Page remove event
6590 router
.pageCallback('beforeRemove', $pagesInView
[i
$2], $navbarsInView
&& $navbarsInView
[i
$2], 'previous', undefined, options
);
6591 router
.removePage($pagesInView
[i
$2]);
6592 if (separateNavbar
&& oldNavbarInnerEl
) {
6593 router
.removeNavbar(oldNavbarInnerEl
);
6599 .children('.page:not(.stacked)')
6600 .filter(function (index
, page
) { return page
!== $newPage
[0]; });
6601 if (separateNavbar
) {
6602 $oldNavbarInner
= $navbarEl
6603 .children('.navbar-inner:not(.stacked)')
6604 .filter(function (index
, navbarInner
) { return navbarInner
!== $newNavbarInner
[0]; });
6608 if (dynamicNavbar
&& !separateNavbar
) {
6609 $oldNavbarInner
= $oldPage
.children('.navbar').children('.navbar-inner');
6611 if (isDetail
&& !options
.reloadAll
) {
6612 if ($oldPage
.length
> 1 || reloadDetail
) {
6613 $oldPage
= $oldPage
.filter(function (pageIndex
, pageEl
) { return !pageEl
.classList
.contains('page-master'); });
6615 if ($oldNavbarInner
&& ($oldNavbarInner
.length
> 1 || reloadDetail
)) {
6616 $oldNavbarInner
= $oldNavbarInner
.filter(function (navbarIndex
, navbarEl
) { return !navbarEl
.classList
.contains('navbar-master'); });
6621 if (router
.params
.pushState
&& (options
.pushState
|| options
.replaceState
) && !options
.reloadPrevious
) {
6622 var pushStateRoot
= router
.params
.pushStateRoot
|| '';
6623 History
[options
.reloadCurrent
|| (reloadDetail
&& otherDetailPageEl
) || options
.reloadAll
|| options
.replaceState
? 'replace' : 'push'](
6626 url
: options
.route
.url
,
6628 pushStateRoot
+ router
.params
.pushStateSeparator
+ options
.route
.url
6632 if (!options
.reloadPrevious
) {
6633 // Current Page & Navbar
6634 router
.currentPageEl
= $newPage
[0];
6635 if (dynamicNavbar
&& $newNavbarInner
.length
) {
6636 router
.currentNavbarEl
= $newNavbarInner
[0];
6638 delete router
.currentNavbarEl
;
6642 router
.currentRoute
= options
.route
;
6645 // Update router history
6646 var url
= options
.route
.url
;
6648 if (options
.history
) {
6649 if (((options
.reloadCurrent
|| (reloadDetail
&& otherDetailPageEl
)) && router
.history
.length
) > 0 || options
.replaceState
) {
6650 router
.history
[router
.history
.length
- (options
.reloadPrevious
? 2 : 1)] = url
;
6651 } else if (options
.reloadPrevious
) {
6652 router
.history
[router
.history
.length
- 2] = url
;
6653 } else if (options
.reloadAll
) {
6654 router
.history
= [url
];
6656 router
.history
.push(url
);
6659 router
.saveHistory();
6661 // Insert new page and navbar
6662 var newPageInDom
= $newPage
.parents(doc
).length
> 0;
6663 var f7Component
= $newPage
[0].f7Component
;
6664 if (options
.reloadPrevious
) {
6665 if (f7Component
&& !newPageInDom
) {
6666 f7Component
.$mount(function (componentEl
) {
6667 $(componentEl
).insertBefore($oldPage
);
6670 $newPage
.insertBefore($oldPage
);
6672 if (separateNavbar
&& $newNavbarInner
.length
) {
6673 if ($newNavbarInner
.children('.title-large').length
) {
6674 $newNavbarInner
.addClass('navbar-inner-large');
6676 if ($oldNavbarInner
.length
) {
6677 $newNavbarInner
.insertBefore($oldNavbarInner
);
6679 if (!router
.$navbarEl
.parents(doc
).length
) {
6680 router
.$el
.prepend(router
.$navbarEl
);
6682 $navbarEl
.append($newNavbarInner
);
6686 if ($oldPage
.next('.page')[0] !== $newPage
[0]) {
6687 if (f7Component
&& !newPageInDom
) {
6688 f7Component
.$mount(function (componentEl
) {
6689 $viewEl
.append(componentEl
);
6692 $viewEl
.append($newPage
[0]);
6695 if (separateNavbar
&& $newNavbarInner
.length
) {
6696 if ($newNavbarInner
.children('.title-large').length
) {
6697 $newNavbarInner
.addClass('navbar-inner-large');
6699 if (!router
.$navbarEl
.parents(doc
).length
) {
6700 router
.$el
.prepend(router
.$navbarEl
);
6702 $navbarEl
.append($newNavbarInner
[0]);
6705 if (!newPageInDom
) {
6706 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, newPagePosition
, reload
? newPagePosition
: 'current', options
, $oldPage
);
6707 } else if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !$newPage
[0].f7PageMounted
) {
6708 $newPage
[0].f7PageMounted
= true;
6709 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, newPagePosition
, reload
? newPagePosition
: 'current', options
, $oldPage
);
6713 if ((options
.reloadCurrent
|| reloadDetail
) && $oldPage
.length
> 0) {
6714 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPage
[0]) >= 0) {
6715 $oldPage
.addClass('stacked');
6716 $oldPage
.trigger('page:stack');
6717 router
.emit('pageStack', $oldPage
[0]);
6718 if (separateNavbar
) {
6719 $oldNavbarInner
.addClass('stacked');
6722 // Page remove event
6723 router
.pageCallback('beforeOut', $oldPage
, $oldNavbarInner
, 'current', undefined, options
);
6724 router
.pageCallback('afterOut', $oldPage
, $oldNavbarInner
, 'current', undefined, options
);
6725 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'current', undefined, options
);
6726 router
.removePage($oldPage
);
6727 if (separateNavbar
&& $oldNavbarInner
&& $oldNavbarInner
.length
) {
6728 router
.removeNavbar($oldNavbarInner
);
6731 } else if (options
.reloadAll
) {
6732 $oldPage
.each(function (index
, pageEl
) {
6733 var $oldPageEl
= $(pageEl
);
6734 var $oldNavbarInnerEl
= $(app
.navbar
.getElByPage($oldPageEl
));
6735 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPageEl
[0]) >= 0) {
6736 $oldPageEl
.addClass('stacked');
6737 $oldPageEl
.trigger('page:stack');
6738 router
.emit('pageStack', $oldPageEl
[0]);
6739 if (separateNavbar
) {
6740 $oldNavbarInnerEl
.addClass('stacked');
6743 // Page remove event
6744 if ($oldPageEl
.hasClass('page-current')) {
6745 router
.pageCallback('beforeOut', $oldPage
, $oldNavbarInner
, 'current', undefined, options
);
6746 router
.pageCallback('afterOut', $oldPage
, $oldNavbarInner
, 'current', undefined, options
);
6748 router
.pageCallback('beforeRemove', $oldPageEl
, $oldNavbarInner
&& $oldNavbarInner
.eq(index
), 'previous', undefined, options
);
6749 router
.removePage($oldPageEl
);
6750 if (separateNavbar
&& $oldNavbarInnerEl
.length
) {
6751 router
.removeNavbar($oldNavbarInnerEl
);
6755 } else if (options
.reloadPrevious
) {
6756 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPage
[0]) >= 0) {
6757 $oldPage
.addClass('stacked');
6758 $oldPage
.trigger('page:stack');
6759 router
.emit('pageStack', $oldPage
[0]);
6760 if (separateNavbar
) {
6761 $oldNavbarInner
.addClass('stacked');
6764 // Page remove event
6765 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'previous', undefined, options
);
6766 router
.removePage($oldPage
);
6767 if (separateNavbar
&& $oldNavbarInner
&& $oldNavbarInner
.length
) {
6768 router
.removeNavbar($oldNavbarInner
);
6774 if (options
.route
.route
.tab
) {
6775 router
.tabLoad(options
.route
.route
.tab
, Utils
.extend({}, options
, {
6781 // Page init and before init events
6782 router
.pageCallback('init', $newPage
, $newNavbarInner
, newPagePosition
, reload
? newPagePosition
: 'current', options
, $oldPage
);
6784 if (options
.reloadCurrent
|| options
.reloadAll
|| reloadDetail
) {
6785 router
.allowPageChange
= true;
6786 router
.pageCallback('beforeIn', $newPage
, $newNavbarInner
, newPagePosition
, 'current', options
);
6787 $newPage
.removeAttr('aria-hidden');
6788 if (dynamicNavbar
&& $newNavbarInner
) {
6789 $newNavbarInner
.removeAttr('aria-hidden');
6791 router
.pageCallback('afterIn', $newPage
, $newNavbarInner
, newPagePosition
, 'current', options
);
6792 if (options
.reloadCurrent
&& options
.clearPreviousHistory
) { router
.clearPreviousHistory(); }
6794 masterPageEl
.classList
.add('page-previous');
6795 masterPageEl
.classList
.remove('page-current');
6796 $(masterPageEl
).trigger('page:position', { position
: 'previous' });
6797 router
.emit('pagePosition', masterPageEl
, 'previous');
6799 if (masterPageEl
.f7Page
&& masterPageEl
.f7Page
.navbarEl
) {
6800 masterPageEl
.f7Page
.navbarEl
.classList
.add('navbar-previous');
6801 masterPageEl
.f7Page
.navbarEl
.classList
.remove('navbar-current');
6806 if (options
.reloadPrevious
) {
6807 router
.allowPageChange
= true;
6811 // Before animation event
6812 router
.pageCallback('beforeOut', $oldPage
, $oldNavbarInner
, 'current', 'previous', options
);
6813 router
.pageCallback('beforeIn', $newPage
, $newNavbarInner
, 'next', 'current', options
);
6816 function afterAnimation() {
6817 var pageClasses
= 'page-previous page-current page-next';
6818 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
6819 $newPage
.removeClass(pageClasses
).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position
: 'current' });
6820 router
.emit('pagePosition', $newPage
[0], 'current');
6821 $oldPage
.removeClass(pageClasses
).addClass('page-previous').trigger('page:position', { position
: 'previous' });
6822 router
.emit('pagePosition', $oldPage
[0], 'previous');
6824 if (!$oldPage
.hasClass('page-master')) {
6825 $oldPage
.attr('aria-hidden', 'true');
6827 if (dynamicNavbar
) {
6828 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current').removeAttr('aria-hidden');
6829 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-previous');
6830 if (!$oldNavbarInner
.hasClass('navbar-master')) {
6831 $oldNavbarInner
.attr('aria-hidden', 'true');
6834 // After animation event
6835 router
.allowPageChange
= true;
6836 router
.pageCallback('afterOut', $oldPage
, $oldNavbarInner
, 'current', 'previous', options
);
6837 router
.pageCallback('afterIn', $newPage
, $newNavbarInner
, 'next', 'current', options
);
6839 var keepOldPage
= (router
.params
.preloadPreviousPage
|| router
.params
[((app
.theme
) + "SwipeBack")]) && !isMaster
;
6841 if ($newPage
.hasClass('smart-select-page') || $newPage
.hasClass('photo-browser-page') || $newPage
.hasClass('autocomplete-page') || $newPage
.hasClass('color-picker-page')) {
6846 if (router
.params
.stackPages
) {
6847 $oldPage
.addClass('stacked');
6848 $oldPage
.trigger('page:stack');
6849 router
.emit('pageStack', $oldPage
[0]);
6850 if (separateNavbar
) {
6851 $oldNavbarInner
.addClass('stacked');
6853 } else if (!($newPage
.attr('data-name') && $newPage
.attr('data-name') === 'smart-select-page')) {
6855 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'previous', undefined, options
);
6856 router
.removePage($oldPage
);
6857 if (separateNavbar
&& $oldNavbarInner
.length
) {
6858 router
.removeNavbar($oldNavbarInner
);
6862 if (options
.clearPreviousHistory
) { router
.clearPreviousHistory(); }
6863 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
6865 if (router
.params
.pushState
) {
6866 History
.clearRouterQueue();
6869 function setPositionClasses() {
6870 var pageClasses
= 'page-previous page-current page-next';
6871 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
6872 $oldPage
.removeClass(pageClasses
).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position
: 'current' });
6873 router
.emit('pagePosition', $oldPage
[0], 'current');
6874 $newPage
.removeClass(pageClasses
).addClass('page-next').removeAttr('aria-hidden').trigger('page:position', { position
: 'next' });
6875 router
.emit('pagePosition', $newPage
[0], 'next');
6876 if (dynamicNavbar
) {
6877 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current').removeAttr('aria-hidden');
6878 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-next').removeAttr('aria-hidden');
6881 if (options
.animate
&& !(isMaster
&& app
.width
>= router
.params
.masterDetailBreakpoint
)) {
6882 var delay
= router
.params
[((router
.app
.theme
) + "PageLoadDelay")];
6884 setTimeout(function () {
6885 setPositionClasses();
6886 router
.animate($oldPage
, $newPage
, $oldNavbarInner
, $newNavbarInner
, 'forward', function () {
6891 setPositionClasses();
6892 router
.animate($oldPage
, $newPage
, $oldNavbarInner
, $newNavbarInner
, 'forward', function () {
6901 function load(loadParams
, loadOptions
, ignorePageChange
) {
6902 if ( loadParams
=== void 0 ) loadParams
= {};
6903 if ( loadOptions
=== void 0 ) loadOptions
= {};
6906 if (!router
.allowPageChange
&& !ignorePageChange
) { return router
; }
6907 var params
= loadParams
;
6908 var options
= loadOptions
;
6909 var url
= params
.url
;
6910 var content
= params
.content
;
6912 var pageName
= params
.pageName
;
6913 var template
= params
.template
;
6914 var templateUrl
= params
.templateUrl
;
6915 var component
= params
.component
;
6916 var componentUrl
= params
.componentUrl
;
6918 if (!options
.reloadCurrent
6920 && options
.route
.route
6921 && options
.route
.route
.parentPath
6922 && router
.currentRoute
.route
6923 && router
.currentRoute
.route
.parentPath
=== options
.route
.route
.parentPath
) {
6924 // Do something nested
6925 if (options
.route
.url
=== router
.url
) {
6926 router
.allowPageChange
= true;
6929 // Check for same params
6930 var sameParams
= Object
.keys(options
.route
.params
).length
=== Object
.keys(router
.currentRoute
.params
).length
;
6932 // Check for equal params name
6933 Object
.keys(options
.route
.params
).forEach(function (paramName
) {
6935 !(paramName
in router
.currentRoute
.params
)
6936 || (router
.currentRoute
.params
[paramName
] !== options
.route
.params
[paramName
])
6943 if (options
.route
.route
.tab
) {
6944 return router
.tabLoad(options
.route
.route
.tab
, options
);
6949 && options
.route
.route
.tab
6950 && router
.currentRoute
.route
.tab
6951 && router
.currentRoute
.parentPath
=== options
.route
.parentPath
6953 return router
.tabLoad(options
.route
.route
.tab
, options
);
6959 && options
.route
.url
6960 && router
.url
=== options
.route
.url
6961 && !(options
.reloadCurrent
|| options
.reloadPrevious
)
6962 && !router
.params
.allowDuplicateUrls
6964 router
.allowPageChange
= true;
6968 if (!options
.route
&& url
) {
6969 options
.route
= router
.parseRouteUrl(url
);
6970 Utils
.extend(options
.route
, { route
: { url
: url
, path
: url
} });
6973 // Component Callbacks
6974 function resolve(pageEl
, newOptions
) {
6975 return router
.forward(pageEl
, Utils
.extend(options
, newOptions
));
6978 router
.allowPageChange
= true;
6982 if (url
|| templateUrl
|| componentUrl
) {
6983 router
.allowPageChange
= false;
6988 router
.forward(router
.getPageEl(content
), options
);
6989 } else if (template
|| templateUrl
) {
6990 // Parse template and send page element
6992 router
.pageTemplateLoader(template
, templateUrl
, options
, resolve
, reject
);
6994 router
.allowPageChange
= true;
6998 // Load page from specified HTMLElement or by page name in pages container
6999 router
.forward(router
.getPageEl(el
), options
);
7000 } else if (pageName
) {
7001 // Load page by page name in pages container
7002 router
.forward(router
.$el
.children((".page[data-name=\"" + pageName
+ "\"]")).eq(0), options
);
7003 } else if (component
|| componentUrl
) {
7004 // Load from component (F7/Vue/React/...)
7006 router
.pageComponentLoader(router
.el
, component
, componentUrl
, options
, resolve
, reject
);
7008 router
.allowPageChange
= true;
7017 router
.xhrRequest(url
, options
)
7018 .then(function (pageContent
) {
7019 router
.forward(router
.getPageEl(pageContent
), options
);
7021 .catch(function () {
7022 router
.allowPageChange
= true;
7027 function navigate(navigateParams
, navigateOptions
) {
7028 if ( navigateOptions
=== void 0 ) navigateOptions
= {};
7031 if (router
.swipeBackActive
) { return router
; }
7038 if (typeof navigateParams
=== 'string') {
7039 url
= navigateParams
;
7041 url
= navigateParams
.url
;
7042 createRoute
= navigateParams
.route
;
7043 name
= navigateParams
.name
;
7044 query
= navigateParams
.query
;
7045 params
= navigateParams
.params
;
7048 // find route by name
7049 route
= router
.findRouteByKey('name', name
);
7051 throw new Error(("Framework7: route with name \"" + name
+ "\" not found"));
7053 url
= router
.constructRouteUrl(route
, { params
: params
, query
: query
});
7055 return router
.navigate(url
, navigateOptions
);
7057 throw new Error(("Framework7: can't construct URL for route with name \"" + name
+ "\""));
7059 var app
= router
.app
;
7060 appRouterCheck(router
, 'navigate');
7061 if (url
=== '#' || url
=== '') {
7065 var navigateUrl
= url
.replace('./', '');
7066 if (navigateUrl
[0] !== '/' && navigateUrl
.indexOf('#') !== 0) {
7067 var currentPath
= router
.currentRoute
.parentPath
|| router
.currentRoute
.path
;
7068 navigateUrl
= ((currentPath
? (currentPath
+ "/") : '/') + navigateUrl
)
7069 .replace('///', '/')
7070 .replace('//', '/');
7073 route
= Utils
.extend(router
.parseRouteUrl(navigateUrl
), {
7074 route
: Utils
.extend({}, createRoute
),
7077 route
= router
.findMatchingRoute(navigateUrl
);
7084 if (route
.route
.redirect
) {
7085 return redirect
.call(router
, 'navigate', route
, navigateOptions
);
7090 if (route
.route
.options
) {
7091 Utils
.extend(options
, route
.route
.options
, navigateOptions
);
7093 Utils
.extend(options
, navigateOptions
);
7095 options
.route
= route
;
7097 if (options
&& options
.context
) {
7098 route
.context
= options
.context
;
7099 options
.route
.context
= options
.context
;
7102 function resolve() {
7103 var routerLoaded
= false;
7104 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
7105 if (route
.route
[modalLoadProp
] && !routerLoaded
) {
7106 routerLoaded
= true;
7107 router
.modalLoad(modalLoadProp
, route
, options
);
7110 if (route
.route
.keepAlive
&& route
.route
.keepAliveData
) {
7111 router
.load({ el
: route
.route
.keepAliveData
.pageEl
}, options
, false);
7112 routerLoaded
= true;
7114 ('url content component pageName el componentUrl template templateUrl').split(' ').forEach(function (pageLoadProp
) {
7117 if (route
.route
[pageLoadProp
] && !routerLoaded
) {
7118 routerLoaded
= true;
7119 router
.load(( obj
= {}, obj
[pageLoadProp
] = route
.route
[pageLoadProp
], obj
), options
, false);
7122 if (routerLoaded
) { return; }
7124 function asyncResolve(resolveParams
, resolveOptions
) {
7125 router
.allowPageChange
= false;
7126 var resolvedAsModal
= false;
7127 if (resolveOptions
&& resolveOptions
.context
) {
7128 if (!route
.context
) { route
.context
= resolveOptions
.context
; }
7129 else { route
.context
= Utils
.extend({}, route
.context
, resolveOptions
.context
); }
7130 options
.route
.context
= route
.context
;
7132 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
7133 if (resolveParams
[modalLoadProp
]) {
7134 resolvedAsModal
= true;
7135 var modalRoute
= Utils
.extend({}, route
, { route
: resolveParams
});
7136 router
.allowPageChange
= true;
7137 router
.modalLoad(modalLoadProp
, modalRoute
, Utils
.extend(options
, resolveOptions
));
7140 if (resolvedAsModal
) { return; }
7141 router
.load(resolveParams
, Utils
.extend(options
, resolveOptions
), true);
7143 function asyncReject() {
7144 router
.allowPageChange
= true;
7146 if (route
.route
.async
) {
7147 router
.allowPageChange
= false;
7149 route
.route
.async
.call(router
, options
.route
, router
.currentRoute
, asyncResolve
, asyncReject
);
7153 router
.allowPageChange
= true;
7156 if (router
.params
.masterDetailBreakpoint
> 0 && route
.route
.masterRoute
) {
7157 // load detail route
7158 var preloadMaster
= true;
7159 var masterLoaded
= false;
7160 if (router
.currentRoute
&& router
.currentRoute
.route
) {
7162 router
.currentRoute
.route
.master
7164 router
.currentRoute
.route
=== route
.route
.masterRoute
7165 || router
.currentRoute
.route
.path
=== route
.route
.masterRoute
.path
7168 preloadMaster
= false;
7171 router
.currentRoute
.route
.masterRoute
7172 && (router
.currentRoute
.route
.masterRoute
=== route
.route
.masterRoute
7173 || router
.currentRoute
.route
.masterRoute
.path
=== route
.route
.masterRoute
.path
7176 preloadMaster
= false;
7177 masterLoaded
= true;
7180 if (preloadMaster
|| (masterLoaded
&& navigateOptions
.reloadAll
)) {
7181 router
.navigate(route
.route
.masterRoute
.path
, {
7183 reloadAll
: navigateOptions
.reloadAll
,
7184 reloadCurrent
: navigateOptions
.reloadCurrent
,
7185 reloadPrevious
: navigateOptions
.reloadPrevious
,
7186 pushState
: !navigateOptions
.initial
,
7187 history
: !navigateOptions
.initial
,
7189 pageAfterIn
: function pageAfterIn() {
7190 router
.navigate(navigateParams
, Utils
.extend({}, navigateOptions
, {
7193 reloadCurrent
: false,
7194 reloadPrevious
: false,
7195 history
: !navigateOptions
.initial
,
7196 pushState
: !navigateOptions
.initial
,
7205 processRouteQueue
.call(
7208 router
.currentRoute
,
7210 if (route
.route
.modules
) {
7212 .loadModules(Array
.isArray(route
.route
.modules
) ? route
.route
.modules
: [route
.route
.modules
])
7216 .catch(function () {
7232 function tabLoad(tabRoute
, loadOptions
) {
7233 if ( loadOptions
=== void 0 ) loadOptions
= {};
7236 var options
= Utils
.extend({
7237 animate
: router
.params
.animate
,
7247 if (options
.route
) {
7249 if (!options
.preload
&& options
.route
!== router
.currentRoute
) {
7250 previousRoute
= router
.previousRoute
;
7251 router
.currentRoute
= options
.route
;
7253 if (options
.preload
) {
7254 currentRoute
= options
.route
;
7255 previousRoute
= router
.currentRoute
;
7257 currentRoute
= router
.currentRoute
;
7258 if (!previousRoute
) { previousRoute
= router
.previousRoute
; }
7261 // Update Browser History
7262 if (router
.params
.pushState
&& options
.pushState
&& !options
.reloadPrevious
) {
7266 url
: options
.route
.url
,
7268 (router
.params
.pushStateRoot
|| '') + router
.params
.pushStateSeparator
+ options
.route
.url
7272 // Update Router History
7273 if (options
.history
) {
7274 router
.history
[Math
.max(router
.history
.length
- 1, 0)] = options
.route
.url
;
7275 router
.saveHistory();
7280 var $parentPageEl
= $(options
.parentPageEl
|| router
.currentPageEl
);
7282 if ($parentPageEl
.length
&& $parentPageEl
.find(("#" + (tabRoute
.id
))).length
) {
7283 tabEl
= $parentPageEl
.find(("#" + (tabRoute
.id
))).eq(0);
7284 } else if (router
.view
.selector
) {
7285 tabEl
= (router
.view
.selector
) + " #" + (tabRoute
.id
);
7287 tabEl
= "#" + (tabRoute
.id
);
7289 var tabShowResult
= router
.app
.tab
.show({
7291 animate
: options
.animate
,
7292 tabRoute
: options
.route
,
7295 var $newTabEl
= tabShowResult
.$newTabEl
;
7296 var $oldTabEl
= tabShowResult
.$oldTabEl
;
7297 var animated
= tabShowResult
.animated
;
7298 var onTabsChanged
= tabShowResult
.onTabsChanged
;
7300 if ($newTabEl
&& $newTabEl
.parents('.page').length
> 0 && options
.route
) {
7301 var tabParentPageData
= $newTabEl
.parents('.page')[0].f7Page
;
7302 if (tabParentPageData
&& options
.route
) {
7303 tabParentPageData
.route
= options
.route
;
7307 // Tab Content Loaded
7308 function onTabLoaded(contentEl
) {
7309 // Remove theme elements
7310 router
.removeThemeElements($newTabEl
);
7312 var tabEventTarget
= $newTabEl
;
7313 if (typeof contentEl
!== 'string') { tabEventTarget
= $(contentEl
); }
7315 tabEventTarget
.trigger('tab:init tab:mounted', tabRoute
);
7316 router
.emit('tabInit tabMounted', $newTabEl
[0], tabRoute
);
7318 if ($oldTabEl
&& $oldTabEl
.length
) {
7320 onTabsChanged(function () {
7321 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
7322 if (router
.params
.unloadTabContent
) {
7323 router
.tabRemove($oldTabEl
, $newTabEl
, tabRoute
);
7327 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
7328 if (router
.params
.unloadTabContent
) {
7329 router
.tabRemove($oldTabEl
, $newTabEl
, tabRoute
);
7335 if ($newTabEl
[0].f7RouterTabLoaded
) {
7336 if (!$oldTabEl
|| !$oldTabEl
.length
) { return router
; }
7338 onTabsChanged(function () {
7339 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
7342 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
7348 function loadTab(loadTabParams
, loadTabOptions
) {
7350 var url
= loadTabParams
.url
;
7351 var content
= loadTabParams
.content
;
7352 var el
= loadTabParams
.el
;
7353 var template
= loadTabParams
.template
;
7354 var templateUrl
= loadTabParams
.templateUrl
;
7355 var component
= loadTabParams
.component
;
7356 var componentUrl
= loadTabParams
.componentUrl
;
7357 // Component/Template Callbacks
7358 function resolve(contentEl
) {
7359 router
.allowPageChange
= true;
7360 if (!contentEl
) { return; }
7361 if (typeof contentEl
=== 'string') {
7362 $newTabEl
.html(contentEl
);
7365 if (contentEl
.f7Component
) {
7366 contentEl
.f7Component
.$mount(function (componentEl
) {
7367 $newTabEl
.append(componentEl
);
7370 $newTabEl
.append(contentEl
);
7373 $newTabEl
[0].f7RouterTabLoaded
= true;
7374 onTabLoaded(contentEl
);
7377 router
.allowPageChange
= true;
7383 } else if (template
|| templateUrl
) {
7385 router
.tabTemplateLoader(template
, templateUrl
, loadTabOptions
, resolve
, reject
);
7387 router
.allowPageChange
= true;
7392 } else if (component
|| componentUrl
) {
7393 // Load from component (F7/Vue/React/...)
7395 router
.tabComponentLoader($newTabEl
[0], component
, componentUrl
, loadTabOptions
, resolve
, reject
);
7397 router
.allowPageChange
= true;
7406 router
.xhrRequest(url
, loadTabOptions
)
7407 .then(function (tabContent
) {
7408 resolve(tabContent
);
7410 .catch(function () {
7411 router
.allowPageChange
= true;
7416 var hasContentLoadProp
;
7417 ('url content component el componentUrl template templateUrl').split(' ').forEach(function (tabLoadProp
) {
7420 if (tabRoute
[tabLoadProp
]) {
7421 hasContentLoadProp
= true;
7422 loadTab(( obj
= {}, obj
[tabLoadProp
] = tabRoute
[tabLoadProp
], obj
), options
);
7427 function asyncResolve(resolveParams
, resolveOptions
) {
7428 loadTab(resolveParams
, Utils
.extend(options
, resolveOptions
));
7430 function asyncReject() {
7431 router
.allowPageChange
= true;
7433 if (tabRoute
.async
) {
7434 tabRoute
.async
.call(router
, currentRoute
, previousRoute
, asyncResolve
, asyncReject
);
7435 } else if (!hasContentLoadProp
) {
7436 router
.allowPageChange
= true;
7441 function tabRemove($oldTabEl
, $newTabEl
, tabRoute
) {
7444 var hasTabComponentChild
;
7446 $oldTabEl
[0].f7RouterTabLoaded
= false;
7447 delete $oldTabEl
[0].f7RouterTabLoaded
;
7449 $oldTabEl
.children().each(function (index
, tabChild
) {
7450 if (tabChild
.f7Component
) {
7451 hasTabComponentChild
= true;
7452 $(tabChild
).trigger('tab:beforeremove', tabRoute
);
7453 tabChild
.f7Component
.$destroy();
7456 if (!hasTabComponentChild
) {
7457 $oldTabEl
.trigger('tab:beforeremove', tabRoute
);
7459 router
.emit('tabBeforeRemove', $oldTabEl
[0], $newTabEl
[0], tabRoute
);
7460 router
.removeTabContent($oldTabEl
[0], tabRoute
);
7463 function modalLoad(modalType
, route
, loadOptions
) {
7464 if ( loadOptions
=== void 0 ) loadOptions
= {};
7467 var app
= router
.app
;
7468 var isPanel
= modalType
=== 'panel';
7469 var modalOrPanel
= isPanel
? 'panel' : 'modal';
7471 var options
= Utils
.extend({
7472 animate
: router
.params
.animate
,
7478 var modalParams
= Utils
.extend({}, route
.route
[modalType
]);
7479 var modalRoute
= route
.route
;
7481 function onModalLoaded() {
7483 var modal
= app
[modalType
].create(modalParams
);
7484 modalRoute
.modalInstance
= modal
;
7486 var hasEl
= modal
.el
;
7488 function closeOnSwipeBack() {
7491 modal
.on((modalOrPanel
+ "Open"), function () {
7493 // Remove theme elements
7494 router
.removeThemeElements(modal
.el
);
7497 modal
.$el
.trigger(((modalType
.toLowerCase()) + ":init " + (modalType
.toLowerCase()) + ":mounted"), route
, modal
);
7498 router
.emit(((!isPanel
? 'modalInit' : '') + " " + modalType
+ "Init " + modalType
+ "Mounted"), modal
.el
, route
, modal
);
7500 router
.once('swipeBackMove', closeOnSwipeBack
);
7502 modal
.on((modalOrPanel
+ "Close"), function () {
7503 router
.off('swipeBackMove', closeOnSwipeBack
);
7504 if (!modal
.closeByRouter
) {
7509 modal
.on((modalOrPanel
+ "Closed"), function () {
7510 modal
.$el
.trigger(((modalType
.toLowerCase()) + ":beforeremove"), route
, modal
);
7511 modal
.emit(("" + (!isPanel
? 'modalBeforeRemove ' : '') + modalType
+ "BeforeRemove"), modal
.el
, route
, modal
);
7512 var modalComponent
= modal
.el
.f7Component
;
7513 if (modalComponent
) {
7514 modalComponent
.$destroy();
7516 Utils
.nextTick(function () {
7517 if (modalComponent
|| modalParams
.component
) {
7518 router
.removeModal(modal
.el
);
7522 delete modalRoute
.modalInstance
;
7526 if (options
.route
) {
7527 // Update Browser History
7528 if (router
.params
.pushState
&& options
.pushState
) {
7532 url
: options
.route
.url
,
7535 (router
.params
.pushStateRoot
|| '') + router
.params
.pushStateSeparator
+ options
.route
.url
7540 if (options
.route
!== router
.currentRoute
) {
7541 modal
.route
= Utils
.extend(options
.route
, { modal
: modal
});
7542 router
.currentRoute
= modal
.route
;
7545 // Update Router History
7546 if (options
.history
) {
7547 router
.history
.push(options
.route
.url
);
7548 router
.saveHistory();
7553 // Remove theme elements
7554 router
.removeThemeElements(modal
.el
);
7557 modal
.$el
.trigger(((modalType
.toLowerCase()) + ":init " + (modalType
.toLowerCase()) + ":mounted"), route
, modal
);
7558 router
.emit((modalOrPanel
+ "Init " + modalType
+ "Init " + modalType
+ "Mounted"), modal
.el
, route
, modal
);
7565 // Load Modal Content
7566 function loadModal(loadModalParams
, loadModalOptions
) {
7568 var url
= loadModalParams
.url
;
7569 var content
= loadModalParams
.content
;
7570 var template
= loadModalParams
.template
;
7571 var templateUrl
= loadModalParams
.templateUrl
;
7572 var component
= loadModalParams
.component
;
7573 var componentUrl
= loadModalParams
.componentUrl
;
7575 // Component/Template Callbacks
7576 function resolve(contentEl
) {
7578 if (typeof contentEl
=== 'string') {
7579 modalParams
.content
= contentEl
;
7580 } else if (contentEl
.f7Component
) {
7581 contentEl
.f7Component
.$mount(function (componentEl
) {
7582 modalParams
.el
= componentEl
;
7583 app
.root
.append(componentEl
);
7586 modalParams
.el
= contentEl
;
7592 router
.allowPageChange
= true;
7598 } else if (template
|| templateUrl
) {
7600 router
.modalTemplateLoader(template
, templateUrl
, loadModalOptions
, resolve
, reject
);
7602 router
.allowPageChange
= true;
7605 } else if (component
|| componentUrl
) {
7606 // Load from component (F7/Vue/React/...)
7608 router
.modalComponentLoader(app
.root
[0], component
, componentUrl
, loadModalOptions
, resolve
, reject
);
7610 router
.allowPageChange
= true;
7619 router
.xhrRequest(url
, loadModalOptions
)
7620 .then(function (modalContent
) {
7621 modalParams
.content
= modalContent
;
7624 .catch(function () {
7625 router
.allowPageChange
= true;
7633 ('url content component el componentUrl template templateUrl').split(' ').forEach(function (modalLoadProp
) {
7636 if (modalParams
[modalLoadProp
] && !foundLoadProp
) {
7637 foundLoadProp
= true;
7638 loadModal(( obj
= {}, obj
[modalLoadProp
] = modalParams
[modalLoadProp
], obj
), options
);
7641 if (!foundLoadProp
&& modalType
=== 'actions') {
7646 function asyncResolve(resolveParams
, resolveOptions
) {
7647 loadModal(resolveParams
, Utils
.extend(options
, resolveOptions
));
7649 function asyncReject() {
7650 router
.allowPageChange
= true;
7652 if (modalParams
.async
) {
7653 modalParams
.async
.call(router
, options
.route
, router
.currentRoute
, asyncResolve
, asyncReject
);
7657 function modalRemove(modal
) {
7658 Utils
.extend(modal
, { closeByRouter
: true });
7662 function backward(el
, backwardOptions
) {
7665 var app
= router
.app
;
7666 var view
= router
.view
;
7668 var options
= Utils
.extend({
7669 animate
: router
.params
.animate
,
7671 replaceState
: false,
7672 }, backwardOptions
);
7674 var masterDetailEnabled
= router
.params
.masterDetailBreakpoint
> 0;
7675 var isMaster
= masterDetailEnabled
&& options
.route
&& options
.route
.route
&& options
.route
.route
.master
=== true;
7678 var dynamicNavbar
= router
.dynamicNavbar
;
7679 var separateNavbar
= router
.separateNavbar
;
7682 var $oldPage
= router
.$el
.children('.page-current');
7683 var currentIsMaster
= masterDetailEnabled
&& $oldPage
.hasClass('page-master');
7685 if ($newPage
.length
) {
7686 // Remove theme elements
7687 router
.removeThemeElements($newPage
);
7691 var $newNavbarInner
;
7692 var $oldNavbarInner
;
7694 if (dynamicNavbar
) {
7695 $newNavbarInner
= $newPage
.children('.navbar').children('.navbar-inner');
7696 if (separateNavbar
) {
7697 $navbarEl
= router
.$navbarEl
;
7698 if ($newNavbarInner
.length
> 0) {
7699 $newPage
.children('.navbar').remove();
7701 if ($newNavbarInner
.length
=== 0 && $newPage
[0] && $newPage
[0].f7Page
) {
7702 // Try from pageData
7703 $newNavbarInner
= $newPage
[0].f7Page
.$navbarEl
;
7705 $oldNavbarInner
= $navbarEl
.find('.navbar-current');
7707 $oldNavbarInner
= $oldPage
.children('.navbar').children('.navbar-inner');
7711 router
.allowPageChange
= false;
7712 if ($newPage
.length
=== 0 || $oldPage
.length
=== 0) {
7713 router
.allowPageChange
= true;
7717 // Remove theme elements
7718 router
.removeThemeElements($newPage
);
7720 // Save Keep Alive Cache
7721 if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !options
.route
.route
.keepAliveData
) {
7722 options
.route
.route
.keepAliveData
= {
7729 if (masterDetailEnabled
) {
7730 var $pagesInView
= router
.$el
7731 .children('.page:not(.stacked)')
7732 .filter(function (index
, pageInView
) { return pageInView
!== $newPage
[0]; });
7734 // Find Detail' master page
7735 for (var i
= 0; i
< $pagesInView
.length
; i
+= 1) {
7737 && $pagesInView
[i
].classList
.contains('page-master')
7739 masterPageEl
= $pagesInView
[i
];
7740 continue; // eslint-disable-line
7744 isDetail
= !isMaster
7746 && (router
.history
.indexOf(options
.route
.url
) > router
.history
.indexOf(masterPageEl
.f7Page
.route
.url
));
7748 if (!isDetail
&& !isMaster
&& masterPageEl
&& masterPageEl
.f7Page
&& options
.route
.route
.masterRoute
) {
7749 isDetail
= options
.route
.route
.masterRoute
.path
=== masterPageEl
.f7Page
.route
.route
.path
;
7756 .addClass(("page-previous" + (isMaster
? ' page-master' : '') + (isDetail
? ' page-master-detail' : '')))
7757 .removeClass('stacked')
7758 .removeAttr('aria-hidden')
7759 .trigger('page:unstack')
7760 .trigger('page:position', { position
: 'previous' });
7761 router
.emit('pageUnstack', $newPage
[0]);
7762 router
.emit('pagePosition', $newPage
[0], 'previous');
7763 if (isMaster
|| isDetail
) {
7764 $newPage
.trigger('page:role', { role
: isMaster
? 'master' : 'detail' });
7767 if (dynamicNavbar
&& $newNavbarInner
.length
> 0) {
7769 .addClass(("navbar-previous" + (isMaster
? ' navbar-master' : '') + (isDetail
? ' navbar-master-detail' : '')))
7770 .removeClass('stacked')
7771 .removeAttr('aria-hidden');
7774 // Remove previous page in case of "forced"
7776 if (options
.force
) {
7777 if ($oldPage
.prev('.page-previous:not(.stacked)').length
> 0 || $oldPage
.prev('.page-previous').length
=== 0) {
7778 if (router
.history
.indexOf(options
.route
.url
) >= 0) {
7779 backIndex
= router
.history
.length
- router
.history
.indexOf(options
.route
.url
) - 1;
7780 router
.history
= router
.history
.slice(0, router
.history
.indexOf(options
.route
.url
) + 2);
7781 view
.history
= router
.history
;
7782 } else if (router
.history
[[router
.history
.length
- 2]]) {
7783 router
.history
[router
.history
.length
- 2] = options
.route
.url
;
7785 router
.history
.unshift(router
.url
);
7788 if (backIndex
&& router
.params
.stackPages
) {
7789 $oldPage
.prevAll('.page-previous').each(function (index
, pageToRemove
) {
7790 var $pageToRemove
= $(pageToRemove
);
7791 var $navbarToRemove
;
7792 if (separateNavbar
) {
7793 // $navbarToRemove = $oldNavbarInner.prevAll('.navbar-previous').eq(index);
7794 $navbarToRemove
= $(app
.navbar
.getElByPage($pageToRemove
));
7796 if ($pageToRemove
[0] !== $newPage
[0] && $pageToRemove
.index() > $newPage
.index()) {
7797 if (router
.initialPages
.indexOf($pageToRemove
[0]) >= 0) {
7798 $pageToRemove
.addClass('stacked');
7799 $pageToRemove
.trigger('page:stack');
7800 router
.emit('pageStack', $pageToRemove
[0]);
7801 if (separateNavbar
) {
7802 $navbarToRemove
.addClass('stacked');
7805 router
.pageCallback('beforeRemove', $pageToRemove
, $navbarToRemove
, 'previous', undefined, options
);
7806 router
.removePage($pageToRemove
);
7807 if (separateNavbar
&& $navbarToRemove
.length
> 0) {
7808 router
.removeNavbar($navbarToRemove
);
7814 var $pageToRemove
= $oldPage
.prev('.page-previous:not(.stacked)');
7815 var $navbarToRemove
;
7816 if (separateNavbar
) {
7817 // $navbarToRemove = $oldNavbarInner.prev('.navbar-inner:not(.stacked)');
7818 $navbarToRemove
= $(app
.navbar
.getElByPage($pageToRemove
));
7820 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($pageToRemove
[0]) >= 0) {
7821 $pageToRemove
.addClass('stacked');
7822 $pageToRemove
.trigger('page:stack');
7823 router
.emit('pageStack', $pageToRemove
[0]);
7824 $navbarToRemove
.addClass('stacked');
7825 } else if ($pageToRemove
.length
> 0) {
7826 router
.pageCallback('beforeRemove', $pageToRemove
, $navbarToRemove
, 'previous', undefined, options
);
7827 router
.removePage($pageToRemove
);
7828 if (separateNavbar
&& $navbarToRemove
.length
) {
7829 router
.removeNavbar($navbarToRemove
);
7837 var newPageInDom
= $newPage
.parents(doc
).length
> 0;
7838 var f7Component
= $newPage
[0].f7Component
;
7840 function insertPage() {
7841 if ($newPage
.next($oldPage
).length
=== 0) {
7842 if (!newPageInDom
&& f7Component
) {
7843 f7Component
.$mount(function (componentEl
) {
7844 $(componentEl
).insertBefore($oldPage
);
7847 $newPage
.insertBefore($oldPage
);
7850 if (separateNavbar
&& $newNavbarInner
.length
) {
7851 if ($newNavbarInner
.children('.title-large').length
) {
7852 $newNavbarInner
.addClass('navbar-inner-large');
7854 $newNavbarInner
.insertBefore($oldNavbarInner
);
7855 if ($oldNavbarInner
.length
> 0) {
7856 $newNavbarInner
.insertBefore($oldNavbarInner
);
7858 if (!router
.$navbarEl
.parents(doc
).length
) {
7859 router
.$el
.prepend(router
.$navbarEl
);
7861 $navbarEl
.append($newNavbarInner
);
7864 if (!newPageInDom
) {
7865 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7866 } else if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !$newPage
[0].f7PageMounted
) {
7867 $newPage
[0].f7PageMounted
= true;
7868 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7872 if (options
.preload
) {
7876 if (options
.route
.route
.tab
) {
7877 router
.tabLoad(options
.route
.route
.tab
, Utils
.extend({}, options
, {
7885 .removeClass('page-master-stacked')
7886 .trigger('page:masterunstack');
7887 router
.emit('pageMasterUnstack', $newPage
[0]);
7888 if (separateNavbar
) {
7889 $(app
.navbar
.getElByPage($newPage
)).removeClass('navbar-master-stacked');
7892 // Page init and before init events
7893 router
.pageCallback('init', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7894 var $previousPages
= $newPage
.prevAll('.page-previous:not(.stacked):not(.page-master)');
7895 if ($previousPages
.length
> 0) {
7896 $previousPages
.each(function (index
, pageToRemove
) {
7897 var $pageToRemove
= $(pageToRemove
);
7898 var $navbarToRemove
;
7899 if (separateNavbar
) {
7900 // $navbarToRemove = $newNavbarInner.prevAll('.navbar-previous:not(.stacked)').eq(index);
7901 $navbarToRemove
= $(app
.navbar
.getElByPage($pageToRemove
));
7903 if (router
.params
.stackPages
&& router
.initialPages
.indexOf(pageToRemove
) >= 0) {
7904 $pageToRemove
.addClass('stacked');
7905 $pageToRemove
.trigger('page:stack');
7906 router
.emit('pageStack', $pageToRemove
[0]);
7907 if (separateNavbar
) {
7908 $navbarToRemove
.addClass('stacked');
7911 router
.pageCallback('beforeRemove', $pageToRemove
, $navbarToRemove
, 'previous', undefined);
7912 router
.removePage($pageToRemove
);
7913 if (separateNavbar
&& $navbarToRemove
.length
) {
7914 router
.removeNavbar($navbarToRemove
);
7919 router
.allowPageChange
= true;
7924 if (!(Device
.ie
|| Device
.edge
|| (Device
.firefox
&& !Device
.ios
))) {
7925 if (router
.params
.pushState
&& options
.pushState
) {
7926 if (options
.replaceState
) {
7927 var pushStateRoot
= router
.params
.pushStateRoot
|| '';
7931 url
: options
.route
.url
,
7933 pushStateRoot
+ router
.params
.pushStateSeparator
+ options
.route
.url
7935 } else if (backIndex
) {
7936 History
.go(-backIndex
);
7944 if (options
.replaceState
) {
7945 router
.history
[router
.history
.length
- 1] = options
.route
.url
;
7947 if (router
.history
.length
=== 1) {
7948 router
.history
.unshift(router
.url
);
7950 router
.history
.pop();
7952 router
.saveHistory();
7954 // Current Page & Navbar
7955 router
.currentPageEl
= $newPage
[0];
7956 if (dynamicNavbar
&& $newNavbarInner
.length
) {
7957 router
.currentNavbarEl
= $newNavbarInner
[0];
7959 delete router
.currentNavbarEl
;
7963 router
.currentRoute
= options
.route
;
7966 if (Device
.ie
|| Device
.edge
|| (Device
.firefox
&& !Device
.ios
)) {
7967 if (router
.params
.pushState
&& options
.pushState
) {
7968 if (options
.replaceState
) {
7969 var pushStateRoot
$1 = router
.params
.pushStateRoot
|| '';
7973 url
: options
.route
.url
,
7975 pushStateRoot
$1 + router
.params
.pushStateSeparator
+ options
.route
.url
7977 } else if (backIndex
) {
7978 History
.go(-backIndex
);
7989 if (options
.route
.route
.tab
) {
7990 router
.tabLoad(options
.route
.route
.tab
, Utils
.extend({}, options
, {
7996 // Page init and before init events
7997 router
.pageCallback('init', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7999 // Before animation callback
8000 router
.pageCallback('beforeOut', $oldPage
, $oldNavbarInner
, 'current', 'next', options
);
8001 router
.pageCallback('beforeIn', $newPage
, $newNavbarInner
, 'previous', 'current', options
);
8004 function afterAnimation() {
8006 var pageClasses
= 'page-previous page-current page-next';
8007 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
8008 $newPage
.removeClass(pageClasses
).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position
: 'current' });
8009 router
.emit('pagePosition', $newPage
[0], 'current');
8010 $oldPage
.removeClass(pageClasses
).addClass('page-next').attr('aria-hidden', 'true').trigger('page:position', { position
: 'next' });
8011 router
.emit('pagePosition', $oldPage
[0], 'next');
8012 if (dynamicNavbar
) {
8013 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current').removeAttr('aria-hidden');
8014 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-next').attr('aria-hidden', 'true');
8017 // After animation event
8018 router
.pageCallback('afterOut', $oldPage
, $oldNavbarInner
, 'current', 'next', options
);
8019 router
.pageCallback('afterIn', $newPage
, $newNavbarInner
, 'previous', 'current', options
);
8022 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPage
[0]) >= 0) {
8023 $oldPage
.addClass('stacked');
8024 $oldPage
.trigger('page:stack');
8025 router
.emit('pageStack', $oldPage
[0]);
8026 if (separateNavbar
) {
8027 $oldNavbarInner
.addClass('stacked');
8030 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'next', undefined, options
);
8031 router
.removePage($oldPage
);
8032 if (separateNavbar
&& $oldNavbarInner
.length
) {
8033 router
.removeNavbar($oldNavbarInner
);
8037 router
.allowPageChange
= true;
8038 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
8040 // Preload previous page
8041 var preloadPreviousPage
= router
.params
.preloadPreviousPage
|| router
.params
[((app
.theme
) + "SwipeBack")];
8042 if (preloadPreviousPage
&& router
.history
[router
.history
.length
- 2] && !isMaster
) {
8043 router
.back(router
.history
[router
.history
.length
- 2], { preload
: true });
8045 if (router
.params
.pushState
) {
8046 History
.clearRouterQueue();
8050 function setPositionClasses() {
8051 var pageClasses
= 'page-previous page-current page-next';
8052 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
8053 $oldPage
.removeClass(pageClasses
).addClass('page-current').trigger('page:position', { position
: 'current' });
8054 router
.emit('pagePosition', $oldPage
[0], 'current');
8055 $newPage
.removeClass(pageClasses
).addClass('page-previous').removeAttr('aria-hidden').trigger('page:position', { position
: 'previous' });
8056 router
.emit('pagePosition', $newPage
[0], 'previous');
8057 if (dynamicNavbar
) {
8058 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current');
8059 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-previous').removeAttr('aria-hidden');
8063 if (options
.animate
&& !(currentIsMaster
&& app
.width
>= router
.params
.masterDetailBreakpoint
)) {
8064 setPositionClasses();
8065 router
.animate($oldPage
, $newPage
, $oldNavbarInner
, $newNavbarInner
, 'backward', function () {
8074 function loadBack(backParams
, backOptions
, ignorePageChange
) {
8077 if (!router
.allowPageChange
&& !ignorePageChange
) { return router
; }
8078 var params
= backParams
;
8079 var options
= backOptions
;
8080 var url
= params
.url
;
8081 var content
= params
.content
;
8083 var pageName
= params
.pageName
;
8084 var template
= params
.template
;
8085 var templateUrl
= params
.templateUrl
;
8086 var component
= params
.component
;
8087 var componentUrl
= params
.componentUrl
;
8091 && router
.url
=== options
.route
.url
8092 && !(options
.reloadCurrent
|| options
.reloadPrevious
)
8093 && !router
.params
.allowDuplicateUrls
8098 if (!options
.route
&& url
) {
8099 options
.route
= router
.parseRouteUrl(url
);
8102 // Component Callbacks
8103 function resolve(pageEl
, newOptions
) {
8104 return router
.backward(pageEl
, Utils
.extend(options
, newOptions
));
8107 router
.allowPageChange
= true;
8111 if (url
|| templateUrl
|| componentUrl
) {
8112 router
.allowPageChange
= false;
8117 router
.backward(router
.getPageEl(content
), options
);
8118 } else if (template
|| templateUrl
) {
8119 // Parse template and send page element
8121 router
.pageTemplateLoader(template
, templateUrl
, options
, resolve
, reject
);
8123 router
.allowPageChange
= true;
8127 // Load page from specified HTMLElement or by page name in pages container
8128 router
.backward(router
.getPageEl(el
), options
);
8129 } else if (pageName
) {
8130 // Load page by page name in pages container
8131 router
.backward(router
.$el
.children((".page[data-name=\"" + pageName
+ "\"]")).eq(0), options
);
8132 } else if (component
|| componentUrl
) {
8133 // Load from component (F7/Vue/React/...)
8135 router
.pageComponentLoader(router
.el
, component
, componentUrl
, options
, resolve
, reject
);
8137 router
.allowPageChange
= true;
8146 router
.xhrRequest(url
, options
)
8147 .then(function (pageContent
) {
8148 router
.backward(router
.getPageEl(pageContent
), options
);
8150 .catch(function () {
8151 router
.allowPageChange
= true;
8157 var args
= [], len
= arguments
.length
;
8158 while ( len
-- ) args
[ len
] = arguments
[ len
];
8161 if (router
.swipeBackActive
) { return router
; }
8163 var navigateOptions
;
8165 if (typeof args
[0] === 'object') {
8166 navigateOptions
= args
[0] || {};
8168 navigateUrl
= args
[0];
8169 navigateOptions
= args
[1] || {};
8172 var name
= navigateOptions
.name
;
8173 var params
= navigateOptions
.params
;
8174 var query
= navigateOptions
.query
;
8176 // find route by name
8177 route
= router
.findRouteByKey('name', name
);
8179 throw new Error(("Framework7: route with name \"" + name
+ "\" not found"));
8181 navigateUrl
= router
.constructRouteUrl(route
, { params
: params
, query
: query
});
8183 return router
.back(navigateUrl
, Utils
.extend({}, navigateOptions
, {
8189 throw new Error(("Framework7: can't construct URL for route with name \"" + name
+ "\""));
8192 var app
= router
.app
;
8193 appRouterCheck(router
, 'back');
8195 var currentRouteIsModal
= router
.currentRoute
.modal
;
8197 if (!currentRouteIsModal
) {
8198 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
8199 if (router
.currentRoute
.route
[modalLoadProp
]) {
8200 currentRouteIsModal
= true;
8201 modalType
= modalLoadProp
;
8205 if (currentRouteIsModal
) {
8206 var modalToClose
= router
.currentRoute
.modal
8207 || router
.currentRoute
.route
.modalInstance
8208 || app
[modalType
].get();
8209 var previousUrl
= router
.history
[router
.history
.length
- 2];
8211 // check if previous route is modal too
8212 if (modalToClose
&& modalToClose
.$el
) {
8213 var prevOpenedModals
= modalToClose
.$el
.prevAll('.modal-in');
8214 if (prevOpenedModals
.length
&& prevOpenedModals
[0].f7Modal
) {
8215 previousRoute
= prevOpenedModals
[0].f7Modal
.route
;
8218 if (!previousRoute
) {
8219 previousRoute
= router
.findMatchingRoute(previousUrl
);
8222 if (!previousRoute
&& previousUrl
) {
8225 path
: previousUrl
.split('?')[0],
8226 query
: Utils
.parseUrlQuery(previousUrl
),
8228 path
: previousUrl
.split('?')[0],
8233 if (!navigateUrl
|| navigateUrl
.replace(/[# ]/g, '').trim().length
=== 0) {
8234 if (!previousRoute
|| !modalToClose
) {
8238 var forceOtherUrl
= navigateOptions
.force
&& previousRoute
&& navigateUrl
;
8239 if (previousRoute
&& modalToClose
) {
8240 if (router
.params
.pushState
&& navigateOptions
.pushState
!== false) {
8243 router
.currentRoute
= previousRoute
;
8244 router
.history
.pop();
8245 router
.saveHistory();
8246 router
.modalRemove(modalToClose
);
8247 if (forceOtherUrl
) {
8248 router
.navigate(navigateUrl
, { reloadCurrent
: true });
8250 } else if (modalToClose
) {
8251 router
.modalRemove(modalToClose
);
8253 router
.navigate(navigateUrl
, { reloadCurrent
: true });
8258 var $previousPage
= router
.$el
.children('.page-current').prevAll('.page-previous:not(.page-master)').eq(0);
8261 if (router
.params
.masterDetailBreakpoint
> 0) {
8262 var $previousMaster
= router
.$el
.children('.page-current').prevAll('.page-master').eq(0);
8263 if ($previousMaster
.length
) {
8264 var expectedPreviousPageUrl
= router
.history
[router
.history
.length
- 2];
8265 var expectedPreviousPageRoute
= router
.findMatchingRoute(expectedPreviousPageUrl
);
8266 if (expectedPreviousPageRoute
&& expectedPreviousPageRoute
.route
=== $previousMaster
[0].f7Page
.route
.route
) {
8267 $previousPage
= $previousMaster
;
8268 if (!navigateOptions
.preload
) {
8269 skipMaster
= app
.width
>= router
.params
.masterDetailBreakpoint
;
8274 if (!navigateOptions
.force
&& $previousPage
.length
&& !skipMaster
) {
8275 if (router
.params
.pushState
8276 && $previousPage
[0].f7Page
8277 && router
.history
[router
.history
.length
- 2] !== $previousPage
[0].f7Page
.route
.url
8280 router
.history
[router
.history
.length
- 2],
8281 Utils
.extend(navigateOptions
, { force
: true })
8285 var previousPageRoute
= $previousPage
[0].f7Page
.route
;
8287 processRouteQueue
.call(
8290 router
.currentRoute
,
8292 router
.loadBack({ el
: $previousPage
}, Utils
.extend(navigateOptions
, {
8293 route
: previousPageRoute
,
8303 if (navigateUrl
=== '#') {
8304 navigateUrl
= undefined;
8306 if (navigateUrl
&& navigateUrl
[0] !== '/' && navigateUrl
.indexOf('#') !== 0) {
8307 navigateUrl
= ((router
.path
|| '/') + navigateUrl
).replace('//', '/');
8309 if (!navigateUrl
&& router
.history
.length
> 1) {
8310 navigateUrl
= router
.history
[router
.history
.length
- 2];
8312 if (skipMaster
&& !navigateOptions
.force
&& router
.history
[router
.history
.length
- 3]) {
8313 return router
.back(router
.history
[router
.history
.length
- 3], Utils
.extend({}, navigateOptions
|| {}, {
8318 if (skipMaster
&& !navigateOptions
.force
) {
8322 // Find route to load
8323 route
= router
.findMatchingRoute(navigateUrl
);
8328 path
: navigateUrl
.split('?')[0],
8329 query
: Utils
.parseUrlQuery(navigateUrl
),
8331 path
: navigateUrl
.split('?')[0],
8341 if (route
.route
.redirect
) {
8342 return redirect
.call(router
, 'back', route
, navigateOptions
);
8346 if (route
.route
.options
) {
8347 Utils
.extend(options
, route
.route
.options
, navigateOptions
);
8349 Utils
.extend(options
, navigateOptions
);
8351 options
.route
= route
;
8353 if (options
&& options
.context
) {
8354 route
.context
= options
.context
;
8355 options
.route
.context
= options
.context
;
8358 var backForceLoaded
;
8359 if (options
.force
&& router
.params
.stackPages
) {
8360 router
.$el
.children('.page-previous.stacked').each(function (index
, pageEl
) {
8361 if (pageEl
.f7Page
&& pageEl
.f7Page
.route
&& pageEl
.f7Page
.route
.url
=== route
.url
) {
8362 backForceLoaded
= true;
8363 router
.loadBack({ el
: pageEl
}, options
);
8366 if (backForceLoaded
) {
8370 function resolve() {
8371 var routerLoaded
= false;
8372 if (route
.route
.keepAlive
&& route
.route
.keepAliveData
) {
8373 router
.loadBack({ el
: route
.route
.keepAliveData
.pageEl
}, options
);
8374 routerLoaded
= true;
8376 ('url content component pageName el componentUrl template templateUrl').split(' ').forEach(function (pageLoadProp
) {
8379 if (route
.route
[pageLoadProp
] && !routerLoaded
) {
8380 routerLoaded
= true;
8381 router
.loadBack(( obj
= {}, obj
[pageLoadProp
] = route
.route
[pageLoadProp
], obj
), options
);
8384 if (routerLoaded
) { return; }
8386 function asyncResolve(resolveParams
, resolveOptions
) {
8387 router
.allowPageChange
= false;
8388 if (resolveOptions
&& resolveOptions
.context
) {
8389 if (!route
.context
) { route
.context
= resolveOptions
.context
; }
8390 else { route
.context
= Utils
.extend({}, route
.context
, resolveOptions
.context
); }
8391 options
.route
.context
= route
.context
;
8393 router
.loadBack(resolveParams
, Utils
.extend(options
, resolveOptions
), true);
8395 function asyncReject() {
8396 router
.allowPageChange
= true;
8398 if (route
.route
.async
) {
8399 router
.allowPageChange
= false;
8401 route
.route
.async
.call(router
, route
, router
.currentRoute
, asyncResolve
, asyncReject
);
8405 router
.allowPageChange
= true;
8408 if (options
.preload
) {
8411 processRouteQueue
.call(
8414 router
.currentRoute
,
8416 if (route
.route
.modules
) {
8418 .loadModules(Array
.isArray(route
.route
.modules
) ? route
.route
.modules
: [route
.route
.modules
])
8422 .catch(function () {
8439 function clearPreviousPages() {
8441 appRouterCheck(router
, 'clearPreviousPages');
8442 var app
= router
.app
;
8443 var separateNavbar
= router
.separateNavbar
;
8445 var $pagesToRemove
= router
.$el
8447 .filter(function (index
, pageInView
) {
8448 if (router
.currentRoute
&& (router
.currentRoute
.modal
|| router
.currentRoute
.panel
)) { return true; }
8449 return pageInView
!== router
.currentPageEl
;
8452 $pagesToRemove
.each(function (index
, pageEl
) {
8453 var $oldPageEl
= $(pageEl
);
8454 var $oldNavbarInnerEl
= $(app
.navbar
.getElByPage($oldPageEl
));
8455 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPageEl
[0]) >= 0) {
8456 $oldPageEl
.addClass('stacked');
8457 if (separateNavbar
) {
8458 $oldNavbarInnerEl
.addClass('stacked');
8461 // Page remove event
8462 router
.pageCallback('beforeRemove', $oldPageEl
, $oldNavbarInnerEl
, 'previous', undefined, {});
8463 router
.removePage($oldPageEl
);
8464 if (separateNavbar
&& $oldNavbarInnerEl
.length
) {
8465 router
.removeNavbar($oldNavbarInnerEl
);
8471 function clearPreviousHistory() {
8473 appRouterCheck(router
, 'clearPreviousHistory');
8474 var url
= router
.history
[router
.history
.length
- 1];
8476 router
.clearPreviousPages();
8478 router
.history
= [url
];
8479 router
.view
.history
= [url
];
8480 router
.saveHistory();
8483 var Router
= /*@__PURE__*/(function (Framework7Class
) {
8484 function Router(app
, view
) {
8485 Framework7Class
.call(this, {}, [typeof view
=== 'undefined' ? app
: view
]);
8489 router
.isAppRouter
= typeof view
=== 'undefined';
8491 if (router
.isAppRouter
) {
8493 Utils
.extend(false, router
, {
8495 params
: app
.params
.view
,
8496 routes
: app
.routes
|| [],
8501 Utils
.extend(false, router
, {
8505 params
: view
.params
,
8506 routes
: view
.routes
,
8509 $navbarEl
: view
.$navbarEl
,
8510 navbarEl
: view
.navbarEl
,
8511 history
: view
.history
,
8512 scrollHistory
: view
.scrollHistory
,
8514 dynamicNavbar
: app
.theme
=== 'ios' && view
.params
.iosDynamicNavbar
,
8515 separateNavbar
: app
.theme
=== 'ios' && view
.params
.iosDynamicNavbar
&& view
.params
.iosSeparateDynamicNavbar
,
8522 router
.useModules();
8525 router
.tempDom
= doc
.createElement('div');
8528 router
.allowPageChange
= true;
8531 var currentRoute
= {};
8532 var previousRoute
= {};
8533 Object
.defineProperty(router
, 'currentRoute', {
8536 set: function set(newRoute
) {
8537 if ( newRoute
=== void 0 ) newRoute
= {};
8539 previousRoute
= Utils
.extend({}, currentRoute
);
8540 currentRoute
= newRoute
;
8541 if (!currentRoute
) { return; }
8542 router
.url
= currentRoute
.url
;
8543 router
.emit('routeChange', newRoute
, previousRoute
, router
);
8545 get: function get() {
8546 return currentRoute
;
8549 Object
.defineProperty(router
, 'previousRoute', {
8552 get: function get() {
8553 return previousRoute
;
8555 set: function set(newRoute
) {
8556 previousRoute
= newRoute
;
8563 if ( Framework7Class
) Router
.__proto__
= Framework7Class
;
8564 Router
.prototype = Object
.create( Framework7Class
&& Framework7Class
.prototype );
8565 Router
.prototype.constructor = Router
;
8567 Router
.prototype.animatableNavElements
= function animatableNavElements (newNavbarInner
, oldNavbarInner
, toLarge
, fromLarge
, direction
) {
8569 var dynamicNavbar
= router
.dynamicNavbar
;
8570 var separateNavbar
= router
.separateNavbar
;
8571 var animateIcon
= router
.params
.iosAnimateNavbarBackIcon
;
8575 function animatableNavEl($el
, navbarInner
) {
8576 var isSliding
= $el
.hasClass('sliding') || navbarInner
.hasClass('sliding');
8577 var isSubnavbar
= $el
.hasClass('subnavbar');
8578 var needsOpacityTransition
= isSliding
? !isSubnavbar
: true;
8579 var $iconEl
= $el
.find('.back .icon');
8581 if (isSliding
&& animateIcon
&& $el
.hasClass('left') && $iconEl
.length
> 0 && $iconEl
.next('span').length
) {
8582 $el
= $iconEl
.next('span'); // eslint-disable-line
8587 isIconLabel
: isIconLabel
,
8588 leftOffset
: $el
[0].f7NavbarLeftOffset
,
8589 rightOffset
: $el
[0].f7NavbarRightOffset
,
8590 isSliding
: isSliding
,
8591 isSubnavbar
: isSubnavbar
,
8592 needsOpacityTransition
: needsOpacityTransition
,
8595 if (dynamicNavbar
) {
8598 newNavbarInner
.children('.left, .right, .title, .subnavbar').each(function (index
, navEl
) {
8599 var $navEl
= $(navEl
);
8600 if ($navEl
.hasClass('left') && fromLarge
&& direction
=== 'forward' && separateNavbar
) { return; }
8601 if ($navEl
.hasClass('title') && toLarge
) { return; }
8602 newNavEls
.push(animatableNavEl($navEl
, newNavbarInner
));
8604 if (!(oldNavbarInner
.hasClass('navbar-master') && router
.params
.masterDetailBreakpoint
> 0 && router
.app
.width
>= router
.params
.masterDetailBreakpoint
)) {
8605 oldNavbarInner
.children('.left, .right, .title, .subnavbar').each(function (index
, navEl
) {
8606 var $navEl
= $(navEl
);
8607 if ($navEl
.hasClass('left') && toLarge
&& !fromLarge
&& direction
=== 'forward' && separateNavbar
) { return; }
8608 if ($navEl
.hasClass('left') && toLarge
&& direction
=== 'backward' && separateNavbar
) { return; }
8609 if ($navEl
.hasClass('title') && fromLarge
) {
8612 oldNavEls
.push(animatableNavEl($navEl
, oldNavbarInner
));
8615 [oldNavEls
, newNavEls
].forEach(function (navEls
) {
8616 navEls
.forEach(function (navEl
) {
8618 var isSliding
= navEl
.isSliding
;
8619 var $el
= navEl
.$el
;
8620 var otherEls
= navEls
=== oldNavEls
? newNavEls
: oldNavEls
;
8621 if (!(isSliding
&& $el
.hasClass('title') && otherEls
)) { return; }
8622 otherEls
.forEach(function (otherNavEl
) {
8623 if (otherNavEl
.isIconLabel
) {
8624 var iconTextEl
= otherNavEl
.$el
[0];
8625 n
.leftOffset
+= iconTextEl
? (iconTextEl
.offsetLeft
|| 0) : 0;
8632 return { newNavEls
: newNavEls
, oldNavEls
: oldNavEls
};
8635 Router
.prototype.animate
= function animate (oldPage
, newPage
, oldNavbarInner
, newNavbarInner
, direction
, callback
) {
8637 if (router
.params
.animateCustom
) {
8638 router
.params
.animateCustom
.apply(router
, [oldPage
, newPage
, oldNavbarInner
, newNavbarInner
, direction
, callback
]);
8641 var dynamicNavbar
= router
.dynamicNavbar
;
8642 var ios
= router
.app
.theme
=== 'ios';
8643 // Router Animation class
8644 var routerTransitionClass
= "router-transition-" + direction
+ " router-transition";
8655 if (ios
&& dynamicNavbar
) {
8656 oldIsLarge
= oldNavbarInner
&& oldNavbarInner
.hasClass('navbar-inner-large');
8657 newIsLarge
= newNavbarInner
&& newNavbarInner
.hasClass('navbar-inner-large');
8658 fromLarge
= oldIsLarge
&& !oldNavbarInner
.hasClass('navbar-inner-large-collapsed');
8659 toLarge
= newIsLarge
&& !newNavbarInner
.hasClass('navbar-inner-large-collapsed');
8660 var navEls
= router
.animatableNavElements(newNavbarInner
, oldNavbarInner
, toLarge
, fromLarge
, direction
);
8661 newNavEls
= navEls
.newNavEls
;
8662 oldNavEls
= navEls
.oldNavEls
;
8665 function animateNavbars(progress
) {
8666 if (!(ios
&& dynamicNavbar
)) { return; }
8667 if (progress
=== 1) {
8669 newNavbarInner
.addClass('router-navbar-transition-to-large');
8670 oldNavbarInner
.addClass('router-navbar-transition-to-large');
8673 newNavbarInner
.addClass('router-navbar-transition-from-large');
8674 oldNavbarInner
.addClass('router-navbar-transition-from-large');
8677 newNavEls
.forEach(function (navEl
) {
8678 var $el
= navEl
.$el
;
8679 var offset
= direction
=== 'forward' ? navEl
.rightOffset
: navEl
.leftOffset
;
8680 if (navEl
.isSliding
) {
8681 if (navEl
.isSubnavbar
&& newIsLarge
) {
8682 $el
[0].style
.setProperty('transform', ("translate3d(" + (offset
* (1 - progress
)) + "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)"), 'important');
8684 $el
.transform(("translate3d(" + (offset
* (1 - progress
)) + "px,0,0)"));
8688 oldNavEls
.forEach(function (navEl
) {
8689 var $el
= navEl
.$el
;
8690 var offset
= direction
=== 'forward' ? navEl
.leftOffset
: navEl
.rightOffset
;
8691 if (navEl
.isSliding
) {
8692 if (navEl
.isSubnavbar
&& oldIsLarge
) {
8693 $el
.transform(("translate3d(" + (offset
* (progress
)) + "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)"));
8695 $el
.transform(("translate3d(" + (offset
* (progress
)) + "px,0,0)"));
8701 // AnimationEnd Callback
8703 if (router
.dynamicNavbar
) {
8704 if (newNavbarInner
) {
8705 newNavbarInner
.removeClass('router-navbar-transition-to-large router-navbar-transition-from-large');
8706 newNavbarInner
.addClass('navbar-no-title-large-transition');
8707 Utils
.nextFrame(function () {
8708 newNavbarInner
.removeClass('navbar-no-title-large-transition');
8711 if (oldNavbarInner
) {
8712 oldNavbarInner
.removeClass('router-navbar-transition-to-large router-navbar-transition-from-large');
8714 if (newNavbarInner
.hasClass('sliding')) {
8715 newNavbarInner
.find('.title, .left, .right, .left .icon, .subnavbar').transform('');
8717 newNavbarInner
.find('.sliding').transform('');
8719 if (oldNavbarInner
.hasClass('sliding')) {
8720 oldNavbarInner
.find('.title, .left, .right, .left .icon, .subnavbar').transform('');
8722 oldNavbarInner
.find('.sliding').transform('');
8725 router
.$el
.removeClass(routerTransitionClass
);
8726 if (callback
) { callback(); }
8729 (direction
=== 'forward' ? newPage
: oldPage
).animationEnd(function () {
8734 if (dynamicNavbar
) {
8737 Utils
.nextFrame(function () {
8738 // Add class, start animation
8740 router
.$el
.addClass(routerTransitionClass
);
8743 // Add class, start animation
8744 router
.$el
.addClass(routerTransitionClass
);
8748 Router
.prototype.removeModal
= function removeModal (modalEl
) {
8750 router
.removeEl(modalEl
);
8752 // eslint-disable-next-line
8753 Router
.prototype.removeTabContent
= function removeTabContent (tabEl
) {
8754 var $tabEl
= $(tabEl
);
8758 Router
.prototype.removeNavbar
= function removeNavbar (el
) {
8760 router
.removeEl(el
);
8763 Router
.prototype.removePage
= function removePage (el
) {
8765 var f7Page
= $el
&& $el
[0] && $el
[0].f7Page
;
8767 if (f7Page
&& f7Page
.route
&& f7Page
.route
.route
&& f7Page
.route
.route
.keepAlive
) {
8771 router
.removeEl(el
);
8774 Router
.prototype.removeEl
= function removeEl (el
) {
8775 if (!el
) { return; }
8778 if ($el
.length
=== 0) { return; }
8779 $el
.find('.tab').each(function (tabIndex
, tabEl
) {
8780 $(tabEl
).children().each(function (index
, tabChild
) {
8781 if (tabChild
.f7Component
) {
8782 $(tabChild
).trigger('tab:beforeremove');
8783 tabChild
.f7Component
.$destroy();
8787 if ($el
[0].f7Component
&& $el
[0].f7Component
.$destroy
) {
8788 $el
[0].f7Component
.$destroy();
8790 if (!router
.params
.removeElements
) {
8793 if (router
.params
.removeElementsWithTimeout
) {
8794 setTimeout(function () {
8796 }, router
.params
.removeElementsTimeout
);
8802 Router
.prototype.getPageEl
= function getPageEl (content
) {
8804 if (typeof content
=== 'string') {
8805 router
.tempDom
.innerHTML
= content
;
8807 if ($(content
).hasClass('page')) {
8810 router
.tempDom
.innerHTML
= '';
8811 $(router
.tempDom
).append(content
);
8814 return router
.findElement('.page', router
.tempDom
);
8817 Router
.prototype.findElement
= function findElement (stringSelector
, container
, notStacked
) {
8819 var view
= router
.view
;
8820 var app
= router
.app
;
8823 var modalsSelector
= '.popup, .dialog, .popover, .actions-modal, .sheet-modal, .login-screen, .page';
8825 var $container
= $(container
);
8826 var selector
= stringSelector
;
8827 if (notStacked
) { selector
+= ':not(.stacked)'; }
8829 var found
= $container
8831 .filter(function (index
, el
) { return $(el
).parents(modalsSelector
).length
=== 0; });
8833 if (found
.length
> 1) {
8834 if (typeof view
.selector
=== 'string') {
8835 // Search in related view
8836 found
= $container
.find(((view
.selector
) + " " + selector
));
8838 if (found
.length
> 1) {
8839 // Search in main view
8840 found
= $container
.find(("." + (app
.params
.viewMainClass
) + " " + selector
));
8843 if (found
.length
=== 1) { return found
; }
8845 // Try to find not stacked
8846 if (!notStacked
) { found
= router
.findElement(selector
, $container
, true); }
8847 if (found
&& found
.length
=== 1) { return found
; }
8848 if (found
&& found
.length
> 1) { return $(found
[0]); }
8852 Router
.prototype.flattenRoutes
= function flattenRoutes (routes
) {
8853 if ( routes
=== void 0 ) routes
= this.routes
;
8856 var flattenedRoutes
= [];
8857 routes
.forEach(function (route
) {
8858 var hasTabRoutes
= false;
8859 if ('tabs' in route
&& route
.tabs
) {
8860 var mergedPathsRoutes
= route
.tabs
.map(function (tabRoute
) {
8861 var tRoute
= Utils
.extend({}, route
, {
8862 path
: (((route
.path
) + "/" + (tabRoute
.path
))).replace('///', '/').replace('//', '/'),
8863 parentPath
: route
.path
,
8867 delete tRoute
.routes
;
8870 hasTabRoutes
= true;
8871 flattenedRoutes
= flattenedRoutes
.concat(router
.flattenRoutes(mergedPathsRoutes
));
8873 if ('detailRoutes' in route
) {
8874 var mergedPathsRoutes
$1 = route
.detailRoutes
.map(function (detailRoute
) {
8875 var dRoute
= Utils
.extend({}, detailRoute
);
8876 dRoute
.masterRoute
= route
;
8877 dRoute
.masterRoutePath
= route
.path
;
8880 flattenedRoutes
= flattenedRoutes
.concat(route
, router
.flattenRoutes(mergedPathsRoutes
$1));
8882 if ('routes' in route
) {
8883 var mergedPathsRoutes
$2 = route
.routes
.map(function (childRoute
) {
8884 var cRoute
= Utils
.extend({}, childRoute
);
8885 cRoute
.path
= (((route
.path
) + "/" + (cRoute
.path
))).replace('///', '/').replace('//', '/');
8889 flattenedRoutes
= flattenedRoutes
.concat(router
.flattenRoutes(mergedPathsRoutes
$2));
8891 flattenedRoutes
= flattenedRoutes
.concat(route
, router
.flattenRoutes(mergedPathsRoutes
$2));
8894 if (!('routes' in route
) && !('tabs' in route
&& route
.tabs
) && !('detailRoutes' in route
)) {
8895 flattenedRoutes
.push(route
);
8898 return flattenedRoutes
;
8901 // eslint-disable-next-line
8902 Router
.prototype.parseRouteUrl
= function parseRouteUrl (url
) {
8903 if (!url
) { return {}; }
8904 var query
= Utils
.parseUrlQuery(url
);
8905 var hash
= url
.split('#')[1];
8907 var path
= url
.split('#')[0].split('?')[0];
8917 // eslint-disable-next-line
8918 Router
.prototype.constructRouteUrl
= function constructRouteUrl (route
, ref
) {
8919 if ( ref
=== void 0 ) ref
= {};
8920 var params
= ref
.params
;
8921 var query
= ref
.query
;
8923 var path
= route
.path
;
8924 var toUrl
= pathToRegexp_1
.compile(path
);
8927 url
= toUrl(params
|| {});
8929 throw new Error(("Framework7: error constructing route URL from passed params:\nRoute: " + path
+ "\n" + (error
.toString())));
8933 if (typeof query
=== 'string') { url
+= "?" + query
; }
8934 else { url
+= "?" + (Utils
.serializeObject(query
)); }
8940 Router
.prototype.findTabRoute
= function findTabRoute (tabEl
) {
8942 var $tabEl
= $(tabEl
);
8943 var parentPath
= router
.currentRoute
.route
.parentPath
;
8944 var tabId
= $tabEl
.attr('id');
8945 var flattenedRoutes
= router
.flattenRoutes(router
.routes
);
8947 flattenedRoutes
.forEach(function (route
) {
8949 route
.parentPath
=== parentPath
8951 && route
.tab
.id
=== tabId
8953 foundTabRoute
= route
;
8956 return foundTabRoute
;
8959 Router
.prototype.findRouteByKey
= function findRouteByKey (key
, value
) {
8961 var routes
= router
.routes
;
8962 var flattenedRoutes
= router
.flattenRoutes(routes
);
8965 flattenedRoutes
.forEach(function (route
) {
8966 if (matchingRoute
) { return; }
8967 if (route
[key
] === value
) {
8968 matchingRoute
= route
;
8971 return matchingRoute
;
8974 Router
.prototype.findMatchingRoute
= function findMatchingRoute (url
) {
8975 if (!url
) { return undefined; }
8977 var routes
= router
.routes
;
8978 var flattenedRoutes
= router
.flattenRoutes(routes
);
8979 var ref
= router
.parseRouteUrl(url
);
8980 var path
= ref
.path
;
8981 var query
= ref
.query
;
8982 var hash
= ref
.hash
;
8983 var params
= ref
.params
;
8985 flattenedRoutes
.forEach(function (route
) {
8986 if (matchingRoute
) { return; }
8989 var pathsToMatch
= [route
.path
];
8991 if (typeof route
.alias
=== 'string') { pathsToMatch
.push(route
.alias
); }
8992 else if (Array
.isArray(route
.alias
)) {
8993 route
.alias
.forEach(function (aliasPath
) {
8994 pathsToMatch
.push(aliasPath
);
9000 pathsToMatch
.forEach(function (pathToMatch
) {
9001 if (matched
) { return; }
9002 matched
= pathToRegexp_1(pathToMatch
, keys
).exec(path
);
9006 keys
.forEach(function (keyObj
, index
) {
9007 if (typeof keyObj
.name
=== 'number') { return; }
9008 var paramValue
= matched
[index
+ 1];
9009 if (typeof paramValue
=== 'undefined' || paramValue
=== null) {
9010 params
[keyObj
.name
] = paramValue
;
9012 params
[keyObj
.name
] = decodeURIComponent(paramValue
);
9017 if (route
.parentPath
) {
9018 parentPath
= path
.split('/').slice(0, route
.parentPath
.split('/').length
- 1).join('/');
9027 parentPath
: parentPath
,
9033 return matchingRoute
;
9036 // eslint-disable-next-line
9037 Router
.prototype.replaceRequestUrlParams
= function replaceRequestUrlParams (url
, options
) {
9038 if ( url
=== void 0 ) url
= '';
9039 if ( options
=== void 0 ) options
= {};
9041 var compiledUrl
= url
;
9042 if (typeof compiledUrl
=== 'string'
9043 && compiledUrl
.indexOf('{{') >= 0
9046 && options
.route
.params
9047 && Object
.keys(options
.route
.params
).length
9049 Object
.keys(options
.route
.params
).forEach(function (paramName
) {
9050 var regExp
= new RegExp(("{{" + paramName
+ "}}"), 'g');
9051 compiledUrl
= compiledUrl
.replace(regExp
, options
.route
.params
[paramName
] || '');
9057 Router
.prototype.removeFromXhrCache
= function removeFromXhrCache (url
) {
9059 var xhrCache
= router
.cache
.xhr
;
9061 for (var i
= 0; i
< xhrCache
.length
; i
+= 1) {
9062 if (xhrCache
[i
].url
=== url
) { index
= i
; }
9064 if (index
!== false) { xhrCache
.splice(index
, 1); }
9067 Router
.prototype.xhrRequest
= function xhrRequest (requestUrl
, options
) {
9069 var params
= router
.params
;
9070 var ignoreCache
= options
.ignoreCache
;
9071 var url
= requestUrl
;
9073 var hasQuery
= url
.indexOf('?') >= 0;
9074 if (params
.passRouteQueryToRequest
9077 && options
.route
.query
9078 && Object
.keys(options
.route
.query
).length
9080 url
+= "" + (hasQuery
? '&' : '?') + (Utils
.serializeObject(options
.route
.query
));
9084 if (params
.passRouteParamsToRequest
9087 && options
.route
.params
9088 && Object
.keys(options
.route
.params
).length
9090 url
+= "" + (hasQuery
? '&' : '?') + (Utils
.serializeObject(options
.route
.params
));
9094 if (url
.indexOf('{{') >= 0) {
9095 url
= router
.replaceRequestUrlParams(url
, options
);
9097 // should we ignore get params or not
9098 if (params
.xhrCacheIgnoreGetParameters
&& url
.indexOf('?') >= 0) {
9099 url
= url
.split('?')[0];
9101 return new Promise(function (resolve
, reject
) {
9102 if (params
.xhrCache
&& !ignoreCache
&& url
.indexOf('nocache') < 0 && params
.xhrCacheIgnore
.indexOf(url
) < 0) {
9103 for (var i
= 0; i
< router
.cache
.xhr
.length
; i
+= 1) {
9104 var cachedUrl
= router
.cache
.xhr
[i
];
9105 if (cachedUrl
.url
=== url
) {
9107 if (Utils
.now() - cachedUrl
.time
< params
.xhrCacheDuration
) {
9109 resolve(cachedUrl
.content
);
9115 router
.xhr
= router
.app
.request({
9118 beforeSend
: function beforeSend(xhr
) {
9119 router
.emit('routerAjaxStart', xhr
, options
);
9121 complete
: function complete(xhr
, status
) {
9122 router
.emit('routerAjaxComplete', xhr
);
9123 if ((status
!== 'error' && status
!== 'timeout' && (xhr
.status
>= 200 && xhr
.status
< 300)) || xhr
.status
=== 0) {
9124 if (params
.xhrCache
&& xhr
.responseText
!== '') {
9125 router
.removeFromXhrCache(url
);
9126 router
.cache
.xhr
.push({
9129 content
: xhr
.responseText
,
9132 router
.emit('routerAjaxSuccess', xhr
, options
);
9133 resolve(xhr
.responseText
);
9135 router
.emit('routerAjaxError', xhr
, options
);
9139 error
: function error(xhr
) {
9140 router
.emit('routerAjaxError', xhr
, options
);
9147 // Remove theme elements
9148 Router
.prototype.removeThemeElements
= function removeThemeElements (el
) {
9150 var theme
= router
.app
.theme
;
9152 if (theme
=== 'ios') {
9153 toRemove
= '.md-only, .aurora-only, .if-md, .if-aurora, .if-not-ios, .not-ios';
9154 } else if (theme
=== 'md') {
9155 toRemove
= '.ios-only, .aurora-only, .if-ios, .if-aurora, .if-not-md, .not-md';
9156 } else if (theme
=== 'aurora') {
9157 toRemove
= '.ios-only, .md-only, .if-ios, .if-md, .if-not-aurora, .not-aurora';
9159 $(el
).find(toRemove
).remove();
9162 Router
.prototype.getPageData
= function getPageData (pageEl
, navbarEl
, from, to
, route
, pageFromEl
) {
9163 if ( route
=== void 0 ) route
= {};
9166 var $pageEl
= $(pageEl
).eq(0);
9167 var $navbarEl
= $(navbarEl
).eq(0);
9168 var currentPage
= $pageEl
[0].f7Page
|| {};
9171 if ((from === 'next' && to
=== 'current') || (from === 'current' && to
=== 'previous')) { direction
= 'forward'; }
9172 if ((from === 'current' && to
=== 'next') || (from === 'previous' && to
=== 'current')) { direction
= 'backward'; }
9173 if (currentPage
&& !currentPage
.fromPage
) {
9174 var $pageFromEl
= $(pageFromEl
);
9175 if ($pageFromEl
.length
) {
9176 pageFrom
= $pageFromEl
[0].f7Page
;
9179 pageFrom
= currentPage
.pageFrom
|| pageFrom
;
9180 if (pageFrom
&& pageFrom
.pageFrom
) {
9181 pageFrom
.pageFrom
= null;
9191 $navbarEl
: $navbarEl
,
9192 navbarEl
: $navbarEl
[0],
9193 name
: $pageEl
.attr('data-name'),
9197 direction
: direction
,
9198 route
: currentPage
.route
? currentPage
.route
: route
,
9202 $pageEl
[0].f7Page
= page
;
9207 Router
.prototype.pageCallback
= function pageCallback (callback
, pageEl
, navbarEl
, from, to
, options
, pageFromEl
) {
9208 if ( options
=== void 0 ) options
= {};
9210 if (!pageEl
) { return; }
9212 var $pageEl
= $(pageEl
);
9213 if (!$pageEl
.length
) { return; }
9214 var $navbarEl
= $(navbarEl
);
9215 var route
= options
.route
;
9216 var restoreScrollTopOnBack
= router
.params
.restoreScrollTopOnBack
9218 router
.params
.masterDetailBreakpoint
> 0
9219 && $pageEl
.hasClass('page-master')
9220 && router
.app
.width
>= router
.params
.masterDetailBreakpoint
9222 var keepAlive
= $pageEl
[0].f7Page
&& $pageEl
[0].f7Page
.route
&& $pageEl
[0].f7Page
.route
.route
&& $pageEl
[0].f7Page
.route
.route
.keepAlive
;
9224 if (callback
=== 'beforeRemove' && keepAlive
) {
9225 callback
= 'beforeUnmount'; // eslint-disable-line
9228 var camelName
= "page" + (callback
[0].toUpperCase() + callback
.slice(1, callback
.length
));
9229 var colonName
= "page:" + (callback
.toLowerCase());
9232 if (callback
=== 'beforeRemove' && $pageEl
[0].f7Page
) {
9233 page
= Utils
.extend($pageEl
[0].f7Page
, { from: from, to
: to
, position
: from });
9235 page
= router
.getPageData($pageEl
[0], $navbarEl
[0], from, to
, route
, pageFromEl
);
9237 page
.swipeBack
= !!options
.swipeBack
;
9239 var ref
= options
.route
? options
.route
.route
: {};
9240 var on
= ref
.on
; if ( on
=== void 0 ) on
= {};
9241 var once
= ref
.once
; if ( once
=== void 0 ) once
= {};
9243 Utils
.extend(on
, options
.on
);
9246 Utils
.extend(once
, options
.once
);
9249 function attachEvents() {
9250 if ($pageEl
[0].f7RouteEventsAttached
) { return; }
9251 $pageEl
[0].f7RouteEventsAttached
= true;
9252 if (on
&& Object
.keys(on
).length
> 0) {
9253 $pageEl
[0].f7RouteEventsOn
= on
;
9254 Object
.keys(on
).forEach(function (eventName
) {
9255 on
[eventName
] = on
[eventName
].bind(router
);
9256 $pageEl
.on(Utils
.eventNameToColonCase(eventName
), on
[eventName
]);
9259 if (once
&& Object
.keys(once
).length
> 0) {
9260 $pageEl
[0].f7RouteEventsOnce
= once
;
9261 Object
.keys(once
).forEach(function (eventName
) {
9262 once
[eventName
] = once
[eventName
].bind(router
);
9263 $pageEl
.once(Utils
.eventNameToColonCase(eventName
), once
[eventName
]);
9268 function detachEvents() {
9269 if (!$pageEl
[0].f7RouteEventsAttached
) { return; }
9270 if ($pageEl
[0].f7RouteEventsOn
) {
9271 Object
.keys($pageEl
[0].f7RouteEventsOn
).forEach(function (eventName
) {
9272 $pageEl
.off(Utils
.eventNameToColonCase(eventName
), $pageEl
[0].f7RouteEventsOn
[eventName
]);
9275 if ($pageEl
[0].f7RouteEventsOnce
) {
9276 Object
.keys($pageEl
[0].f7RouteEventsOnce
).forEach(function (eventName
) {
9277 $pageEl
.off(Utils
.eventNameToColonCase(eventName
), $pageEl
[0].f7RouteEventsOnce
[eventName
]);
9280 $pageEl
[0].f7RouteEventsAttached
= null;
9281 $pageEl
[0].f7RouteEventsOn
= null;
9282 $pageEl
[0].f7RouteEventsOnce
= null;
9283 delete $pageEl
[0].f7RouteEventsAttached
;
9284 delete $pageEl
[0].f7RouteEventsOn
;
9285 delete $pageEl
[0].f7RouteEventsOnce
;
9288 if (callback
=== 'mounted') {
9291 if (callback
=== 'init') {
9292 if (restoreScrollTopOnBack
&& (from === 'previous' || !from) && to
=== 'current' && router
.scrollHistory
[page
.route
.url
] && !$pageEl
.hasClass('no-restore-scroll')) {
9293 var $pageContent
= $pageEl
.find('.page-content');
9294 if ($pageContent
.length
> 0) {
9295 // eslint-disable-next-line
9296 $pageContent
= $pageContent
.filter(function (pageContentIndex
, pageContentEl
) {
9298 $(pageContentEl
).parents('.tab:not(.tab-active)').length
=== 0
9299 && !$(pageContentEl
).is('.tab:not(.tab-active)')
9303 $pageContent
.scrollTop(router
.scrollHistory
[page
.route
.url
]);
9306 if ($pageEl
[0].f7PageInitialized
) {
9307 $pageEl
.trigger('page:reinit', page
);
9308 router
.emit('pageReinit', page
);
9311 $pageEl
[0].f7PageInitialized
= true;
9313 if (restoreScrollTopOnBack
&& callback
=== 'beforeOut' && from === 'current' && to
=== 'previous') {
9314 // Save scroll position
9315 var $pageContent
$1 = $pageEl
.find('.page-content');
9316 if ($pageContent
$1.length
> 0) {
9317 // eslint-disable-next-line
9318 $pageContent
$1 = $pageContent
$1.filter(function (pageContentIndex
, pageContentEl
) {
9320 $(pageContentEl
).parents('.tab:not(.tab-active)').length
=== 0
9321 && !$(pageContentEl
).is('.tab:not(.tab-active)')
9325 router
.scrollHistory
[page
.route
.url
] = $pageContent
$1.scrollTop();
9327 if (restoreScrollTopOnBack
&& callback
=== 'beforeOut' && from === 'current' && to
=== 'next') {
9328 // Delete scroll position
9329 delete router
.scrollHistory
[page
.route
.url
];
9332 $pageEl
.trigger(colonName
, page
);
9333 router
.emit(camelName
, page
);
9335 if (callback
=== 'beforeRemove' || callback
=== 'beforeUnmount') {
9338 if ($pageEl
[0].f7Page
&& $pageEl
[0].f7Page
.navbarEl
) {
9339 delete $pageEl
[0].f7Page
.navbarEl
.f7Page
;
9341 $pageEl
[0].f7Page
= null;
9346 Router
.prototype.saveHistory
= function saveHistory () {
9348 router
.view
.history
= router
.history
;
9349 if (router
.params
.pushState
) {
9350 win
.localStorage
[("f7router-" + (router
.view
.id
) + "-history")] = JSON
.stringify(router
.history
);
9354 Router
.prototype.restoreHistory
= function restoreHistory () {
9356 if (router
.params
.pushState
&& win
.localStorage
[("f7router-" + (router
.view
.id
) + "-history")]) {
9357 router
.history
= JSON
.parse(win
.localStorage
[("f7router-" + (router
.view
.id
) + "-history")]);
9358 router
.view
.history
= router
.history
;
9362 Router
.prototype.clearHistory
= function clearHistory () {
9364 router
.history
= [];
9365 if (router
.view
) { router
.view
.history
= []; }
9366 router
.saveHistory();
9369 Router
.prototype.updateCurrentUrl
= function updateCurrentUrl (newUrl
) {
9371 appRouterCheck(router
, 'updateCurrentUrl');
9373 if (router
.history
.length
) {
9374 router
.history
[router
.history
.length
- 1] = newUrl
;
9376 router
.history
.push(newUrl
);
9379 // Update current route params
9380 var ref
= router
.parseRouteUrl(newUrl
);
9381 var query
= ref
.query
;
9382 var hash
= ref
.hash
;
9383 var params
= ref
.params
;
9385 var path
= ref
.path
;
9386 if (router
.currentRoute
) {
9387 Utils
.extend(router
.currentRoute
, {
9396 if (router
.params
.pushState
) {
9397 var pushStateRoot
= router
.params
.pushStateRoot
|| '';
9403 pushStateRoot
+ router
.params
.pushStateSeparator
+ newUrl
9408 router
.saveHistory();
9410 router
.emit('routeUrlUpdate', router
.currentRoute
, router
);
9413 Router
.prototype.init
= function init () {
9415 var app
= router
.app
;
9416 var view
= router
.view
;
9421 (view
&& router
.params
.iosSwipeBack
&& app
.theme
=== 'ios')
9422 || (view
&& router
.params
.mdSwipeBack
&& app
.theme
=== 'md')
9423 || (view
&& router
.params
.auroraSwipeBack
&& app
.theme
=== 'aurora')
9429 // Dynamic not separated navbbar
9430 if (router
.dynamicNavbar
&& !router
.separateNavbar
) {
9431 router
.$el
.addClass('router-dynamic-navbar-inside');
9434 var initUrl
= router
.params
.url
;
9435 var documentUrl
= doc
.location
.href
.split(doc
.location
.origin
)[1];
9436 var historyRestored
;
9437 var ref
= router
.params
;
9438 var pushState
= ref
.pushState
;
9439 var pushStateOnLoad
= ref
.pushStateOnLoad
;
9440 var pushStateSeparator
= ref
.pushStateSeparator
;
9441 var pushStateAnimateOnLoad
= ref
.pushStateAnimateOnLoad
;
9442 var ref
$1 = router
.params
;
9443 var pushStateRoot
= ref
$1.pushStateRoot
;
9444 if (win
.cordova
&& pushState
&& !pushStateSeparator
&& !pushStateRoot
&& doc
.location
.pathname
.indexOf('index.html')) {
9445 // eslint-disable-next-line
9446 console
.warn('Framework7: wrong or not complete pushState configuration, trying to guess pushStateRoot');
9447 pushStateRoot
= doc
.location
.pathname
.split('index.html')[0];
9449 if (!pushState
|| !pushStateOnLoad
) {
9451 initUrl
= documentUrl
;
9453 if (doc
.location
.search
&& initUrl
.indexOf('?') < 0) {
9454 initUrl
+= doc
.location
.search
;
9456 if (doc
.location
.hash
&& initUrl
.indexOf('#') < 0) {
9457 initUrl
+= doc
.location
.hash
;
9460 if (pushStateRoot
&& documentUrl
.indexOf(pushStateRoot
) >= 0) {
9461 documentUrl
= documentUrl
.split(pushStateRoot
)[1];
9462 if (documentUrl
=== '') { documentUrl
= '/'; }
9464 if (pushStateSeparator
.length
> 0 && documentUrl
.indexOf(pushStateSeparator
) >= 0) {
9465 initUrl
= documentUrl
.split(pushStateSeparator
)[1];
9467 initUrl
= documentUrl
;
9469 router
.restoreHistory();
9470 if (router
.history
.indexOf(initUrl
) >= 0) {
9471 router
.history
= router
.history
.slice(0, router
.history
.indexOf(initUrl
) + 1);
9472 } else if (router
.params
.url
=== initUrl
) {
9473 router
.history
= [initUrl
];
9474 } else if (History
.state
&& History
.state
[view
.id
] && History
.state
[view
.id
].url
=== router
.history
[router
.history
.length
- 1]) {
9475 initUrl
= router
.history
[router
.history
.length
- 1];
9477 router
.history
= [documentUrl
.split(pushStateSeparator
)[0] || '/', initUrl
];
9479 if (router
.history
.length
> 1) {
9480 historyRestored
= true;
9482 router
.history
= [];
9484 router
.saveHistory();
9487 if (router
.history
.length
> 1) {
9489 currentRoute
= router
.findMatchingRoute(router
.history
[0]);
9490 if (!currentRoute
) {
9491 currentRoute
= Utils
.extend(router
.parseRouteUrl(router
.history
[0]), {
9493 url
: router
.history
[0],
9494 path
: router
.history
[0].split('?')[0],
9500 currentRoute
= router
.findMatchingRoute(initUrl
);
9501 if (!currentRoute
) {
9502 currentRoute
= Utils
.extend(router
.parseRouteUrl(initUrl
), {
9505 path
: initUrl
.split('?')[0],
9511 if (router
.params
.stackPages
) {
9512 router
.$el
.children('.page').each(function (index
, pageEl
) {
9513 var $pageEl
= $(pageEl
);
9514 router
.initialPages
.push($pageEl
[0]);
9515 if (router
.separateNavbar
&& $pageEl
.children('.navbar').length
> 0) {
9516 router
.initialNavbars
.push($pageEl
.children('.navbar').find('.navbar-inner')[0]);
9521 if (router
.$el
.children('.page:not(.stacked)').length
=== 0 && initUrl
) {
9522 // No pages presented in DOM, reload new page
9523 router
.navigate(initUrl
, {
9525 reloadCurrent
: true,
9529 // Init current DOM page
9531 router
.currentRoute
= currentRoute
;
9532 router
.$el
.children('.page:not(.stacked)').each(function (index
, pageEl
) {
9533 var $pageEl
= $(pageEl
);
9535 $pageEl
.addClass('page-current');
9536 if (router
.separateNavbar
) {
9537 $navbarInnerEl
= $pageEl
.children('.navbar').children('.navbar-inner');
9538 if ($navbarInnerEl
.length
> 0) {
9539 if (!router
.$navbarEl
.parents(doc
).length
) {
9540 router
.$el
.prepend(router
.$navbarEl
);
9542 $navbarInnerEl
.addClass('navbar-current');
9543 router
.$navbarEl
.append($navbarInnerEl
);
9544 if ($navbarInnerEl
.children('.title-large').length
) {
9545 $navbarInnerEl
.addClass('navbar-inner-large');
9547 $pageEl
.children('.navbar').remove();
9549 router
.$navbarEl
.addClass('navbar-hidden');
9550 if ($navbarInnerEl
.children('.title-large').length
) {
9551 router
.$navbarEl
.addClass('navbar-hidden navbar-large-hidden');
9555 if (router
.currentRoute
&& router
.currentRoute
.route
&& router
.currentRoute
.route
.master
&& router
.params
.masterDetailBreakpoint
> 0) {
9556 $pageEl
.addClass('page-master');
9557 $pageEl
.trigger('page:role', { role
: 'master' });
9558 if ($navbarInnerEl
&& $navbarInnerEl
.length
) {
9559 $navbarInnerEl
.addClass('navbar-master');
9563 route
: router
.currentRoute
,
9565 if (router
.currentRoute
&& router
.currentRoute
.route
&& router
.currentRoute
.route
.options
) {
9566 Utils
.extend(initOptions
, router
.currentRoute
.route
.options
);
9568 router
.currentPageEl
= $pageEl
[0];
9569 if (router
.separateNavbar
&& $navbarInnerEl
.length
) {
9570 router
.currentNavbarEl
= $navbarInnerEl
[0];
9572 router
.removeThemeElements($pageEl
);
9573 if (router
.separateNavbar
&& $navbarInnerEl
.length
) {
9574 router
.removeThemeElements($navbarInnerEl
);
9576 if (initOptions
.route
.route
.tab
) {
9578 router
.tabLoad(initOptions
.route
.route
.tab
, Utils
.extend({}, initOptions
));
9580 router
.pageCallback('init', $pageEl
, $navbarInnerEl
, 'current', undefined, initOptions
);
9582 if (historyRestored
) {
9583 router
.navigate(initUrl
, {
9587 animate
: pushStateAnimateOnLoad
,
9589 pageAfterIn
: function pageAfterIn() {
9590 var preloadPreviousPage
= router
.params
.preloadPreviousPage
|| router
.params
[((app
.theme
) + "SwipeBack")];
9591 if (preloadPreviousPage
&& router
.history
.length
> 2) {
9592 router
.back({ preload
: true });
9598 if (!historyRestored
&& !hasTabRoute
) {
9599 router
.history
.push(initUrl
);
9600 router
.saveHistory();
9603 if (initUrl
&& pushState
&& pushStateOnLoad
&& (!History
.state
|| !History
.state
[view
.id
])) {
9604 History
.initViewState(view
.id
, {
9608 router
.emit('local::init routerInit', router
);
9611 Router
.prototype.destroy
= function destroy () {
9614 router
.emit('local::destroy routerDestroy', router
);
9616 // Delete props & methods
9617 Object
.keys(router
).forEach(function (routerProp
) {
9618 router
[routerProp
] = null;
9619 delete router
[routerProp
];
9626 }(Framework7Class
));
9629 Router
.prototype.forward
= forward
;
9630 Router
.prototype.load
= load
;
9631 Router
.prototype.navigate
= navigate
;
9632 Router
.prototype.refreshPage
= refreshPage
;
9634 Router
.prototype.tabLoad
= tabLoad
;
9635 Router
.prototype.tabRemove
= tabRemove
;
9637 Router
.prototype.modalLoad
= modalLoad
;
9638 Router
.prototype.modalRemove
= modalRemove
;
9640 Router
.prototype.backward
= backward
;
9641 Router
.prototype.loadBack
= loadBack
;
9642 Router
.prototype.back
= back
;
9643 // Clear previoius pages from the DOM
9644 Router
.prototype.clearPreviousPages
= clearPreviousPages
;
9646 Router
.prototype.clearPreviousHistory
= clearPreviousHistory
;
9648 var RouterModule
= {
9660 create
: function create() {
9661 var instance
= this;
9664 if (instance
.params
.router
) {
9665 instance
.router
= new Router(instance
.app
, instance
);
9669 instance
.router
= new Router(instance
);
9674 var View
= /*@__PURE__*/(function (Framework7Class
) {
9675 function View(appInstance
, el
, viewParams
) {
9676 if ( viewParams
=== void 0 ) viewParams
= {};
9678 Framework7Class
.call(this, viewParams
, [appInstance
]);
9680 var app
= appInstance
;
9689 // Default View params
9690 view
.params
= Utils
.extend(defaults
, app
.params
.view
, viewParams
);
9693 if (view
.params
.routes
.length
> 0) {
9694 view
.routes
= view
.params
.routes
;
9696 view
.routes
= [].concat(app
.routes
, view
.params
.routesAdd
);
9701 if (typeof el
=== 'string') { selector
= el
; }
9703 // Supposed to be HTMLElement or Dom7
9704 selector
= ($el
.attr('id') ? ("#" + ($el
.attr('id'))) : '') + ($el
.attr('class') ? ("." + ($el
.attr('class').replace(/ /g
, '.').replace('.active', ''))) : '');
9709 if (app
.theme
=== 'ios' && view
.params
.iosDynamicNavbar
&& view
.params
.iosSeparateDynamicNavbar
) {
9710 $navbarEl
= $el
.children('.navbar').eq(0);
9711 if ($navbarEl
.length
=== 0) {
9712 $navbarEl
= $('<div class="navbar"></div>');
9717 Utils
.extend(false, view
, {
9721 name
: view
.params
.name
,
9722 main
: view
.params
.main
|| $el
.hasClass('view-main'),
9723 $navbarEl
: $navbarEl
,
9724 navbarEl
: $navbarEl
? $navbarEl
[0] : undefined,
9731 $el
[0].f7View
= view
;
9737 app
.views
.push(view
);
9739 app
.views
.main
= view
;
9742 app
.views
[view
.name
] = view
;
9746 view
.index
= app
.views
.indexOf(view
);
9751 viewId
= "view_" + (view
.name
);
9752 } else if (view
.main
) {
9753 viewId
= 'view_main';
9755 viewId
= "view_" + (view
.index
);
9760 if (app
.initialized
) {
9763 app
.on('init', function () {
9771 if ( Framework7Class
) View
.__proto__
= Framework7Class
;
9772 View
.prototype = Object
.create( Framework7Class
&& Framework7Class
.prototype );
9773 View
.prototype.constructor = View
;
9775 View
.prototype.destroy
= function destroy () {
9779 view
.$el
.trigger('view:beforedestroy', view
);
9780 view
.emit('local::beforeDestroy viewBeforeDestroy', view
);
9782 app
.off('resize', view
.checkmasterDetailBreakpoint
);
9785 app
.views
.main
= null;
9786 delete app
.views
.main
;
9787 } else if (view
.name
) {
9788 app
.views
[view
.name
] = null;
9789 delete app
.views
[view
.name
];
9791 view
.$el
[0].f7View
= null;
9792 delete view
.$el
[0].f7View
;
9794 app
.views
.splice(app
.views
.indexOf(view
), 1);
9797 if (view
.params
.router
&& view
.router
) {
9798 view
.router
.destroy();
9801 view
.emit('local::destroy viewDestroy', view
);
9803 // Delete props & methods
9804 Object
.keys(view
).forEach(function (viewProp
) {
9805 view
[viewProp
] = null;
9806 delete view
[viewProp
];
9812 View
.prototype.checkmasterDetailBreakpoint
= function checkmasterDetailBreakpoint () {
9815 var wasMasterDetail
= view
.$el
.hasClass('view-master-detail');
9816 if (app
.width
>= view
.params
.masterDetailBreakpoint
) {
9817 view
.$el
.addClass('view-master-detail');
9818 if (!wasMasterDetail
) {
9819 view
.emit('local::masterDetailBreakpoint viewMasterDetailBreakpoint');
9820 view
.$el
.trigger('view:masterDetailBreakpoint', view
);
9823 view
.$el
.removeClass('view-master-detail');
9824 if (wasMasterDetail
) {
9825 view
.emit('local::masterDetailBreakpoint viewMasterDetailBreakpoint');
9826 view
.$el
.trigger('view:masterDetailBreakpoint', view
);
9831 View
.prototype.initMasterDetail
= function initMasterDetail () {
9834 view
.checkmasterDetailBreakpoint
= view
.checkmasterDetailBreakpoint
.bind(view
);
9835 view
.checkmasterDetailBreakpoint();
9836 app
.on('resize', view
.checkmasterDetailBreakpoint
);
9839 View
.prototype.init
= function init () {
9841 if (view
.params
.router
) {
9842 if (view
.params
.masterDetailBreakpoint
> 0) {
9843 view
.initMasterDetail();
9846 view
.$el
.trigger('view:init', view
);
9847 view
.emit('local::init viewInit', view
);
9852 }(Framework7Class
));
9855 View
.use(RouterModule
);
9857 function initClicks(app
) {
9858 function handleClicks(e
) {
9859 var $clickedEl
= $(e
.target
);
9860 var $clickedLinkEl
= $clickedEl
.closest('a');
9861 var isLink
= $clickedLinkEl
.length
> 0;
9862 var url
= isLink
&& $clickedLinkEl
.attr('href');
9863 // const isTabLink = isLink && $clickedLinkEl.hasClass('tab-link') && ($clickedLinkEl.attr('data-tab') || (url && url.indexOf('#') === 0));
9865 // Check if link is external
9867 // eslint-disable-next-line
9868 if ($clickedLinkEl
.is(app
.params
.clicks
.externalLinks
) || (url
&& url
.indexOf('javascript:') >= 0)) {
9869 var target
= $clickedLinkEl
.attr('target');
9873 && win
.cordova
.InAppBrowser
9874 && (target
=== '_system' || target
=== '_blank')
9877 win
.cordova
.InAppBrowser
.open(url
, target
);
9884 Object
.keys(app
.modules
).forEach(function (moduleName
) {
9885 var moduleClicks
= app
.modules
[moduleName
].clicks
;
9886 if (!moduleClicks
) { return; }
9887 if (e
.preventF7Router
) { return; }
9888 Object
.keys(moduleClicks
).forEach(function (clickSelector
) {
9889 var matchingClickedElement
= $clickedEl
.closest(clickSelector
).eq(0);
9890 if (matchingClickedElement
.length
> 0) {
9891 moduleClicks
[clickSelector
].call(app
, matchingClickedElement
, matchingClickedElement
.dataset(), e
);
9897 var clickedLinkData
= {};
9900 clickedLinkData
= $clickedLinkEl
.dataset();
9904 if (e
.preventF7Router
) { return; }
9905 if ($clickedLinkEl
.hasClass('prevent-router') || $clickedLinkEl
.hasClass('router-prevent')) { return; }
9907 var validUrl
= url
&& url
.length
> 0 && url
[0] !== '#';
9908 if (validUrl
|| $clickedLinkEl
.hasClass('back')) {
9910 if (clickedLinkData
.view
) {
9911 view
= $(clickedLinkData
.view
)[0].f7View
;
9913 view
= $clickedEl
.parents('.view')[0] && $clickedEl
.parents('.view')[0].f7View
;
9914 if (!$clickedLinkEl
.hasClass('back') && view
&& view
.params
.linksView
) {
9915 if (typeof view
.params
.linksView
=== 'string') { view
= $(view
.params
.linksView
)[0].f7View
; }
9916 else if (view
.params
.linksView
instanceof View
) { view
= view
.params
.linksView
; }
9920 if (app
.views
.main
) { view
= app
.views
.main
; }
9922 if (!view
|| !view
.router
) { return; }
9923 if (clickedLinkData
.context
&& typeof clickedLinkData
.context
=== 'string') {
9925 clickedLinkData
.context
= JSON
.parse(clickedLinkData
.context
);
9927 // something wrong there
9930 if ($clickedLinkEl
[0].f7RouteProps
) {
9931 clickedLinkData
.props
= $clickedLinkEl
[0].f7RouteProps
;
9933 if ($clickedLinkEl
.hasClass('back')) { view
.router
.back(url
, clickedLinkData
); }
9934 else { view
.router
.navigate(url
, clickedLinkData
); }
9938 app
.on('click', handleClicks
);
9940 // TODO: check if need this in iOS
9941 // Prevent scrolling on overlays
9942 // function preventScrolling(e) {
9943 // e.preventDefault();
9945 // if (Support.touch && !Device.android) {
9946 // const activeListener = Support.passiveListener ? { passive: false, capture: false } : false;
9947 // $(document).on((app.params.touch.fastClicks ? 'touchstart' : 'touchmove'), '.panel-backdrop, .dialog-backdrop, .preloader-backdrop, .popup-backdrop, .searchbar-backdrop', preventScrolling, activeListener);
9950 var ClicksModule
= {
9955 externalLinks
: '.external',
9959 init
: function init() {
9966 var RouterTemplateLoaderModule
= {
9967 name
: 'routerTemplateLoader',
9969 templateLoader
: function templateLoader(template
, templateUrl
, options
, resolve
, reject
) {
9971 function compile(t
) {
9975 context
= options
.context
|| {};
9976 if (typeof context
=== 'function') { context
= context
.call(router
); }
9977 else if (typeof context
=== 'string') {
9979 context
= JSON
.parse(context
);
9985 if (typeof t
=== 'function') {
9986 compiledHtml
= t(context
);
9988 compiledHtml
= Template7
.compile(t
)(Utils
.extend({}, context
|| {}, {
9990 $root
: Utils
.extend({}, router
.app
.data
, router
.app
.methods
),
9991 $route
: options
.route
,
9992 $f7route
: options
.route
,
9996 ios
: router
.app
.theme
=== 'ios',
9997 md
: router
.app
.theme
=== 'md',
9998 aurora
: router
.app
.theme
=== 'aurora',
10006 resolve(compiledHtml
, { context
: context
});
10011 router
.xhr
.abort();
10012 router
.xhr
= false;
10015 .xhrRequest(templateUrl
, options
)
10016 .then(function (templateContent
) {
10017 compile(templateContent
);
10019 .catch(function () {
10027 modalTemplateLoader
: function modalTemplateLoader(template
, templateUrl
, options
, resolve
, reject
) {
10029 return router
.templateLoader(template
, templateUrl
, options
, function (html
) {
10034 tabTemplateLoader
: function tabTemplateLoader(template
, templateUrl
, options
, resolve
, reject
) {
10036 return router
.templateLoader(template
, templateUrl
, options
, function (html
) {
10041 pageTemplateLoader
: function pageTemplateLoader(template
, templateUrl
, options
, resolve
, reject
) {
10043 return router
.templateLoader(template
, templateUrl
, options
, function (html
, newOptions
) {
10044 if ( newOptions
=== void 0 ) newOptions
= {};
10046 resolve(router
.getPageEl(html
), newOptions
);
10052 var RouterComponentLoaderModule
= {
10053 name
: 'routerComponentLoader',
10055 componentLoader
: function componentLoader(component
, componentUrl
, options
, resolve
, reject
) {
10056 if ( options
=== void 0 ) options
= {};
10059 var app
= router
.app
;
10060 var url
= typeof component
=== 'string' ? component
: componentUrl
;
10061 var compiledUrl
= router
.replaceRequestUrlParams(url
, options
);
10062 function compile(componentOptions
) {
10063 var context
= options
.context
|| {};
10064 if (typeof context
=== 'function') { context
= context
.call(router
); }
10065 else if (typeof context
=== 'string') {
10067 context
= JSON
.parse(context
);
10073 var extendContext
= Utils
.merge(
10077 $route
: options
.route
,
10078 $f7route
: options
.route
,
10082 ios
: app
.theme
=== 'ios',
10083 md
: app
.theme
=== 'md',
10084 aurora
: app
.theme
=== 'aurora',
10088 var createdComponent
= app
.component
.create(componentOptions
, extendContext
);
10089 resolve(createdComponent
.el
);
10091 var cachedComponent
;
10093 router
.cache
.components
.forEach(function (cached
) {
10094 if (cached
.url
=== compiledUrl
) { cachedComponent
= cached
.component
; }
10097 if (compiledUrl
&& cachedComponent
) {
10098 compile(cachedComponent
);
10099 } else if (compiledUrl
&& !cachedComponent
) {
10102 router
.xhr
.abort();
10103 router
.xhr
= false;
10106 .xhrRequest(url
, options
)
10107 .then(function (loadedComponent
) {
10108 var parsedComponent
= app
.component
.parse(loadedComponent
);
10109 router
.cache
.components
.push({
10111 component
: parsedComponent
,
10113 compile(parsedComponent
);
10115 .catch(function (err
) {
10120 compile(component
);
10124 modalComponentLoader
: function modalComponentLoader(rootEl
, component
, componentUrl
, options
, resolve
, reject
) {
10126 router
.componentLoader(component
, componentUrl
, options
, function (el
) {
10131 tabComponentLoader
: function tabComponentLoader(tabEl
, component
, componentUrl
, options
, resolve
, reject
) {
10133 router
.componentLoader(component
, componentUrl
, options
, function (el
) {
10138 pageComponentLoader
: function pageComponentLoader(routerEl
, component
, componentUrl
, options
, resolve
, reject
) {
10140 router
.componentLoader(component
, componentUrl
, options
, function (el
, newOptions
) {
10141 if ( newOptions
=== void 0 ) newOptions
= {};
10143 resolve(el
, newOptions
);
10149 var HistoryModule
= {
10155 init
: function init() {
10156 History
.init(this);
10161 var keyPrefix
= 'f7storage-';
10163 get: function get(key
) {
10164 return new Promise(function (resolve
, reject
) {
10166 var value
= JSON
.parse(win
.localStorage
.getItem(("" + keyPrefix
+ key
)));
10173 set: function set(key
, value
) {
10174 return new Promise(function (resolve
, reject
) {
10176 win
.localStorage
.setItem(("" + keyPrefix
+ key
), JSON
.stringify(value
));
10183 remove
: function remove(key
) {
10184 return new Promise(function (resolve
, reject
) {
10186 win
.localStorage
.removeItem(("" + keyPrefix
+ key
));
10193 clear
: function clear() {
10196 length
: function length() {
10199 keys
: function keys() {
10200 return new Promise(function (resolve
, reject
) {
10202 var keys
= Object
.keys(win
.localStorage
)
10203 .filter(function (keyName
) { return keyName
.indexOf(keyPrefix
) === 0; })
10204 .map(function (keyName
) { return keyName
.replace(keyPrefix
, ''); });
10211 forEach
: function forEach(callback
) {
10212 return new Promise(function (resolve
, reject
) {
10214 Object
.keys(win
.localStorage
)
10215 .filter(function (keyName
) { return keyName
.indexOf(keyPrefix
) === 0; })
10216 .forEach(function (keyName
, index
) {
10217 var key
= keyName
.replace(keyPrefix
, '');
10218 Storage
.get(key
).then(function (value
) {
10219 callback(key
, value
, index
);
10230 var StorageModule
= {
10238 function vnode(sel
, data
, children
, text
, elm
) {
10239 var key
= data
=== undefined ? undefined : data
.key
;
10240 return { sel
: sel
, data
: data
, children
: children
,
10241 text
: text
, elm
: elm
, key
: key
};
10244 var array
= Array
.isArray
;
10245 function primitive(s
) {
10246 return typeof s
=== 'string' || typeof s
=== 'number';
10249 function addNS(data
, children
, sel
) {
10250 data
.ns
= 'http://www.w3.org/2000/svg';
10251 if (sel
!== 'foreignObject' && children
!== undefined) {
10252 for (var i
= 0; i
< children
.length
; ++i
) {
10253 var childData
= children
[i
].data
;
10254 if (childData
!== undefined) {
10255 addNS(childData
, children
[i
].children
, children
[i
].sel
);
10260 function h(sel
, b
, c
) {
10261 var data
= {}, children
, text
, i
;
10262 if (c
!== undefined) {
10267 else if (primitive(c
)) {
10270 else if (c
&& c
.sel
) {
10274 else if (b
!== undefined) {
10278 else if (primitive(b
)) {
10281 else if (b
&& b
.sel
) {
10288 if (array(children
)) {
10289 for (i
= 0; i
< children
.length
; ++i
) {
10290 if (primitive(children
[i
]))
10291 { children
[i
] = vnode(undefined, undefined, undefined, children
[i
], undefined); }
10294 if (sel
[0] === 's' && sel
[1] === 'v' && sel
[2] === 'g' &&
10295 (sel
.length
=== 3 || sel
[3] === '.' || sel
[3] === '#')) {
10296 addNS(data
, children
, sel
);
10298 return vnode(sel
, data
, children
, text
, undefined);
10301 /* eslint no-use-before-define: "off" */
10303 var selfClosing
= 'area base br col command embed hr img input keygen link menuitem meta param source track wbr'.split(' ');
10304 var propsAttrs
= 'hidden checked disabled readonly selected autocomplete autofocus autoplay required multiple value indeterminate'.split(' ');
10305 var booleanProps
= 'hidden checked disabled readonly selected autocomplete autofocus autoplay required multiple readOnly indeterminate'.split(' ');
10306 var tempDom
= doc
.createElement('div');
10308 function getHooks(data
, app
, initial
, isRoot
) {
10310 if (!data
|| !data
.attrs
|| !data
.attrs
.class) { return hooks
; }
10311 var classNames
= data
.attrs
.class;
10315 var postpatch
= [];
10316 classNames
.split(' ').forEach(function (className
) {
10318 insert
.push
.apply(insert
, app
.getVnodeHooks('insert', className
));
10320 destroy
.push
.apply(destroy
, app
.getVnodeHooks('destroy', className
));
10321 update
.push
.apply(update
, app
.getVnodeHooks('update', className
));
10322 postpatch
.push
.apply(postpatch
, app
.getVnodeHooks('postpatch', className
));
10325 if (isRoot
&& !initial
) {
10326 postpatch
.push(function (oldVnode
, vnode
) {
10327 var vn
= vnode
|| oldVnode
;
10328 if (!vn
) { return; }
10329 if (vn
.data
&& vn
.data
.context
&& vn
.data
.context
.$options
.updated
) {
10330 vn
.data
.context
.$options
.updated();
10334 if (insert
.length
=== 0 && destroy
.length
=== 0 && update
.length
=== 0 && postpatch
.length
=== 0) {
10337 if (insert
.length
) {
10338 hooks
.insert = function (vnode
) {
10339 insert
.forEach(function (f
) { return f(vnode
); });
10342 if (destroy
.length
) {
10343 hooks
.destroy = function (vnode
) {
10344 destroy
.forEach(function (f
) { return f(vnode
); });
10347 if (update
.length
) {
10348 hooks
.update = function (oldVnode
, vnode
) {
10349 update
.forEach(function (f
) { return f(oldVnode
, vnode
); });
10352 if (postpatch
.length
) {
10353 hooks
.postpatch = function (oldVnode
, vnode
) {
10354 postpatch
.forEach(function (f
) { return f(oldVnode
, vnode
); });
10360 function getEventHandler(handlerString
, context
, ref
) {
10361 if ( ref
=== void 0 ) ref
= {};
10362 var stop
= ref
.stop
;
10363 var prevent
= ref
.prevent
;
10364 var once
= ref
.once
;
10369 var customArgs
= [];
10370 var needMethodBind
= true;
10372 if (handlerString
.indexOf('(') < 0) {
10373 methodName
= handlerString
;
10375 methodName
= handlerString
.split('(')[0];
10377 if (methodName
.indexOf('.') >= 0) {
10378 methodName
.split('.').forEach(function (path
, pathIndex
) {
10379 if (pathIndex
=== 0 && path
=== 'this') { return; }
10380 if (pathIndex
=== 0 && path
=== 'window') {
10381 // eslint-disable-next-line
10383 needMethodBind
= false;
10386 if (!method
) { method
= context
; }
10387 if (method
[path
]) { method
= method
[path
]; }
10389 throw new Error(("Framework7: Component doesn't have method \"" + (methodName
.split('.').slice(0, pathIndex
+ 1).join('.')) + "\""));
10393 if (!context
[methodName
]) {
10394 throw new Error(("Framework7: Component doesn't have method \"" + methodName
+ "\""));
10396 method
= context
[methodName
];
10398 if (needMethodBind
) {
10399 method
= method
.bind(context
);
10402 function handler() {
10403 var args
= [], len
= arguments
.length
;
10404 while ( len
-- ) args
[ len
] = arguments
[ len
];
10407 if (once
&& fired
) { return; }
10408 if (stop
) { e
.stopPropagation(); }
10409 if (prevent
) { e
.preventDefault(); }
10412 if (handlerString
.indexOf('(') < 0) {
10415 var handlerArguments
= handlerString
10418 .replace(/'[^']*'|"[^"]*"/g, function (a
) { return a
.replace(/,/g
, '<_comma_>'); })
10420 .map(function (a
) { return a
.replace(/<_comma_>/g, ','); });
10421 handlerArguments
.forEach(function (argument
) {
10422 var arg
= argument
.trim();
10423 // eslint-disable-next-line
10424 if (!isNaN(arg
)) { arg
= parseFloat(arg
); }
10425 else if (arg
=== 'true') { arg
= true; }
10426 else if (arg
=== 'false') { arg
= false; }
10427 else if (arg
=== 'null') { arg
= null; }
10428 else if (arg
=== 'undefined') { arg
= undefined; }
10429 else if (arg
[0] === '"') { arg
= arg
.replace(/"/g, ''); }
10430 else if (arg[0] === '\'') { arg = arg.replace(/'/g, ''); }
10431 else if (arg.indexOf('.') > 0) {
10433 arg.split('.').forEach(function (path) {
10434 if (!deepArg) { deepArg = context; }
10435 deepArg = deepArg[path];
10439 arg = context[arg];
10441 customArgs.push(arg);
10445 method.apply(void 0, customArgs);
10451 function getData(el, context, app, initial, isRoot) {
10455 var attributes = el.attributes;
10456 Array.prototype.forEach.call(attributes, function (attr) {
10457 var attrName = attr.name;
10458 var attrValue = attr.value;
10459 if (propsAttrs.indexOf(attrName) >= 0) {
10461 if (!data.props) { data.props = {}; }
10462 if (attrName === 'readonly') {
10463 attrName = 'readOnly';
10465 if (booleanProps.indexOf(attrName) >= 0) {
10466 // eslint-disable-next-line
10467 data.props[attrName] = attrValue === false ? false : true;
10469 data.props[attrName] = attrValue;
10471 } else if (attrName === 'key') {
10473 data.key = attrValue;
10474 } else if (attrName.indexOf('@') === 0) {
10476 if (!data.on) { data.on = {}; }
10477 var eventName = attrName.substr(1);
10479 var prevent = false;
10481 if (eventName.indexOf('.') >= 0) {
10482 eventName.split('.').forEach(function (eventNamePart, eventNameIndex) {
10483 if (eventNameIndex === 0) { eventName = eventNamePart; }
10485 if (eventNamePart === 'stop') { stop = true; }
10486 if (eventNamePart === 'prevent') { prevent = true; }
10487 if (eventNamePart === 'once') { once = true; }
10491 data.on[eventName] = getEventHandler(attrValue, context, { stop: stop, prevent: prevent, once: once });
10492 } else if (attrName === 'style') {
10494 if (attrValue.indexOf('{') >= 0 && attrValue.indexOf('}') >= 0) {
10496 data.style = JSON.parse(attrValue);
10498 if (!data.attrs) { data.attrs = {}; }
10499 data.attrs.style = attrValue;
10502 if (!data.attrs) { data.attrs = {}; }
10503 data.attrs.style = attrValue;
10506 // Rest of attribures
10507 if (!data.attrs) { data.attrs = {}; }
10508 data.attrs[attrName] = attrValue;
10511 if (attrName === 'id' && !data.key && !isRoot) {
10512 data.key = attrValue;
10516 var hooks = getHooks(data, app, initial, isRoot);
10517 hooks.prepatch = function (oldVnode, vnode) {
10518 if (!oldVnode || !vnode) { return; }
10519 if (oldVnode && oldVnode.data && oldVnode.data.props) {
10520 Object.keys(oldVnode.data.props).forEach(function (key) {
10521 if (booleanProps.indexOf(key) < 0) { return; }
10522 if (!vnode.data) { vnode.data = {}; }
10523 if (!vnode.data.props) { vnode.data.props = {}; }
10524 if (oldVnode.data.props[key] === true && !(key in vnode.data.props)) {
10525 vnode.data.props[key] = false;
10536 function getChildren(el, context, app, initial) {
10538 var nodes = el.childNodes;
10539 for (var i = 0; i < nodes.length; i += 1) {
10540 var childNode = nodes[i];
10541 var child = elementToVNode(childNode, context, app, initial);
10543 children.push(child);
10549 function elementToVNode(el, context, app, initial, isRoot) {
10550 if (el.nodeType === 1) {
10551 // element (statement adds inline SVG compatibility)
10552 var tagName = (el instanceof win.SVGElement) ? el.nodeName : el.nodeName.toLowerCase();
10555 getData(el, context, app, initial, isRoot),
10556 selfClosing.indexOf(tagName) >= 0 ? [] : getChildren(el, context, app, initial)
10559 if (el.nodeType === 3) {
10561 return el.textContent;
10566 function vdom (html, context, app, initial) {
10567 if ( html === void 0 ) html = '';
10569 // Save to temp dom
10570 tempDom.innerHTML = html.trim();
10574 for (var i = 0; i < tempDom.childNodes.length; i += 1) {
10575 if (!rootEl && tempDom.childNodes[i].nodeType === 1) {
10576 rootEl = tempDom.childNodes[i];
10579 var result = elementToVNode(rootEl, context, app, initial, true);
10582 tempDom.innerHTML = '';
10587 function createElement(tagName) {
10588 return document.createElement(tagName);
10590 function createElementNS(namespaceURI, qualifiedName) {
10591 return document.createElementNS(namespaceURI, qualifiedName);
10593 function createTextNode(text) {
10594 return document.createTextNode(text);
10596 function createComment(text) {
10597 return document.createComment(text);
10599 function insertBefore$1(parentNode, newNode, referenceNode) {
10600 parentNode.insertBefore(newNode, referenceNode);
10602 function removeChild(node, child) {
10603 if (!node) { return; }
10604 node.removeChild(child);
10606 function appendChild(node, child) {
10607 node.appendChild(child);
10609 function parentNode(node) {
10610 return node.parentNode;
10612 function nextSibling(node) {
10613 return node.nextSibling;
10615 function tagName(elm) {
10616 return elm.tagName;
10618 function setTextContent(node, text) {
10619 node.textContent = text;
10621 function getTextContent(node) {
10622 return node.textContent;
10624 function isElement(node) {
10625 return node.nodeType === 1;
10627 function isText(node) {
10628 return node.nodeType === 3;
10630 function isComment(node) {
10631 return node.nodeType === 8;
10634 createElement: createElement,
10635 createElementNS: createElementNS,
10636 createTextNode: createTextNode,
10637 createComment: createComment,
10638 insertBefore: insertBefore$1,
10639 removeChild: removeChild,
10640 appendChild: appendChild,
10641 parentNode: parentNode,
10642 nextSibling: nextSibling,
10644 setTextContent: setTextContent,
10645 getTextContent: getTextContent,
10646 isElement: isElement,
10648 isComment: isComment,
10651 function isUndef(s) { return s === undefined; }
10652 function isDef(s) { return s !== undefined; }
10653 var emptyNode = vnode('', {}, [], undefined, undefined);
10654 function sameVnode(vnode1, vnode2) {
10655 return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;
10657 function isVnode(vnode) {
10658 return vnode.sel !== undefined;
10660 function createKeyToOldIdx(children, beginIdx, endIdx) {
10661 var i, map = {}, key, ch;
10662 for (i = beginIdx; i <= endIdx; ++i) {
10666 if (key !== undefined)
10672 var hooks = ['create', 'update', 'remove', 'destroy', 'pre', 'post'];
10673 function init(modules, domApi) {
10674 var i, j, cbs = {};
10675 var api = domApi !== undefined ? domApi : htmlDomApi;
10676 for (i = 0; i < hooks.length; ++i) {
10677 cbs[hooks[i]] = [];
10678 for (j = 0; j < modules.length; ++j) {
10679 var hook = modules[j][hooks[i]];
10680 if (hook !== undefined) {
10681 cbs[hooks[i]].push(hook);
10685 function emptyNodeAt(elm) {
10686 var id = elm.id ? '#' + elm.id : '';
10687 var c = elm.className ? '.' + elm.className.split(' ').join('.') : '';
10688 return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm);
10690 function createRmCb(childElm, listeners) {
10691 return function rmCb() {
10692 if (--listeners === 0) {
10693 var parent_1 = api.parentNode(childElm);
10694 api.removeChild(parent_1, childElm);
10698 function createElm(vnode, insertedVnodeQueue) {
10699 var i, data = vnode.data;
10700 if (data !== undefined) {
10701 if (isDef(i = data.hook) && isDef(i = i.init)) {
10706 var children = vnode.children, sel = vnode.sel;
10708 if (isUndef(vnode.text)) {
10711 vnode.elm = api.createComment(vnode.text);
10713 else if (sel !== undefined) {
10715 var hashIdx = sel.indexOf('#');
10716 var dotIdx = sel.indexOf('.', hashIdx);
10717 var hash = hashIdx > 0 ? hashIdx : sel.length;
10718 var dot = dotIdx > 0 ? dotIdx : sel.length;
10719 var tag = hashIdx !== -1 || dotIdx !== -1 ? sel.slice(0, Math.min(hash, dot)) : sel;
10720 var elm = vnode.elm = isDef(data) && isDef(i = data.ns) ? api.createElementNS(i, tag)
10721 : api.createElement(tag);
10723 { elm.setAttribute('id', sel.slice(hash + 1, dot)); }
10725 { elm.setAttribute('class', sel.slice(dot + 1).replace(/\./g, ' ')); }
10726 for (i = 0; i < cbs.create.length; ++i)
10727 { cbs.create[i](emptyNode, vnode); }
10728 if (array(children)) {
10729 for (i = 0; i < children.length; ++i) {
10730 var ch = children[i];
10732 api.appendChild(elm, createElm(ch, insertedVnodeQueue));
10736 else if (primitive(vnode.text)) {
10737 api.appendChild(elm, api.createTextNode(vnode.text));
10739 i = vnode.data.hook; // Reuse variable
10742 { i.create(emptyNode, vnode); }
10744 { insertedVnodeQueue.push(vnode); }
10748 vnode.elm = api.createTextNode(vnode.text);
10752 function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
10753 for (; startIdx <= endIdx; ++startIdx) {
10754 var ch = vnodes[startIdx];
10756 api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before);
10760 function invokeDestroyHook(vnode) {
10761 var i, j, data = vnode.data;
10762 if (data !== undefined) {
10763 if (isDef(i = data.hook) && isDef(i = i.destroy))
10765 for (i = 0; i < cbs.destroy.length; ++i)
10766 { cbs.destroy[i](vnode); }
10767 if (vnode.children !== undefined) {
10768 for (j = 0; j < vnode.children.length; ++j) {
10769 i = vnode.children[j];
10770 if (i != null && typeof i !== "string
") {
10771 invokeDestroyHook(i);
10777 function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
10778 for (; startIdx <= endIdx; ++startIdx) {
10779 var i_1 = void 0, listeners = void 0, rm = void 0, ch = vnodes[startIdx];
10781 if (isDef(ch.sel)) {
10782 invokeDestroyHook(ch);
10783 listeners = cbs.remove.length + 1;
10784 rm = createRmCb(ch.elm, listeners);
10785 for (i_1 = 0; i_1 < cbs.remove.length; ++i_1)
10786 { cbs.remove[i_1](ch, rm); }
10787 if (isDef(i_1 = ch.data) && isDef(i_1 = i_1.hook) && isDef(i_1 = i_1.remove)) {
10795 api.removeChild(parentElm, ch.elm);
10800 function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {
10801 var oldStartIdx = 0, newStartIdx = 0;
10802 var oldEndIdx = oldCh.length - 1;
10803 var oldStartVnode = oldCh[0];
10804 var oldEndVnode = oldCh[oldEndIdx];
10805 var newEndIdx = newCh.length - 1;
10806 var newStartVnode = newCh[0];
10807 var newEndVnode = newCh[newEndIdx];
10812 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
10813 if (oldStartVnode == null) {
10814 oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
10816 else if (oldEndVnode == null) {
10817 oldEndVnode = oldCh[--oldEndIdx];
10819 else if (newStartVnode == null) {
10820 newStartVnode = newCh[++newStartIdx];
10822 else if (newEndVnode == null) {
10823 newEndVnode = newCh[--newEndIdx];
10825 else if (sameVnode(oldStartVnode, newStartVnode)) {
10826 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);
10827 oldStartVnode = oldCh[++oldStartIdx];
10828 newStartVnode = newCh[++newStartIdx];
10830 else if (sameVnode(oldEndVnode, newEndVnode)) {
10831 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);
10832 oldEndVnode = oldCh[--oldEndIdx];
10833 newEndVnode = newCh[--newEndIdx];
10835 else if (sameVnode(oldStartVnode, newEndVnode)) {
10836 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);
10837 api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));
10838 oldStartVnode = oldCh[++oldStartIdx];
10839 newEndVnode = newCh[--newEndIdx];
10841 else if (sameVnode(oldEndVnode, newStartVnode)) {
10842 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);
10843 api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
10844 oldEndVnode = oldCh[--oldEndIdx];
10845 newStartVnode = newCh[++newStartIdx];
10848 if (oldKeyToIdx === undefined) {
10849 oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
10851 idxInOld = oldKeyToIdx[newStartVnode.key];
10852 if (isUndef(idxInOld)) {
10853 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
10854 newStartVnode = newCh[++newStartIdx];
10857 elmToMove = oldCh[idxInOld];
10858 if (elmToMove.sel !== newStartVnode.sel) {
10859 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
10862 patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
10863 oldCh[idxInOld] = undefined;
10864 api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
10866 newStartVnode = newCh[++newStartIdx];
10870 if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
10871 if (oldStartIdx > oldEndIdx) {
10872 before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
10873 addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
10876 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
10880 function patchVnode(oldVnode, vnode, insertedVnodeQueue) {
10882 if (isDef(i = vnode.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {
10883 i(oldVnode, vnode);
10885 var elm = vnode.elm = oldVnode.elm;
10886 var oldCh = oldVnode.children;
10887 var ch = vnode.children;
10888 if (oldVnode === vnode)
10890 if (vnode.data !== undefined) {
10891 for (i = 0; i < cbs.update.length; ++i)
10892 { cbs.update[i](oldVnode, vnode); }
10893 i = vnode.data.hook;
10894 if (isDef(i) && isDef(i = i.update))
10895 { i(oldVnode, vnode); }
10897 if (isUndef(vnode.text)) {
10898 if (isDef(oldCh) && isDef(ch)) {
10900 { updateChildren(elm, oldCh, ch, insertedVnodeQueue); }
10902 else if (isDef(ch)) {
10903 if (isDef(oldVnode.text))
10904 { api.setTextContent(elm, ''); }
10905 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
10907 else if (isDef(oldCh)) {
10908 removeVnodes(elm, oldCh, 0, oldCh.length - 1);
10910 else if (isDef(oldVnode.text)) {
10911 api.setTextContent(elm, '');
10914 else if (oldVnode.text !== vnode.text) {
10915 api.setTextContent(elm, vnode.text);
10917 if (isDef(hook) && isDef(i = hook.postpatch)) {
10918 i(oldVnode, vnode);
10921 return function patch(oldVnode, vnode) {
10922 var i, elm, parent;
10923 var insertedVnodeQueue = [];
10924 for (i = 0; i < cbs.pre.length; ++i)
10926 if (!isVnode(oldVnode)) {
10927 oldVnode = emptyNodeAt(oldVnode);
10929 if (sameVnode(oldVnode, vnode)) {
10930 patchVnode(oldVnode, vnode, insertedVnodeQueue);
10933 elm = oldVnode.elm;
10934 parent = api.parentNode(elm);
10935 createElm(vnode, insertedVnodeQueue);
10936 if (parent !== null) {
10937 api.insertBefore(parent, vnode.elm, api.nextSibling(elm));
10938 removeVnodes(parent, [oldVnode], 0, 0);
10941 for (i = 0; i < insertedVnodeQueue.length; ++i) {
10942 insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]);
10944 for (i = 0; i < cbs.post.length; ++i)
10950 var xlinkNS = 'http://www.w3.org/1999/xlink';
10951 var xmlNS = 'http://www.w3.org/XML/1998/namespace';
10952 var colonChar = 58;
10954 function updateAttrs(oldVnode, vnode) {
10955 var key, elm = vnode.elm, oldAttrs = oldVnode.data.attrs, attrs = vnode.data.attrs;
10956 if (!oldAttrs && !attrs)
10958 if (oldAttrs === attrs)
10960 oldAttrs = oldAttrs || {};
10961 attrs = attrs || {};
10962 // update modified attributes, add new attributes
10963 for (key in attrs) {
10964 var cur = attrs[key];
10965 var old = oldAttrs[key];
10967 if (cur === true) {
10968 elm.setAttribute(key, "");
10970 else if (cur === false) {
10971 elm.removeAttribute(key);
10974 if (key.charCodeAt(0) !== xChar) {
10975 elm.setAttribute(key, cur);
10977 else if (key.charCodeAt(3) === colonChar) {
10978 // Assume xml namespace
10979 elm.setAttributeNS(xmlNS, key, cur);
10981 else if (key.charCodeAt(5) === colonChar) {
10982 // Assume xlink namespace
10983 elm.setAttributeNS(xlinkNS, key, cur);
10986 elm.setAttribute(key, cur);
10991 // remove removed attributes
10992 // use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value)
10993 // the other option is to remove all attributes with value == undefined
10994 for (key in oldAttrs) {
10995 if (!(key in attrs)) {
10996 elm.removeAttribute(key);
11000 var attributesModule = { create: updateAttrs, update: updateAttrs };
11002 function updateProps(oldVnode, vnode) {
11003 var key, cur, old, elm = vnode.elm, oldProps = oldVnode.data.props, props = vnode.data.props;
11004 if (!oldProps && !props)
11006 if (oldProps === props)
11008 oldProps = oldProps || {};
11009 props = props || {};
11010 for (key in oldProps) {
11015 for (key in props) {
11017 old = oldProps[key];
11018 if (old !== cur && (key !== 'value' || elm[key] !== cur)) {
11023 var propsModule = { create: updateProps, update: updateProps };
11025 var raf = (typeof window !== 'undefined' && window.requestAnimationFrame) || setTimeout;
11026 var nextFrame = function (fn) { raf(function () { raf(fn); }); };
11027 function setNextFrame(obj, prop, val) {
11028 nextFrame(function () { obj[prop] = val; });
11030 function updateStyle(oldVnode, vnode) {
11031 var cur, name, elm = vnode.elm, oldStyle = oldVnode.data.style, style = vnode.data.style;
11032 if (!oldStyle && !style)
11034 if (oldStyle === style)
11036 oldStyle = oldStyle || {};
11037 style = style || {};
11038 var oldHasDel = 'delayed' in oldStyle;
11039 for (name in oldStyle) {
11040 if (!style[name]) {
11041 if (name[0] === '-' && name[1] === '-') {
11042 elm.style.removeProperty(name);
11045 elm.style[name] = '';
11049 for (name in style) {
11051 if (name === 'delayed' && style.delayed) {
11052 for (var name2 in style.delayed) {
11053 cur = style.delayed[name2];
11054 if (!oldHasDel || cur !== oldStyle.delayed[name2]) {
11055 setNextFrame(elm.style, name2, cur);
11059 else if (name !== 'remove' && cur !== oldStyle[name]) {
11060 if (name[0] === '-' && name[1] === '-') {
11061 elm.style.setProperty(name, cur);
11064 elm.style[name] = cur;
11069 function applyDestroyStyle(vnode) {
11070 var style, name, elm = vnode.elm, s = vnode.data.style;
11071 if (!s || !(style = s.destroy))
11073 for (name in style) {
11074 elm.style[name] = style[name];
11077 function applyRemoveStyle(vnode, rm) {
11078 var s = vnode.data.style;
11079 if (!s || !s.remove) {
11083 var name, elm = vnode.elm, i = 0, compStyle, style = s.remove, amount = 0, applied = [];
11084 for (name in style) {
11085 applied.push(name);
11086 elm.style[name] = style[name];
11088 compStyle = getComputedStyle(elm);
11089 var props = compStyle['transition-property'].split(', ');
11090 for (; i < props.length; ++i) {
11091 if (applied.indexOf(props[i]) !== -1)
11094 elm.addEventListener('transitionend', function (ev) {
11095 if (ev.target === elm)
11101 var styleModule = {
11102 create: updateStyle,
11103 update: updateStyle,
11104 destroy: applyDestroyStyle,
11105 remove: applyRemoveStyle
11108 function invokeHandler(handler, event, args) {
11109 if (typeof handler === 'function') {
11110 // call function handler
11111 handler.apply(void 0, [ event ].concat( args ));
11114 function handleEvent(event, args, vnode) {
11115 var name = event.type;
11116 var on = vnode.data.on;
11117 // call event handler(s) if exists
11118 if (on && on[name]) {
11119 invokeHandler(on[name], event, args);
11122 function createListener() {
11123 return function handler(event) {
11124 var args = [], len = arguments.length - 1;
11125 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
11127 handleEvent(event, args, handler.vnode);
11130 function updateEvents(oldVnode, vnode) {
11131 var oldOn = oldVnode.data.on;
11132 var oldListener = oldVnode.listener;
11133 var oldElm = oldVnode.elm;
11134 var on = vnode && vnode.data.on;
11135 var elm = (vnode && vnode.elm);
11136 // optimization for reused immutable handlers
11137 if (oldOn === on) {
11140 // remove existing listeners which no longer used
11141 if (oldOn && oldListener) {
11142 // if element changed or deleted we remove all existing listeners unconditionally
11144 Object.keys(oldOn).forEach(function (name) {
11145 $(oldElm).off(name, oldListener);
11148 Object.keys(oldOn).forEach(function (name) {
11150 $(oldElm).off(name, oldListener);
11155 // add new listeners which has not already attached
11157 // reuse existing listener or create new
11158 var listener = oldVnode.listener || createListener();
11159 vnode.listener = listener;
11160 // update vnode for listener
11161 listener.vnode = vnode;
11162 // if element changed or added we add all needed listeners unconditionally
11164 Object.keys(on).forEach(function (name) {
11165 $(elm).on(name, listener);
11168 Object.keys(on).forEach(function (name) {
11169 if (!oldOn[name]) {
11170 $(elm).on(name, listener);
11177 var eventListenersModule = {
11178 create: updateEvents,
11179 update: updateEvents,
11180 destroy: updateEvents,
11183 /* eslint import/no-named-as-default: off */
11189 eventListenersModule ]);
11191 var Framework7Component = function Framework7Component(app, options, extendContext) {
11192 if ( extendContext === void 0 ) extendContext = {};
11194 var id = Utils.id();
11195 var self = Utils.merge(
11204 $options: Utils.extend({ id: id }, options),
11205 $id: options.id || id,
11208 var $options = self.$options;
11210 // Root data and methods
11211 Object.defineProperty(self, '$root', {
11213 configurable: true,
11214 get: function get() {
11215 var root = Utils.merge({}, app.data, app.methods);
11216 if (win && win.Proxy) {
11217 root = new win.Proxy(root, {
11218 set: function set(target, name, val) {
11219 app.data[name] = val;
11221 deleteProperty: function deleteProperty(target, name) {
11222 delete app.data[name];
11223 delete app.methods[name];
11225 has: function has(target, name) {
11226 return (name in app.data || name in app.methods);
11232 set: function set() {},
11236 ('beforeCreate created beforeMount mounted beforeDestroy destroyed updated').split(' ').forEach(function (cycleKey) {
11237 if ($options[cycleKey]) { $options[cycleKey] = $options[cycleKey].bind(self); }
11240 if ($options.data) {
11241 $options.data = $options.data.bind(self);
11243 Utils.extend(self, $options.data());
11245 if ($options.render) { $options.render = $options.render.bind(self); }
11246 if ($options.methods) {
11247 Object.keys($options.methods).forEach(function (methodName) {
11248 self[methodName] = $options.methods[methodName].bind(self);
11254 Object.keys($options.on).forEach(function (eventName) {
11255 $options.on[eventName] = $options.on[eventName].bind(self);
11258 if ($options.once) {
11259 Object.keys($options.once).forEach(function (eventName) {
11260 $options.once[eventName] = $options.once[eventName].bind(self);
11264 // Before create hook
11265 if ($options.beforeCreate) { $options.beforeCreate(); }
11268 var html = self.$render();
11271 if (html && typeof html === 'string') {
11272 html = html.trim();
11273 self.$vnode = vdom(html, self, app, true);
11274 self.el = doc.createElement('div');
11275 patch(self.el, self.$vnode);
11279 self.$el = $(self.el);
11281 // Set styles scope ID
11282 if ($options.style) {
11283 self.$styleEl = doc.createElement('style');
11284 self.$styleEl.innerHTML = $options.style;
11285 if ($options.styleScoped) {
11286 self.el.setAttribute(("data
-f7
-" + ($options.id)), '');
11290 self.$attachEvents();
11292 // Created callback
11293 if ($options.created) { $options.created(); }
11295 // Store component instance
11296 self.el.f7Component = self;
11301 Framework7Component.prototype.$attachEvents = function $attachEvents () {
11303 var $options = self.$options;
11304 var $el = self.$el;
11306 Object.keys($options.on).forEach(function (eventName) {
11307 $el.on(Utils.eventNameToColonCase(eventName), $options.on[eventName]);
11310 if ($options.once) {
11311 Object.keys($options.once).forEach(function (eventName) {
11312 $el.once(Utils.eventNameToColonCase(eventName), $options.once[eventName]);
11317 Framework7Component.prototype.$detachEvents = function $detachEvents () {
11319 var $options = self.$options;
11320 var $el = self.$el;
11322 Object.keys($options.on).forEach(function (eventName) {
11323 $el.off(Utils.eventNameToColonCase(eventName), $options.on[eventName]);
11326 if ($options.once) {
11327 Object.keys($options.once).forEach(function (eventName) {
11328 $el.off(Utils.eventNameToColonCase(eventName), $options.once[eventName]);
11333 Framework7Component.prototype.$render = function $render () {
11335 var $options = self.$options;
11337 if ($options.render) {
11338 html = $options.render();
11339 } else if ($options.template) {
11340 if (typeof $options.template === 'string') {
11342 html = Template7.compile($options.template)(self);
11347 // Supposed to be function
11348 html = $options.template(self);
11354 Framework7Component.prototype.$forceUpdate = function $forceUpdate () {
11356 var html = self.$render();
11359 if (html && typeof html === 'string') {
11360 html = html.trim();
11361 var newVNode = vdom(html, self, self.$app);
11362 self.$vnode = patch(self.$vnode, newVNode);
11366 Framework7Component.prototype.$setState = function $setState (mergeState) {
11368 Utils.merge(self, mergeState);
11369 self.$forceUpdate();
11372 Framework7Component.prototype.$mount = function $mount (mountMethod) {
11374 if (self.$options.beforeMount) { self.$options.beforeMount(); }
11375 if (self.$styleEl) { $('head').append(self.$styleEl); }
11376 if (mountMethod) { mountMethod(self.el); }
11377 if (self.$options.mounted) { self.$options.mounted(); }
11380 Framework7Component.prototype.$destroy = function $destroy () {
11382 if (self.$options.beforeDestroy) { self.$options.beforeDestroy(); }
11383 if (self.$styleEl) { $(self.$styleEl).remove(); }
11384 self.$detachEvents();
11385 if (self.$options.destroyed) { self.$options.destroyed(); }
11386 // Delete component instance
11387 if (self.el && self.el.f7Component) {
11388 self.el.f7Component = null;
11389 delete self.el.f7Component;
11391 // Patch with empty node
11393 self.$vnode = patch(self.$vnode, { sel: self.$vnode.sel, data: {} });
11395 Utils.deleteProps(self);
11398 function parseComponent(componentString) {
11399 var id = Utils.id();
11400 var callbackCreateName = "f7_component_create_callback_
" + id;
11401 var callbackRenderName = "f7_component_render_callback_
" + id;
11405 var hasTemplate = componentString.match(/<template([ ]?)([a-z0-9-]*)>/);
11406 var templateType = hasTemplate[2] || 't7';
11408 template = componentString
11409 .split(/<template[ ]?[a-z0-9-]*>/)
11410 .filter(function (item, index) { return index > 0; })
11411 .join('<template>')
11412 .split('</template>')
11413 .filter(function (item, index, arr) { return index < arr.length - 1; })
11414 .join('</template>')
11415 .replace(/{{#raw}}([ \n]*)<template/g, '{{#raw}}<template')
11416 .replace(/\/template>([ \n]*){{\/raw}}/g, '/template>{{/raw}}')
11417 .replace(/([ \n])<template/g, '$1{{#raw}}<template')
11418 .replace(/\/template>([ \n])/g, '/template>{{/raw}}$1');
11423 var styleScoped = false;
11425 if (componentString.indexOf('<style>') >= 0) {
11426 style = componentString.split('<style>')[1].split('</style>')[0];
11427 } else if (componentString.indexOf('<style scoped>') >= 0) {
11428 styleScoped = true;
11429 style = componentString.split('<style scoped>')[1].split('</style>')[0];
11430 style = style.split('\n').map(function (line) {
11431 var trimmedLine = line.trim();
11432 if (trimmedLine.indexOf('@') === 0) { return line; }
11433 if (line.indexOf('{') >= 0) {
11434 if (line.indexOf('{{this}}') >= 0) {
11435 return line.replace('{{this}}', ("[data
-f7
-" + id + "]"));
11437 return ("[data
-f7
-" + id + "] " + (line.trim()));
11446 if (componentString.indexOf('<script>') >= 0) {
11447 var scripts = componentString.split('<script>');
11448 scriptContent = scripts[scripts.length - 1].split('</script>')[0].trim();
11450 scriptContent = 'return {}';
11452 if (!scriptContent || !scriptContent.trim()) { scriptContent = 'return {}'; }
11454 scriptContent = "window
." + callbackCreateName + " = function () {" + scriptContent + "}";
11456 // Insert Script El
11457 scriptEl = doc.createElement('script');
11458 scriptEl.innerHTML = scriptContent;
11459 $('head').append(scriptEl);
11461 var component = win[callbackCreateName]();
11463 // Remove Script El
11464 $(scriptEl).remove();
11465 win[callbackCreateName] = null;
11466 delete win[callbackCreateName];
11469 if (!component.template && !component.render) {
11470 component.template = template;
11471 component.templateType = templateType;
11473 if (component.template) {
11474 if (component.templateType === 't7') {
11475 component.template = Template7.compile(component.template);
11477 if (component.templateType === 'es') {
11478 var renderContent = "window
." + callbackRenderName + " = function () {\n return function render() {\n return `" + (component.template) + "`;\n }\n }";
11479 scriptEl = doc.createElement('script');
11480 scriptEl.innerHTML = renderContent;
11481 $('head').append(scriptEl);
11483 component.render = win[callbackRenderName]();
11485 // Remove Script El
11486 $(scriptEl).remove();
11487 win[callbackRenderName] = null;
11488 delete win[callbackRenderName];
11494 component.style = style;
11495 component.styleScoped = styleScoped;
11503 var ComponentModule = {
11505 create: function create() {
11508 parse: function parse(componentString) {
11509 return parseComponent(componentString);
11511 create: function create(options, extendContext) {
11512 return new Framework7Component(app, options, extendContext);
11520 register: function register(path, scope) {
11522 if (!('serviceWorker' in window.navigator) || !app.serviceWorker.container) {
11523 return new Promise(function (resolve, reject) {
11524 reject(new Error('Service worker is not supported'));
11527 return new Promise(function (resolve, reject) {
11528 app.serviceWorker.container.register(path, (scope ? { scope: scope } : {}))
11529 .then(function (reg) {
11530 SW.registrations.push(reg);
11531 app.emit('serviceWorkerRegisterSuccess', reg);
11533 }).catch(function (error) {
11534 app.emit('serviceWorkerRegisterError', error);
11539 unregister: function unregister(registration) {
11541 if (!('serviceWorker' in window.navigator) || !app.serviceWorker.container) {
11542 return new Promise(function (resolve, reject) {
11543 reject(new Error('Service worker is not supported'));
11547 if (!registration) { registrations = SW.registrations; }
11548 else if (Array.isArray(registration)) { registrations = registration; }
11549 else { registrations = [registration]; }
11550 return Promise.all(registrations.map(function (reg) { return new Promise(function (resolve, reject) {
11552 .then(function () {
11553 if (SW.registrations.indexOf(reg) >= 0) {
11554 SW.registrations.splice(SW.registrations.indexOf(reg), 1);
11556 app.emit('serviceWorkerUnregisterSuccess', reg);
11559 .catch(function (error) {
11560 app.emit('serviceWorkerUnregisterError', reg, error);
11567 var ServiceWorkerModule = {
11575 create: function create() {
11577 Utils.extend(app, {
11579 container: ('serviceWorker' in window.navigator) ? window.navigator.serviceWorker : undefined,
11580 registrations: SW.registrations,
11581 register: SW.register.bind(app),
11582 unregister: SW.unregister.bind(app),
11587 init: function init() {
11588 if (!('serviceWorker' in window.navigator)) { return; }
11590 if (!app.serviceWorker.container) { return; }
11591 var paths = app.params.serviceWorker.path;
11592 var scope = app.params.serviceWorker.scope;
11593 if (!paths || (Array.isArray(paths) && !paths.length)) { return; }
11594 var toRegister = Array.isArray(paths) ? paths : [paths];
11595 toRegister.forEach(function (path) {
11596 app.serviceWorker.register(path, scope);
11603 hide: function hide() {
11604 $('html').removeClass('with-statusbar');
11605 if (Device.cordova && win.StatusBar) {
11606 win.StatusBar.hide();
11609 show: function show() {
11610 if (Device.cordova && win.StatusBar) {
11611 win.StatusBar.show();
11612 Utils.nextTick(function () {
11613 if (Device.needsStatusbarOverlay()) {
11614 $('html').addClass('with-statusbar');
11619 $('html').addClass('with-statusbar');
11621 onClick: function onClick() {
11624 if ($('.popup.modal-in').length > 0) {
11625 // Check for opened popup
11626 pageContent = $('.popup.modal-in').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11627 } else if ($('.panel.panel-active').length > 0) {
11628 // Check for opened panel
11629 pageContent = $('.panel.panel-active').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11630 } else if ($('.views > .view.tab-active').length > 0) {
11631 // View in tab bar app layout
11632 pageContent = $('.views > .view.tab-active').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11633 } else if ($('.views').length > 0) {
11634 pageContent = $('.views').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11636 pageContent = app.root.children('.view').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11639 if (pageContent && pageContent.length > 0) {
11641 if (pageContent.hasClass('tab')) {
11642 pageContent = pageContent.parent('.tabs').children('.page-content.tab-active');
11644 if (pageContent.length > 0) { pageContent.scrollTop(0, 300); }
11647 setTextColor: function setTextColor(color) {
11648 if (Device.cordova && win.StatusBar) {
11649 if (color === 'white') {
11650 win.StatusBar.styleLightContent();
11652 win.StatusBar.styleDefault();
11656 setIosTextColor: function setIosTextColor(color) {
11657 if (!Device.ios) { return; }
11658 Statusbar.setTextColor(color);
11660 setBackgroundColor: function setBackgroundColor(color) {
11661 $('.statusbar').css('background-color', color);
11662 if (Device.cordova && win.StatusBar) {
11663 win.StatusBar.backgroundColorByHexString(color);
11666 isVisible: function isVisible() {
11667 if (Device.cordova && win.StatusBar) {
11668 return win.StatusBar.isVisible;
11672 overlaysWebView: function overlaysWebView(overlays) {
11673 if ( overlays === void 0 ) overlays = true;
11675 if (Device.cordova && win.StatusBar) {
11676 win.StatusBar.overlaysWebView(overlays);
11678 $('html').addClass('with-statusbar');
11680 $('html').removeClass('with-statusbar');
11684 checkOverlay: function checkOverlay() {
11685 if (Device.needsStatusbarOverlay()) {
11686 $('html').addClass('with-statusbar');
11688 $('html').removeClass('with-statusbar');
11691 init: function init() {
11693 var params = app.params.statusbar;
11694 if (!params.enabled) { return; }
11696 if (params.overlay === 'auto') {
11697 if (Device.needsStatusbarOverlay()) {
11698 $('html').addClass('with-statusbar');
11700 $('html').removeClass('with-statusbar');
11703 if (Device.ios && (Device.cordova || Device.webView)) {
11704 if (win.orientation === 0) {
11705 app.once('resize', function () {
11706 Statusbar.checkOverlay();
11710 $(doc).on('resume', function () {
11711 Statusbar.checkOverlay();
11714 app.on(Device.ios ? 'orientationchange' : 'orientationchange resize', function () {
11715 Statusbar.checkOverlay();
11718 } else if (params.overlay === true) {
11719 $('html').addClass('with-statusbar');
11720 } else if (params.overlay === false) {
11721 $('html').removeClass('with-statusbar');
11724 if (Device.cordova && win.StatusBar) {
11725 if (params.scrollTopOnClick) {
11726 $(win).on('statusTap', Statusbar.onClick.bind(app));
11729 if (params.iosOverlaysWebView) {
11730 win.StatusBar.overlaysWebView(true);
11732 win.StatusBar.overlaysWebView(false);
11734 if (params.iosTextColor === 'white') {
11735 win.StatusBar.styleLightContent();
11737 win.StatusBar.styleDefault();
11740 if (Device.android) {
11741 if (params.androidOverlaysWebView) {
11742 win.StatusBar.overlaysWebView(true);
11744 win.StatusBar.overlaysWebView(false);
11746 if (params.androidTextColor === 'white') {
11747 win.StatusBar.styleLightContent();
11749 win.StatusBar.styleDefault();
11753 if (params.iosBackgroundColor && Device.ios) {
11754 Statusbar.setBackgroundColor(params.iosBackgroundColor);
11756 if ((params.materialBackgroundColor || params.androidBackgroundColor) && Device.android) {
11757 Statusbar.setBackgroundColor(params.materialBackgroundColor || params.androidBackgroundColor);
11762 var Statusbar$1 = {
11768 scrollTopOnClick: true,
11770 iosOverlaysWebView: true,
11771 iosTextColor: 'black',
11772 iosBackgroundColor: null,
11774 androidOverlaysWebView: false,
11775 androidTextColor: 'black',
11776 androidBackgroundColor: null,
11779 create: function create() {
11781 Utils.extend(app, {
11783 checkOverlay: Statusbar.checkOverlay,
11784 hide: Statusbar.hide,
11785 show: Statusbar.show,
11786 overlaysWebView: Statusbar.overlaysWebView,
11787 setTextColor: Statusbar.setTextColor,
11788 setBackgroundColor: Statusbar.setBackgroundColor,
11789 isVisible: Statusbar.isVisible,
11790 init: Statusbar.init.bind(app),
11795 init: function init() {
11797 Statusbar.init.call(app);
11801 '.statusbar': function onStatusbarClick() {
11803 if (!app.params.statusbar.enabled) { return; }
11804 if (!app.params.statusbar.scrollTopOnClick) { return; }
11805 Statusbar.onClick.call(app);
11810 function getCurrentView(app) {
11811 var $popoverView = $('.popover.modal-in .view');
11812 var $popupView = $('.popup.modal-in .view');
11813 var $panelView = $('.panel.panel-active .view');
11814 var $viewsEl = $('.views');
11815 if ($viewsEl.length === 0) { $viewsEl = app.root; }
11816 // Find active view as tab
11817 var $viewEl = $viewsEl.children('.view');
11818 // Propably in tabs or split view
11819 if ($viewEl.length > 1) {
11820 if ($viewEl.hasClass('tab')) {
11822 $viewEl = $viewsEl.children('.view.tab-active');
11825 if ($popoverView.length > 0 && $popoverView[0].f7View) { return $popoverView[0].f7View; }
11826 if ($popupView.length > 0 && $popupView[0].f7View) { return $popupView[0].f7View; }
11827 if ($panelView.length > 0 && $panelView[0].f7View) { return $panelView[0].f7View; }
11828 if ($viewEl.length > 0) {
11829 if ($viewEl.length === 1 && $viewEl[0].f7View) { return $viewEl[0].f7View; }
11830 if ($viewEl.length > 1) {
11831 return app.views.main;
11847 xhrCacheIgnore: [],
11848 xhrCacheIgnoreGetParameters: false,
11849 xhrCacheDuration: 1000 * 60 * 10, // Ten minutes
11850 preloadPreviousPage: true,
11851 allowDuplicateUrls: false,
11852 reloadPages: false,
11853 reloadDetail: false,
11854 masterDetailBreakpoint: 0,
11855 removeElements: true,
11856 removeElementsWithTimeout: false,
11857 removeElementsTimeout: 0,
11858 restoreScrollTopOnBack: true,
11859 unloadTabContent: true,
11860 passRouteQueryToRequest: true,
11861 passRouteParamsToRequest: false,
11863 iosSwipeBack: true,
11864 iosSwipeBackAnimateShadow: true,
11865 iosSwipeBackAnimateOpacity: true,
11866 iosSwipeBackActiveArea: 30,
11867 iosSwipeBackThreshold: 0,
11868 mdSwipeBack: false,
11869 mdSwipeBackAnimateShadow: true,
11870 mdSwipeBackAnimateOpacity: false,
11871 mdSwipeBackActiveArea: 30,
11872 mdSwipeBackThreshold: 0,
11873 auroraSwipeBack: false,
11874 auroraSwipeBackAnimateShadow: false,
11875 auroraSwipeBackAnimateOpacity: true,
11876 auroraSwipeBackActiveArea: 30,
11877 auroraSwipeBackThreshold: 0,
11880 pushStateRoot: undefined,
11881 pushStateAnimate: true,
11882 pushStateAnimateOnLoad: false,
11883 pushStateSeparator: '#!',
11884 pushStateOnLoad: true,
11887 // iOS Dynamic Navbar
11888 iosDynamicNavbar: true,
11889 iosSeparateDynamicNavbar: true,
11890 // Animate iOS Navbar Back Icon
11891 iosAnimateNavbarBackIcon: true,
11893 iosPageLoadDelay: 0,
11894 mdPageLoadDelay: 0,
11895 auroraPageLoadDelay: 0,
11897 routesBeforeEnter: null,
11898 routesBeforeLeave: null,
11904 create: function create() {
11906 Utils.extend(app, {
11907 views: Utils.extend([], {
11908 create: function create(el, params) {
11909 return new View(app, el, params);
11911 get: function get(viewEl) {
11912 var $viewEl = $(viewEl);
11913 if ($viewEl.length && $viewEl[0].f7View) { return $viewEl[0].f7View; }
11918 Object.defineProperty(app.views, 'current', {
11920 configurable: true,
11921 get: function get() {
11922 return getCurrentView(app);
11926 app.view = app.views;
11929 init: function init() {
11931 $('.view-init').each(function (index, viewEl) {
11932 if (viewEl.f7View) { return; }
11933 var viewParams = $(viewEl).dataset();
11934 app.views.create(viewEl, viewParams);
11937 modalOpen: function modalOpen(modal) {
11939 modal.$el.find('.view-init').each(function (index, viewEl) {
11940 if (viewEl.f7View) { return; }
11941 var viewParams = $(viewEl).dataset();
11942 app.views.create(viewEl, viewParams);
11945 modalBeforeDestroy: function modalBeforeDestroy(modal) {
11946 if (!modal || !modal.$el) { return; }
11947 modal.$el.find('.view-init').each(function (index, viewEl) {
11948 var view = viewEl.f7View;
11949 if (!view) { return; }
11957 size: function size(el) {
11959 if (app.theme !== 'ios' && !app.params.navbar[((app.theme) + "CenterTitle
")]) {
11963 if ($el.hasClass('navbar')) {
11964 $el = $el.children('.navbar-inner').each(function (index, navbarEl) {
11965 app.navbar.size(navbarEl);
11971 $el.hasClass('stacked')
11972 || $el.parents('.stacked').length > 0
11973 || $el.parents('.tab:not(.tab-active)').length > 0
11974 || $el.parents('.popup:not(.modal-in)').length > 0
11979 if (app.theme !== 'ios' && app.params.navbar[((app.theme) + "CenterTitle
")]) {
11980 $el.addClass('navbar-inner-centered-title');
11982 if (app.theme === 'ios' && !app.params.navbar.iosCenterTitle) {
11983 $el.addClass('navbar-inner-left-title');
11986 var $viewEl = $el.parents('.view').eq(0);
11987 var left = app.rtl ? $el.children('.right') : $el.children('.left');
11988 var right = app.rtl ? $el.children('.left') : $el.children('.right');
11989 var title = $el.children('.title');
11990 var subnavbar = $el.children('.subnavbar');
11991 var noLeft = left.length === 0;
11992 var noRight = right.length === 0;
11993 var leftWidth = noLeft ? 0 : left.outerWidth(true);
11994 var rightWidth = noRight ? 0 : right.outerWidth(true);
11995 var titleWidth = title.outerWidth(true);
11996 var navbarStyles = $el.styles();
11997 var navbarWidth = $el[0].offsetWidth;
11998 var navbarInnerWidth = navbarWidth - parseInt(navbarStyles.paddingLeft, 10) - parseInt(navbarStyles.paddingRight, 10);
11999 var isPrevious = $el.hasClass('navbar-previous');
12000 var sliding = $el.hasClass('sliding');
12004 var separateNavbar;
12005 var separateNavbarRightOffset = 0;
12006 var separateNavbarLeftOffset = 0;
12008 if ($viewEl.length > 0 && $viewEl[0].f7View) {
12009 router = $viewEl[0].f7View.router;
12010 dynamicNavbar = router && router.dynamicNavbar;
12011 separateNavbar = router && router.separateNavbar;
12012 if (!separateNavbar) {
12013 separateNavbarRightOffset = navbarWidth;
12014 separateNavbarLeftOffset = navbarWidth / 5;
12021 currLeft = navbarInnerWidth - titleWidth;
12026 if (!noLeft && !noRight) {
12027 currLeft = ((navbarInnerWidth - rightWidth - titleWidth) + leftWidth) / 2;
12029 var requiredLeft = (navbarInnerWidth - titleWidth) / 2;
12030 if (navbarInnerWidth - leftWidth - rightWidth > titleWidth) {
12031 if (requiredLeft < leftWidth) {
12032 requiredLeft = leftWidth;
12034 if (requiredLeft + titleWidth > navbarInnerWidth - rightWidth) {
12035 requiredLeft = navbarInnerWidth - rightWidth - titleWidth;
12037 diff = requiredLeft - currLeft;
12043 var inverter = app.rtl ? -1 : 1;
12045 if (dynamicNavbar && app.theme === 'ios') {
12046 if (title.hasClass('sliding') || (title.length > 0 && sliding)) {
12047 var titleLeftOffset = (-(currLeft + diff) * inverter) + separateNavbarLeftOffset;
12048 var titleRightOffset = ((navbarInnerWidth - currLeft - diff - titleWidth) * inverter) - separateNavbarRightOffset;
12051 if (router && router.params.iosAnimateNavbarBackIcon) {
12052 var activeNavbarBackLink = $el.parent().find('.navbar-current').children('.left.sliding').find('.back .icon ~ span');
12053 if (activeNavbarBackLink.length > 0) {
12054 titleLeftOffset += activeNavbarBackLink[0].offsetLeft;
12058 title[0].f7NavbarLeftOffset = titleLeftOffset;
12059 title[0].f7NavbarRightOffset = titleRightOffset;
12061 if (!noLeft && (left.hasClass('sliding') || sliding)) {
12063 left[0].f7NavbarLeftOffset = (-(navbarInnerWidth - left[0].offsetWidth) / 2) * inverter;
12064 left[0].f7NavbarRightOffset = leftWidth * inverter;
12066 left[0].f7NavbarLeftOffset = -leftWidth + separateNavbarLeftOffset;
12067 left[0].f7NavbarRightOffset = ((navbarInnerWidth - left[0].offsetWidth) / 2) - separateNavbarRightOffset;
12068 if (router && router.params.iosAnimateNavbarBackIcon && left.find('.back .icon').length > 0) {
12069 if (left.find('.back .icon ~ span').length) {
12070 var leftOffset = left[0].f7NavbarLeftOffset;
12071 var rightOffset = left[0].f7NavbarRightOffset;
12072 left[0].f7NavbarLeftOffset = 0;
12073 left[0].f7NavbarRightOffset = 0;
12074 left.find('.back .icon ~ span')[0].f7NavbarLeftOffset = leftOffset;
12075 left.find('.back .icon ~ span')[0].f7NavbarRightOffset = rightOffset - left.find('.back .icon')[0].offsetWidth;
12080 if (!noRight && (right.hasClass('sliding') || sliding)) {
12082 right[0].f7NavbarLeftOffset = -rightWidth * inverter;
12083 right[0].f7NavbarRightOffset = ((navbarInnerWidth - right[0].offsetWidth) / 2) * inverter;
12085 right[0].f7NavbarLeftOffset = (-(navbarInnerWidth - right[0].offsetWidth) / 2) + separateNavbarLeftOffset;
12086 right[0].f7NavbarRightOffset = rightWidth - separateNavbarRightOffset;
12089 if (subnavbar.length && (subnavbar.hasClass('sliding') || sliding)) {
12090 subnavbar[0].f7NavbarLeftOffset = app.rtl ? subnavbar[0].offsetWidth : (-subnavbar[0].offsetWidth + separateNavbarLeftOffset);
12091 subnavbar[0].f7NavbarRightOffset = (-subnavbar[0].f7NavbarLeftOffset - separateNavbarRightOffset) + separateNavbarLeftOffset;
12096 if (app.params.navbar[((app.theme) + "CenterTitle
")]) {
12097 var titleLeft = diff;
12098 if (app.rtl && noLeft && noRight && title.length > 0) { titleLeft = -titleLeft; }
12099 title.css({ left: (titleLeft + "px
") });
12102 hide: function hide(el, animate) {
12103 if ( animate === void 0 ) animate = true;
12107 if ($el.hasClass('navbar-inner')) { $el = $el.parents('.navbar'); }
12108 if (!$el.length) { return; }
12109 if ($el.hasClass('navbar-hidden')) { return; }
12110 var className = "navbar
-hidden
" + (animate ? ' navbar-transitioning' : '');
12111 var currentIsLarge = app.theme === 'ios'
12112 ? $el.find('.navbar-current .title-large').length
12113 : $el.find('.title-large').length;
12114 if (currentIsLarge) {
12115 className += ' navbar-large-hidden';
12117 $el.transitionEnd(function () {
12118 $el.removeClass('navbar-transitioning');
12120 $el.addClass(className);
12121 $el.trigger('navbar:hide');
12122 app.emit('navbarHide', $el[0]);
12124 show: function show(el, animate) {
12125 if ( el === void 0 ) el = '.navbar-hidden';
12126 if ( animate === void 0 ) animate = true;
12130 if ($el.hasClass('navbar-inner')) { $el = $el.parents('.navbar'); }
12131 if (!$el.length) { return; }
12132 if (!$el.hasClass('navbar-hidden')) { return; }
12134 $el.addClass('navbar-transitioning');
12135 $el.transitionEnd(function () {
12136 $el.removeClass('navbar-transitioning');
12139 $el.removeClass('navbar-hidden navbar-large-hidden');
12140 $el.trigger('navbar:show');
12141 app.emit('navbarShow', $el[0]);
12143 getElByPage: function getElByPage(page) {
12145 var $navbarInnerEl;
12147 if (page.$navbarEl || page.$el) {
12149 $pageEl = page.$el;
12152 if ($pageEl.length > 0) { pageData = $pageEl[0].f7Page; }
12154 if (pageData && pageData.$navbarEl && pageData.$navbarEl.length > 0) {
12155 $navbarInnerEl = pageData.$navbarEl;
12156 } else if ($pageEl) {
12157 $navbarInnerEl = $pageEl.children('.navbar').children('.navbar-inner');
12159 if (!$navbarInnerEl || ($navbarInnerEl && $navbarInnerEl.length === 0)) { return undefined; }
12160 return $navbarInnerEl[0];
12162 getPageByEl: function getPageByEl(navbarInnerEl) {
12163 var $navbarInnerEl = $(navbarInnerEl);
12164 if ($navbarInnerEl.hasClass('navbar')) {
12165 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner');
12166 if ($navbarInnerEl.length > 1) { return undefined; }
12168 if ($navbarInnerEl.parents('.page').length) {
12169 return $navbarInnerEl.parents('.page')[0];
12172 $navbarInnerEl.parents('.view').find('.page').each(function (index, el) {
12173 if (el && el.f7Page && el.f7Page.navbarEl && $navbarInnerEl[0] === el.f7Page.navbarEl) {
12180 collapseLargeTitle: function collapseLargeTitle(navbarInnerEl) {
12182 var $navbarInnerEl = $(navbarInnerEl);
12183 if ($navbarInnerEl.hasClass('navbar')) {
12184 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner-large');
12185 if ($navbarInnerEl.length > 1) {
12186 $navbarInnerEl = $(navbarInnerEl).find('.navbar-inner-large.navbar-current');
12188 if ($navbarInnerEl.length > 1 || !$navbarInnerEl.length) {
12192 var $pageEl = $(app.navbar.getPageByEl($navbarInnerEl));
12193 $navbarInnerEl.addClass('navbar-inner-large-collapsed');
12194 $pageEl.eq(0).addClass('page-with-navbar-large-collapsed').trigger('page:navbarlargecollapsed');
12195 app.emit('pageNavbarLargeCollapsed', $pageEl[0]);
12196 var $navbarEl = $navbarInnerEl.parents('.navbar');
12197 if (app.theme === 'md' || app.theme === 'aurora') {
12198 $navbarEl.addClass('navbar-large-collapsed');
12200 $navbarEl.trigger('navbar:collapse');
12201 app.emit('navbarCollapse', $navbarEl[0]);
12203 expandLargeTitle: function expandLargeTitle(navbarInnerEl) {
12205 var $navbarInnerEl = $(navbarInnerEl);
12206 if ($navbarInnerEl.hasClass('navbar')) {
12207 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner-large');
12208 if ($navbarInnerEl.length > 1) {
12209 $navbarInnerEl = $(navbarInnerEl).find('.navbar-inner-large.navbar-current');
12211 if ($navbarInnerEl.length > 1 || !$navbarInnerEl.length) {
12215 var $pageEl = $(app.navbar.getPageByEl($navbarInnerEl));
12216 $navbarInnerEl.removeClass('navbar-inner-large-collapsed');
12217 $pageEl.eq(0).removeClass('page-with-navbar-large-collapsed').trigger('page:navbarlargeexpanded');
12218 app.emit('pageNavbarLargeExpanded', $pageEl[0]);
12219 var $navbarEl = $navbarInnerEl.parents('.navbar');
12220 if (app.theme === 'md' || app.theme === 'aurora') {
12221 $navbarEl.removeClass('navbar-large-collapsed');
12223 $navbarEl.trigger('navbar:expand');
12224 app.emit('navbarExpand', $navbarEl[0]);
12226 toggleLargeTitle: function toggleLargeTitle(navbarInnerEl) {
12228 var $navbarInnerEl = $(navbarInnerEl);
12229 if ($navbarInnerEl.hasClass('navbar')) {
12230 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner-large');
12231 if ($navbarInnerEl.length > 1) {
12232 $navbarInnerEl = $(navbarInnerEl).find('.navbar-inner-large.navbar-current');
12234 if ($navbarInnerEl.length > 1 || !$navbarInnerEl.length) {
12238 if ($navbarInnerEl.hasClass('navbar-inner-large-collapsed')) {
12239 app.navbar.expandLargeTitle($navbarInnerEl);
12241 app.navbar.collapseLargeTitle($navbarInnerEl);
12244 initNavbarOnScroll: function initNavbarOnScroll(pageEl, navbarInnerEl, needHide, needCollapse) {
12246 var $pageEl = $(pageEl);
12247 var $navbarInnerEl = $(navbarInnerEl);
12248 var $navbarEl = app.theme === 'md' || app.theme === 'aurora'
12249 ? $navbarInnerEl.parents('.navbar')
12250 : $(navbarInnerEl || app.navbar.getElByPage(pageEl)).closest('.navbar');
12251 var isLarge = $navbarInnerEl.find('.title-large').length || $navbarInnerEl.hasClass('.navbar-inner-large');
12252 var navbarHideHeight = 44;
12253 var snapPageScrollToLargeTitle = app.params.navbar.snapPageScrollToLargeTitle;
12255 var previousScrollTop;
12256 var currentScrollTop;
12264 var navbarCollapsed;
12265 var navbarTitleLargeHeight;
12266 if (needCollapse || (needHide && isLarge)) {
12267 navbarTitleLargeHeight = $navbarInnerEl.css('--f7-navbar-large-title-height');
12268 if (navbarTitleLargeHeight && navbarTitleLargeHeight.indexOf('px') >= 0) {
12269 navbarTitleLargeHeight = parseInt(navbarTitleLargeHeight, 10);
12270 if (Number.isNaN(navbarTitleLargeHeight)) {
12271 if (app.theme === 'ios') { navbarTitleLargeHeight = 52; }
12272 else if (app.theme === 'md') { navbarTitleLargeHeight = 48; }
12273 else if (app.theme === 'aurora') { navbarTitleLargeHeight = 38; }
12275 } else { // eslint-disable-next-line
12276 if (app.theme === 'ios') { navbarTitleLargeHeight = 52; }
12277 else if (app.theme === 'md') { navbarTitleLargeHeight = 48; }
12278 else if (app.theme === 'aurora') { navbarTitleLargeHeight = 38; }
12281 if (needHide && isLarge) {
12282 navbarHideHeight += navbarTitleLargeHeight;
12287 var scrollTimeoutId;
12288 var touchEndTimeoutId;
12289 var touchSnapTimeout = 70;
12290 var desktopSnapTimeout = 300;
12292 function snapLargeNavbar() {
12293 var inSearchbarExpanded = $navbarInnerEl.hasClass('with-searchbar-expandable-enabled');
12294 if (inSearchbarExpanded) { return; }
12295 if (!scrollContent || currentScrollTop < 0) { return; }
12296 if (currentScrollTop >= navbarTitleLargeHeight / 2 && currentScrollTop < navbarTitleLargeHeight) {
12297 $(scrollContent).scrollTop(navbarTitleLargeHeight, 100);
12298 } else if (currentScrollTop < navbarTitleLargeHeight) {
12299 $(scrollContent).scrollTop(0, 200);
12303 function handleLargeNavbarCollapse() {
12304 var collapseProgress = Math.min(Math.max((currentScrollTop / navbarTitleLargeHeight), 0), 1);
12305 var inSearchbarExpanded = $navbarInnerEl.hasClass('with-searchbar-expandable-enabled');
12306 if (inSearchbarExpanded) { return; }
12307 navbarCollapsed = $navbarInnerEl.hasClass('navbar-inner-large-collapsed');
12308 if (collapseProgress === 0 && navbarCollapsed) {
12309 app.navbar.expandLargeTitle($navbarInnerEl[0]);
12310 $navbarInnerEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12311 $pageEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12312 $navbarInnerEl[0].style.overflow = '';
12313 if (app.theme === 'md' || app.theme === 'aurora') {
12314 $navbarEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12316 } else if (collapseProgress === 1 && !navbarCollapsed) {
12317 app.navbar.collapseLargeTitle($navbarInnerEl[0]);
12318 $navbarInnerEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12319 $navbarInnerEl[0].style.overflow = '';
12320 $pageEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12321 if (app.theme === 'md' || app.theme === 'aurora') {
12322 $navbarEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12324 } else if ((collapseProgress === 1 && navbarCollapsed) || (collapseProgress === 0 && !navbarCollapsed)) {
12325 $navbarInnerEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12326 $navbarInnerEl[0].style.overflow = '';
12327 $pageEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12328 if (app.theme === 'md' || app.theme === 'aurora') {
12329 $navbarEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12332 $navbarInnerEl[0].style.setProperty('--f7-navbar-large-collapse-progress', collapseProgress);
12333 $navbarInnerEl[0].style.overflow = 'visible';
12334 $pageEl[0].style.setProperty('--f7-navbar-large-collapse-progress', collapseProgress);
12335 if (app.theme === 'md' || app.theme === 'aurora') {
12336 $navbarEl[0].style.setProperty('--f7-navbar-large-collapse-progress', collapseProgress);
12340 if (snapPageScrollToLargeTitle) {
12341 if (!Support.touch) {
12342 clearTimeout(scrollTimeoutId);
12343 scrollTimeoutId = setTimeout(function () {
12345 }, desktopSnapTimeout);
12346 } else if (touchEndTimeoutId) {
12347 clearTimeout(touchEndTimeoutId);
12348 touchEndTimeoutId = null;
12349 touchEndTimeoutId = setTimeout(function () {
12351 clearTimeout(touchEndTimeoutId);
12352 touchEndTimeoutId = null;
12353 }, touchSnapTimeout);
12358 function handleTitleHideShow() {
12359 scrollHeight = scrollContent.scrollHeight;
12360 offsetHeight = scrollContent.offsetHeight;
12361 reachEnd = currentScrollTop + offsetHeight >= scrollHeight;
12362 navbarHidden = $navbarEl.hasClass('navbar-hidden');
12365 if (app.params.navbar.showOnPageScrollEnd) {
12368 } else if (previousScrollTop > currentScrollTop) {
12369 if (app.params.navbar.showOnPageScrollTop || currentScrollTop <= navbarHideHeight) {
12374 } else if (currentScrollTop > navbarHideHeight) {
12380 if (action === 'show' && navbarHidden) {
12381 app.navbar.show($navbarEl);
12382 navbarHidden = false;
12383 } else if (action === 'hide' && !navbarHidden) {
12384 app.navbar.hide($navbarEl);
12385 navbarHidden = true;
12387 previousScrollTop = currentScrollTop;
12390 function handleScroll() {
12391 scrollContent = this;
12392 currentScrollTop = scrollContent.scrollTop;
12393 scrollChanged = currentScrollTop;
12395 if (needCollapse) {
12396 handleLargeNavbarCollapse();
12398 if ($pageEl.hasClass('page-previous')) { return; }
12400 handleTitleHideShow();
12403 function handeTouchStart() {
12404 scrollChanged = false;
12406 function handleTouchEnd() {
12407 clearTimeout(touchEndTimeoutId);
12408 touchEndTimeoutId = null;
12409 touchEndTimeoutId = setTimeout(function () {
12410 if (scrollChanged !== false) {
12412 clearTimeout(touchEndTimeoutId);
12413 touchEndTimeoutId = null;
12415 }, touchSnapTimeout);
12417 $pageEl.on('scroll', '.page-content', handleScroll, true);
12418 if (Support.touch && needCollapse && snapPageScrollToLargeTitle) {
12419 app.on('touchstart:passive', handeTouchStart);
12420 app.on('touchend:passive', handleTouchEnd);
12422 if (needCollapse) {
12423 $pageEl.find('.page-content').each(function (pageContentIndex, pageContentEl) {
12424 if (pageContentEl.scrollTop > 0) { handleScroll.call(pageContentEl); }
12427 $pageEl[0].f7DetachNavbarScrollHandlers = function f7DetachNavbarScrollHandlers() {
12428 delete $pageEl[0].f7DetachNavbarScrollHandlers;
12429 $pageEl.off('scroll', '.page-content', handleScroll, true);
12430 if (Support.touch && needCollapse && snapPageScrollToLargeTitle) {
12431 app.off('touchstart:passive', handeTouchStart);
12432 app.off('touchend:passive', handleTouchEnd);
12439 create: function create() {
12441 Utils.extend(app, {
12443 size: Navbar.size.bind(app),
12444 hide: Navbar.hide.bind(app),
12445 show: Navbar.show.bind(app),
12446 getElByPage: Navbar.getElByPage.bind(app),
12447 getPageByEl: Navbar.getPageByEl.bind(app),
12448 collapseLargeTitle: Navbar.collapseLargeTitle.bind(app),
12449 expandLargeTitle: Navbar.expandLargeTitle.bind(app),
12450 toggleLargeTitle: Navbar.toggleLargeTitle.bind(app),
12451 initNavbarOnScroll: Navbar.initNavbarOnScroll.bind(app),
12457 scrollTopOnTitleClick: true,
12458 iosCenterTitle: true,
12459 mdCenterTitle: false,
12460 auroraCenterTitle: true,
12461 hideOnPageScroll: false,
12462 showOnPageScrollEnd: true,
12463 showOnPageScrollTop: true,
12464 collapseLargeTitleOnScroll: true,
12465 snapPageScrollToLargeTitle: true,
12469 'panelBreakpoint panelResize resize viewMasterDetailBreakpoint': function onResize() {
12471 $('.navbar').each(function (index, navbarEl) {
12472 app.navbar.size(navbarEl);
12475 pageBeforeRemove: function pageBeforeRemove(page) {
12476 if (page.$el[0].f7DetachNavbarScrollHandlers) {
12477 page.$el[0].f7DetachNavbarScrollHandlers();
12480 pageBeforeIn: function pageBeforeIn(page) {
12482 if (app.theme !== 'ios') { return; }
12484 var view = page.$el.parents('.view')[0].f7View;
12485 var navbarInnerEl = app.navbar.getElByPage(page);
12486 if (!navbarInnerEl) {
12487 $navbarEl = page.$el.parents('.view').children('.navbar');
12489 $navbarEl = $(navbarInnerEl).parents('.navbar');
12491 if (page.$el.hasClass('no-navbar') || (view.router.dynamicNavbar && !navbarInnerEl)) {
12492 var animate = !!(page.pageFrom && page.router.history.length > 0);
12493 app.navbar.hide($navbarEl, animate);
12495 app.navbar.show($navbarEl);
12498 pageReinit: function pageReinit(page) {
12500 var $navbarInnerEl = $(app.navbar.getElByPage(page));
12501 if (!$navbarInnerEl || $navbarInnerEl.length === 0) { return; }
12502 app.navbar.size($navbarInnerEl);
12504 pageInit: function pageInit(page) {
12506 var $navbarInnerEl = $(app.navbar.getElByPage(page));
12507 if (!$navbarInnerEl || $navbarInnerEl.length === 0) { return; }
12510 app.navbar.size($navbarInnerEl);
12512 // Need Collapse On Scroll
12513 var needCollapseOnScrollHandler;
12514 if ($navbarInnerEl.children('.title-large').length > 0) {
12515 $navbarInnerEl.addClass('navbar-inner-large');
12517 if ($navbarInnerEl.hasClass('navbar-inner-large')) {
12518 if (app.params.navbar.collapseLargeTitleOnScroll) { needCollapseOnScrollHandler = true; }
12519 if (app.theme === 'md' || app.theme === 'aurora') {
12520 $navbarInnerEl.parents('.navbar').addClass('navbar-large');
12522 page.$el.addClass('page-with-navbar-large');
12525 // Need Hide On Scroll
12526 var needHideOnScrollHandler;
12528 app.params.navbar.hideOnPageScroll
12529 || page.$el.find('.hide-navbar-on-scroll').length
12530 || page.$el.hasClass('hide-navbar-on-scroll')
12531 || page.$el.find('.hide-bars-on-scroll').length
12532 || page.$el.hasClass('hide-bars-on-scroll')
12535 page.$el.find('.keep-navbar-on-scroll').length
12536 || page.$el.hasClass('keep-navbar-on-scroll')
12537 || page.$el.find('.keep-bars-on-scroll').length
12538 || page.$el.hasClass('keep-bars-on-scroll')
12540 needHideOnScrollHandler = false;
12542 needHideOnScrollHandler = true;
12546 if (needCollapseOnScrollHandler || needHideOnScrollHandler) {
12547 app.navbar.initNavbarOnScroll(page.el, $navbarInnerEl[0], needHideOnScrollHandler, needCollapseOnScrollHandler);
12550 modalOpen: function modalOpen(modal) {
12552 if (!app.params.navbar[((app.theme) + "CenterTitle
")]) {
12555 modal.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12556 app.navbar.size(navbarEl);
12559 panelOpen: function panelOpen(panel) {
12561 if (!app.params.navbar[((app.theme) + "CenterTitle
")]) {
12564 panel.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12565 app.navbar.size(navbarEl);
12568 panelSwipeOpen: function panelSwipeOpen(panel) {
12570 if (!app.params.navbar[((app.theme) + "CenterTitle
")]) {
12573 panel.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12574 app.navbar.size(navbarEl);
12577 tabShow: function tabShow(tabEl) {
12579 if (!app.params.navbar[((app.theme) + "CenterTitle
")]) {
12582 $(tabEl).find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12583 app.navbar.size(navbarEl);
12588 '.navbar .title': function onTitleClick($clickedEl) {
12590 if (!app.params.navbar.scrollTopOnTitleClick) { return; }
12591 if ($clickedEl.closest('a').length > 0) {
12595 // Find active page
12596 var navbar = $clickedEl.parents('.navbar');
12599 pageContent = navbar.parents('.page-content');
12601 if (pageContent.length === 0) {
12603 if (navbar.parents('.page').length > 0) {
12604 pageContent = navbar.parents('.page').find('.page-content');
12607 if (pageContent.length === 0) {
12608 if (navbar.nextAll('.page-current:not(.stacked)').length > 0) {
12609 pageContent = navbar.nextAll('.page-current:not(.stacked)').find('.page-content');
12613 if (pageContent && pageContent.length > 0) {
12615 if (pageContent.hasClass('tab')) {
12616 pageContent = pageContent.parent('.tabs').children('.page-content.tab-active');
12618 if (pageContent.length > 0) { pageContent.scrollTop(0, 300); }
12624 postpatch: function postpatch(vnode) {
12626 if (!app.params.navbar[((app.theme) + "CenterTitle
")]) {
12629 app.navbar.size(vnode.elm);
12636 setHighlight: function setHighlight(tabbarEl) {
12638 if (app.theme !== 'md') { return; }
12640 var $tabbarEl = $(tabbarEl);
12642 if ($tabbarEl.length === 0 || !($tabbarEl.hasClass('tabbar') || $tabbarEl.hasClass('tabbar-labels'))) { return; }
12644 var $highlightEl = $tabbarEl.find('.tab-link-highlight');
12645 var tabLinksCount = $tabbarEl.find('.tab-link').length;
12646 if (tabLinksCount === 0) {
12647 $highlightEl.remove();
12651 if ($highlightEl.length === 0) {
12652 $tabbarEl.children('.toolbar-inner').append('<span class="tab
-link
-highlight
"></span>');
12653 $highlightEl = $tabbarEl.find('.tab-link-highlight');
12654 } else if ($highlightEl.next().length) {
12655 $tabbarEl.children('.toolbar-inner').append($highlightEl);
12658 var $activeLink = $tabbarEl.find('.tab-link-active');
12659 var highlightWidth;
12660 var highlightTranslate;
12662 if ($tabbarEl.hasClass('tabbar-scrollable') && $activeLink && $activeLink[0]) {
12663 highlightWidth = ($activeLink[0].offsetWidth) + "px
";
12664 highlightTranslate = ($activeLink[0].offsetLeft) + "px
";
12666 var activeIndex = $activeLink.index();
12667 highlightWidth = (100 / tabLinksCount) + "%";
12668 highlightTranslate = ((app.rtl ? -activeIndex : activeIndex) * 100) + "%";
12671 Utils.nextFrame(function () {
12673 .css('width', highlightWidth)
12674 .transform(("translate3d(" + highlightTranslate + ",0,0)"));
12677 init: function init(tabbarEl) {
12679 app.toolbar.setHighlight(tabbarEl);
12681 hide: function hide(el, animate) {
12682 if ( animate === void 0 ) animate = true;
12685 if ($el.hasClass('toolbar-hidden')) { return; }
12686 var className = "toolbar
-hidden
" + (animate ? ' toolbar-transitioning' : '');
12687 $el.transitionEnd(function () {
12688 $el.removeClass('toolbar-transitioning');
12690 $el.addClass(className);
12692 show: function show(el, animate) {
12693 if ( animate === void 0 ) animate = true;
12696 if (!$el.hasClass('toolbar-hidden')) { return; }
12698 $el.addClass('toolbar-transitioning');
12699 $el.transitionEnd(function () {
12700 $el.removeClass('toolbar-transitioning');
12703 $el.removeClass('toolbar-hidden');
12705 initHideToolbarOnScroll: function initHideToolbarOnScroll(pageEl) {
12707 var $pageEl = $(pageEl);
12708 var $toolbarEl = $pageEl.parents('.view').children('.toolbar');
12709 if ($toolbarEl.length === 0) {
12710 $toolbarEl = $pageEl.find('.toolbar');
12712 if ($toolbarEl.length === 0) {
12713 $toolbarEl = $pageEl.parents('.views').children('.tabbar, .tabbar-labels');
12715 if ($toolbarEl.length === 0) {
12719 var previousScrollTop;
12720 var currentScrollTop;
12727 function handleScroll() {
12728 var scrollContent = this;
12729 if ($pageEl.hasClass('page-previous')) { return; }
12730 currentScrollTop = scrollContent.scrollTop;
12731 scrollHeight = scrollContent.scrollHeight;
12732 offsetHeight = scrollContent.offsetHeight;
12733 reachEnd = currentScrollTop + offsetHeight >= scrollHeight;
12734 toolbarHidden = $toolbarEl.hasClass('toolbar-hidden');
12737 if (app.params.toolbar.showOnPageScrollEnd) {
12740 } else if (previousScrollTop > currentScrollTop) {
12741 if (app.params.toolbar.showOnPageScrollTop || currentScrollTop <= 44) {
12746 } else if (currentScrollTop > 44) {
12752 if (action === 'show' && toolbarHidden) {
12753 app.toolbar.show($toolbarEl);
12754 toolbarHidden = false;
12755 } else if (action === 'hide' && !toolbarHidden) {
12756 app.toolbar.hide($toolbarEl);
12757 toolbarHidden = true;
12760 previousScrollTop = currentScrollTop;
12762 $pageEl.on('scroll', '.page-content', handleScroll, true);
12763 $pageEl[0].f7ScrollToolbarHandler = handleScroll;
12768 create: function create() {
12770 Utils.extend(app, {
12772 hide: Toolbar.hide.bind(app),
12773 show: Toolbar.show.bind(app),
12774 setHighlight: Toolbar.setHighlight.bind(app),
12775 initHideToolbarOnScroll: Toolbar.initHideToolbarOnScroll.bind(app),
12776 init: Toolbar.init.bind(app),
12782 hideOnPageScroll: false,
12783 showOnPageScrollEnd: true,
12784 showOnPageScrollTop: true,
12788 pageBeforeRemove: function pageBeforeRemove(page) {
12789 if (page.$el[0].f7ScrollToolbarHandler) {
12790 page.$el.off('scroll', '.page-content', page.$el[0].f7ScrollToolbarHandler, true);
12793 pageBeforeIn: function pageBeforeIn(page) {
12795 var $toolbarEl = page.$el.parents('.view').children('.toolbar');
12796 if ($toolbarEl.length === 0) {
12797 $toolbarEl = page.$el.parents('.views').children('.tabbar, .tabbar-labels');
12799 if ($toolbarEl.length === 0) {
12800 $toolbarEl = page.$el.find('.toolbar');
12802 if ($toolbarEl.length === 0) {
12805 if (page.$el.hasClass('no-toolbar')) {
12806 app.toolbar.hide($toolbarEl);
12808 app.toolbar.show($toolbarEl);
12811 pageInit: function pageInit(page) {
12813 page.$el.find('.tabbar, .tabbar-labels').each(function (index, tabbarEl) {
12814 app.toolbar.init(tabbarEl);
12817 app.params.toolbar.hideOnPageScroll
12818 || page.$el.find('.hide-toolbar-on-scroll').length
12819 || page.$el.hasClass('hide-toolbar-on-scroll')
12820 || page.$el.find('.hide-bars-on-scroll').length
12821 || page.$el.hasClass('hide-bars-on-scroll')
12824 page.$el.find('.keep-toolbar-on-scroll').length
12825 || page.$el.hasClass('keep-toolbar-on-scroll')
12826 || page.$el.find('.keep-bars-on-scroll').length
12827 || page.$el.hasClass('keep-bars-on-scroll')
12831 app.toolbar.initHideToolbarOnScroll(page.el);
12834 init: function init() {
12836 app.root.find('.tabbar, .tabbar-labels').each(function (index, tabbarEl) {
12837 app.toolbar.init(tabbarEl);
12846 pageInit: function pageInit(page) {
12847 if (page.$navbarEl && page.$navbarEl.length && page.$navbarEl.find('.subnavbar').length) {
12848 page.$el.addClass('page-with-subnavbar');
12850 if (page.$el.find('.subnavbar').length) {
12851 page.$el.addClass('page-with-subnavbar');
12857 var TouchRipple = function TouchRipple($el, x, y) {
12859 if (!$el) { return undefined; }
12860 var box = $el[0].getBoundingClientRect();
12865 var width = box.width;
12866 var height = box.height;
12867 var diameter = Math.max((Math.pow( ((Math.pow( height, 2 )) + (Math.pow( width, 2 ))), 0.5 )), 48);
12869 ripple.$rippleWaveEl = $(("<div
class=\"ripple
-wave
\" style
=\"width
: " + diameter + "px
; height
: " + diameter + "px
; margin
-top
:-" + (diameter / 2) + "px
; margin
-left
:-" + (diameter / 2) + "px
; left
:" + (center.x) + "px
; top
:" + (center.y) + "px
;\"></div
>"));
12871 $el.prepend(ripple.$rippleWaveEl);
12873 ripple.rippleTransform = "translate3d(" + (-center.x + (width / 2)) + "px
, " + (-center.y + (height / 2)) + "px
, 0) scale(1)";
12875 Utils.nextFrame(function () {
12876 if (!ripple || !ripple.$rippleWaveEl) { return; }
12877 ripple.$rippleWaveEl.transform(ripple.rippleTransform);
12883 TouchRipple.prototype.destroy = function destroy () {
12885 if (ripple.$rippleWaveEl) {
12886 ripple.$rippleWaveEl.remove();
12888 Object.keys(ripple).forEach(function (key) {
12889 ripple[key] = null;
12890 delete ripple[key];
12895 TouchRipple.prototype.remove = function remove () {
12897 if (ripple.removing) { return; }
12898 var $rippleWaveEl = this.$rippleWaveEl;
12899 var rippleTransform = this.rippleTransform;
12900 var removeTimeout = Utils.nextTick(function () {
12903 ripple.removing = true;
12905 .addClass('ripple-wave-fill')
12906 .transform(rippleTransform.replace('scale(1)', 'scale(1.01)'))
12907 .transitionEnd(function () {
12908 clearTimeout(removeTimeout);
12909 Utils.nextFrame(function () {
12911 .addClass('ripple-wave-out')
12912 .transform(rippleTransform.replace('scale(1)', 'scale(1.01)'));
12914 removeTimeout = Utils.nextTick(function () {
12918 $rippleWaveEl.transitionEnd(function () {
12919 clearTimeout(removeTimeout);
12926 var TouchRipple$1 = {
12927 name: 'touch-ripple',
12929 TouchRipple: TouchRipple,
12931 create: function create() {
12933 app.touchRipple = {
12934 create: function create() {
12935 var args = [], len = arguments.length;
12936 while ( len-- ) args[ len ] = arguments[ len ];
12938 return new (Function.prototype.bind.apply( TouchRipple, [ null ].concat( args) ));
12944 var openedModals = [];
12945 var dialogsQueue = [];
12946 function clearDialogsQueue() {
12947 if (dialogsQueue.length === 0) { return; }
12948 var dialog = dialogsQueue.shift();
12951 var Modal = /*@__PURE__*/(function (Framework7Class) {
12952 function Modal(app, params) {
12953 Framework7Class.call(this, params, [app]);
12959 // Extend defaults with modules params
12960 modal.useModulesParams(defaults);
12962 modal.params = Utils.extend(defaults, params);
12963 modal.opened = false;
12966 modal.useModules();
12971 if ( Framework7Class ) Modal.__proto__ = Framework7Class;
12972 Modal.prototype = Object.create( Framework7Class && Framework7Class.prototype );
12973 Modal.prototype.constructor = Modal;
12975 Modal.prototype.onOpen = function onOpen () {
12977 modal.opened = true;
12978 openedModals.push(modal);
12979 $('html').addClass(("with-modal
-" + (modal.type.toLowerCase())));
12980 modal.$el.trigger(("modal
:open
" + (modal.type.toLowerCase()) + ":open
"), modal);
12981 modal.emit(("local
::open modalOpen
" + (modal.type) + "Open
"), modal);
12984 Modal.prototype.onOpened = function onOpened () {
12986 modal.$el.trigger(("modal
:opened
" + (modal.type.toLowerCase()) + ":opened
"), modal);
12987 modal.emit(("local
::opened modalOpened
" + (modal.type) + "Opened
"), modal);
12990 Modal.prototype.onClose = function onClose () {
12992 modal.opened = false;
12993 if (!modal.type || !modal.$el) { return; }
12994 openedModals.splice(openedModals.indexOf(modal), 1);
12995 $('html').removeClass(("with-modal
-" + (modal.type.toLowerCase())));
12996 modal.$el.trigger(("modal
:close
" + (modal.type.toLowerCase()) + ":close
"), modal);
12997 modal.emit(("local
::close modalClose
" + (modal.type) + "Close
"), modal);
13000 Modal.prototype.onClosed = function onClosed () {
13002 if (!modal.type || !modal.$el) { return; }
13003 modal.$el.removeClass('modal-out');
13005 modal.$el.trigger(("modal
:closed
" + (modal.type.toLowerCase()) + ":closed
"), modal);
13006 modal.emit(("local
::closed modalClosed
" + (modal.type) + "Closed
"), modal);
13009 Modal.prototype.open = function open (animateModal) {
13011 var app = modal.app;
13012 var $el = modal.$el;
13013 var $backdropEl = modal.$backdropEl;
13014 var type = modal.type;
13015 var animate = true;
13016 if (typeof animateModal !== 'undefined') { animate = animateModal; }
13017 else if (typeof modal.params.animate !== 'undefined') {
13018 animate = modal.params.animate;
13021 if (!$el || $el.hasClass('modal-in')) {
13025 if (type === 'dialog' && app.params.modal.queueDialogs) {
13027 if ($('.dialog.modal-in').length > 0) {
13028 pushToQueue = true;
13029 } else if (openedModals.length > 0) {
13030 openedModals.forEach(function (openedModal) {
13031 if (openedModal.type === 'dialog') { pushToQueue = true; }
13035 dialogsQueue.push(modal);
13040 var $modalParentEl = $el.parent();
13041 var wasInDom = $el.parents(doc).length > 0;
13042 if (app.params.modal.moveToRoot && !$modalParentEl.is(app.root)) {
13043 app.root.append($el);
13044 modal.once((type + "Closed
"), function () {
13046 $modalParentEl.append($el);
13055 /* eslint no-underscore-dangle: ["error
", { "allow
": ["_clientLeft
"] }] */
13056 modal._clientLeft = $el[0].clientLeft;
13059 function transitionEnd() {
13060 if ($el.hasClass('modal-out')) {
13062 } else if ($el.hasClass('modal-in')) {
13068 $backdropEl.removeClass('not-animated');
13069 $backdropEl.addClass('backdrop-in');
13072 .animationEnd(function () {
13076 .transitionEnd(function () {
13080 .removeClass('modal-out not-animated')
13081 .addClass('modal-in');
13085 $backdropEl.addClass('backdrop-in not-animated');
13087 $el.removeClass('modal-out').addClass('modal-in not-animated');
13095 Modal.prototype.close = function close (animateModal) {
13097 var $el = modal.$el;
13098 var $backdropEl = modal.$backdropEl;
13100 var animate = true;
13101 if (typeof animateModal !== 'undefined') { animate = animateModal; }
13102 else if (typeof modal.params.animate !== 'undefined') {
13103 animate = modal.params.animate;
13106 if (!$el || !$el.hasClass('modal-in')) {
13112 var needToHideBackdrop = true;
13113 if (modal.type === 'popup') {
13114 modal.$el.prevAll('.popup.modal-in').each(function (index, popupEl) {
13115 var popupInstance = popupEl.f7Modal;
13116 if (!popupInstance) { return; }
13118 popupInstance.params.closeByBackdropClick
13119 && popupInstance.params.backdrop
13120 && popupInstance.backdropEl === modal.backdropEl
13122 needToHideBackdrop = false;
13126 if (needToHideBackdrop) {
13127 $backdropEl[animate ? 'removeClass' : 'addClass']('not-animated');
13128 $backdropEl.removeClass('backdrop-in');
13133 $el[animate ? 'removeClass' : 'addClass']('not-animated');
13134 function transitionEnd() {
13135 if ($el.hasClass('modal-out')) {
13137 } else if ($el.hasClass('modal-in')) {
13143 .animationEnd(function () {
13147 .transitionEnd(function () {
13151 .removeClass('modal-in')
13152 .addClass('modal-out');
13157 .addClass('not-animated')
13158 .removeClass('modal-in')
13159 .addClass('modal-out');
13165 if (modal.type === 'dialog') {
13166 clearDialogsQueue();
13172 Modal.prototype.destroy = function destroy () {
13174 if (modal.destroyed) { return; }
13175 modal.emit(("local
::beforeDestroy modalBeforeDestroy
" + (modal.type) + "BeforeDestroy
"), modal);
13177 modal.$el.trigger(("modal
:beforedestroy
" + (modal.type.toLowerCase()) + ":beforedestroy
"), modal);
13178 if (modal.$el.length && modal.$el[0].f7Modal) {
13179 delete modal.$el[0].f7Modal;
13182 Utils.deleteProps(modal);
13183 modal.destroyed = true;
13187 }(Framework7Class));
13189 var CustomModal = /*@__PURE__*/(function (Modal) {
13190 function CustomModal(app, params) {
13191 var extendedParams = Utils.extend({
13193 closeByBackdropClick: true,
13197 // Extends with open/close Modal methods;
13198 Modal.call(this, app, extendedParams);
13200 var customModal = this;
13202 customModal.params = extendedParams;
13206 if (!customModal.params.el) {
13207 $el = $(customModal.params.content);
13209 $el = $(customModal.params.el);
13212 if ($el && $el.length > 0 && $el[0].f7Modal) {
13213 return $el[0].f7Modal;
13216 if ($el.length === 0) {
13217 return customModal.destroy();
13220 if (customModal.params.backdrop) {
13221 $backdropEl = app.root.children('.custom-modal-backdrop');
13222 if ($backdropEl.length === 0) {
13223 $backdropEl = $('<div class="custom
-modal
-backdrop
"></div>');
13224 app.root.append($backdropEl);
13228 function handleClick(e) {
13229 if (!customModal || customModal.destroyed) { return; }
13230 if ($backdropEl && e.target === $backdropEl[0]) {
13231 customModal.close();
13235 customModal.on('customModalOpened', function () {
13236 if (customModal.params.closeByBackdropClick && customModal.params.backdrop) {
13237 app.on('click', handleClick);
13240 customModal.on('customModalClose', function () {
13241 if (customModal.params.closeByBackdropClick && customModal.params.backdrop) {
13242 app.off('click', handleClick);
13246 Utils.extend(customModal, {
13250 $backdropEl: $backdropEl,
13251 backdropEl: $backdropEl && $backdropEl[0],
13252 type: 'customModal',
13255 $el[0].f7Modal = customModal;
13257 return customModal;
13260 if ( Modal ) CustomModal.__proto__ = Modal;
13261 CustomModal.prototype = Object.create( Modal && Modal.prototype );
13262 CustomModal.prototype.constructor = CustomModal;
13264 return CustomModal;
13271 CustomModal: CustomModal,
13273 create: function create() {
13275 app.customModal = {
13276 create: function create(params) {
13277 return new CustomModal(app, params);
13284 queueDialogs: true,
13290 if (typeof window !== 'undefined') {
13292 if (!window.Template7) { window.Template7 = Template7; }
13295 if (!window.Dom7) { window.Dom7 = $; }
13299 // Install Core Modules & Components
13301 RouterTemplateLoaderModule,
13302 RouterComponentLoaderModule ]);
13316 ServiceWorkerModule,