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: February 5, 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: February 5, 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; }
263 if (typeof variable
=== 'string') {
264 variable
= JSON
.stringify(variable
);
266 if (variable
=== undefined) { variable
= 'undefined'; }
272 parseJsParents
: function parseJsParents(expression
, parents
) {
273 return expression
.split(/([+ \-*^()&=|<>!%:?])/g).reduce(function (arr
, part
) {
278 if (part
.indexOf('../') < 0) {
283 if (!parents
|| parents
.length
=== 0) {
284 arr
.push(JSON
.stringify(''));
288 var levelsUp
= part
.split('../').length
- 1;
289 var parentData
= levelsUp
> parents
.length
? parents
[parents
.length
- 1] : parents
[levelsUp
- 1];
291 var variable
= parentData
;
292 var parentPart
= part
.replace(/..\//g, '');
293 parentPart
.split('.').forEach(function (partName
) {
294 if (typeof variable
[partName
] !== 'undefined') { variable
= variable
[partName
]; }
295 else { variable
= 'undefined'; }
297 if (variable
=== false || variable
=== true) {
298 arr
.push(JSON
.stringify(variable
));
301 if (variable
=== null || variable
=== 'undefined') {
302 arr
.push(JSON
.stringify(''));
305 arr
.push(JSON
.stringify(variable
));
309 getCompileVar
: function getCompileVar(name
, ctx
, data
) {
310 if ( data
=== void 0 ) data
= 'data_1';
316 if (name
.indexOf('../') === 0) {
317 levelsUp
= name
.split('../').length
- 1;
318 newDepth
= variable
.split('_')[1] - levelsUp
;
319 variable
= "ctx_" + (newDepth
>= 1 ? newDepth
: 1);
320 parts
= name
.split('../')[levelsUp
].split('.');
321 } else if (name
.indexOf('@global') === 0) {
322 variable
= 'Template7.global';
323 parts
= name
.split('@global.')[1].split('.');
324 } else if (name
.indexOf('@root') === 0) {
326 parts
= name
.split('@root.')[1].split('.');
328 parts
= name
.split('.');
330 for (var i
= 0; i
< parts
.length
; i
+= 1) {
332 if (part
.indexOf('@') === 0) {
333 var dataLevel
= data
.split('_')[1];
335 dataLevel
= newDepth
;
338 variable
+= "[(data_" + dataLevel
+ " && data_" + dataLevel
+ "." + (part
.replace('@', '')) + ")]";
340 variable
= "(data_" + dataLevel
+ " && data_" + dataLevel
+ "." + (part
.replace('@', '')) + ")";
342 } else if (Number
.isFinite
? Number
.isFinite(part
) : Template7Context
.isFinite(part
)) {
343 variable
+= "[" + part
+ "]";
344 } else if (part
=== 'this' || part
.indexOf('this.') >= 0 || part
.indexOf('this[') >= 0 || part
.indexOf('this(') >= 0) {
345 variable
= part
.replace('this', ctx
);
347 variable
+= "." + part
;
352 getCompiledArguments
: function getCompiledArguments(contextArray
, ctx
, data
) {
354 for (var i
= 0; i
< contextArray
.length
; i
+= 1) {
355 if (/^['"]/.test(contextArray
[i
])) { arr
.push(contextArray
[i
]); }
356 else if (/^(true|false|\d+)$/.test(contextArray
[i
])) { arr
.push(contextArray
[i
]); }
358 arr
.push(Template7Utils
.getCompileVar(contextArray
[i
], ctx
, data
));
362 return arr
.join(', ');
366 /* eslint no-eval: "off" */
368 var Template7Helpers
= {
369 _partial
: function _partial(partialName
, options
) {
371 var p
= Template7Class
.partials
[partialName
];
372 if (!p
|| (p
&& !p
.template
)) { return ''; }
374 p
.compiled
= new Template7Class(p
.template
).compile();
376 Object
.keys(options
.hash
).forEach(function (hashName
) {
377 ctx
[hashName
] = options
.hash
[hashName
];
379 return p
.compiled(ctx
, options
.data
, options
.root
);
381 escape
: function escape(context
) {
382 if (typeof context
!== 'string') {
383 throw new Error('Template7: Passed context to "escape" helper should be a string');
385 return Template7Utils
.escape(context
);
387 if: function if$1(context
, options
) {
389 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
391 return options
.fn(this, options
.data
);
394 return options
.inverse(this, options
.data
);
396 unless
: function unless(context
, options
) {
398 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
400 return options
.fn(this, options
.data
);
403 return options
.inverse(this, options
.data
);
405 each
: function each(context
, options
) {
409 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
410 if (Array
.isArray(ctx
)) {
411 if (options
.hash
.reverse
) {
414 for (i
= 0; i
< ctx
.length
; i
+= 1) {
415 ret
+= options
.fn(ctx
[i
], { first
: i
=== 0, last
: i
=== ctx
.length
- 1, index
: i
});
417 if (options
.hash
.reverse
) {
421 // eslint-disable-next-line
422 for (var key
in ctx
) {
424 ret
+= options
.fn(ctx
[key
], { key
: key
});
427 if (i
> 0) { return ret
; }
428 return options
.inverse(this);
430 with: function with$1(context
, options
) {
432 if (Template7Utils
.isFunction(ctx
)) { ctx
= context
.call(this); }
433 return options
.fn(ctx
);
435 join
: function join(context
, options
) {
437 if (Template7Utils
.isFunction(ctx
)) { ctx
= ctx
.call(this); }
438 return ctx
.join(options
.hash
.delimiter
|| options
.hash
.delimeter
);
440 js
: function js(expression
, options
) {
441 var data
= options
.data
;
443 var execute
= expression
;
444 ('index first last key').split(' ').forEach(function (prop
) {
445 if (typeof data
[prop
] !== 'undefined') {
446 var re1
= new RegExp(("this.@" + prop
), 'g');
447 var re2
= new RegExp(("@" + prop
), 'g');
449 .replace(re1
, JSON
.stringify(data
[prop
]))
450 .replace(re2
, JSON
.stringify(data
[prop
]));
453 if (options
.root
&& execute
.indexOf('@root') >= 0) {
454 execute
= Template7Utils
.parseJsVariable(execute
, '@root', options
.root
);
456 if (execute
.indexOf('@global') >= 0) {
457 execute
= Template7Utils
.parseJsVariable(execute
, '@global', Template7Context
.Template7
.global
);
459 if (execute
.indexOf('../') >= 0) {
460 execute
= Template7Utils
.parseJsParents(execute
, options
.parents
);
462 if (execute
.indexOf('return') >= 0) {
463 func
= "(function(){" + execute
+ "})";
465 func
= "(function(){return (" + execute
+ ")})";
467 return eval(func
).call(this);
469 js_if
: function js_if(expression
, options
) {
470 var data
= options
.data
;
472 var execute
= expression
;
473 ('index first last key').split(' ').forEach(function (prop
) {
474 if (typeof data
[prop
] !== 'undefined') {
475 var re1
= new RegExp(("this.@" + prop
), 'g');
476 var re2
= new RegExp(("@" + prop
), 'g');
478 .replace(re1
, JSON
.stringify(data
[prop
]))
479 .replace(re2
, JSON
.stringify(data
[prop
]));
482 if (options
.root
&& execute
.indexOf('@root') >= 0) {
483 execute
= Template7Utils
.parseJsVariable(execute
, '@root', options
.root
);
485 if (execute
.indexOf('@global') >= 0) {
486 execute
= Template7Utils
.parseJsVariable(execute
, '@global', Template7Context
.Template7
.global
);
488 if (execute
.indexOf('../') >= 0) {
489 execute
= Template7Utils
.parseJsParents(execute
, options
.parents
);
491 if (execute
.indexOf('return') >= 0) {
492 func
= "(function(){" + execute
+ "})";
494 func
= "(function(){return (" + execute
+ ")})";
496 var condition
= eval(func
).call(this);
498 return options
.fn(this, options
.data
);
501 return options
.inverse(this, options
.data
);
504 Template7Helpers
.js_compare
= Template7Helpers
.js_if
;
506 var Template7Options
= {};
507 var Template7Partials
= {};
509 var Template7Class
= function Template7Class(template
) {
511 t
.template
= template
;
514 var staticAccessors
= { options
: { configurable
: true },partials
: { configurable
: true },helpers
: { configurable
: true } };
515 Template7Class
.prototype.compile
= function compile (template
, depth
) {
516 if ( template
=== void 0 ) template
= this.template
;
517 if ( depth
=== void 0 ) depth
= 1;
520 if (t
.compiled
) { return t
.compiled
; }
522 if (typeof template
!== 'string') {
523 throw new Error('Template7: Template must be a string');
525 var stringToBlocks
= Template7Utils
.stringToBlocks
;
526 var getCompileVar
= Template7Utils
.getCompileVar
;
527 var getCompiledArguments
= Template7Utils
.getCompiledArguments
;
529 var blocks
= stringToBlocks(template
);
530 var ctx
= "ctx_" + depth
;
531 var data
= "data_" + depth
;
532 if (blocks
.length
=== 0) {
533 return function empty() { return ''; };
536 function getCompileFn(block
, newDepth
) {
537 if (block
.content
) { return t
.compile(block
.content
, newDepth
); }
538 return function empty() { return ''; };
540 function getCompileInverse(block
, newDepth
) {
541 if (block
.inverseContent
) { return t
.compile(block
.inverseContent
, newDepth
); }
542 return function empty() { return ''; };
545 var resultString
= '';
547 resultString
+= "(function (" + ctx
+ ", " + data
+ ", root) {\n";
549 resultString
+= "(function (" + ctx
+ ", " + data
+ ") {\n";
552 resultString
+= 'function isArray(arr){return Array.isArray(arr);}\n';
553 resultString
+= 'function isFunction(func){return (typeof func === \'function\');}\n';
554 resultString
+= 'function c(val, ctx) {if (typeof val !== "undefined" && val !== null) {if (isFunction(val)) {return val.call(ctx);} else return val;} else return "";}\n';
555 resultString
+= 'root = root || ctx_1 || {};\n';
557 resultString
+= 'var r = \'\';\n';
559 for (i
= 0; i
< blocks
.length
; i
+= 1) {
560 var block
= blocks
[i
];
562 if (block
.type
=== 'plain') {
563 // eslint-disable-next-line
564 resultString
+= "r +='" + ((block
.content
).replace(/\r/g, '\\r').replace(/\n/g, '\\n').replace(/'/g, '\\' + '\'')) + "';";
567 var variable = (void 0);
568 var compiledArguments = (void 0);
570 if (block.type === 'variable') {
571 variable = getCompileVar(block.contextName, ctx, data);
572 resultString += "r
+= c(" + variable + ", " + ctx + ");";
575 if (block.type === 'helper') {
576 var parents = (void 0);
577 if (ctx !== 'ctx_1') {
578 var level = ctx.split('_')[1];
579 var parentsString = "ctx_
" + (level - 1);
580 for (var j = level - 2; j >= 1; j -= 1) {
581 parentsString += ", ctx_
" + j;
583 parents = "[" + parentsString + "]";
585 parents = "[" + ctx + "]";
587 var dynamicHelper = (void 0);
588 if (block.helperName.indexOf('[') === 0) {
589 block.helperName = getCompileVar(block.helperName.replace(/[[\]]/g, ''), ctx, data);
590 dynamicHelper = true;
592 if (dynamicHelper || block.helperName in Template7Helpers) {
593 compiledArguments = getCompiledArguments(block.contextName, ctx, data);
594 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 + "});";
595 } else if (block.contextName.length > 0) {
596 throw new Error(("Template7
: Missing helper
: \"" + (block.helperName) + "\""));
598 variable = getCompileVar(block.helperName, ctx, data);
599 resultString += "if (" + variable + ") {";
600 resultString += "if (isArray(" + variable + ")) {";
601 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 + "});";
602 resultString += '}else {';
603 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 + "});";
604 resultString += '}}';
608 resultString += '\nreturn r;})';
611 // eslint-disable-next-line
612 t.compiled = eval(resultString);
617 staticAccessors.options.get = function () {
618 return Template7Options;
620 staticAccessors.partials.get = function () {
621 return Template7Partials;
623 staticAccessors.helpers.get = function () {
624 return Template7Helpers;
627 Object.defineProperties( Template7Class, staticAccessors );
629 function Template7() {
630 var args = [], len = arguments.length;
631 while ( len-- ) args[ len ] = arguments[ len ];
633 var template = args[0];
635 if (args.length === 2) {
636 var instance = new Template7Class(template);
637 var rendered = instance.compile()(data);
641 return new Template7Class(template);
643 Template7.registerHelper = function registerHelper(name, fn) {
644 Template7Class.helpers[name] = fn;
646 Template7.unregisterHelper = function unregisterHelper(name) {
647 Template7Class.helpers[name] = undefined;
648 delete Template7Class.helpers[name];
650 Template7.registerPartial = function registerPartial(name, template) {
651 Template7Class.partials[name] = { template: template };
653 Template7.unregisterPartial = function unregisterPartial(name) {
654 if (Template7Class.partials[name]) {
655 Template7Class.partials[name] = undefined;
656 delete Template7Class.partials[name];
659 Template7.compile = function compile(template, options) {
660 var instance = new Template7Class(template, options);
661 return instance.compile();
664 Template7.options = Template7Class.options;
665 Template7.helpers = Template7Class.helpers;
666 Template7.partials = Template7Class.partials;
670 * Better handling for window object in SSR environment
671 * https://github.com/nolimits4web/ssr-window
673 * Copyright 2018, Vladimir Kharlampidi
677 * Released on: July 18, 2018
679 var doc = (typeof document === 'undefined') ? {
681 addEventListener: function addEventListener() {},
682 removeEventListener: function removeEventListener() {},
684 blur: function blur() {},
687 querySelector: function querySelector() {
690 querySelectorAll: function querySelectorAll() {
693 getElementById: function getElementById() {
696 createEvent: function createEvent() {
698 initEvent: function initEvent() {},
701 createElement: function createElement() {
706 setAttribute: function setAttribute() {},
707 getElementsByTagName: function getElementsByTagName() {
712 location: { hash: '' },
713 } : document; // eslint-disable-line
715 var win = (typeof window === 'undefined') ? {
722 CustomEvent: function CustomEvent() {
725 addEventListener: function addEventListener() {},
726 removeEventListener: function removeEventListener() {},
727 getComputedStyle: function getComputedStyle() {
729 getPropertyValue: function getPropertyValue() {
734 Image: function Image() {},
735 Date: function Date() {},
737 setTimeout: function setTimeout() {},
738 clearTimeout: function clearTimeout() {},
739 } : window; // eslint-disable-line
743 * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API
744 * http://framework7.io/docs/dom.html
746 * Copyright 2018, Vladimir Kharlampidi
748 * http://www.idangero.us/
752 * Released on: September 13, 2018
755 var Dom7 = function Dom7(arr) {
757 // Create array-like object
758 for (var i = 0; i < arr.length; i += 1) {
761 self.length = arr.length;
762 // Return collection with methods
766 function $(selector, context) {
769 if (selector && !context) {
770 if (selector instanceof Dom7) {
776 if (typeof selector === 'string') {
779 var html = selector.trim();
780 if (html.indexOf('<') >= 0 && html.indexOf('>') >= 0) {
781 var toCreate = 'div';
782 if (html.indexOf('<li') === 0) { toCreate = 'ul'; }
783 if (html.indexOf('<tr') === 0) { toCreate = 'tbody'; }
784 if (html.indexOf('<td') === 0 || html.indexOf('<th') === 0) { toCreate = 'tr'; }
785 if (html.indexOf('<tbody') === 0) { toCreate = 'table'; }
786 if (html.indexOf('<option') === 0) { toCreate = 'select'; }
787 tempParent = doc.createElement(toCreate);
788 tempParent.innerHTML = html;
789 for (i = 0; i < tempParent.childNodes.length; i += 1) {
790 arr.push(tempParent.childNodes[i]);
793 if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
795 els = [doc.getElementById(selector.trim().split('#')[1])];
798 els = (context || doc).querySelectorAll(selector.trim());
800 for (i = 0; i < els.length; i += 1) {
801 if (els[i]) { arr.push(els[i]); }
804 } else if (selector.nodeType || selector === win || selector === doc) {
807 } else if (selector.length > 0 && selector[0].nodeType) {
808 // Array of elements or instance of Dom
809 for (i = 0; i < selector.length; i += 1) {
810 arr.push(selector[i]);
814 return new Dom7(arr);
817 $.fn = Dom7.prototype;
821 function unique(arr) {
822 var uniqueArray = [];
823 for (var i = 0; i < arr.length; i += 1) {
824 if (uniqueArray.indexOf(arr[i]) === -1) { uniqueArray.push(arr[i]); }
828 function toCamelCase(string) {
829 return string.toLowerCase().replace(/-(.)/g, function (match, group1) { return group1.toUpperCase(); });
832 function requestAnimationFrame(callback) {
833 if (win.requestAnimationFrame) { return win.requestAnimationFrame(callback); }
834 else if (win.webkitRequestAnimationFrame) { return win.webkitRequestAnimationFrame(callback); }
835 return win.setTimeout(callback, 1000 / 60);
837 function cancelAnimationFrame(id) {
838 if (win.cancelAnimationFrame) { return win.cancelAnimationFrame(id); }
839 else if (win.webkitCancelAnimationFrame) { return win.webkitCancelAnimationFrame(id); }
840 return win.clearTimeout(id);
843 // Classes and attributes
844 function addClass(className) {
845 if (typeof className === 'undefined') {
848 var classes = className.split(' ');
849 for (var i = 0; i < classes.length; i += 1) {
850 for (var j = 0; j < this.length; j += 1) {
851 if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.add(classes[i]); }
856 function removeClass(className) {
857 var classes = className.split(' ');
858 for (var i = 0; i < classes.length; i += 1) {
859 for (var j = 0; j < this.length; j += 1) {
860 if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.remove(classes[i]); }
865 function hasClass(className) {
866 if (!this[0]) { return false; }
867 return this[0].classList.contains(className);
869 function toggleClass(className) {
870 var classes = className.split(' ');
871 for (var i = 0; i < classes.length; i += 1) {
872 for (var j = 0; j < this.length; j += 1) {
873 if (typeof this[j] !== 'undefined' && typeof this[j].classList !== 'undefined') { this[j].classList.toggle(classes[i]); }
878 function attr(attrs, value) {
879 var arguments$1 = arguments;
881 if (arguments.length === 1 && typeof attrs === 'string') {
883 if (this[0]) { return this[0].getAttribute(attrs); }
888 for (var i = 0; i < this.length; i += 1) {
889 if (arguments$1.length === 2) {
891 this[i].setAttribute(attrs, value);
894 // eslint-disable-next-line
895 for (var attrName in attrs) {
896 this[i][attrName] = attrs[attrName];
897 this[i].setAttribute(attrName, attrs[attrName]);
903 // eslint-disable-next-line
904 function removeAttr(attr) {
905 for (var i = 0; i < this.length; i += 1) {
906 this[i].removeAttribute(attr);
910 // eslint-disable-next-line
911 function prop(props, value) {
912 var arguments$1 = arguments;
914 if (arguments.length === 1 && typeof props === 'string') {
916 if (this[0]) { return this[0][props]; }
919 for (var i = 0; i < this.length; i += 1) {
920 if (arguments$1.length === 2) {
922 this[i][props] = value;
925 // eslint-disable-next-line
926 for (var propName in props) {
927 this[i][propName] = props[propName];
934 function data(key, value) {
936 if (typeof value === 'undefined') {
940 if (el.dom7ElementDataStorage && (key in el.dom7ElementDataStorage)) {
941 return el.dom7ElementDataStorage[key];
944 var dataKey = el.getAttribute(("data
-" + key));
954 for (var i = 0; i < this.length; i += 1) {
956 if (!el.dom7ElementDataStorage) { el.dom7ElementDataStorage = {}; }
957 el.dom7ElementDataStorage[key] = value;
961 function removeData(key) {
962 for (var i = 0; i < this.length; i += 1) {
964 if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) {
965 el.dom7ElementDataStorage[key] = null;
966 delete el.dom7ElementDataStorage[key];
972 if (!el) { return undefined; }
973 var dataset = {}; // eslint-disable-line
975 // eslint-disable-next-line
976 for (var dataKey in el.dataset) {
977 dataset[dataKey] = el.dataset[dataKey];
980 for (var i = 0; i < el.attributes.length; i += 1) {
981 // eslint-disable-next-line
982 var attr = el.attributes[i];
983 if (attr.name.indexOf('data-') >= 0) {
984 dataset[toCamelCase(attr.name.split('data-')[1])] = attr.value;
988 // eslint-disable-next-line
989 for (var key in dataset) {
990 if (dataset[key] === 'false') { dataset[key] = false; }
991 else if (dataset[key] === 'true') { dataset[key] = true; }
992 else if (parseFloat(dataset[key]) === dataset[key] * 1) { dataset[key] *= 1; }
996 function val(value) {
998 if (typeof value === 'undefined') {
1000 if (dom[0].multiple && dom[0].nodeName.toLowerCase() === 'select') {
1002 for (var i = 0; i < dom[0].selectedOptions.length; i += 1) {
1003 values.push(dom[0].selectedOptions[i].value);
1007 return dom[0].value;
1012 for (var i$1 = 0; i$1 < dom.length; i$1 += 1) {
1014 if (Array.isArray(value) && el.multiple && el.nodeName.toLowerCase() === 'select') {
1015 for (var j = 0; j < el.options.length; j += 1) {
1016 el.options[j].selected = value.indexOf(el.options[j].value) >= 0;
1025 // eslint-disable-next-line
1026 function transform(transform) {
1027 for (var i = 0; i < this.length; i += 1) {
1028 var elStyle = this[i].style;
1029 elStyle.webkitTransform = transform;
1030 elStyle.transform = transform;
1034 function transition(duration) {
1035 if (typeof duration !== 'string') {
1036 duration = duration + "ms
"; // eslint-disable-line
1038 for (var i = 0; i < this.length; i += 1) {
1039 var elStyle = this[i].style;
1040 elStyle.webkitTransitionDuration = duration;
1041 elStyle.transitionDuration = duration;
1049 var args = [], len = arguments.length;
1050 while ( len-- ) args[ len ] = arguments[ len ];
1051 var eventType = args[0];
1052 var targetSelector = args[1];
1053 var listener = args[2];
1054 var capture = args[3];
1055 if (typeof args[1] === 'function') {
1056 (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]);
1057 targetSelector = undefined;
1059 if (!capture) { capture = false; }
1061 function handleLiveEvent(e) {
1062 var target = e.target;
1063 if (!target) { return; }
1064 var eventData = e.target.dom7EventData || [];
1065 if (eventData.indexOf(e) < 0) {
1066 eventData.unshift(e);
1068 if ($(target).is(targetSelector)) { listener.apply(target, eventData); }
1070 var parents = $(target).parents(); // eslint-disable-line
1071 for (var k = 0; k < parents.length; k += 1) {
1072 if ($(parents[k]).is(targetSelector)) { listener.apply(parents[k], eventData); }
1076 function handleEvent(e) {
1077 var eventData = e && e.target ? e.target.dom7EventData || [] : [];
1078 if (eventData.indexOf(e) < 0) {
1079 eventData.unshift(e);
1081 listener.apply(this, eventData);
1083 var events = eventType.split(' ');
1085 for (var i = 0; i < this.length; i += 1) {
1087 if (!targetSelector) {
1088 for (j = 0; j < events.length; j += 1) {
1089 var event = events[j];
1090 if (!el.dom7Listeners) { el.dom7Listeners = {}; }
1091 if (!el.dom7Listeners[event]) { el.dom7Listeners[event] = []; }
1092 el.dom7Listeners[event].push({
1094 proxyListener: handleEvent,
1096 el.addEventListener(event, handleEvent, capture);
1100 for (j = 0; j < events.length; j += 1) {
1101 var event$1 = events[j];
1102 if (!el.dom7LiveListeners) { el.dom7LiveListeners = {}; }
1103 if (!el.dom7LiveListeners[event$1]) { el.dom7LiveListeners[event$1] = []; }
1104 el.dom7LiveListeners[event$1].push({
1106 proxyListener: handleLiveEvent,
1108 el.addEventListener(event$1, handleLiveEvent, capture);
1117 var args = [], len = arguments.length;
1118 while ( len-- ) args[ len ] = arguments[ len ];
1119 var eventType = args[0];
1120 var targetSelector = args[1];
1121 var listener = args[2];
1122 var capture = args[3];
1123 if (typeof args[1] === 'function') {
1124 (assign = args, eventType = assign[0], listener = assign[1], capture = assign[2]);
1125 targetSelector = undefined;
1127 if (!capture) { capture = false; }
1129 var events = eventType.split(' ');
1130 for (var i = 0; i < events.length; i += 1) {
1131 var event = events[i];
1132 for (var j = 0; j < this.length; j += 1) {
1134 var handlers = (void 0);
1135 if (!targetSelector && el.dom7Listeners) {
1136 handlers = el.dom7Listeners[event];
1137 } else if (targetSelector && el.dom7LiveListeners) {
1138 handlers = el.dom7LiveListeners[event];
1140 if (handlers && handlers.length) {
1141 for (var k = handlers.length - 1; k >= 0; k -= 1) {
1142 var handler = handlers[k];
1143 if (listener && handler.listener === listener) {
1144 el.removeEventListener(event, handler.proxyListener, capture);
1145 handlers.splice(k, 1);
1146 } else if (!listener) {
1147 el.removeEventListener(event, handler.proxyListener, capture);
1148 handlers.splice(k, 1);
1159 var args = [], len = arguments.length;
1160 while ( len-- ) args[ len ] = arguments[ len ];
1162 var eventName = args[0];
1163 var targetSelector = args[1];
1164 var listener = args[2];
1165 var capture = args[3];
1166 if (typeof args[1] === 'function') {
1167 (assign = args, eventName = assign[0], listener = assign[1], capture = assign[2]);
1168 targetSelector = undefined;
1171 var eventArgs = [], len = arguments.length;
1172 while ( len-- ) eventArgs[ len ] = arguments[ len ];
1174 listener.apply(this, eventArgs);
1175 dom.off(eventName, targetSelector, proxy, capture);
1177 return dom.on(eventName, targetSelector, proxy, capture);
1179 function trigger() {
1180 var args = [], len = arguments.length;
1181 while ( len-- ) args[ len ] = arguments[ len ];
1183 var events = args[0].split(' ');
1184 var eventData = args[1];
1185 for (var i = 0; i < events.length; i += 1) {
1186 var event = events[i];
1187 for (var j = 0; j < this.length; j += 1) {
1191 evt = new win.CustomEvent(event, {
1197 evt = doc.createEvent('Event');
1198 evt.initEvent(event, true, true);
1199 evt.detail = eventData;
1201 // eslint-disable-next-line
1202 el.dom7EventData = args.filter(function (data, dataIndex) { return dataIndex > 0; });
1203 el.dispatchEvent(evt);
1204 el.dom7EventData = [];
1205 delete el.dom7EventData;
1210 function transitionEnd(callback) {
1211 var events = ['webkitTransitionEnd', 'transitionend'];
1214 function fireCallBack(e) {
1215 /* jshint validthis:true */
1216 if (e.target !== this) { return; }
1217 callback.call(this, e);
1218 for (i = 0; i < events.length; i += 1) {
1219 dom.off(events[i], fireCallBack);
1223 for (i = 0; i < events.length; i += 1) {
1224 dom.on(events[i], fireCallBack);
1229 function animationEnd(callback) {
1230 var events = ['webkitAnimationEnd', 'animationend'];
1233 function fireCallBack(e) {
1234 if (e.target !== this) { return; }
1235 callback.call(this, e);
1236 for (i = 0; i < events.length; i += 1) {
1237 dom.off(events[i], fireCallBack);
1241 for (i = 0; i < events.length; i += 1) {
1242 dom.on(events[i], fireCallBack);
1249 if (this[0] === win) {
1250 return win.innerWidth;
1253 if (this.length > 0) {
1254 return parseFloat(this.css('width'));
1259 function outerWidth(includeMargins) {
1260 if (this.length > 0) {
1261 if (includeMargins) {
1262 // eslint-disable-next-line
1263 var styles = this.styles();
1264 return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left'));
1266 return this[0].offsetWidth;
1271 if (this[0] === win) {
1272 return win.innerHeight;
1275 if (this.length > 0) {
1276 return parseFloat(this.css('height'));
1281 function outerHeight(includeMargins) {
1282 if (this.length > 0) {
1283 if (includeMargins) {
1284 // eslint-disable-next-line
1285 var styles = this.styles();
1286 return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom'));
1288 return this[0].offsetHeight;
1293 if (this.length > 0) {
1295 var box = el.getBoundingClientRect();
1296 var body = doc.body;
1297 var clientTop = el.clientTop || body.clientTop || 0;
1298 var clientLeft = el.clientLeft || body.clientLeft || 0;
1299 var scrollTop = el === win ? win.scrollY : el.scrollTop;
1300 var scrollLeft = el === win ? win.scrollX : el.scrollLeft;
1302 top: (box.top + scrollTop) - clientTop,
1303 left: (box.left + scrollLeft) - clientLeft,
1310 for (var i = 0; i < this.length; i += 1) {
1311 this[i].style.display = 'none';
1316 for (var i = 0; i < this.length; i += 1) {
1318 if (el.style.display === 'none') {
1319 el.style.display = '';
1321 if (win.getComputedStyle(el, null).getPropertyValue('display') === 'none') {
1322 // Still not visible
1323 el.style.display = 'block';
1329 if (this[0]) { return win.getComputedStyle(this[0], null); }
1332 function css(props, value) {
1334 if (arguments.length === 1) {
1335 if (typeof props === 'string') {
1336 if (this[0]) { return win.getComputedStyle(this[0], null).getPropertyValue(props); }
1338 for (i = 0; i < this.length; i += 1) {
1339 // eslint-disable-next-line
1340 for (var prop in props) {
1341 this[i].style[prop] = props[prop];
1347 if (arguments.length === 2 && typeof props === 'string') {
1348 for (i = 0; i < this.length; i += 1) {
1349 this[i].style[props] = value;
1357 function toArray() {
1359 for (var i = 0; i < this.length; i += 1) {
1364 // Iterate over the collection passing elements to `callback`
1365 function each(callback) {
1366 // Don't bother continuing without a callback
1367 if (!callback) { return this; }
1368 // Iterate over the current collection
1369 for (var i = 0; i < this.length; i += 1) {
1370 // If the callback returns false
1371 if (callback.call(this[i], i, this[i]) === false) {
1372 // End the loop early
1376 // Return `this` to allow chained DOM operations
1379 function forEach(callback) {
1380 // Don't bother continuing without a callback
1381 if (!callback) { return this; }
1382 // Iterate over the current collection
1383 for (var i = 0; i < this.length; i += 1) {
1384 // If the callback returns false
1385 if (callback.call(this[i], this[i], i) === false) {
1386 // End the loop early
1390 // Return `this` to allow chained DOM operations
1393 function filter(callback) {
1394 var matchedItems = [];
1396 for (var i = 0; i < dom.length; i += 1) {
1397 if (callback.call(dom[i], i, dom[i])) { matchedItems.push(dom[i]); }
1399 return new Dom7(matchedItems);
1401 function map(callback) {
1402 var modifiedItems = [];
1404 for (var i = 0; i < dom.length; i += 1) {
1405 modifiedItems.push(callback.call(dom[i], i, dom[i]));
1407 return new Dom7(modifiedItems);
1409 // eslint-disable-next-line
1410 function html(html) {
1411 if (typeof html === 'undefined') {
1412 return this[0] ? this[0].innerHTML : undefined;
1415 for (var i = 0; i < this.length; i += 1) {
1416 this[i].innerHTML = html;
1420 // eslint-disable-next-line
1421 function text(text) {
1422 if (typeof text === 'undefined') {
1424 return this[0].textContent.trim();
1429 for (var i = 0; i < this.length; i += 1) {
1430 this[i].textContent = text;
1434 function is(selector) {
1438 if (!el || typeof selector === 'undefined') { return false; }
1439 if (typeof selector === 'string') {
1440 if (el.matches) { return el.matches(selector); }
1441 else if (el.webkitMatchesSelector) { return el.webkitMatchesSelector(selector); }
1442 else if (el.msMatchesSelector) { return el.msMatchesSelector(selector); }
1444 compareWith = $(selector);
1445 for (i = 0; i < compareWith.length; i += 1) {
1446 if (compareWith[i] === el) { return true; }
1449 } else if (selector === doc) { return el === doc; }
1450 else if (selector === win) { return el === win; }
1452 if (selector.nodeType || selector instanceof Dom7) {
1453 compareWith = selector.nodeType ? [selector] : selector;
1454 for (i = 0; i < compareWith.length; i += 1) {
1455 if (compareWith[i] === el) { return true; }
1461 function indexOf(el) {
1462 for (var i = 0; i < this.length; i += 1) {
1463 if (this[i] === el) { return i; }
1468 var child = this[0];
1472 // eslint-disable-next-line
1473 while ((child = child.previousSibling) !== null) {
1474 if (child.nodeType === 1) { i += 1; }
1480 // eslint-disable-next-line
1481 function eq(index) {
1482 if (typeof index === 'undefined') { return this; }
1483 var length = this.length;
1485 if (index > length - 1) {
1486 return new Dom7([]);
1489 returnIndex = length + index;
1490 if (returnIndex < 0) { return new Dom7([]); }
1491 return new Dom7([this[returnIndex]]);
1493 return new Dom7([this[index]]);
1496 var args = [], len = arguments.length;
1497 while ( len-- ) args[ len ] = arguments[ len ];
1501 for (var k = 0; k < args.length; k += 1) {
1503 for (var i = 0; i < this.length; i += 1) {
1504 if (typeof newChild === 'string') {
1505 var tempDiv = doc.createElement('div');
1506 tempDiv.innerHTML = newChild;
1507 while (tempDiv.firstChild) {
1508 this[i].appendChild(tempDiv.firstChild);
1510 } else if (newChild instanceof Dom7) {
1511 for (var j = 0; j < newChild.length; j += 1) {
1512 this[i].appendChild(newChild[j]);
1515 this[i].appendChild(newChild);
1522 // eslint-disable-next-line
1523 function appendTo(parent) {
1524 $(parent).append(this);
1527 function prepend(newChild) {
1530 for (i = 0; i < this.length; i += 1) {
1531 if (typeof newChild === 'string') {
1532 var tempDiv = doc.createElement('div');
1533 tempDiv.innerHTML = newChild;
1534 for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {
1535 this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
1537 } else if (newChild instanceof Dom7) {
1538 for (j = 0; j < newChild.length; j += 1) {
1539 this[i].insertBefore(newChild[j], this[i].childNodes[0]);
1542 this[i].insertBefore(newChild, this[i].childNodes[0]);
1547 // eslint-disable-next-line
1548 function prependTo(parent) {
1549 $(parent).prepend(this);
1552 function insertBefore(selector) {
1553 var before = $(selector);
1554 for (var i = 0; i < this.length; i += 1) {
1555 if (before.length === 1) {
1556 before[0].parentNode.insertBefore(this[i], before[0]);
1557 } else if (before.length > 1) {
1558 for (var j = 0; j < before.length; j += 1) {
1559 before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
1564 function insertAfter(selector) {
1565 var after = $(selector);
1566 for (var i = 0; i < this.length; i += 1) {
1567 if (after.length === 1) {
1568 after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
1569 } else if (after.length > 1) {
1570 for (var j = 0; j < after.length; j += 1) {
1571 after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
1576 function next(selector) {
1577 if (this.length > 0) {
1579 if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {
1580 return new Dom7([this[0].nextElementSibling]);
1582 return new Dom7([]);
1585 if (this[0].nextElementSibling) { return new Dom7([this[0].nextElementSibling]); }
1586 return new Dom7([]);
1588 return new Dom7([]);
1590 function nextAll(selector) {
1593 if (!el) { return new Dom7([]); }
1594 while (el.nextElementSibling) {
1595 var next = el.nextElementSibling; // eslint-disable-line
1597 if ($(next).is(selector)) { nextEls.push(next); }
1598 } else { nextEls.push(next); }
1601 return new Dom7(nextEls);
1603 function prev(selector) {
1604 if (this.length > 0) {
1607 if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {
1608 return new Dom7([el.previousElementSibling]);
1610 return new Dom7([]);
1613 if (el.previousElementSibling) { return new Dom7([el.previousElementSibling]); }
1614 return new Dom7([]);
1616 return new Dom7([]);
1618 function prevAll(selector) {
1621 if (!el) { return new Dom7([]); }
1622 while (el.previousElementSibling) {
1623 var prev = el.previousElementSibling; // eslint-disable-line
1625 if ($(prev).is(selector)) { prevEls.push(prev); }
1626 } else { prevEls.push(prev); }
1629 return new Dom7(prevEls);
1631 function siblings(selector) {
1632 return this.nextAll(selector).add(this.prevAll(selector));
1634 function parent(selector) {
1635 var parents = []; // eslint-disable-line
1636 for (var i = 0; i < this.length; i += 1) {
1637 if (this[i].parentNode !== null) {
1639 if ($(this[i].parentNode).is(selector)) { parents.push(this[i].parentNode); }
1641 parents.push(this[i].parentNode);
1645 return $(unique(parents));
1647 function parents(selector) {
1648 var parents = []; // eslint-disable-line
1649 for (var i = 0; i < this.length; i += 1) {
1650 var parent = this[i].parentNode; // eslint-disable-line
1653 if ($(parent).is(selector)) { parents.push(parent); }
1655 parents.push(parent);
1657 parent = parent.parentNode;
1660 return $(unique(parents));
1662 function closest(selector) {
1663 var closest = this; // eslint-disable-line
1664 if (typeof selector === 'undefined') {
1665 return new Dom7([]);
1667 if (!closest.is(selector)) {
1668 closest = closest.parents(selector).eq(0);
1672 function find(selector) {
1673 var foundElements = [];
1674 for (var i = 0; i < this.length; i += 1) {
1675 var found = this[i].querySelectorAll(selector);
1676 for (var j = 0; j < found.length; j += 1) {
1677 foundElements.push(found[j]);
1680 return new Dom7(foundElements);
1682 function children(selector) {
1683 var children = []; // eslint-disable-line
1684 for (var i = 0; i < this.length; i += 1) {
1685 var childNodes = this[i].childNodes;
1687 for (var j = 0; j < childNodes.length; j += 1) {
1689 if (childNodes[j].nodeType === 1) { children.push(childNodes[j]); }
1690 } else if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) {
1691 children.push(childNodes[j]);
1695 return new Dom7(unique(children));
1698 for (var i = 0; i < this.length; i += 1) {
1699 if (this[i].parentNode) { this[i].parentNode.removeChild(this[i]); }
1704 return this.remove();
1707 var args = [], len = arguments.length;
1708 while ( len-- ) args[ len ] = arguments[ len ];
1713 for (i = 0; i < args.length; i += 1) {
1714 var toAdd = $(args[i]);
1715 for (j = 0; j < toAdd.length; j += 1) {
1716 dom[dom.length] = toAdd[j];
1723 for (var i = 0; i < this.length; i += 1) {
1725 if (el.nodeType === 1) {
1726 for (var j = 0; j < el.childNodes.length; j += 1) {
1727 if (el.childNodes[j].parentNode) {
1728 el.childNodes[j].parentNode.removeChild(el.childNodes[j]);
1731 el.textContent = '';
1737 var Methods = /*#__PURE__*/Object.freeze({
1739 removeClass: removeClass,
1741 toggleClass: toggleClass,
1743 removeAttr: removeAttr,
1746 removeData: removeData,
1749 transform: transform,
1750 transition: transition,
1755 transitionEnd: transitionEnd,
1756 animationEnd: animationEnd,
1758 outerWidth: outerWidth,
1760 outerHeight: outerHeight,
1780 prependTo: prependTo,
1781 insertBefore: insertBefore,
1782 insertAfter: insertAfter,
1799 function scrollTo() {
1802 var args = [], len = arguments.length;
1803 while ( len-- ) args[ len ] = arguments[ len ];
1806 var duration = args[2];
1807 var easing = args[3];
1808 var callback = args[4];
1809 if (args.length === 4 && typeof easing === 'function') {
1811 (assign = args, left = assign[0], top = assign[1], duration = assign[2], callback = assign[3], easing = assign[4]);
1813 if (typeof easing === 'undefined') { easing = 'swing'; }
1815 return this.each(function animate() {
1823 var scrollTop; // eslint-disable-line
1824 var scrollLeft; // eslint-disable-line
1825 var animateTop = top > 0 || top === 0;
1826 var animateLeft = left > 0 || left === 0;
1827 if (typeof easing === 'undefined') {
1831 currentTop = el.scrollTop;
1837 currentLeft = el.scrollLeft;
1839 el.scrollLeft = left;
1842 if (!duration) { return; }
1844 maxTop = el.scrollHeight - el.offsetHeight;
1845 newTop = Math.max(Math.min(top, maxTop), 0);
1848 maxLeft = el.scrollWidth - el.offsetWidth;
1849 newLeft = Math.max(Math.min(left, maxLeft), 0);
1851 var startTime = null;
1852 if (animateTop && newTop === currentTop) { animateTop = false; }
1853 if (animateLeft && newLeft === currentLeft) { animateLeft = false; }
1854 function render(time) {
1855 if ( time === void 0 ) time = new Date().getTime();
1857 if (startTime === null) {
1860 var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
1861 var easeProgress = easing === 'linear' ? progress : (0.5 - (Math.cos(progress * Math.PI) / 2));
1863 if (animateTop) { scrollTop = currentTop + (easeProgress * (newTop - currentTop)); }
1864 if (animateLeft) { scrollLeft = currentLeft + (easeProgress * (newLeft - currentLeft)); }
1865 if (animateTop && newTop > currentTop && scrollTop >= newTop) {
1866 el.scrollTop = newTop;
1869 if (animateTop && newTop < currentTop && scrollTop <= newTop) {
1870 el.scrollTop = newTop;
1873 if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {
1874 el.scrollLeft = newLeft;
1877 if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {
1878 el.scrollLeft = newLeft;
1883 if (callback) { callback(); }
1886 if (animateTop) { el.scrollTop = scrollTop; }
1887 if (animateLeft) { el.scrollLeft = scrollLeft; }
1888 requestAnimationFrame(render);
1890 requestAnimationFrame(render);
1893 // scrollTop(top, duration, easing, callback) {
1894 function scrollTop() {
1897 var args = [], len = arguments.length;
1898 while ( len-- ) args[ len ] = arguments[ len ];
1900 var duration = args[1];
1901 var easing = args[2];
1902 var callback = args[3];
1903 if (args.length === 3 && typeof easing === 'function') {
1904 (assign = args, top = assign[0], duration = assign[1], callback = assign[2], easing = assign[3]);
1907 if (typeof top === 'undefined') {
1908 if (dom.length > 0) { return dom[0].scrollTop; }
1911 return dom.scrollTo(undefined, top, duration, easing, callback);
1913 function scrollLeft() {
1916 var args = [], len = arguments.length;
1917 while ( len-- ) args[ len ] = arguments[ len ];
1919 var duration = args[1];
1920 var easing = args[2];
1921 var callback = args[3];
1922 if (args.length === 3 && typeof easing === 'function') {
1923 (assign = args, left = assign[0], duration = assign[1], callback = assign[2], easing = assign[3]);
1926 if (typeof left === 'undefined') {
1927 if (dom.length > 0) { return dom[0].scrollLeft; }
1930 return dom.scrollTo(left, undefined, duration, easing, callback);
1933 var Scroll = /*#__PURE__*/Object.freeze({
1935 scrollTop: scrollTop,
1936 scrollLeft: scrollLeft
1939 function animate(initialProps, initialParams) {
1942 props: Object.assign({}, initialProps),
1943 params: Object.assign({
1945 easing: 'swing', // or 'linear'
1949 progress(elements, complete, remaining, start, tweenValue)
1957 easingProgress: function easingProgress(easing, progress) {
1958 if (easing === 'swing') {
1959 return 0.5 - (Math.cos(progress * Math.PI) / 2);
1961 if (typeof easing === 'function') {
1962 return easing(progress);
1966 stop: function stop() {
1968 cancelAnimationFrame(a.frameId);
1970 a.animating = false;
1971 a.elements.each(function (index, el) {
1973 delete element.dom7AnimateInstance;
1977 done: function done(complete) {
1978 a.animating = false;
1979 a.elements.each(function (index, el) {
1981 delete element.dom7AnimateInstance;
1983 if (complete) { complete(els); }
1984 if (a.que.length > 0) {
1985 var que = a.que.shift();
1986 a.animate(que[0], que[1]);
1989 animate: function animate(props, params) {
1991 a.que.push([props, params]);
1996 // Define & Cache Initials & Units
1997 a.elements.each(function (index, el) {
1998 var initialFullValue;
2004 if (!el.dom7AnimateInstance) { a.elements[index].dom7AnimateInstance = a; }
2009 Object.keys(props).forEach(function (prop) {
2010 initialFullValue = win.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');
2011 initialValue = parseFloat(initialFullValue);
2012 unit = initialFullValue.replace(initialValue, '');
2013 finalValue = parseFloat(props[prop]);
2014 finalFullValue = props[prop] + unit;
2015 elements[index][prop] = {
2016 initialFullValue: initialFullValue,
2017 initialValue: initialValue,
2019 finalValue: finalValue,
2020 finalFullValue: finalFullValue,
2021 currentValue: initialValue,
2026 var startTime = null;
2028 var elementsDone = 0;
2036 time = new Date().getTime();
2042 if (params.begin) { params.begin(els); }
2044 if (startTime === null) {
2047 if (params.progress) {
2048 // eslint-disable-next-line
2049 params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), ((startTime + params.duration) - time < 0 ? 0 : (startTime + params.duration) - time), startTime);
2052 elements.forEach(function (element) {
2054 if (done || el.done) { return; }
2055 Object.keys(props).forEach(function (prop) {
2056 if (done || el.done) { return; }
2057 progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);
2058 easeProgress = a.easingProgress(params.easing, progress);
2060 var initialValue = ref.initialValue;
2061 var finalValue = ref.finalValue;
2062 var unit = ref.unit;
2063 el[prop].currentValue = initialValue + (easeProgress * (finalValue - initialValue));
2064 var currentValue = el[prop].currentValue;
2067 (finalValue > initialValue && currentValue >= finalValue) ||
2068 (finalValue < initialValue && currentValue <= finalValue)) {
2069 el.container.style[prop] = finalValue + unit;
2071 if (propsDone === Object.keys(props).length) {
2075 if (elementsDone === elements.length) {
2080 a.done(params.complete);
2083 el.container.style[prop] = currentValue + unit;
2086 if (done) { return; }
2088 a.frameId = requestAnimationFrame(render);
2090 a.frameId = requestAnimationFrame(render);
2095 if (a.elements.length === 0) {
2099 var animateInstance;
2100 for (var i = 0; i < a.elements.length; i += 1) {
2101 if (a.elements[i].dom7AnimateInstance) {
2102 animateInstance = a.elements[i].dom7AnimateInstance;
2103 } else { a.elements[i].dom7AnimateInstance = a; }
2105 if (!animateInstance) {
2106 animateInstance = a;
2109 if (initialProps === 'stop') {
2110 animateInstance.stop();
2112 animateInstance.animate(a.props, a.params);
2120 for (var i = 0; i < els.length; i += 1) {
2121 if (els[i].dom7AnimateInstance) {
2122 els[i].dom7AnimateInstance.stop();
2127 var Animate = /*#__PURE__*/Object.freeze({
2132 var noTrigger = ('resize scroll').split(' ');
2133 function eventShortcut(name) {
2136 var args = [], len = arguments.length - 1;
2137 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
2138 if (typeof args[0] === 'undefined') {
2139 for (var i = 0; i < this.length; i += 1) {
2140 if (noTrigger.indexOf(name) < 0) {
2141 if (name in this[i]) { this[i][name](); }
2143 $(this[i]).trigger(name);
2149 return (ref = this).on.apply(ref, [ name ].concat( args ));
2153 var args = [], len = arguments.length;
2154 while ( len-- ) args[ len ] = arguments[ len ];
2156 return eventShortcut.bind(this).apply(void 0, [ 'click' ].concat( args ));
2159 var args = [], len = arguments.length;
2160 while ( len-- ) args[ len ] = arguments[ len ];
2162 return eventShortcut.bind(this).apply(void 0, [ 'blur' ].concat( args ));
2165 var args = [], len = arguments.length;
2166 while ( len-- ) args[ len ] = arguments[ len ];
2168 return eventShortcut.bind(this).apply(void 0, [ 'focus' ].concat( args ));
2170 function focusin() {
2171 var args = [], len = arguments.length;
2172 while ( len-- ) args[ len ] = arguments[ len ];
2174 return eventShortcut.bind(this).apply(void 0, [ 'focusin' ].concat( args ));
2176 function focusout() {
2177 var args = [], len = arguments.length;
2178 while ( len-- ) args[ len ] = arguments[ len ];
2180 return eventShortcut.bind(this).apply(void 0, [ 'focusout' ].concat( args ));
2183 var args = [], len = arguments.length;
2184 while ( len-- ) args[ len ] = arguments[ len ];
2186 return eventShortcut.bind(this).apply(void 0, [ 'keyup' ].concat( args ));
2188 function keydown() {
2189 var args = [], len = arguments.length;
2190 while ( len-- ) args[ len ] = arguments[ len ];
2192 return eventShortcut.bind(this).apply(void 0, [ 'keydown' ].concat( args ));
2194 function keypress() {
2195 var args = [], len = arguments.length;
2196 while ( len-- ) args[ len ] = arguments[ len ];
2198 return eventShortcut.bind(this).apply(void 0, [ 'keypress' ].concat( args ));
2201 var args = [], len = arguments.length;
2202 while ( len-- ) args[ len ] = arguments[ len ];
2204 return eventShortcut.bind(this).apply(void 0, [ 'submit' ].concat( args ));
2207 var args = [], len = arguments.length;
2208 while ( len-- ) args[ len ] = arguments[ len ];
2210 return eventShortcut.bind(this).apply(void 0, [ 'change' ].concat( args ));
2212 function mousedown() {
2213 var args = [], len = arguments.length;
2214 while ( len-- ) args[ len ] = arguments[ len ];
2216 return eventShortcut.bind(this).apply(void 0, [ 'mousedown' ].concat( args ));
2218 function mousemove() {
2219 var args = [], len = arguments.length;
2220 while ( len-- ) args[ len ] = arguments[ len ];
2222 return eventShortcut.bind(this).apply(void 0, [ 'mousemove' ].concat( args ));
2224 function mouseup() {
2225 var args = [], len = arguments.length;
2226 while ( len-- ) args[ len ] = arguments[ len ];
2228 return eventShortcut.bind(this).apply(void 0, [ 'mouseup' ].concat( args ));
2230 function mouseenter() {
2231 var args = [], len = arguments.length;
2232 while ( len-- ) args[ len ] = arguments[ len ];
2234 return eventShortcut.bind(this).apply(void 0, [ 'mouseenter' ].concat( args ));
2236 function mouseleave() {
2237 var args = [], len = arguments.length;
2238 while ( len-- ) args[ len ] = arguments[ len ];
2240 return eventShortcut.bind(this).apply(void 0, [ 'mouseleave' ].concat( args ));
2242 function mouseout() {
2243 var args = [], len = arguments.length;
2244 while ( len-- ) args[ len ] = arguments[ len ];
2246 return eventShortcut.bind(this).apply(void 0, [ 'mouseout' ].concat( args ));
2248 function mouseover() {
2249 var args = [], len = arguments.length;
2250 while ( len-- ) args[ len ] = arguments[ len ];
2252 return eventShortcut.bind(this).apply(void 0, [ 'mouseover' ].concat( args ));
2254 function touchstart() {
2255 var args = [], len = arguments.length;
2256 while ( len-- ) args[ len ] = arguments[ len ];
2258 return eventShortcut.bind(this).apply(void 0, [ 'touchstart' ].concat( args ));
2260 function touchend() {
2261 var args = [], len = arguments.length;
2262 while ( len-- ) args[ len ] = arguments[ len ];
2264 return eventShortcut.bind(this).apply(void 0, [ 'touchend' ].concat( args ));
2266 function touchmove() {
2267 var args = [], len = arguments.length;
2268 while ( len-- ) args[ len ] = arguments[ len ];
2270 return eventShortcut.bind(this).apply(void 0, [ 'touchmove' ].concat( args ));
2273 var args = [], len = arguments.length;
2274 while ( len-- ) args[ len ] = arguments[ len ];
2276 return eventShortcut.bind(this).apply(void 0, [ 'resize' ].concat( args ));
2279 var args = [], len = arguments.length;
2280 while ( len-- ) args[ len ] = arguments[ len ];
2282 return eventShortcut.bind(this).apply(void 0, [ 'scroll' ].concat( args ));
2285 var eventShortcuts = /*#__PURE__*/Object.freeze({
2296 mousedown: mousedown,
2297 mousemove: mousemove,
2299 mouseenter: mouseenter,
2300 mouseleave: mouseleave,
2302 mouseover: mouseover,
2303 touchstart: touchstart,
2305 touchmove: touchmove,
2310 [Methods, Scroll, Animate, eventShortcuts].forEach(function (group) {
2311 Object.keys(group).forEach(function (methodName) {
2312 $.fn[methodName] = group[methodName];
2317 * https://github.com/gre/bezier-easing
2318 * BezierEasing - use bezier curve for transition easing function
2319 * by Gaëtan Renaudeau 2014 - 2015 – MIT License
2322 /* eslint-disable */
2324 // These values are established by empiricism with tests (tradeoff: performance VS precision)
2325 var NEWTON_ITERATIONS = 4;
2326 var NEWTON_MIN_SLOPE = 0.001;
2327 var SUBDIVISION_PRECISION = 0.0000001;
2328 var SUBDIVISION_MAX_ITERATIONS = 10;
2330 var kSplineTableSize = 11;
2331 var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
2333 var float32ArraySupported = typeof Float32Array === 'function';
2335 function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
2336 function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
2337 function C (aA1) { return 3.0 * aA1; }
2339 // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
2340 function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
2342 // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
2343 function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
2345 function binarySubdivide (aX, aA, aB, mX1, mX2) {
2346 var currentX, currentT, i = 0;
2348 currentT = aA + (aB - aA) / 2.0;
2349 currentX = calcBezier(currentT, mX1, mX2) - aX;
2350 if (currentX > 0.0) {
2355 } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
2359 function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
2360 for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
2361 var currentSlope = getSlope(aGuessT, mX1, mX2);
2362 if (currentSlope === 0.0) {
2365 var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
2366 aGuessT -= currentX / currentSlope;
2371 function bezier (mX1, mY1, mX2, mY2) {
2372 if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
2373 throw new Error('bezier x values must be in [0, 1] range');
2376 // Precompute samples table
2377 var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
2378 if (mX1 !== mY1 || mX2 !== mY2) {
2379 for (var i = 0; i < kSplineTableSize; ++i) {
2380 sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
2384 function getTForX (aX) {
2385 var intervalStart = 0.0;
2386 var currentSample = 1;
2387 var lastSample = kSplineTableSize - 1;
2389 for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
2390 intervalStart += kSampleStepSize;
2394 // Interpolate to provide an initial guess for t
2395 var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
2396 var guessForT = intervalStart + dist * kSampleStepSize;
2398 var initialSlope = getSlope(guessForT, mX1, mX2);
2399 if (initialSlope >= NEWTON_MIN_SLOPE) {
2400 return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
2401 } else if (initialSlope === 0.0) {
2404 return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
2408 return function BezierEasing (x) {
2409 if (mX1 === mY1 && mX2 === mY2) {
2412 // Because JavaScript number are imprecise, we should guarantee the extremes are right.
2419 return calcBezier(getTForX(x), mY1, mY2);
2423 /* eslint no-control-regex: "off
" */
2425 // Remove Diacritics
2426 var defaultDiacriticsRemovalap = [
2427 { 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' },
2428 { base: 'AA', letters: '\uA732' },
2429 { base: 'AE', letters: '\u00C6\u01FC\u01E2' },
2430 { base: 'AO', letters: '\uA734' },
2431 { base: 'AU', letters: '\uA736' },
2432 { base: 'AV', letters: '\uA738\uA73A' },
2433 { base: 'AY', letters: '\uA73C' },
2434 { base: 'B', letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181' },
2435 { base: 'C', letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E' },
2436 { base: 'D', letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779' },
2437 { base: 'DZ', letters: '\u01F1\u01C4' },
2438 { base: 'Dz', letters: '\u01F2\u01C5' },
2439 { 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' },
2440 { base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
2441 { base: 'G', letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E' },
2442 { base: 'H', letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D' },
2443 { base: 'I', letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197' },
2444 { base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
2445 { base: 'K', letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2' },
2446 { base: 'L', letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780' },
2447 { base: 'LJ', letters: '\u01C7' },
2448 { base: 'Lj', letters: '\u01C8' },
2449 { base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
2450 { base: 'N', letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4' },
2451 { base: 'NJ', letters: '\u01CA' },
2452 { base: 'Nj', letters: '\u01CB' },
2453 { 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' },
2454 { base: 'OI', letters: '\u01A2' },
2455 { base: 'OO', letters: '\uA74E' },
2456 { base: 'OU', letters: '\u0222' },
2457 { base: 'OE', letters: '\u008C\u0152' },
2458 { base: 'oe', letters: '\u009C\u0153' },
2459 { base: 'P', letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754' },
2460 { base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
2461 { base: 'R', letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782' },
2462 { base: 'S', letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784' },
2463 { base: 'T', letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786' },
2464 { base: 'TZ', letters: '\uA728' },
2465 { 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' },
2466 { base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
2467 { base: 'VY', letters: '\uA760' },
2468 { base: 'W', letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72' },
2469 { base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
2470 { base: 'Y', letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE' },
2471 { base: 'Z', letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762' },
2472 { 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' },
2473 { base: 'aa', letters: '\uA733' },
2474 { base: 'ae', letters: '\u00E6\u01FD\u01E3' },
2475 { base: 'ao', letters: '\uA735' },
2476 { base: 'au', letters: '\uA737' },
2477 { base: 'av', letters: '\uA739\uA73B' },
2478 { base: 'ay', letters: '\uA73D' },
2479 { base: 'b', letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253' },
2480 { base: 'c', letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184' },
2481 { base: 'd', letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A' },
2482 { base: 'dz', letters: '\u01F3\u01C6' },
2483 { 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' },
2484 { base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
2485 { base: 'g', letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F' },
2486 { base: 'h', letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265' },
2487 { base: 'hv', letters: '\u0195' },
2488 { base: 'i', letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131' },
2489 { base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
2490 { base: 'k', letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3' },
2491 { base: 'l', letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747' },
2492 { base: 'lj', letters: '\u01C9' },
2493 { base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
2494 { base: 'n', letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5' },
2495 { base: 'nj', letters: '\u01CC' },
2496 { 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' },
2497 { base: 'oi', letters: '\u01A3' },
2498 { base: 'ou', letters: '\u0223' },
2499 { base: 'oo', letters: '\uA74F' },
2500 { base: 'p', letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755' },
2501 { base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
2502 { base: 'r', letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783' },
2503 { base: 's', letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B' },
2504 { base: 't', letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787' },
2505 { base: 'tz', letters: '\uA729' },
2506 { 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' },
2507 { base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
2508 { base: 'vy', letters: '\uA761' },
2509 { base: 'w', letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73' },
2510 { base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
2511 { base: 'y', letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF' },
2512 { base: 'z', letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' } ];
2514 var diacriticsMap = {};
2515 for (var i = 0; i < defaultDiacriticsRemovalap.length; i += 1) {
2516 var letters = defaultDiacriticsRemovalap[i].letters;
2517 for (var j = 0; j < letters.length; j += 1) {
2518 diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base;
2522 var createPromise = function createPromise(handler) {
2523 var resolved = false;
2524 var rejected = false;
2527 var promiseHandlers = {
2532 then: function then(thenHandler) {
2534 thenHandler.apply(void 0, resolveArgs);
2536 promiseHandlers.then = thenHandler;
2540 catch: function catch$1(catchHandler) {
2542 catchHandler.apply(void 0, rejectArgs);
2544 promiseHandlers.catch = catchHandler;
2550 function resolve() {
2551 var args = [], len = arguments.length;
2552 while ( len-- ) args[ len ] = arguments[ len ];
2555 if (promiseHandlers.then) { promiseHandlers.then.apply(promiseHandlers, args); }
2556 else { resolveArgs = args; }
2559 var args = [], len = arguments.length;
2560 while ( len-- ) args[ len ] = arguments[ len ];
2563 if (promiseHandlers.catch) { promiseHandlers.catch.apply(promiseHandlers, args); }
2564 else { rejectArgs = args; }
2566 handler(resolve, reject);
2571 var uniqueNumber = 1;
2574 uniqueNumber: function uniqueNumber$1() {
2576 return uniqueNumber;
2578 id: function id(mask, map) {
2579 if ( mask === void 0 ) mask = 'xxxxxxxxxx';
2580 if ( map === void 0 ) map = '0123456789abcdef';
2582 var length = map.length;
2583 return mask.replace(/x/g, function () { return map[Math.floor((Math.random() * length))]; });
2585 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(),
2586 eventNameToColonCase: function eventNameToColonCase(eventName) {
2588 return eventName.split('').map(function (char, index) {
2589 if (char.match(/[A-Z]/) && index !== 0 && !hasColon) {
2591 return (":" + (char.toLowerCase()));
2593 return char.toLowerCase();
2596 deleteProps: function deleteProps(obj) {
2598 Object.keys(object).forEach(function (key) {
2602 // no setter for object
2607 // something got wrong
2611 bezier: function bezier$1() {
2612 var args = [], len = arguments.length;
2613 while ( len-- ) args[ len ] = arguments[ len ];
2615 return bezier.apply(void 0, args);
2617 nextTick: function nextTick(callback, delay) {
2618 if ( delay === void 0 ) delay = 0;
2620 return setTimeout(callback, delay);
2622 nextFrame: function nextFrame(callback) {
2623 return Utils.requestAnimationFrame(function () {
2624 Utils.requestAnimationFrame(callback);
2627 now: function now() {
2630 promise: function promise(handler) {
2631 return win.Promise ? new Promise(handler) : createPromise(handler);
2633 requestAnimationFrame: function requestAnimationFrame(callback) {
2634 if (win.requestAnimationFrame) { return win.requestAnimationFrame(callback); }
2635 if (win.webkitRequestAnimationFrame) { return win.webkitRequestAnimationFrame(callback); }
2636 return win.setTimeout(callback, 1000 / 60);
2638 cancelAnimationFrame: function cancelAnimationFrame(id) {
2639 if (win.cancelAnimationFrame) { return win.cancelAnimationFrame(id); }
2640 if (win.webkitCancelAnimationFrame) { return win.webkitCancelAnimationFrame(id); }
2641 return win.clearTimeout(id);
2643 removeDiacritics: function removeDiacritics(str) {
2644 return str.replace(/[^\u0000-\u007E]/g, function (a) { return diacriticsMap[a] || a; });
2646 parseUrlQuery: function parseUrlQuery(url) {
2648 var urlToParse = url || win.location.href;
2653 if (typeof urlToParse === 'string' && urlToParse.length) {
2654 urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\S*\?/, '') : '';
2655 params = urlToParse.split('&').filter(function (paramsPart) { return paramsPart !== ''; });
2656 length = params.length;
2658 for (i = 0; i < length; i += 1) {
2659 param = params[i].replace(/#\S+/g, '').split('=');
2660 query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param.slice(1).join('=')) || '';
2665 getTranslate: function getTranslate(el, axis) {
2666 if ( axis === void 0 ) axis = 'x';
2670 var transformMatrix;
2672 var curStyle = win.getComputedStyle(el, null);
2674 if (win.WebKitCSSMatrix) {
2675 curTransform = curStyle.transform || curStyle.webkitTransform;
2676 if (curTransform.split(',').length > 6) {
2677 curTransform = curTransform.split(', ').map(function (a) { return a.replace(',', '.'); }).join(', ');
2679 // Some old versions of Webkit choke when 'none' is passed; pass
2680 // empty string instead in this case
2681 transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
2683 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
2684 matrix = transformMatrix.toString().split(',');
2688 // Latest Chrome and webkits Fix
2689 if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m41; }
2690 // Crazy IE10 Matrix
2691 else if (matrix.length === 16) { curTransform = parseFloat(matrix[12]); }
2693 else { curTransform = parseFloat(matrix[4]); }
2696 // Latest Chrome and webkits Fix
2697 if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m42; }
2698 // Crazy IE10 Matrix
2699 else if (matrix.length === 16) { curTransform = parseFloat(matrix[13]); }
2701 else { curTransform = parseFloat(matrix[5]); }
2703 return curTransform || 0;
2705 serializeObject: function serializeObject(obj, parents) {
2706 if ( parents === void 0 ) parents = [];
2708 if (typeof obj === 'string') { return obj; }
2709 var resultArray = [];
2710 var separator = '&';
2712 function varName(name) {
2713 if (parents.length > 0) {
2714 var parentParts = '';
2715 for (var j = 0; j < parents.length; j += 1) {
2716 if (j === 0) { parentParts += parents[j]; }
2717 else { parentParts += "[" + (encodeURIComponent(parents[j])) + "]"; }
2719 return (parentParts + "[" + (encodeURIComponent(name)) + "]");
2721 return encodeURIComponent(name);
2723 function varValue(value) {
2724 return encodeURIComponent(value);
2726 Object.keys(obj).forEach(function (prop) {
2728 if (Array.isArray(obj[prop])) {
2730 for (var i = 0; i < obj[prop].length; i += 1) {
2731 if (!Array.isArray(obj[prop][i]) && typeof obj[prop][i] === 'object') {
2732 newParents = parents.slice();
2733 newParents.push(prop);
2734 newParents.push(String(i));
2735 toPush.push(Utils.serializeObject(obj[prop][i], newParents));
2737 toPush.push(((varName(prop)) + "[]=" + (varValue(obj[prop][i]))));
2740 if (toPush.length > 0) { resultArray.push(toPush.join(separator)); }
2741 } else if (obj[prop] === null || obj[prop] === '') {
2742 resultArray.push(((varName(prop)) + "="));
2743 } else if (typeof obj[prop] === 'object') {
2744 // Object, convert to named array
2745 newParents = parents.slice();
2746 newParents.push(prop);
2747 toPush = Utils.serializeObject(obj[prop], newParents);
2748 if (toPush !== '') { resultArray.push(toPush); }
2749 } else if (typeof obj[prop] !== 'undefined' && obj[prop] !== '') {
2750 // Should be string or plain value
2751 resultArray.push(((varName(prop)) + "=" + (varValue(obj[prop]))));
2752 } else if (obj[prop] === '') { resultArray.push(varName(prop)); }
2754 return resultArray.join(separator);
2756 isObject: function isObject(o) {
2757 return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object;
2759 merge: function merge() {
2760 var args = [], len$1 = arguments.length;
2761 while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];
2767 for (var i = 0; i < from.length; i += 1) {
2768 var nextSource = args[i];
2769 if (nextSource !== undefined && nextSource !== null) {
2770 var keysArray = Object.keys(Object(nextSource));
2771 for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
2772 var nextKey = keysArray[nextIndex];
2773 var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
2774 if (desc !== undefined && desc.enumerable) {
2775 to[nextKey] = nextSource[nextKey];
2782 extend: function extend() {
2783 var args = [], len$1 = arguments.length;
2784 while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];
2789 if (typeof args[0] === 'boolean') {
2799 for (var i = 0; i < from.length; i += 1) {
2800 var nextSource = args[i];
2801 if (nextSource !== undefined && nextSource !== null) {
2802 var keysArray = Object.keys(Object(nextSource));
2803 for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
2804 var nextKey = keysArray[nextIndex];
2805 var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
2806 if (desc !== undefined && desc.enumerable) {
2808 to[nextKey] = nextSource[nextKey];
2809 } else if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
2810 Utils.extend(to[nextKey], nextSource[nextKey]);
2811 } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
2813 Utils.extend(to[nextKey], nextSource[nextKey]);
2815 to[nextKey] = nextSource[nextKey];
2825 var Device = (function Device() {
2826 var platform = win.navigator.platform;
2827 var ua = win.navigator.userAgent;
2832 androidChrome: false,
2834 windowsPhone: false,
2844 cordova: !!(win.cordova || win.phonegap),
2845 phonegap: !!(win.cordova || win.phonegap),
2848 var screenWidth = win.screen.width;
2849 var screenHeight = win.screen.height;
2851 var windowsPhone = ua.match(/(Windows Phone);?[\s\/]+([\d.]+)?/); // eslint-disable-line
2852 var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
2853 var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
2854 var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
2855 var iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
2856 var iphoneX = iphone && (
2857 (screenWidth === 375 && screenHeight === 812) // X/XS
2858 || (screenWidth === 414 && screenHeight === 896) // XR / XS Max
2860 var ie = ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;
2861 var edge = ua.indexOf('Edge/') >= 0;
2862 var firefox = ua.indexOf('Gecko/') >= 0 && ua.indexOf('Firefox/') >= 0;
2863 var macos = platform === 'MacIntel';
2864 var windows = platform === 'Win32';
2868 device.firefox = firefox;
2872 device.os = 'windows';
2873 device.osVersion = windowsPhone[2];
2874 device.windowsPhone = true;
2877 if (android && !windows) {
2878 device.os = 'android';
2879 device.osVersion = android[2];
2880 device.android = true;
2881 device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;
2883 if (ipad || iphone || ipod) {
2888 if (iphone && !ipod) {
2889 device.osVersion = iphone[2].replace(/_/g, '.');
2890 device.iphone = true;
2891 device.iphoneX = iphoneX;
2894 device.osVersion = ipad[2].replace(/_/g, '.');
2898 device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
2899 device.iphone = true;
2901 // iOS 8+ changed UA
2902 if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {
2903 if (device.osVersion.split('.')[0] === '10') {
2904 device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];
2909 device.webView = !!((iphone || ipad || ipod) && (ua.match(/.*AppleWebKit(?!.*Safari)/i) || win.navigator.standalone))
2910 || (win.matchMedia && win.matchMedia('(display-mode: standalone)').matches);
2911 device.webview = device.webView;
2912 device.standalone = device.webView;
2916 device.desktop = !(device.os || device.android || device.webView);
2917 if (device.desktop) {
2918 device.macos = macos;
2919 device.windows = windows;
2923 if (device.os && device.os === 'ios') {
2924 var osVersionArr = device.osVersion.split('.');
2925 var metaViewport = doc.querySelector('meta[name="viewport
"]');
2926 device.minimalUi = !device.webView
2928 && (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7)
2929 && metaViewport && metaViewport.getAttribute('content').indexOf('minimal-ui') >= 0;
2932 // Check for status bar and fullscreen app mode
2933 device.needsStatusbarOverlay = function needsStatusbarOverlay() {
2934 if ((device.webView || (device.android && device.cordova)) && (win.innerWidth * win.innerHeight === win.screen.width * win.screen.height)) {
2935 if (device.iphoneX && (win.orientation === 90 || win.orientation === -90)) {
2942 device.statusbar = device.needsStatusbarOverlay();
2945 device.pixelRatio = win.devicePixelRatio || 1;
2951 var Framework7Class = function Framework7Class(params, parents) {
2952 if ( params === void 0 ) params = {};
2953 if ( parents === void 0 ) parents = [];
2956 self.params = params;
2959 self.eventsParents = parents;
2960 self.eventsListeners = {};
2962 if (self.params && self.params.on) {
2963 Object.keys(self.params.on).forEach(function (eventName) {
2964 self.on(eventName, self.params.on[eventName]);
2969 var staticAccessors$1 = { components: { configurable: true } };
2971 Framework7Class.prototype.on = function on (events, handler, priority) {
2973 if (typeof handler !== 'function') { return self; }
2974 var method = priority ? 'unshift' : 'push';
2975 events.split(' ').forEach(function (event) {
2976 if (!self.eventsListeners[event]) { self.eventsListeners[event] = []; }
2977 self.eventsListeners[event][method](handler);
2982 Framework7Class.prototype.once = function once (events, handler, priority) {
2984 if (typeof handler !== 'function') { return self; }
2985 function onceHandler() {
2986 var args = [], len = arguments.length;
2987 while ( len-- ) args[ len ] = arguments[ len ];
2989 handler.apply(self, args);
2990 self.off(events, onceHandler);
2992 return self.on(events, onceHandler, priority);
2995 Framework7Class.prototype.off = function off (events, handler) {
2997 if (!self.eventsListeners) { return self; }
2998 events.split(' ').forEach(function (event) {
2999 if (typeof handler === 'undefined') {
3000 self.eventsListeners[event] = [];
3001 } else if (self.eventsListeners[event]) {
3002 self.eventsListeners[event].forEach(function (eventHandler, index) {
3003 if (eventHandler === handler) {
3004 self.eventsListeners[event].splice(index, 1);
3012 Framework7Class.prototype.emit = function emit () {
3013 var args = [], len = arguments.length;
3014 while ( len-- ) args[ len ] = arguments[ len ];
3017 if (!self.eventsListeners) { return self; }
3022 if (typeof args[0] === 'string' || Array.isArray(args[0])) {
3024 data = args.slice(1, args.length);
3026 eventsParents = self.eventsParents;
3028 events = args[0].events;
3029 data = args[0].data;
3030 context = args[0].context || self;
3031 eventsParents = args[0].local ? [] : args[0].parents || self.eventsParents;
3033 var eventsArray = Array.isArray(events) ? events : events.split(' ');
3034 var localEvents = eventsArray.map(function (eventName) { return eventName.replace('local::', ''); });
3035 var parentEvents = eventsArray.filter(function (eventName) { return eventName.indexOf('local::') < 0; });
3037 localEvents.forEach(function (event) {
3038 if (self.eventsListeners && self.eventsListeners[event]) {
3040 self.eventsListeners[event].forEach(function (eventHandler) {
3041 handlers.push(eventHandler);
3043 handlers.forEach(function (eventHandler) {
3044 eventHandler.apply(context, data);
3048 if (eventsParents && eventsParents.length > 0) {
3049 eventsParents.forEach(function (eventsParent) {
3050 eventsParent.emit.apply(eventsParent, [ parentEvents ].concat( data ));
3056 // eslint-disable-next-line
3057 Framework7Class.prototype.useModuleParams = function useModuleParams (module, instanceParams) {
3058 if (module.params) {
3059 var originalParams = {};
3060 Object.keys(module.params).forEach(function (paramKey) {
3061 if (typeof instanceParams[paramKey] === 'undefined') { return; }
3062 originalParams[paramKey] = Utils.extend({}, instanceParams[paramKey]);
3064 Utils.extend(instanceParams, module.params);
3065 Object.keys(originalParams).forEach(function (paramKey) {
3066 Utils.extend(instanceParams[paramKey], originalParams[paramKey]);
3071 Framework7Class.prototype.useModulesParams = function useModulesParams (instanceParams) {
3072 var instance = this;
3073 if (!instance.modules) { return; }
3074 Object.keys(instance.modules).forEach(function (moduleName) {
3075 var module = instance.modules[moduleName];
3077 if (module.params) {
3078 Utils.extend(instanceParams, module.params);
3083 Framework7Class.prototype.useModule = function useModule (moduleName, moduleParams) {
3084 if ( moduleName === void 0 ) moduleName = '';
3085 if ( moduleParams === void 0 ) moduleParams = {};
3087 var instance = this;
3088 if (!instance.modules) { return; }
3089 var module = typeof moduleName === 'string' ? instance.modules[moduleName] : moduleName;
3090 if (!module) { return; }
3092 // Extend instance methods and props
3093 if (module.instance) {
3094 Object.keys(module.instance).forEach(function (modulePropName) {
3095 var moduleProp = module.instance[modulePropName];
3096 if (typeof moduleProp === 'function') {
3097 instance[modulePropName] = moduleProp.bind(instance);
3099 instance[modulePropName] = moduleProp;
3103 // Add event listeners
3104 if (module.on && instance.on) {
3105 Object.keys(module.on).forEach(function (moduleEventName) {
3106 instance.on(moduleEventName, module.on[moduleEventName]);
3111 if (!instance.vnodeHooks) { instance.vnodeHooks = {}; }
3112 Object.keys(module.vnode).forEach(function (vnodeId) {
3113 Object.keys(module.vnode[vnodeId]).forEach(function (hookName) {
3114 var handler = module.vnode[vnodeId][hookName];
3115 if (!instance.vnodeHooks[hookName]) { instance.vnodeHooks[hookName] = {}; }
3116 if (!instance.vnodeHooks[hookName][vnodeId]) { instance.vnodeHooks[hookName][vnodeId] = []; }
3117 instance.vnodeHooks[hookName][vnodeId].push(handler.bind(instance));
3121 // Module create callback
3122 if (module.create) {
3123 module.create.bind(instance)(moduleParams);
3127 Framework7Class.prototype.useModules = function useModules (modulesParams) {
3128 if ( modulesParams === void 0 ) modulesParams = {};
3130 var instance = this;
3131 if (!instance.modules) { return; }
3132 Object.keys(instance.modules).forEach(function (moduleName) {
3133 var moduleParams = modulesParams[moduleName] || {};
3134 instance.useModule(moduleName, moduleParams);
3138 staticAccessors$1.components.set = function (components) {
3140 if (!Class.use) { return; }
3141 Class.use(components);
3144 Framework7Class.installModule = function installModule (module) {
3145 var params = [], len = arguments.length - 1;
3146 while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];
3149 if (!Class.prototype.modules) { Class.prototype.modules = {}; }
3150 var name = module.name || (((Object.keys(Class.prototype.modules).length) + "_
" + (Utils.now())));
3151 Class.prototype.modules[name] = module;
3154 Object.keys(module.proto).forEach(function (key) {
3155 Class.prototype[key] = module.proto[key];
3159 if (module.static) {
3160 Object.keys(module.static).forEach(function (key) {
3161 Class[key] = module.static[key];
3165 if (module.install) {
3166 module.install.apply(Class, params);
3171 Framework7Class.use = function use (module) {
3172 var params = [], len = arguments.length - 1;
3173 while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];
3176 if (Array.isArray(module)) {
3177 module.forEach(function (m) { return Class.installModule(m); });
3180 return Class.installModule.apply(Class, [ module ].concat( params ));
3183 Object.defineProperties( Framework7Class, staticAccessors$1 );
3185 function ConstructorMethods (parameters) {
3186 if ( parameters === void 0 ) parameters = {};
3188 var defaultSelector = parameters.defaultSelector;
3189 var constructor = parameters.constructor;
3190 var domProp = parameters.domProp;
3191 var app = parameters.app;
3192 var addMethods = parameters.addMethods;
3194 create: function create() {
3195 var args = [], len = arguments.length;
3196 while ( len-- ) args[ len ] = arguments[ len ];
3198 if (app) { return new (Function.prototype.bind.apply( constructor, [ null ].concat( [app], args) )); }
3199 return new (Function.prototype.bind.apply( constructor, [ null ].concat( args) ));
3201 get: function get(el) {
3202 if ( el === void 0 ) el = defaultSelector;
3204 if (el instanceof constructor) { return el; }
3206 if ($el.length === 0) { return undefined; }
3207 return $el[0][domProp];
3209 destroy: function destroy(el) {
3210 var instance = methods.get(el);
3211 if (instance && instance.destroy) { return instance.destroy(); }
3215 if (addMethods && Array.isArray(addMethods)) {
3216 addMethods.forEach(function (methodName) {
3217 methods[methodName] = function (el) {
3218 if ( el === void 0 ) el = defaultSelector;
3219 var args = [], len = arguments.length - 1;
3220 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
3222 var instance = methods.get(el);
3223 if (instance && instance[methodName]) { return instance[methodName].apply(instance, args); }
3231 function ModalMethods (parameters) {
3232 if ( parameters === void 0 ) parameters = {};
3234 var defaultSelector = parameters.defaultSelector;
3235 var constructor = parameters.constructor;
3236 var app = parameters.app;
3237 var methods = Utils.extend(
3238 ConstructorMethods({
3239 defaultSelector: defaultSelector,
3240 constructor: constructor,
3245 open: function open(el, animate) {
3247 var instance = $el[0].f7Modal;
3248 if (!instance) { instance = new constructor(app, { el: $el }); }
3249 return instance.open(animate);
3251 close: function close(el, animate) {
3252 if ( el === void 0 ) el = defaultSelector;
3255 if ($el.length === 0) { return undefined; }
3256 var instance = $el[0].f7Modal;
3257 if (!instance) { instance = new constructor(app, { el: $el }); }
3258 return instance.close(animate);
3265 var fetchedModules = [];
3266 function loadModule(moduleToLoad) {
3267 var Framework7 = this;
3268 return new Promise(function (resolve, reject) {
3269 var app = Framework7.instance;
3273 if (!moduleToLoad) {
3274 reject(new Error('Framework7: Lazy module must be specified'));
3278 function install(module) {
3279 Framework7.use(module);
3282 app.useModuleParams(module, app.params);
3283 app.useModule(module);
3287 if (typeof moduleToLoad === 'string') {
3288 var matchNamePattern = moduleToLoad.match(/([a-z0-9-]*)/i);
3289 if (moduleToLoad.indexOf('.') < 0 && matchNamePattern && matchNamePattern[0].length === moduleToLoad.length) {
3290 if (!app || (app && !app.params.lazyModulesPath)) {
3291 reject(new Error('Framework7: "lazyModulesPath
" app parameter must be specified to fetch module by name'));
3294 modulePath = (app.params.lazyModulesPath) + "/" + moduleToLoad + ".js
";
3296 modulePath = moduleToLoad;
3298 } else if (typeof moduleToLoad === 'function') {
3299 moduleFunc = moduleToLoad;
3301 // considering F7-Plugin object
3302 moduleObj = moduleToLoad;
3306 var module = moduleFunc(Framework7, false);
3308 reject(new Error('Framework7: Can\'t find Framework7 component in specified component function'));
3311 // Check if it was added
3312 if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
3322 var module$1 = moduleObj;
3324 reject(new Error('Framework7: Can\'t find Framework7 component in specified component'));
3327 // Check if it was added
3328 if (Framework7.prototype.modules && Framework7.prototype.modules[module$1.name]) {
3338 if (fetchedModules.indexOf(modulePath) >= 0) {
3342 fetchedModules.push(modulePath);
3343 var scriptLoad = new Promise(function (resolveScript, rejectScript) {
3344 Framework7.request.get(
3346 function (scriptContent) {
3347 var id = Utils.id();
3348 var callbackLoadName = "f7_component_loader_callback_
" + id;
3350 var scriptEl = document.createElement('script');
3351 scriptEl.innerHTML = "window
." + callbackLoadName + " = function (Framework7
, Framework7AutoInstallComponent
) {return " + (scriptContent.trim()) + "}";
3352 $('head').append(scriptEl);
3354 var componentLoader = window[callbackLoadName];
3355 delete window[callbackLoadName];
3356 $(scriptEl).remove();
3358 var module = componentLoader(Framework7, false);
3361 rejectScript(new Error(("Framework7
: Can
't find Framework7 component in " + modulePath + " file")));
3365 // Check if it was added
3366 if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
3376 function (xhr, status) {
3377 rejectScript(xhr, status);
3381 var styleLoad = new Promise(function (resolveStyle) {
3382 Framework7.request.get(
3383 modulePath.replace('.js
', app.rtl ? '.rtl
.css
' : '.css
'),
3384 function (styleContent) {
3385 var styleEl = document.createElement('style
');
3386 styleEl.innerHTML = styleContent;
3387 $('head
').append(styleEl);
3397 Promise.all([scriptLoad, styleLoad]).then(function () {
3399 }).catch(function (err) {
3406 var Framework7 = /*@__PURE__*/(function (Framework7Class$$1) {
3407 function Framework7(params) {
3408 Framework7Class$$1.call(this, params);
3410 var passedParams = Utils.extend({}, params);
3415 Framework7.instance = app;
3420 id: 'io
.framework7
.testapp
',
3423 language: win.navigator.language,
3426 lazyModulesPath: null,
3427 initOnDeviceReady: true,
3431 // Extend defaults with modules params
3432 app.useModulesParams(defaults);
3434 // Extend defaults with passed params
3435 app.params = Utils.extend(defaults, params);
3437 var $rootEl = $(app.params.root);
3443 name: app.params.name,
3445 version: app.params.version,
3447 routes: app.params.routes,
3449 language: app.params.language,
3453 rtl: $rootEl.css('direction
') === 'rtl
',
3455 theme: (function getTheme() {
3456 if (app.params.theme === 'auto
') {
3457 return Device.ios ? 'ios
' : 'md
';
3459 return app.params.theme;
3461 // Initially passed parameters
3462 passedParams: passedParams,
3466 if (app.root && app.root[0]) {
3467 app.root[0].f7 = app;
3473 // Init Data & Methods
3477 if (app.params.init) {
3478 if (Device.cordova && app.params.initOnDeviceReady) {
3479 $(doc).on('deviceready
', function () {
3486 // Return app instance
3490 if ( Framework7Class$$1 ) Framework7.__proto__ = Framework7Class$$1;
3491 Framework7.prototype = Object.create( Framework7Class$$1 && Framework7Class$$1.prototype );
3492 Framework7.prototype.constructor = Framework7;
3494 var prototypeAccessors = { $: { configurable: true },t7: { configurable: true } };
3495 var staticAccessors = { Dom7: { configurable: true },$: { configurable: true },Template7: { configurable: true },Class: { configurable: true } };
3497 Framework7.prototype.initData = function initData () {
3502 if (app.params.data && typeof app.params.data === 'function') {
3503 Utils.extend(app.data, app.params.data.bind(app)());
3504 } else if (app.params.data) {
3505 Utils.extend(app.data, app.params.data);
3509 if (app.params.methods) {
3510 Object.keys(app.params.methods).forEach(function (methodName) {
3511 if (typeof app.params.methods[methodName] === 'function') {
3512 app.methods[methodName] = app.params.methods[methodName].bind(app);
3514 app.methods[methodName] = app.params.methods[methodName];
3520 Framework7.prototype.init = function init () {
3522 if (app.initialized) { return app; }
3524 app.root.addClass('framework7
-initializing
');
3528 $('html
').attr('dir
', 'rtl
');
3532 app.root.addClass('framework7
-root
');
3535 $('html
').removeClass('ios md
').addClass(app.theme);
3538 Utils.nextFrame(function () {
3539 app.root.removeClass('framework7
-initializing
');
3541 // Emit, init other modules
3542 app.initialized = true;
3548 // eslint-disable-next-line
3549 Framework7.prototype.loadModule = function loadModule$$1 () {
3550 var args = [], len = arguments.length;
3551 while ( len-- ) args[ len ] = arguments[ len ];
3553 return Framework7.loadModule.apply(Framework7, args);
3556 // eslint-disable-next-line
3557 Framework7.prototype.loadModules = function loadModules () {
3558 var args = [], len = arguments.length;
3559 while ( len-- ) args[ len ] = arguments[ len ];
3561 return Framework7.loadModules.apply(Framework7, args);
3564 Framework7.prototype.getVnodeHooks = function getVnodeHooks (hook, id) {
3566 if (!app.vnodeHooks || !app.vnodeHooks[hook]) { return []; }
3567 return app.vnodeHooks[hook][id] || [];
3570 // eslint-disable-next-line
3571 prototypeAccessors.$.get = function () {
3574 // eslint-disable-next-line
3575 prototypeAccessors.t7.get = function () {
3579 staticAccessors.Dom7.get = function () {
3583 staticAccessors.$.get = function () {
3587 staticAccessors.Template7.get = function () {
3591 staticAccessors.Class.get = function () {
3592 return Framework7Class$$1;
3595 Object.defineProperties( Framework7.prototype, prototypeAccessors );
3596 Object.defineProperties( Framework7, staticAccessors );
3599 }(Framework7Class));
3601 Framework7.ModalMethods = ModalMethods;
3602 Framework7.ConstructorMethods = ConstructorMethods;
3604 Framework7.loadModule = loadModule;
3605 Framework7.loadModules = function loadModules(modules) {
3606 return Promise.all(modules.map(function (module) { return Framework7.loadModule(module); }));
3609 var DeviceModule = {
3618 init: function init() {
3619 var classNames = [];
3620 var html = doc.querySelector('html
');
3621 if (!html) { return; }
3623 classNames.push(("device-pixel-ratio-" + (Math.floor(Device.pixelRatio))));
3624 if (Device.pixelRatio >= 2) {
3625 classNames.push('device
-retina
');
3630 ("device-" + (Device.os)),
3631 ("device-" + (Device.os) + "-" + (Device.osVersion.split('.')[0])),
3632 ("device-" + (Device.os) + "-" + (Device.osVersion.replace(/\./g, '-')))
3634 if (Device.os === 'ios
') {
3635 var major = parseInt(Device.osVersion.split('.')[0], 10);
3636 for (var i = major - 1; i >= 6; i -= 1) {
3637 classNames.push(("device-ios-gt-" + i));
3639 if (Device.iphoneX) {
3640 classNames.push('device
-iphone
-x
');
3643 } else if (Device.desktop) {
3644 classNames.push('device
-desktop
');
3645 if (Device.macos) { classNames.push('device
-macos
'); }
3646 else if (Device.windows) { classNames.push('device
-windows
'); }
3648 if (Device.cordova || Device.phonegap) {
3649 classNames.push('device
-cordova
');
3653 classNames.forEach(function (className) {
3654 html.classList.add(className);
3660 var Support = (function Support() {
3661 var positionSticky = (function supportPositionSticky() {
3662 var support = false;
3663 var div = doc.createElement('div
');
3664 ('sticky
-webkit
-sticky
-moz
-sticky
').split(' ').forEach(function (prop) {
3665 if (support) { return; }
3666 div.style.position = prop;
3667 if (div.style.position === prop) {
3674 var testDiv = doc.createElement('div
');
3677 positionSticky: positionSticky,
3678 touch: (function checkTouch() {
3679 return !!((win.navigator.maxTouchPoints > 0) || ('ontouchstart
' in win) || (win.DocumentTouch && doc instanceof win.DocumentTouch));
3682 pointerEvents: !!(win.navigator.pointerEnabled || win.PointerEvent || ('maxTouchPoints
' in win.navigator)),
3683 prefixedPointerEvents: !!win.navigator.msPointerEnabled,
3685 transition: (function checkTransition() {
3686 var style = testDiv.style;
3687 return ('transition
' in style || 'webkitTransition
' in style || 'MozTransition
' in style);
3689 transforms3d: (win.Modernizr && win.Modernizr.csstransforms3d === true) || (function checkTransforms3d() {
3690 var style = testDiv.style;
3691 return ('webkitPerspective
' in style || 'MozPerspective
' in style || 'OPerspective
' in style || 'MsPerspective
' in style || 'perspective
' in style);
3694 flexbox: (function checkFlexbox() {
3695 var div = doc.createElement('div
').style;
3696 var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient
').split(' ');
3697 for (var i = 0; i < styles.length; i += 1) {
3698 if (styles[i] in div) { return true; }
3703 observer: (function checkObserver() {
3704 return ('MutationObserver
' in win || 'WebkitMutationObserver
' in win);
3707 passiveListener: (function checkPassiveListener() {
3708 var supportsPassive = false;
3710 var opts = Object.defineProperty({}, 'passive
', {
3711 // eslint-disable-next-line
3712 get: function get() {
3713 supportsPassive = true;
3716 win.addEventListener('testPassiveListener
', null, opts);
3720 return supportsPassive;
3723 gestures: (function checkGestures() {
3724 return 'ongesturestart
' in win;
3729 var SupportModule = {
3738 init: function init() {
3739 var html = doc.querySelector('html
');
3740 if (!html) { return; }
3741 var classNames = [];
3742 if (Support.positionSticky) {
3743 classNames.push('support
-position
-sticky
');
3746 classNames.forEach(function (className) {
3747 html.classList.add(className);
3763 var ResizeModule = {
3766 getSize: function getSize() {
3768 if (!app.root[0]) { return { width: 0, height: 0, left: 0, top: 0 }; }
3769 var offset = app.root.offset();
3770 var ref = [app.root[0].offsetWidth, app.root[0].offsetHeight, offset.left, offset.top];
3772 var height = ref[1];
3776 app.height = height;
3779 return { width: width, height: height, left: left, top: top };
3783 init: function init() {
3790 win.addEventListener('resize
', function () {
3794 // Emit orientationchange
3795 win.addEventListener('orientationchange
', function () {
3796 app.emit('orientationchange
');
3799 orientationchange: function orientationchange() {
3801 if (app.device && app.device.minimalUi) {
3802 if (win.orientation === 90 || win.orientation === -90) {
3803 doc.body.scrollTop = 0;
3806 // Fix iPad weird body scroll
3807 if (app.device.ipad) {
3808 doc.body.scrollLeft = 0;
3809 setTimeout(function () {
3810 doc.body.scrollLeft = 0;
3814 resize: function resize() {
3822 var jsonpRequests = 0;
3824 function Request(requestOptions) {
3825 var globalsNoCallbacks = Utils.extend({}, globals);
3826 ('beforeCreate beforeOpen beforeSend error complete success statusCode
').split(' ').forEach(function (callbackName) {
3827 delete globalsNoCallbacks[callbackName];
3829 var defaults = Utils.extend({
3830 url: win.location.toString(),
3842 contentType: 'application
/x
-www
-form
-urlencoded
',
3844 }, globalsNoCallbacks);
3846 var options = Utils.extend({}, defaults, requestOptions);
3849 // Function to run XHR callbacks and events
3850 function fireCallback(callbackName) {
3851 var data = [], len = arguments.length - 1;
3852 while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ];
3856 beforeCreate (options),
3857 beforeOpen (xhr, options),
3858 beforeSend (xhr, options),
3859 error (xhr, status),
3860 complete (xhr, stautus),
3861 success (response, status, xhr),
3864 var globalCallbackValue;
3865 var optionCallbackValue;
3866 if (globals[callbackName]) {
3867 globalCallbackValue = globals[callbackName].apply(globals, data);
3869 if (options[callbackName]) {
3870 optionCallbackValue = options[callbackName].apply(options, data);
3872 if (typeof globalCallbackValue !== 'boolean') { globalCallbackValue = true; }
3873 if (typeof optionCallbackValue !== 'boolean') { optionCallbackValue = true; }
3874 return (globalCallbackValue && optionCallbackValue);
3877 // Before create callback
3878 proceedRequest = fireCallback('beforeCreate
', options);
3879 if (proceedRequest === false) { return undefined; }
3882 if (options.type) { options.method = options.type; }
3884 // Parameters Prefix
3885 var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';
3888 var method = options.method.toUpperCase();
3890 // Data to modify GET URL
3891 if ((method === 'GET
' || method === 'HEAD
' || method === 'OPTIONS
' || method === 'DELETE
') && options.data) {
3893 if (typeof options.data === 'string
') {
3894 // Should be key=value string
3895 if (options.data.indexOf('?') >= 0) { stringData = options.data.split('?')[1]; }
3896 else { stringData = options.data; }
3898 // Should be key=value object
3899 stringData = Utils.serializeObject(options.data);
3901 if (stringData.length) {
3902 options.url += paramsPrefix + stringData;
3903 if (paramsPrefix === '?') { paramsPrefix = '&'; }
3908 if (options.dataType === 'json
' && options.url.indexOf('callback
=') >= 0) {
3909 var callbackName = "f7jsonp_" + (Date.now() + ((jsonpRequests += 1)));
3911 var callbackSplit = options.url.split('callback
=');
3912 var requestUrl = (callbackSplit[0]) + "callback=" + callbackName;
3913 if (callbackSplit[1].indexOf('&') >= 0) {
3914 var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');
3915 if (addVars.length > 0) { requestUrl += "&" + addVars; }
3919 var script = doc.createElement('script
');
3920 script.type = 'text
/javascript
';
3921 script.onerror = function onerror() {
3922 clearTimeout(abortTimeout);
3923 fireCallback('error
', null, 'scripterror
');
3924 fireCallback('complete
', null, 'scripterror
');
3926 script.src = requestUrl;
3929 win[callbackName] = function jsonpCallback(data) {
3930 clearTimeout(abortTimeout);
3931 fireCallback('success
', data);
3932 script.parentNode.removeChild(script);
3934 delete win[callbackName];
3936 doc.querySelector('head
').appendChild(script);
3938 if (options.timeout > 0) {
3939 abortTimeout = setTimeout(function () {
3940 script.parentNode.removeChild(script);
3942 fireCallback('error
', null, 'timeout
');
3943 }, options.timeout);
3949 // Cache for GET/HEAD requests
3950 if (method === 'GET
' || method === 'HEAD
' || method === 'OPTIONS
' || method === 'DELETE
') {
3951 if (options.cache === false) {
3952 options.url += paramsPrefix + "_nocache" + (Date.now());
3957 var xhr = new XMLHttpRequest();
3960 xhr.requestUrl = options.url;
3961 xhr.requestParameters = options;
3963 // Before open callback
3964 proceedRequest = fireCallback('beforeOpen
', xhr, options);
3965 if (proceedRequest === false) { return xhr; }
3968 xhr.open(method, options.url, options.async, options.user, options.password);
3971 var postData = null;
3973 if ((method === 'POST
' || method === 'PUT
' || method === 'PATCH
') && options.data) {
3974 if (options.processData) {
3975 var postDataInstances = [ArrayBuffer, Blob, Document, FormData];
3977 if (postDataInstances.indexOf(options.data.constructor) >= 0) {
3978 postData = options.data;
3981 var boundary = "---------------------------" + (Date.now().toString(16));
3983 if (options.contentType === 'multipart
/form
-data
') {
3984 xhr.setRequestHeader('Content
-Type
', ("multipart/form-data; boundary=" + boundary));
3986 xhr.setRequestHeader('Content
-Type
', options.contentType);
3989 var data$1 = Utils.serializeObject(options.data);
3990 if (options.contentType === 'multipart
/form
-data
') {
3991 data$1 = data$1.split('&');
3993 for (var i = 0; i < data$1.length; i += 1) {
3994 newData.push(("Content-Disposition: form-data; name=\"" + (data$1[i].split('=')[0]) + "\"\r\n\r\n" + (data$1[i].split('=')[1]) + "\r\n"));
3996 postData = "--" + boundary + "\r\n" + (newData.join(("--" + boundary + "\r\n"))) + "--" + boundary + "--\r\n";
3997 } else if (options.contentType === 'application
/json
') {
3998 postData = JSON.stringify(options.data);
4004 postData = options.data;
4005 xhr.setRequestHeader('Content
-Type
', options.contentType);
4009 // Additional headers
4010 if (options.headers) {
4011 Object.keys(options.headers).forEach(function (headerName) {
4012 xhr.setRequestHeader(headerName, options.headers[headerName]);
4016 // Check for crossDomain
4017 if (typeof options.crossDomain === 'undefined') {
4018 // eslint-disable-next-line
4019 options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== win.location.host;
4022 if (!options.crossDomain) {
4023 xhr.setRequestHeader('X
-Requested
-With
', 'XMLHttpRequest
');
4026 if (options.xhrFields) {
4027 Utils.extend(xhr, options.xhrFields);
4033 xhr.onload = function onload() {
4034 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4035 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
4037 if (options.dataType === 'json
') {
4040 responseData = JSON.parse(xhr.responseText);
4045 fireCallback('success
', responseData, xhr.status, xhr);
4047 fireCallback('error
', xhr, 'parseerror
');
4050 responseData = xhr.responseType === 'text
' || xhr.responseType === '' ? xhr.responseText : xhr.response;
4051 fireCallback('success
', responseData, xhr.status, xhr);
4054 fireCallback('error
', xhr, xhr.status);
4056 if (options.statusCode) {
4057 if (globals.statusCode && globals.statusCode[xhr.status]) { globals.statusCode[xhr.status](xhr); }
4058 if (options.statusCode[xhr.status]) { options.statusCode[xhr.status](xhr); }
4060 fireCallback('complete
', xhr, xhr.status);
4063 xhr.onerror = function onerror() {
4064 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4065 fireCallback('error
', xhr, xhr.status);
4066 fireCallback('complete
', xhr, 'error
');
4070 if (options.timeout > 0) {
4071 xhr.onabort = function onabort() {
4072 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4074 xhrTimeout = setTimeout(function () {
4076 fireCallback('error
', xhr, 'timeout
');
4077 fireCallback('complete
', xhr, 'timeout
');
4078 }, options.timeout);
4081 // Ajax start callback
4082 proceedRequest = fireCallback('beforeSend
', xhr, options);
4083 if (proceedRequest === false) { return xhr; }
4088 // Return XHR object
4091 function RequestShortcut(method) {
4092 var assign, assign$1;
4094 var args = [], len = arguments.length - 1;
4095 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
4099 var success = ref[2];
4101 var dataType = ref[4];
4102 if (typeof args[1] === 'function') {
4103 (assign = args, url = assign[0], success = assign[1], error = assign[2], dataType = assign[3]);
4105 (assign$1 = args, url = assign$1[0], data = assign$1[1], success = assign$1[2], error = assign$1[3], dataType = assign$1[4]);
4107 [success, error].forEach(function (callback) {
4108 if (typeof callback === 'string
') {
4109 dataType = callback;
4110 if (callback === success) { success = undefined; }
4111 else { error = undefined; }
4114 dataType = dataType || (method === 'json
' || method === 'postJSON
' ? 'json
' : undefined);
4115 var requestOptions = {
4117 method: method === 'post
' || method === 'postJSON
' ? 'POST
' : 'GET
',
4123 if (method === 'postJSON
') {
4124 Utils.extend(requestOptions, {
4125 contentType: 'application
/json
',
4128 data: typeof data === 'string
' ? data : JSON.stringify(data),
4131 return Request(requestOptions);
4133 Request.get = function get() {
4134 var args = [], len = arguments.length;
4135 while ( len-- ) args[ len ] = arguments[ len ];
4137 return RequestShortcut.apply(void 0, [ 'get' ].concat( args ));
4139 Request.post = function post() {
4140 var args = [], len = arguments.length;
4141 while ( len-- ) args[ len ] = arguments[ len ];
4143 return RequestShortcut.apply(void 0, [ 'post
' ].concat( args ));
4145 Request.json = function json() {
4146 var args = [], len = arguments.length;
4147 while ( len-- ) args[ len ] = arguments[ len ];
4149 return RequestShortcut.apply(void 0, [ 'json
' ].concat( args ));
4151 Request.getJSON = Request.json;
4152 Request.postJSON = function postJSON() {
4153 var args = [], len = arguments.length;
4154 while ( len-- ) args[ len ] = arguments[ len ];
4156 return RequestShortcut.apply(void 0, [ 'postJSON
' ].concat( args ));
4158 Request.setup = function setup(options) {
4159 if (options.type && !options.method) {
4160 Utils.extend(options, { method: options.type });
4162 Utils.extend(globals, options);
4165 /* eslint no-param-reassign: "off" */
4167 var RequestModule = {
4177 function initTouch() {
4179 var params = app.params.touch;
4180 var useRipple = app.theme === 'md
' && params.materialRipple;
4182 if (Device.ios && Device.webView) {
4183 // Strange hack required for iOS 8 webview to work on inputs
4184 win.addEventListener('touchstart
', function () {});
4192 var activeSelection;
4199 var activableElement;
4203 var needsFastClickTimeOut;
4209 function findActivableElement(el) {
4211 var parents = target.parents(params.activeStateElements);
4213 if (target.is(params.activeStateElements)) {
4216 if (parents.length > 0) {
4217 activable = activable ? activable.add(parents) : parents;
4219 return activable || target;
4222 function isInsideScrollableView(el) {
4223 var pageContent = el.parents('.page
-content
, .panel
');
4225 if (pageContent.length === 0) {
4229 // This event handler covers the "tap to stop scrolling".
4230 if (pageContent.prop('scrollHandlerSet
') !== 'yes
') {
4231 pageContent.on('scroll
', function () {
4232 clearTimeout(activeTimeout);
4233 clearTimeout(rippleTimeout);
4235 pageContent.prop('scrollHandlerSet
', 'yes
');
4240 function addActive() {
4241 if (!activableElement) { return; }
4242 activableElement.addClass('active
-state
');
4244 function removeActive() {
4245 if (!activableElement) { return; }
4246 activableElement.removeClass('active
-state
');
4247 activableElement = null;
4249 function isFormElement(el) {
4250 var nodes = ('input select textarea label
').split(' ');
4251 if (el.nodeName && nodes.indexOf(el.nodeName.toLowerCase()) >= 0) { return true; }
4254 function androidNeedsBlur(el) {
4255 var noBlur = ('button input textarea select
').split(' ');
4256 if (doc.activeElement && el !== doc.activeElement && doc.activeElement !== doc.body) {
4257 if (noBlur.indexOf(el.nodeName.toLowerCase()) >= 0) {
4264 function targetNeedsFastClick(el) {
4270 Device.osVersion.split('.')[0] > 9
4272 (Device.osVersion.split('.')[0] * 1 === 9 && Device.osVersion.split('.')[1] >= 1)
4279 if (el.nodeName.toLowerCase() === 'input
' && (el.type === 'file
' || el.type === 'range
')) { return false; }
4280 if (el.nodeName.toLowerCase() === 'select
' && Device.android) { return false; }
4281 if ($el.hasClass('no
-fastclick
') || $el.parents('.no
-fastclick
').length > 0) { return false; }
4282 if (params.fastClicksExclude && $el.closest(params.fastClicksExclude).length > 0) { return false; }
4286 function targetNeedsFocus(el) {
4287 if (doc.activeElement === el) {
4290 var tag = el.nodeName.toLowerCase();
4291 var skipInputs = ('button checkbox file image radio submit
').split(' ');
4292 if (el.disabled || el.readOnly) { return false; }
4293 if (tag === 'textarea
') { return true; }
4294 if (tag === 'select
') {
4295 if (Device.android) { return false; }
4298 if (tag === 'input
' && skipInputs.indexOf(el.type) < 0) { return true; }
4301 function targetNeedsPrevent(el) {
4304 if ($el.is('label
') || $el.parents('label
').length > 0) {
4305 if (Device.android) {
4307 } else if (Device.ios && $el.is('input
')) {
4309 } else { prevent = false; }
4315 function findRippleElement(el) {
4316 var rippleElements = params.materialRippleElements;
4318 if ($el.is(rippleElements)) {
4319 if ($el.hasClass('no
-ripple
')) {
4324 if ($el.parents(rippleElements).length > 0) {
4325 var rippleParent = $el.parents(rippleElements).eq(0);
4326 if (rippleParent.hasClass('no
-ripple
')) {
4329 return rippleParent;
4333 function createRipple($el, x, y) {
4334 if (!$el) { return; }
4335 rippleWave = app.touchRipple.create($el, x, y);
4338 function removeRipple() {
4339 if (!rippleWave) { return; }
4340 rippleWave.remove();
4341 rippleWave = undefined;
4342 rippleTarget = undefined;
4344 function rippleTouchStart(el) {
4345 rippleTarget = findRippleElement(el);
4346 if (!rippleTarget || rippleTarget.length === 0) {
4347 rippleTarget = undefined;
4350 if (!isInsideScrollableView(rippleTarget)) {
4351 createRipple(rippleTarget, touchStartX, touchStartY);
4353 rippleTimeout = setTimeout(function () {
4354 createRipple(rippleTarget, touchStartX, touchStartY);
4358 function rippleTouchMove() {
4359 clearTimeout(rippleTimeout);
4362 function rippleTouchEnd() {
4365 } else if (rippleTarget && !isMoved) {
4366 clearTimeout(rippleTimeout);
4367 createRipple(rippleTarget, touchStartX, touchStartY);
4368 setTimeout(removeRipple, 0);
4375 function handleMouseDown(e) {
4376 findActivableElement(e.target).addClass('active
-state
');
4377 if ('which
' in e && e.which === 3) {
4378 setTimeout(function () {
4379 $('.active
-state
').removeClass('active
-state
');
4383 touchStartX = e.pageX;
4384 touchStartY = e.pageY;
4385 rippleTouchStart(e.target, e.pageX, e.pageY);
4388 function handleMouseMove() {
4389 $('.active
-state
').removeClass('active
-state
');
4394 function handleMouseUp() {
4395 $('.active
-state
').removeClass('active
-state
');
4402 function sendClick(e) {
4403 var touch = e.changedTouches[0];
4404 var evt = doc.createEvent('MouseEvents
');
4405 var eventType = 'click
';
4406 if (Device.android && targetElement.nodeName.toLowerCase() === 'select
') {
4407 eventType = 'mousedown
';
4409 evt.initMouseEvent(eventType, true, true, win, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
4410 evt.forwardedTouchEvent = true;
4412 if (app.device.ios && win.navigator.standalone) {
4413 // Fix the issue happens in iOS home screen apps where the wrong element is selected during a momentum scroll.
4414 // Upon tapping, we give the scrolling time to stop, then we grab the element based where the user tapped.
4415 setTimeout(function () {
4416 targetElement = doc.elementFromPoint(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
4417 targetElement.dispatchEvent(evt);
4420 targetElement.dispatchEvent(evt);
4425 function handleTouchStart(e) {
4429 tapHoldFired = false;
4430 if (e.targetTouches.length > 1) {
4431 if (activableElement) { removeActive(); }
4434 if (e.touches.length > 1 && activableElement) {
4437 if (params.tapHold) {
4438 if (tapHoldTimeout) { clearTimeout(tapHoldTimeout); }
4439 tapHoldTimeout = setTimeout(function () {
4440 if (e && e.touches && e.touches.length > 1) { return; }
4441 tapHoldFired = true;
4443 $(e.target).trigger('taphold
');
4444 }, params.tapHoldDelay);
4446 if (needsFastClickTimeOut) { clearTimeout(needsFastClickTimeOut); }
4447 needsFastClick = targetNeedsFastClick(e.target);
4449 if (!needsFastClick) {
4453 if (Device.ios || (Device.android && 'getSelection
' in win)) {
4454 var selection = win.getSelection();
4456 selection.rangeCount
4457 && selection.focusNode !== doc.body
4458 && (!selection.isCollapsed || doc.activeElement === selection.focusNode)
4460 activeSelection = true;
4464 activeSelection = false;
4466 if (Device.android) {
4467 if (androidNeedsBlur(e.target)) {
4468 doc.activeElement.blur();
4473 targetElement = e.target;
4474 touchStartTime = (new Date()).getTime();
4475 touchStartX = e.targetTouches[0].pageX;
4476 touchStartY = e.targetTouches[0].pageY;
4478 // Detect scroll parent
4480 scrollParent = undefined;
4481 $(targetElement).parents().each(function () {
4482 var parent = this$1;
4483 if (parent.scrollHeight > parent.offsetHeight && !scrollParent) {
4484 scrollParent = parent;
4485 scrollParent.f7ScrollTop = scrollParent.scrollTop;
4489 if ((touchStartTime - lastClickTime) < params.fastClicksDelayBetweenClicks) {
4493 if (params.activeState) {
4494 activableElement = findActivableElement(targetElement);
4495 // If it's inside a scrollable view
, we don
't trigger active-state yet,
4496 // because it can be a scroll instead. Based on the link:
4497 // http://labnote.beedesk.com/click-scroll-and-pseudo-active-on-mobile-webk
4498 if (!isInsideScrollableView(activableElement)) {
4501 activeTimeout = setTimeout(addActive, 80);
4505 rippleTouchStart(targetElement, touchStartX, touchStartY);
4509 function handleTouchMove(e) {
4510 if (!trackClick) { return; }
4511 var distance = params.fastClicksDistanceThreshold;
4513 var pageX = e.targetTouches[0].pageX;
4514 var pageY = e.targetTouches[0].pageY;
4515 if (Math.abs(pageX - touchStartX) > distance || Math.abs(pageY - touchStartY) > distance) {
4523 targetElement = null;
4525 if (params.tapHold) {
4526 clearTimeout(tapHoldTimeout);
4528 if (params.activeState) {
4529 clearTimeout(activeTimeout);
4537 function handleTouchEnd(e) {
4538 clearTimeout(activeTimeout);
4539 clearTimeout(tapHoldTimeout);
4541 var touchEndTime = (new Date()).getTime();
4544 if (!activeSelection && needsFastClick) {
4545 if (!(Device.android && !e.cancelable) && e.cancelable) {
4549 if (params.activeState) { removeActive(); }
4556 if (doc.activeElement === e.target) {
4557 if (params.activeState) { removeActive(); }
4564 if (!activeSelection) {
4568 if ((touchEndTime - lastClickTime) < params.fastClicksDelayBetweenClicks) {
4569 setTimeout(removeActive, 0);
4576 lastClickTime = touchEndTime;
4580 if (Device.ios && scrollParent) {
4581 if (scrollParent.scrollTop !== scrollParent.f7ScrollTop) {
4586 // Add active-state here because, in a very fast tap, the timeout didn't
4587 // have the chance to execute. Removing active-state in a timeout gives
4588 // the chance to the animation execute.
4589 if (params
.activeState
) {
4591 setTimeout(removeActive
, 0);
4598 // Trigger focus when required
4599 if (targetNeedsFocus(targetElement
)) {
4600 if (Device
.ios
&& Device
.webView
) {
4601 targetElement
.focus();
4605 targetElement
.focus();
4608 // Blur active elements
4609 if (doc
.activeElement
&& targetElement
!== doc
.activeElement
&& doc
.activeElement
!== doc
.body
&& targetElement
.nodeName
.toLowerCase() !== 'label') {
4610 doc
.activeElement
.blur();
4615 if (params
.tapHoldPreventClicks
&& tapHoldFired
) {
4621 function handleTouchCancel() {
4623 targetElement
= null;
4625 // Remove Active State
4626 clearTimeout(activeTimeout
);
4627 clearTimeout(tapHoldTimeout
);
4628 if (params
.activeState
) {
4638 function handleClick(e
) {
4639 var allowClick
= false;
4641 targetElement
= null;
4645 if ((e
.target
.type
=== 'submit' && e
.detail
=== 0) || e
.target
.type
=== 'file') {
4648 if (!targetElement
) {
4649 if (!isFormElement(e
.target
)) {
4653 if (!needsFastClick
) {
4656 if (doc
.activeElement
=== targetElement
) {
4659 if (e
.forwardedTouchEvent
) {
4662 if (!e
.cancelable
) {
4665 if (params
.tapHold
&& params
.tapHoldPreventClicks
&& tapHoldFired
) {
4669 e
.stopImmediatePropagation();
4670 e
.stopPropagation();
4671 if (targetElement
) {
4672 if (targetNeedsPrevent(targetElement
) || isMoved
) {
4678 targetElement
= null;
4680 needsFastClickTimeOut
= setTimeout(function () {
4681 needsFastClick
= false;
4682 }, (Device
.ios
|| Device
.androidChrome
? 100 : 400));
4684 if (params
.tapHold
) {
4685 tapHoldTimeout
= setTimeout(function () {
4686 tapHoldFired
= false;
4687 }, (Device
.ios
|| Device
.androidChrome
? 100 : 400));
4693 function emitAppTouchEvent(name
, e
) {
4699 function appClick(e
) {
4700 emitAppTouchEvent('click', e
);
4702 function appTouchStartActive(e
) {
4703 emitAppTouchEvent('touchstart touchstart:active', e
);
4705 function appTouchMoveActive(e
) {
4706 emitAppTouchEvent('touchmove touchmove:active', e
);
4708 function appTouchEndActive(e
) {
4709 emitAppTouchEvent('touchend touchend:active', e
);
4711 function appTouchStartPassive(e
) {
4712 emitAppTouchEvent('touchstart:passive', e
);
4714 function appTouchMovePassive(e
) {
4715 emitAppTouchEvent('touchmove:passive', e
);
4717 function appTouchEndPassive(e
) {
4718 emitAppTouchEvent('touchend:passive', e
);
4721 var passiveListener
= Support
.passiveListener
? { passive
: true } : false;
4722 var activeListener
= Support
.passiveListener
? { passive
: false } : false;
4724 doc
.addEventListener('click', appClick
, true);
4726 if (Support
.passiveListener
) {
4727 doc
.addEventListener(app
.touchEvents
.start
, appTouchStartActive
, activeListener
);
4728 doc
.addEventListener(app
.touchEvents
.move, appTouchMoveActive
, activeListener
);
4729 doc
.addEventListener(app
.touchEvents
.end
, appTouchEndActive
, activeListener
);
4731 doc
.addEventListener(app
.touchEvents
.start
, appTouchStartPassive
, passiveListener
);
4732 doc
.addEventListener(app
.touchEvents
.move, appTouchMovePassive
, passiveListener
);
4733 doc
.addEventListener(app
.touchEvents
.end
, appTouchEndPassive
, passiveListener
);
4735 doc
.addEventListener(app
.touchEvents
.start
, function (e
) {
4736 appTouchStartActive(e
);
4737 appTouchStartPassive(e
);
4739 doc
.addEventListener(app
.touchEvents
.move, function (e
) {
4740 appTouchMoveActive(e
);
4741 appTouchMovePassive(e
);
4743 doc
.addEventListener(app
.touchEvents
.end
, function (e
) {
4744 appTouchEndActive(e
);
4745 appTouchEndPassive(e
);
4749 if (Support
.touch
) {
4750 app
.on('click', handleClick
);
4751 app
.on('touchstart', handleTouchStart
);
4752 app
.on('touchmove', handleTouchMove
);
4753 app
.on('touchend', handleTouchEnd
);
4754 doc
.addEventListener('touchcancel', handleTouchCancel
, { passive
: true });
4755 } else if (params
.activeState
) {
4756 app
.on('touchstart', handleMouseDown
);
4757 app
.on('touchmove', handleMouseMove
);
4758 app
.on('touchend', handleMouseUp
);
4760 doc
.addEventListener('contextmenu', function (e
) {
4761 if (params
.disableContextMenu
&& (Device
.ios
|| Device
.android
|| Device
.cordova
)) {
4765 if (activableElement
) { removeActive(); }
4777 fastClicksDistanceThreshold
: 10,
4778 fastClicksDelayBetweenClicks
: 50,
4779 fastClicksExclude
: '', // CSS selector
4781 disableContextMenu
: true,
4785 tapHoldPreventClicks
: true,
4788 activeStateElements
: 'a, button, label, span, .actions-button, .stepper-button, .stepper-button-plus, .stepper-button-minus',
4789 materialRipple
: true,
4790 materialRippleElements
: '.ripple, .link, .item-link, .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',
4795 start
: Support
.touch
? 'touchstart' : 'mousedown',
4796 move: Support
.touch
? 'touchmove' : 'mousemove',
4797 end
: Support
.touch
? 'touchend' : 'mouseup',
4806 * Expose `pathToRegexp`.
4808 var pathToRegexp_1
= pathToRegexp
;
4809 var parse_1
= parse
;
4810 var compile_1
= compile
;
4811 var tokensToFunction_1
= tokensToFunction
;
4812 var tokensToRegExp_1
= tokensToRegExp
;
4817 var DEFAULT_DELIMITER
= '/';
4820 * The main path matching regexp utility.
4824 var PATH_REGEXP
= new RegExp([
4825 // Match escaped characters that would otherwise appear in future matches.
4826 // This allows the user to escape special characters that won't transform.
4828 // Match Express-style parameters and un-named parameters with a prefix
4829 // and optional suffixes. Matches appear as:
4831 // ":test(\\d+)?" => ["test", "\d+", undefined, "?"]
4832 // "(\\d+)" => [undefined, undefined, "\d+", undefined]
4833 '(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?'
4837 * Parse a string for the raw tokens.
4839 * @param {string} str
4840 * @param {Object=} options
4843 function parse (str
, options
) {
4848 var defaultDelimiter
= (options
&& options
.delimiter
) || DEFAULT_DELIMITER
;
4849 var whitelist
= (options
&& options
.whitelist
) || undefined;
4850 var pathEscaped
= false;
4853 while ((res
= PATH_REGEXP
.exec(str
)) !== null) {
4855 var escaped
= res
[1];
4856 var offset
= res
.index
;
4857 path
+= str
.slice(index
, offset
);
4858 index
= offset
+ m
.length
;
4860 // Ignore already escaped sequences.
4869 var capture
= res
[3];
4871 var modifier
= res
[5];
4873 if (!pathEscaped
&& path
.length
) {
4874 var k
= path
.length
- 1;
4876 var matches
= whitelist
? whitelist
.indexOf(c
) > -1 : true;
4880 path
= path
.slice(0, k
);
4884 // Push the current path onto the tokens.
4888 pathEscaped
= false;
4891 var repeat
= modifier
=== '+' || modifier
=== '*';
4892 var optional
= modifier
=== '?' || modifier
=== '*';
4893 var pattern
= capture
|| group
;
4894 var delimiter
= prev
|| defaultDelimiter
;
4897 name
: name
|| key
++,
4899 delimiter
: delimiter
,
4903 ? escapeGroup(pattern
)
4904 : '[^' + escapeString(delimiter
=== defaultDelimiter
? delimiter
: (delimiter
+ defaultDelimiter
)) + ']+?'
4908 // Push any remaining characters.
4909 if (path
|| index
< str
.length
) {
4910 tokens
.push(path
+ str
.substr(index
));
4917 * Compile a string to a template function for the path.
4919 * @param {string} str
4920 * @param {Object=} options
4921 * @return {!function(Object=, Object=)}
4923 function compile (str
, options
) {
4924 return tokensToFunction(parse(str
, options
))
4928 * Expose a method for transforming tokens into the path function.
4930 function tokensToFunction (tokens
) {
4931 // Compile all the tokens into regexps.
4932 var matches
= new Array(tokens
.length
);
4934 // Compile all the patterns before compilation.
4935 for (var i
= 0; i
< tokens
.length
; i
++) {
4936 if (typeof tokens
[i
] === 'object') {
4937 matches
[i
] = new RegExp('^(?:' + tokens
[i
].pattern
+ ')$');
4941 return function (data
, options
) {
4943 var encode
= (options
&& options
.encode
) || encodeURIComponent
;
4945 for (var i
= 0; i
< tokens
.length
; i
++) {
4946 var token
= tokens
[i
];
4948 if (typeof token
=== 'string') {
4953 var value
= data
? data
[token
.name
] : undefined;
4956 if (Array
.isArray(value
)) {
4957 if (!token
.repeat
) {
4958 throw new TypeError('Expected "' + token
.name
+ '" to not repeat, but got array')
4961 if (value
.length
=== 0) {
4962 if (token
.optional
) { continue }
4964 throw new TypeError('Expected "' + token
.name
+ '" to not be empty')
4967 for (var j
= 0; j
< value
.length
; j
++) {
4968 segment
= encode(value
[j
], token
);
4970 if (!matches
[i
].test(segment
)) {
4971 throw new TypeError('Expected all "' + token
.name
+ '" to match "' + token
.pattern
+ '"')
4974 path
+= (j
=== 0 ? token
.prefix
: token
.delimiter
) + segment
;
4980 if (typeof value
=== 'string' || typeof value
=== 'number' || typeof value
=== 'boolean') {
4981 segment
= encode(String(value
), token
);
4983 if (!matches
[i
].test(segment
)) {
4984 throw new TypeError('Expected "' + token
.name
+ '" to match "' + token
.pattern
+ '", but got "' + segment
+ '"')
4987 path
+= token
.prefix
+ segment
;
4991 if (token
.optional
) { continue }
4993 throw new TypeError('Expected "' + token
.name
+ '" to be ' + (token
.repeat
? 'an array' : 'a string'))
5001 * Escape a regular expression string.
5003 * @param {string} str
5006 function escapeString (str
) {
5007 return str
.replace(/([.+*?=^!:${}()[\]|/\\])/g
, '\\$1')
5011 * Escape the capturing group by escaping special characters and meaning.
5013 * @param {string} group
5016 function escapeGroup (group
) {
5017 return group
.replace(/([=!:$/()])/g
, '\\$1')
5021 * Get the flags for a regexp from the options.
5023 * @param {Object} options
5026 function flags (options
) {
5027 return options
&& options
.sensitive
? '' : 'i'
5031 * Pull out keys from a regexp.
5033 * @param {!RegExp} path
5034 * @param {Array=} keys
5037 function regexpToRegexp (path
, keys
) {
5038 if (!keys
) { return path
}
5040 // Use a negative lookahead to match only capturing groups.
5041 var groups
= path
.source
.match(/\((?!\?)/g);
5044 for (var i
= 0; i
< groups
.length
; i
++) {
5060 * Transform an array into a regexp.
5062 * @param {!Array} path
5063 * @param {Array=} keys
5064 * @param {Object=} options
5067 function arrayToRegexp (path
, keys
, options
) {
5070 for (var i
= 0; i
< path
.length
; i
++) {
5071 parts
.push(pathToRegexp(path
[i
], keys
, options
).source
);
5074 return new RegExp('(?:' + parts
.join('|') + ')', flags(options
))
5078 * Create a path regexp from string input.
5080 * @param {string} path
5081 * @param {Array=} keys
5082 * @param {Object=} options
5085 function stringToRegexp (path
, keys
, options
) {
5086 return tokensToRegExp(parse(path
, options
), keys
, options
)
5090 * Expose a function for taking tokens and returning a RegExp.
5092 * @param {!Array} tokens
5093 * @param {Array=} keys
5094 * @param {Object=} options
5097 function tokensToRegExp (tokens
, keys
, options
) {
5098 options
= options
|| {};
5100 var strict
= options
.strict
;
5101 var start
= options
.start
!== false;
5102 var end
= options
.end
!== false;
5103 var delimiter
= options
.delimiter
|| DEFAULT_DELIMITER
;
5104 var endsWith
= [].concat(options
.endsWith
|| []).map(escapeString
).concat('$').join('|');
5105 var route
= start
? '^' : '';
5107 // Iterate over the tokens and create our regexp string.
5108 for (var i
= 0; i
< tokens
.length
; i
++) {
5109 var token
= tokens
[i
];
5111 if (typeof token
=== 'string') {
5112 route
+= escapeString(token
);
5114 var capture
= token
.repeat
5115 ? '(?:' + token
.pattern
+ ')(?:' + escapeString(token
.delimiter
) + '(?:' + token
.pattern
+ '))*'
5118 if (keys
) { keys
.push(token
); }
5120 if (token
.optional
) {
5121 if (!token
.prefix
) {
5122 route
+= '(' + capture
+ ')?';
5124 route
+= '(?:' + escapeString(token
.prefix
) + '(' + capture
+ '))?';
5127 route
+= escapeString(token
.prefix
) + '(' + capture
+ ')';
5133 if (!strict
) { route
+= '(?:' + escapeString(delimiter
) + ')?'; }
5135 route
+= endsWith
=== '$' ? '$' : '(?=' + endsWith
+ ')';
5137 var endToken
= tokens
[tokens
.length
- 1];
5138 var isEndDelimited
= typeof endToken
=== 'string'
5139 ? endToken
[endToken
.length
- 1] === delimiter
5140 : endToken
=== undefined;
5142 if (!strict
) { route
+= '(?:' + escapeString(delimiter
) + '(?=' + endsWith
+ '))?'; }
5143 if (!isEndDelimited
) { route
+= '(?=' + escapeString(delimiter
) + '|' + endsWith
+ ')'; }
5146 return new RegExp(route
, flags(options
))
5150 * Normalize the given path string, returning a regular expression.
5152 * An empty array can be passed in for the keys, which will hold the
5153 * placeholder key descriptions. For example, using `/user/:id`, `keys` will
5154 * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
5156 * @param {(string|RegExp|Array)} path
5157 * @param {Array=} keys
5158 * @param {Object=} options
5161 function pathToRegexp (path
, keys
, options
) {
5162 if (path
instanceof RegExp
) {
5163 return regexpToRegexp(path
, keys
)
5166 if (Array
.isArray(path
)) {
5167 return arrayToRegexp(/** @type {!Array} */ (path
), keys
, options
)
5170 return stringToRegexp(/** @type {string} */ (path
), keys
, options
)
5172 pathToRegexp_1
.parse
= parse_1
;
5173 pathToRegexp_1
.compile
= compile_1
;
5174 pathToRegexp_1
.tokensToFunction
= tokensToFunction_1
;
5175 pathToRegexp_1
.tokensToRegExp
= tokensToRegExp_1
;
5179 clearQueue
: function clearQueue() {
5180 if (History
.queue
.length
=== 0) { return; }
5181 var currentQueue
= History
.queue
.shift();
5185 clearRouterQueue
: function clearRouterQueue() {
5186 if (History
.routerQueue
.length
=== 0) { return; }
5187 var currentQueue
= History
.routerQueue
.pop();
5188 var router
= currentQueue
.router
;
5189 var stateUrl
= currentQueue
.stateUrl
;
5190 var action
= currentQueue
.action
;
5192 var animate
= router
.params
.animate
;
5193 if (router
.params
.pushStateAnimate
=== false) { animate
= false; }
5195 if (action
=== 'back') {
5196 router
.back({ animate
: animate
, pushState
: false });
5198 if (action
=== 'load') {
5199 router
.navigate(stateUrl
, { animate
: animate
, pushState
: false });
5202 handle
: function handle(e
) {
5203 if (History
.blockPopstate
) { return; }
5205 // const mainView = app.views.main;
5206 var state
= e
.state
;
5207 History
.previousState
= History
.state
;
5208 History
.state
= state
;
5210 History
.allowChange
= true;
5211 History
.clearQueue();
5213 state
= History
.state
;
5214 if (!state
) { state
= {}; }
5216 app
.views
.forEach(function (view
) {
5217 var router
= view
.router
;
5218 var viewState
= state
[view
.id
];
5219 if (!viewState
&& view
.params
.pushState
) {
5221 url
: view
.router
.history
[0],
5224 if (!viewState
) { return; }
5225 var stateUrl
= viewState
.url
|| undefined;
5227 var animate
= router
.params
.animate
;
5228 if (router
.params
.pushStateAnimate
=== false) { animate
= false; }
5230 if (stateUrl
!== router
.url
) {
5231 if (router
.history
.indexOf(stateUrl
) >= 0) {
5233 if (router
.allowPageChange
) {
5234 router
.back({ animate
: animate
, pushState
: false });
5236 History
.routerQueue
.push({
5241 } else if (router
.allowPageChange
) {
5243 router
.navigate(stateUrl
, { animate
: animate
, pushState
: false });
5245 History
.routerQueue
.unshift({
5254 initViewState
: function initViewState(viewId
, viewState
) {
5257 var newState
= Utils
.extend({}, (History
.state
|| {}), ( obj
= {}, obj
[viewId
] = viewState
, obj
));
5258 History
.state
= newState
;
5259 win
.history
.replaceState(newState
, '');
5261 push
: function push(viewId
, viewState
, url
) {
5264 if (!History
.allowChange
) {
5265 History
.queue
.push(function () {
5266 History
.push(viewId
, viewState
, url
);
5270 History
.previousState
= History
.state
;
5271 var newState
= Utils
.extend({}, (History
.previousState
|| {}), ( obj
= {}, obj
[viewId
] = viewState
, obj
));
5272 History
.state
= newState
;
5273 win
.history
.pushState(newState
, '', url
);
5275 replace
: function replace(viewId
, viewState
, url
) {
5278 if (!History
.allowChange
) {
5279 History
.queue
.push(function () {
5280 History
.replace(viewId
, viewState
, url
);
5284 History
.previousState
= History
.state
;
5285 var newState
= Utils
.extend({}, (History
.previousState
|| {}), ( obj
= {}, obj
[viewId
] = viewState
, obj
));
5286 History
.state
= newState
;
5287 win
.history
.replaceState(newState
, '', url
);
5289 go
: function go(index
) {
5290 History
.allowChange
= false;
5291 win
.history
.go(index
);
5293 back
: function back() {
5294 History
.allowChange
= false;
5299 state
: win
.history
.state
,
5300 blockPopstate
: true,
5301 init
: function init(app
) {
5302 $(win
).on('load', function () {
5303 setTimeout(function () {
5304 History
.blockPopstate
= false;
5308 if (doc
.readyState
&& doc
.readyState
=== 'complete') {
5309 History
.blockPopstate
= false;
5312 $(win
).on('popstate', History
.handle
.bind(app
));
5316 function SwipeBack(r
) {
5318 var $el
= router
.$el
;
5319 var $navbarEl
= router
.$navbarEl
;
5320 var app
= router
.app
;
5321 var params
= router
.params
;
5322 var isTouched
= false;
5323 var isMoved
= false;
5324 var touchesStart
= {};
5326 var currentPage
= [];
5327 var previousPage
= [];
5328 var viewContainerWidth
;
5330 var allowViewTouchMove
= true;
5332 var currentNavbar
= [];
5333 var previousNavbar
= [];
5334 var currentNavElements
;
5335 var previousNavElements
;
5336 var activeNavBackIcon
;
5337 var activeNavBackIconText
;
5338 var previousNavBackIcon
;
5339 // let previousNavBackIconText;
5346 var paramsSwipeBackAnimateShadow
= params
[((app
.theme
) + "SwipeBackAnimateShadow")];
5347 var paramsSwipeBackAnimateOpacity
= params
[((app
.theme
) + "SwipeBackAnimateOpacity")];
5348 var paramsSwipeBackActiveArea
= params
[((app
.theme
) + "SwipeBackActiveArea")];
5349 var paramsSwipeBackThreshold
= params
[((app
.theme
) + "SwipeBackThreshold")];
5351 function handleTouchStart(e
) {
5352 var swipeBackEnabled
= params
[((app
.theme
) + "SwipeBack")];
5353 if (!allowViewTouchMove
|| !swipeBackEnabled
|| isTouched
|| (app
.swipeout
&& app
.swipeout
.el
) || !router
.allowPageChange
) { return; }
5354 if ($(e
.target
).closest('.range-slider, .calendar-months').length
> 0) { return; }
5357 isScrolling
= undefined;
5358 touchesStart
.x
= e
.type
=== 'touchstart' ? e
.targetTouches
[0].pageX
: e
.pageX
;
5359 touchesStart
.y
= e
.type
=== 'touchstart' ? e
.targetTouches
[0].pageY
: e
.pageY
;
5360 touchStartTime
= Utils
.now();
5361 dynamicNavbar
= router
.dynamicNavbar
;
5362 separateNavbar
= router
.separateNavbar
;
5364 function handleTouchMove(e
) {
5365 if (!isTouched
) { return; }
5366 var pageX
= e
.type
=== 'touchmove' ? e
.targetTouches
[0].pageX
: e
.pageX
;
5367 var pageY
= e
.type
=== 'touchmove' ? e
.targetTouches
[0].pageY
: e
.pageY
;
5368 if (typeof isScrolling
=== 'undefined') {
5369 isScrolling
= !!(isScrolling
|| Math
.abs(pageY
- touchesStart
.y
) > Math
.abs(pageX
- touchesStart
.x
)) || (pageX
< touchesStart
.x
&& !app
.rtl
) || (pageX
> touchesStart
.x
&& app
.rtl
);
5371 if (isScrolling
|| e
.f7PreventSwipeBack
|| app
.preventSwipeBack
) {
5376 // Calc values during first move fired
5378 var target
= $(e
.target
);
5380 var swipeout
= target
.closest('.swipeout');
5381 if (swipeout
.length
> 0) {
5382 if (!app
.rtl
&& swipeout
.find('.swipeout-actions-left').length
> 0) { cancel
= true; }
5383 if (app
.rtl
&& swipeout
.find('.swipeout-actions-right').length
> 0) { cancel
= true; }
5386 currentPage
= target
.closest('.page');
5387 if (currentPage
.hasClass('no-swipeback') || target
.closest('.no-swipeback').length
> 0) { cancel
= true; }
5388 previousPage
= $el
.find('.page-previous:not(.stacked)');
5390 var notFromBorder
= touchesStart
.x
- $el
.offset().left
> paramsSwipeBackActiveArea
;
5391 viewContainerWidth
= $el
.width();
5393 notFromBorder
= touchesStart
.x
< ($el
.offset().left
- $el
[0].scrollLeft
) + (viewContainerWidth
- paramsSwipeBackActiveArea
);
5395 notFromBorder
= touchesStart
.x
- $el
.offset().left
> paramsSwipeBackActiveArea
;
5397 if (notFromBorder
) { cancel
= true; }
5398 if (previousPage
.length
=== 0 || currentPage
.length
=== 0) { cancel
= true; }
5404 if (paramsSwipeBackAnimateShadow
) {
5405 pageShadow
= currentPage
.find('.page-shadow-effect');
5406 if (pageShadow
.length
=== 0) {
5407 pageShadow
= $('<div class="page-shadow-effect"></div>');
5408 currentPage
.append(pageShadow
);
5411 if (paramsSwipeBackAnimateOpacity
) {
5412 pageOpacity
= previousPage
.find('.page-opacity-effect');
5413 if (pageOpacity
.length
=== 0) {
5414 pageOpacity
= $('<div class="page-opacity-effect"></div>');
5415 previousPage
.append(pageOpacity
);
5419 if (dynamicNavbar
) {
5420 if (separateNavbar
) {
5421 currentNavbar
= $navbarEl
.find('.navbar-current:not(.stacked)');
5422 previousNavbar
= $navbarEl
.find('.navbar-previous:not(.stacked)');
5424 currentNavbar
= currentPage
.children('.navbar').children('.navbar-inner');
5425 previousNavbar
= previousPage
.children('.navbar').children('.navbar-inner');
5427 navbarWidth
= $navbarEl
[0].offsetWidth
;
5428 currentNavElements
= currentNavbar
.children('.left, .title, .right, .subnavbar, .fading');
5429 previousNavElements
= previousNavbar
.children('.left, .title, .right, .subnavbar, .fading');
5430 if (params
.iosAnimateNavbarBackIcon
) {
5431 if (currentNavbar
.hasClass('sliding')) {
5432 activeNavBackIcon
= currentNavbar
.children('.left').find('.back .icon');
5433 activeNavBackIconText
= currentNavbar
.children('.left').find('.back span').eq(0);
5435 activeNavBackIcon
= currentNavbar
.children('.left.sliding').find('.back .icon');
5436 activeNavBackIconText
= currentNavbar
.children('.left.sliding').find('.back span').eq(0);
5438 if (previousNavbar
.hasClass('sliding')) {
5439 previousNavBackIcon
= previousNavbar
.children('.left').find('.back .icon');
5441 previousNavBackIcon
= previousNavbar
.children('.left.sliding').find('.back .icon');
5446 // Close/Hide Any Picker
5447 if ($('.sheet.modal-in').length
> 0 && app
.sheet
) {
5448 app
.sheet
.close($('.sheet.modal-in'));
5451 e
.f7PreventPanelSwipe
= true;
5453 app
.preventSwipePanelBySwipeBack
= true;
5457 var inverter
= app
.rtl
? -1 : 1;
5460 touchesDiff
= (pageX
- touchesStart
.x
- paramsSwipeBackThreshold
) * inverter
;
5461 if (touchesDiff
< 0) { touchesDiff
= 0; }
5462 var percentage
= touchesDiff
/ viewContainerWidth
;
5464 // Swipe Back Callback
5465 var callbackData
= {
5466 percentage
: percentage
,
5467 currentPageEl
: currentPage
[0],
5468 previousPageEl
: previousPage
[0],
5469 currentNavbarEl
: currentNavbar
[0],
5470 previousNavbarEl
: previousNavbar
[0],
5472 $el
.trigger('swipeback:move', callbackData
);
5473 router
.emit('swipebackMove', callbackData
);
5476 var currentPageTranslate
= touchesDiff
* inverter
;
5477 var previousPageTranslate
= ((touchesDiff
/ 5) - (viewContainerWidth
/ 5)) * inverter
;
5478 if (Device
.pixelRatio
=== 1) {
5479 currentPageTranslate
= Math
.round(currentPageTranslate
);
5480 previousPageTranslate
= Math
.round(previousPageTranslate
);
5483 router
.swipeBackActive
= true;
5484 $([currentPage
[0], previousPage
[0]]).addClass('page-swipeback-active');
5486 currentPage
.transform(("translate3d(" + currentPageTranslate
+ "px,0,0)"));
5487 if (paramsSwipeBackAnimateShadow
) { pageShadow
[0].style
.opacity
= 1 - (1 * percentage
); }
5489 if (app
.theme
!== 'md') {
5490 previousPage
.transform(("translate3d(" + previousPageTranslate
+ "px,0,0)"));
5492 if (paramsSwipeBackAnimateOpacity
) { pageOpacity
[0].style
.opacity
= 1 - (1 * percentage
); }
5494 // Dynamic Navbars Animation
5495 if (dynamicNavbar
) {
5496 currentNavElements
.each(function (index
, navEl
) {
5497 var $navEl
= $(navEl
);
5498 if (!$navEl
.is('.subnavbar')) { $navEl
[0].style
.opacity
= (1 - (Math
.pow( percentage
, 0.33 ))); }
5499 if ($navEl
[0].className
.indexOf('sliding') >= 0 || currentNavbar
.hasClass('sliding')) {
5500 var activeNavTranslate
= percentage
* $navEl
[0].f7NavbarRightOffset
;
5501 if (Device
.pixelRatio
=== 1) { activeNavTranslate
= Math
.round(activeNavTranslate
); }
5502 $navEl
.transform(("translate3d(" + activeNavTranslate
+ "px,0,0)"));
5503 if (params
.iosAnimateNavbarBackIcon
) {
5504 if ($navEl
[0].className
.indexOf('left') >= 0 && activeNavBackIcon
.length
> 0) {
5505 var iconTranslate
= -activeNavTranslate
;
5506 if (!separateNavbar
) {
5507 iconTranslate
-= navbarWidth
* percentage
;
5509 activeNavBackIcon
.transform(("translate3d(" + iconTranslate
+ "px,0,0)"));
5514 previousNavElements
.each(function (index
, navEl
) {
5515 var $navEl
= $(navEl
);
5516 if (!$navEl
.is('.subnavbar')) { $navEl
[0].style
.opacity
= (Math
.pow( percentage
, 3 )); }
5517 if ($navEl
[0].className
.indexOf('sliding') >= 0 || previousNavbar
.hasClass('sliding')) {
5518 var previousNavTranslate
= $navEl
[0].f7NavbarLeftOffset
* (1 - percentage
);
5519 if ($navEl
[0].className
.indexOf('title') >= 0 && activeNavBackIcon
&& activeNavBackIcon
.length
&& activeNavBackIconText
.length
) {
5520 previousNavTranslate
= ($navEl
[0].f7NavbarLeftOffset
+ activeNavBackIconText
[0].offsetLeft
) * (1 - percentage
);
5522 previousNavTranslate
= $navEl
[0].f7NavbarLeftOffset
* (1 - percentage
);
5524 if (Device
.pixelRatio
=== 1) { previousNavTranslate
= Math
.round(previousNavTranslate
); }
5525 $navEl
.transform(("translate3d(" + previousNavTranslate
+ "px,0,0)"));
5526 if (params
.iosAnimateNavbarBackIcon
) {
5527 if ($navEl
[0].className
.indexOf('left') >= 0 && previousNavBackIcon
.length
> 0) {
5528 var iconTranslate
= -previousNavTranslate
;
5529 if (!separateNavbar
) {
5530 iconTranslate
+= (navbarWidth
/ 5) * (1 - percentage
);
5532 previousNavBackIcon
.transform(("translate3d(" + iconTranslate
+ "px,0,0)"));
5539 function handleTouchEnd() {
5540 app
.preventSwipePanelBySwipeBack
= false;
5541 if (!isTouched
|| !isMoved
) {
5548 router
.swipeBackActive
= false;
5549 $([currentPage
[0], previousPage
[0]]).removeClass('page-swipeback-active');
5550 if (touchesDiff
=== 0) {
5551 $([currentPage
[0], previousPage
[0]]).transform('');
5552 if (pageShadow
&& pageShadow
.length
> 0) { pageShadow
.remove(); }
5553 if (pageOpacity
&& pageOpacity
.length
> 0) { pageOpacity
.remove(); }
5554 if (dynamicNavbar
) {
5555 currentNavElements
.transform('').css({ opacity
: '' });
5556 previousNavElements
.transform('').css({ opacity
: '' });
5557 if (activeNavBackIcon
&& activeNavBackIcon
.length
> 0) { activeNavBackIcon
.transform(''); }
5558 if (previousNavBackIcon
&& activeNavBackIcon
.length
> 0) { previousNavBackIcon
.transform(''); }
5562 var timeDiff
= Utils
.now() - touchStartTime
;
5563 var pageChanged
= false;
5564 // Swipe back to previous page
5566 (timeDiff
< 300 && touchesDiff
> 10)
5567 || (timeDiff
>= 300 && touchesDiff
> viewContainerWidth
/ 2)
5569 currentPage
.removeClass('page-current').addClass(("page-next" + (app
.theme
=== 'md' ? ' page-next-on-right' : '')));
5570 previousPage
.removeClass('page-previous').addClass('page-current').removeAttr('aria-hidden');
5571 if (pageShadow
) { pageShadow
[0].style
.opacity
= ''; }
5572 if (pageOpacity
) { pageOpacity
[0].style
.opacity
= ''; }
5573 if (dynamicNavbar
) {
5574 currentNavbar
.removeClass('navbar-current').addClass('navbar-next');
5575 previousNavbar
.removeClass('navbar-previous').addClass('navbar-current').removeAttr('aria-hidden');
5579 // Reset custom styles
5580 // Add transitioning class for transition-duration
5581 $([currentPage
[0], previousPage
[0]]).addClass('page-transitioning page-transitioning-swipeback').transform('');
5583 if (dynamicNavbar
) {
5584 currentNavElements
.css({ opacity
: '' })
5585 .each(function (navElIndex
, navEl
) {
5586 var translate
= pageChanged
? navEl
.f7NavbarRightOffset
: 0;
5587 var sliding
= $(navEl
);
5588 var iconTranslate
= pageChanged
? -translate
: 0;
5589 if (!separateNavbar
&& pageChanged
) { iconTranslate
-= navbarWidth
; }
5590 sliding
.transform(("translate3d(" + translate
+ "px,0,0)"));
5591 if (params
.iosAnimateNavbarBackIcon
) {
5592 if (sliding
.hasClass('left') && activeNavBackIcon
.length
> 0) {
5593 activeNavBackIcon
.addClass('navbar-transitioning').transform(("translate3d(" + iconTranslate
+ "px,0,0)"));
5596 }).addClass('navbar-transitioning');
5598 previousNavElements
.transform('').css({ opacity
: '' }).each(function (navElIndex
, navEl
) {
5599 var translate
= pageChanged
? 0 : navEl
.f7NavbarLeftOffset
;
5600 var sliding
= $(navEl
);
5601 var iconTranslate
= pageChanged
? 0 : -translate
;
5602 if (!separateNavbar
&& !pageChanged
) { iconTranslate
+= navbarWidth
/ 5; }
5603 sliding
.transform(("translate3d(" + translate
+ "px,0,0)"));
5604 if (params
.iosAnimateNavbarBackIcon
) {
5605 if (sliding
.hasClass('left') && previousNavBackIcon
.length
> 0) {
5606 previousNavBackIcon
.addClass('navbar-transitioning').transform(("translate3d(" + iconTranslate
+ "px,0,0)"));
5609 }).addClass('navbar-transitioning');
5611 allowViewTouchMove
= false;
5612 router
.allowPageChange
= false;
5614 // Swipe Back Callback
5615 var callbackData
= {
5616 currentPageEl
: currentPage
[0],
5617 previousPageEl
: previousPage
[0],
5618 currentNavbarEl
: currentNavbar
[0],
5619 previousNavbarEl
: previousNavbar
[0],
5624 router
.currentRoute
= previousPage
[0].f7Page
.route
;
5625 router
.currentPage
= previousPage
[0];
5627 // Page before animation callback
5628 router
.pageCallback('beforeOut', currentPage
, currentNavbar
, 'current', 'next', { route
: currentPage
[0].f7Page
.route
, swipeBack
: true });
5629 router
.pageCallback('beforeIn', previousPage
, previousNavbar
, 'previous', 'current', { route
: previousPage
[0].f7Page
.route
, swipeBack
: true });
5631 $el
.trigger('swipeback:beforechange', callbackData
);
5632 router
.emit('swipebackBeforeChange', callbackData
);
5634 $el
.trigger('swipeback:beforereset', callbackData
);
5635 router
.emit('swipebackBeforeReset', callbackData
);
5638 currentPage
.transitionEnd(function () {
5639 $([currentPage
[0], previousPage
[0]]).removeClass('page-transitioning page-transitioning-swipeback');
5641 if (dynamicNavbar
) {
5642 currentNavElements
.removeClass('navbar-transitioning').css({ opacity
: '' }).transform('');
5643 previousNavElements
.removeClass('navbar-transitioning').css({ opacity
: '' }).transform('');
5644 if (activeNavBackIcon
&& activeNavBackIcon
.length
> 0) { activeNavBackIcon
.removeClass('navbar-transitioning'); }
5645 if (previousNavBackIcon
&& previousNavBackIcon
.length
> 0) { previousNavBackIcon
.removeClass('navbar-transitioning'); }
5647 allowViewTouchMove
= true;
5648 router
.allowPageChange
= true;
5651 if (router
.history
.length
=== 1) {
5652 router
.history
.unshift(router
.url
);
5654 router
.history
.pop();
5655 router
.saveHistory();
5657 // Update push state
5658 if (params
.pushState
) {
5662 // Page after animation callback
5663 router
.pageCallback('afterOut', currentPage
, currentNavbar
, 'current', 'next', { route
: currentPage
[0].f7Page
.route
, swipeBack
: true });
5664 router
.pageCallback('afterIn', previousPage
, previousNavbar
, 'previous', 'current', { route
: previousPage
[0].f7Page
.route
, swipeBack
: true });
5667 if (params
.stackPages
&& router
.initialPages
.indexOf(currentPage
[0]) >= 0) {
5668 currentPage
.addClass('stacked');
5669 if (separateNavbar
) {
5670 currentNavbar
.addClass('stacked');
5673 router
.pageCallback('beforeRemove', currentPage
, currentNavbar
, 'next', { swipeBack
: true });
5674 router
.removePage(currentPage
);
5675 if (separateNavbar
) {
5676 router
.removeNavbar(currentNavbar
);
5680 $el
.trigger('swipeback:afterchange', callbackData
);
5681 router
.emit('swipebackAfterChange', callbackData
);
5683 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
5685 if (params
.preloadPreviousPage
) {
5686 router
.back(router
.history
[router
.history
.length
- 2], { preload
: true });
5689 $el
.trigger('swipeback:afterreset', callbackData
);
5690 router
.emit('swipebackAfterReset', callbackData
);
5692 if (pageShadow
&& pageShadow
.length
> 0) { pageShadow
.remove(); }
5693 if (pageOpacity
&& pageOpacity
.length
> 0) { pageOpacity
.remove(); }
5697 function attachEvents() {
5698 var passiveListener
= (app
.touchEvents
.start
=== 'touchstart' && Support
.passiveListener
) ? { passive
: true, capture
: false } : false;
5699 $el
.on(app
.touchEvents
.start
, handleTouchStart
, passiveListener
);
5700 app
.on('touchmove:active', handleTouchMove
);
5701 app
.on('touchend:passive', handleTouchEnd
);
5703 function detachEvents() {
5704 var passiveListener
= (app
.touchEvents
.start
=== 'touchstart' && Support
.passiveListener
) ? { passive
: true, capture
: false } : false;
5705 $el
.off(app
.touchEvents
.start
, handleTouchStart
, passiveListener
);
5706 app
.off('touchmove:active', handleTouchMove
);
5707 app
.off('touchend:passive', handleTouchEnd
);
5712 router
.on('routerDestroy', detachEvents
);
5715 function redirect (direction
, route
, options
) {
5717 var redirect
= route
.route
.redirect
;
5718 if (options
.initial
&& router
.params
.pushState
) {
5719 options
.replaceState
= true; // eslint-disable-line
5720 options
.history
= true; // eslint-disable-line
5722 function redirectResolve(redirectUrl
, redirectOptions
) {
5723 if ( redirectOptions
=== void 0 ) redirectOptions
= {};
5725 router
.allowPageChange
= true;
5726 router
[direction
](redirectUrl
, Utils
.extend({}, options
, redirectOptions
));
5728 function redirectReject() {
5729 router
.allowPageChange
= true;
5731 if (typeof redirect
=== 'function') {
5732 router
.allowPageChange
= false;
5733 var redirectUrl
= redirect
.call(router
, route
, redirectResolve
, redirectReject
);
5734 if (redirectUrl
&& typeof redirectUrl
=== 'string') {
5735 router
.allowPageChange
= true;
5736 return router
[direction
](redirectUrl
, options
);
5740 return router
[direction
](redirect
, options
);
5743 function processQueue(router
, routerQueue
, routeQueue
, to
, from, resolve
, reject
) {
5746 if (Array
.isArray(routeQueue
)) {
5747 queue
.push
.apply(queue
, routeQueue
);
5748 } else if (routeQueue
&& typeof routeQueue
=== 'function') {
5749 queue
.push(routeQueue
);
5752 if (Array
.isArray(routerQueue
)) {
5753 queue
.push
.apply(queue
, routerQueue
);
5755 queue
.push(routerQueue
);
5760 if (queue
.length
=== 0) {
5764 var queueItem
= queue
.shift();
5781 function processRouteQueue (to
, from, resolve
, reject
) {
5783 function enterNextRoute() {
5784 if (to
&& to
.route
&& (router
.params
.routesBeforeEnter
|| to
.route
.beforeEnter
)) {
5785 router
.allowPageChange
= false;
5788 router
.params
.routesBeforeEnter
,
5789 to
.route
.beforeEnter
,
5793 router
.allowPageChange
= true;
5804 function leaveCurrentRoute() {
5805 if (from && from.route
&& (router
.params
.routesBeforeLeave
|| from.route
.beforeLeave
)) {
5806 router
.allowPageChange
= false;
5809 router
.params
.routesBeforeLeave
,
5810 from.route
.beforeLeave
,
5814 router
.allowPageChange
= true;
5825 leaveCurrentRoute();
5828 function appRouterCheck (router
, method
) {
5830 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
+ "(...)"));
5834 function refreshPage() {
5836 appRouterCheck(router
, 'refreshPage');
5837 return router
.navigate(router
.currentRoute
.url
, {
5839 reloadCurrent
: true,
5843 function forward(el
, forwardOptions
) {
5844 if ( forwardOptions
=== void 0 ) forwardOptions
= {};
5848 var app
= router
.app
;
5849 var view
= router
.view
;
5850 var options
= Utils
.extend(false, {
5851 animate
: router
.params
.animate
,
5853 replaceState
: false,
5855 reloadCurrent
: router
.params
.reloadPages
,
5856 reloadPrevious
: false,
5858 clearPreviousHistory
: false,
5862 var currentRouteIsModal
= router
.currentRoute
.modal
;
5864 if (!currentRouteIsModal
) {
5865 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
5866 if (router
.currentRoute
&& router
.currentRoute
.route
&& router
.currentRoute
.route
[modalLoadProp
]) {
5867 currentRouteIsModal
= true;
5868 modalType
= modalLoadProp
;
5873 if (currentRouteIsModal
) {
5874 var modalToClose
= router
.currentRoute
.modal
5875 || router
.currentRoute
.route
.modalInstance
5876 || app
[modalType
].get();
5877 var previousUrl
= router
.history
[router
.history
.length
- 2];
5878 var previousRoute
= router
.findMatchingRoute(previousUrl
);
5879 if (!previousRoute
&& previousUrl
) {
5882 path
: previousUrl
.split('?')[0],
5883 query
: Utils
.parseUrlQuery(previousUrl
),
5885 path
: previousUrl
.split('?')[0],
5891 router
.modalRemove(modalToClose
);
5894 var dynamicNavbar
= router
.dynamicNavbar
;
5895 var separateNavbar
= router
.separateNavbar
;
5897 var $viewEl
= router
.$el
;
5899 var reload
= options
.reloadPrevious
|| options
.reloadCurrent
|| options
.reloadAll
;
5903 var $newNavbarInner
;
5904 var $oldNavbarInner
;
5906 router
.allowPageChange
= false;
5907 if ($newPage
.length
=== 0) {
5908 router
.allowPageChange
= true;
5912 if ($newPage
.length
) {
5913 // Remove theme elements
5914 router
.removeThemeElements($newPage
);
5917 if (dynamicNavbar
) {
5918 $newNavbarInner
= $newPage
.children('.navbar').children('.navbar-inner');
5919 if (separateNavbar
) {
5920 $navbarEl
= router
.$navbarEl
;
5921 if ($newNavbarInner
.length
> 0) {
5922 $newPage
.children('.navbar').remove();
5924 if ($newNavbarInner
.length
=== 0 && $newPage
[0] && $newPage
[0].f7Page
) {
5925 // Try from pageData
5926 $newNavbarInner
= $newPage
[0].f7Page
.$navbarEl
;
5931 // Save Keep Alive Cache
5932 if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !options
.route
.route
.keepAliveData
) {
5933 options
.route
.route
.keepAliveData
= {
5939 var $pagesInView
= $viewEl
5940 .children('.page:not(.stacked)')
5941 .filter(function (index
, pageInView
) { return pageInView
!== $newPage
[0]; });
5945 if (separateNavbar
) {
5946 $navbarsInView
= $navbarEl
5947 .children('.navbar-inner:not(.stacked)')
5948 .filter(function (index
, navbarInView
) { return navbarInView
!== $newNavbarInner
[0]; });
5951 // Exit when reload previous and only 1 page in view so nothing ro reload
5952 if (options
.reloadPrevious
&& $pagesInView
.length
< 2) {
5953 router
.allowPageChange
= true;
5958 var newPagePosition
= 'next';
5959 if (options
.reloadCurrent
|| options
.reloadAll
) {
5960 newPagePosition
= 'current';
5961 } else if (options
.reloadPrevious
) {
5962 newPagePosition
= 'previous';
5965 .addClass(("page-" + newPagePosition
))
5966 .removeClass('stacked')
5967 .trigger('page:unstack')
5968 .trigger('page:position', { position
: newPagePosition
});
5970 if (dynamicNavbar
&& $newNavbarInner
.length
) {
5972 .addClass(("navbar-" + newPagePosition
))
5973 .removeClass('stacked');
5977 if (options
.reloadCurrent
) {
5978 $oldPage
= $pagesInView
.eq($pagesInView
.length
- 1);
5979 if (separateNavbar
) {
5980 // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 1);
5981 $oldNavbarInner
= $(app
.navbar
.getElByPage($oldPage
));
5983 } else if (options
.reloadPrevious
) {
5984 $oldPage
= $pagesInView
.eq($pagesInView
.length
- 2);
5985 if (separateNavbar
) {
5986 // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 2);
5987 $oldNavbarInner
= $(app
.navbar
.getElByPage($oldPage
));
5989 } else if (options
.reloadAll
) {
5990 $oldPage
= $pagesInView
.filter(function (index
, pageEl
) { return pageEl
!== $newPage
[0]; });
5991 if (separateNavbar
) {
5992 $oldNavbarInner
= $navbarsInView
.filter(function (index
, navbarEl
) { return navbarEl
!== $newNavbarInner
[0]; });
5995 if ($pagesInView
.length
> 1) {
5997 for (i
= 0; i
< $pagesInView
.length
- 1; i
+= 1) {
5998 var oldNavbarInnerEl
= app
.navbar
.getElByPage($pagesInView
.eq(i
));
5999 if (router
.params
.stackPages
) {
6000 $pagesInView
.eq(i
).addClass('stacked');
6001 $pagesInView
.eq(i
).trigger('page:stack');
6002 if (separateNavbar
) {
6003 // $navbarsInView.eq(i).addClass('stacked');
6004 $(oldNavbarInnerEl
).addClass('stacked');
6007 // Page remove event
6008 router
.pageCallback('beforeRemove', $pagesInView
[i
], $navbarsInView
&& $navbarsInView
[i
], 'previous', undefined, options
);
6009 router
.removePage($pagesInView
[i
]);
6010 if (separateNavbar
&& oldNavbarInnerEl
) {
6011 router
.removeNavbar(oldNavbarInnerEl
);
6017 .children('.page:not(.stacked)')
6018 .filter(function (index
, page
) { return page
!== $newPage
[0]; });
6019 if (separateNavbar
) {
6020 $oldNavbarInner
= $navbarEl
6021 .children('.navbar-inner:not(.stacked)')
6022 .filter(function (index
, navbarInner
) { return navbarInner
!== $newNavbarInner
[0]; });
6025 if (dynamicNavbar
&& !separateNavbar
) {
6026 $oldNavbarInner
= $oldPage
.children('.navbar').children('.navbar-inner');
6030 if (router
.params
.pushState
&& (options
.pushState
|| options
.replaceState
) && !options
.reloadPrevious
) {
6031 var pushStateRoot
= router
.params
.pushStateRoot
|| '';
6032 History
[options
.reloadCurrent
|| options
.reloadAll
|| options
.replaceState
? 'replace' : 'push'](
6035 url
: options
.route
.url
,
6037 pushStateRoot
+ router
.params
.pushStateSeparator
+ options
.route
.url
6041 if (!options
.reloadPrevious
) {
6042 // Current Page & Navbar
6043 router
.currentPageEl
= $newPage
[0];
6044 if (dynamicNavbar
&& $newNavbarInner
.length
) {
6045 router
.currentNavbarEl
= $newNavbarInner
[0];
6047 delete router
.currentNavbarEl
;
6051 router
.currentRoute
= options
.route
;
6054 // Update router history
6055 var url
= options
.route
.url
;
6057 if (options
.history
) {
6058 if ((options
.reloadCurrent
&& router
.history
.length
) > 0 || options
.replaceState
) {
6059 router
.history
[router
.history
.length
- (options
.reloadPrevious
? 2 : 1)] = url
;
6060 } else if (options
.reloadPrevious
) {
6061 router
.history
[router
.history
.length
- 2] = url
;
6062 } else if (options
.reloadAll
) {
6063 router
.history
= [url
];
6065 router
.history
.push(url
);
6068 router
.saveHistory();
6070 // Insert new page and navbar
6071 var newPageInDom
= $newPage
.parents(doc
).length
> 0;
6072 var f7Component
= $newPage
[0].f7Component
;
6073 if (options
.reloadPrevious
) {
6074 if (f7Component
&& !newPageInDom
) {
6075 f7Component
.$mount(function (componentEl
) {
6076 $(componentEl
).insertBefore($oldPage
);
6079 $newPage
.insertBefore($oldPage
);
6081 if (separateNavbar
&& $newNavbarInner
.length
) {
6082 if ($oldNavbarInner
.length
) {
6083 $newNavbarInner
.insertBefore($oldNavbarInner
);
6085 if (!router
.$navbarEl
.parents(doc
).length
) {
6086 router
.$el
.prepend(router
.$navbarEl
);
6088 $navbarEl
.append($newNavbarInner
);
6092 if ($oldPage
.next('.page')[0] !== $newPage
[0]) {
6093 if (f7Component
&& !newPageInDom
) {
6094 f7Component
.$mount(function (componentEl
) {
6095 $viewEl
.append(componentEl
);
6098 $viewEl
.append($newPage
[0]);
6101 if (separateNavbar
&& $newNavbarInner
.length
) {
6102 if (!router
.$navbarEl
.parents(doc
).length
) {
6103 router
.$el
.prepend(router
.$navbarEl
);
6105 $navbarEl
.append($newNavbarInner
[0]);
6108 if (!newPageInDom
) {
6109 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, newPagePosition
, reload
? newPagePosition
: 'current', options
, $oldPage
);
6110 } else if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !$newPage
[0].f7PageMounted
) {
6111 $newPage
[0].f7PageMounted
= true;
6112 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, newPagePosition
, reload
? newPagePosition
: 'current', options
, $oldPage
);
6116 if (options
.reloadCurrent
&& $oldPage
.length
> 0) {
6117 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPage
[0]) >= 0) {
6118 $oldPage
.addClass('stacked');
6119 $oldPage
.trigger('page:stack');
6120 if (separateNavbar
) {
6121 $oldNavbarInner
.addClass('stacked');
6124 // Page remove event
6125 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'previous', undefined, options
);
6126 router
.removePage($oldPage
);
6127 if (separateNavbar
&& $oldNavbarInner
&& $oldNavbarInner
.length
) {
6128 router
.removeNavbar($oldNavbarInner
);
6131 } else if (options
.reloadAll
) {
6132 $oldPage
.each(function (index
, pageEl
) {
6133 var $oldPageEl
= $(pageEl
);
6134 var $oldNavbarInnerEl
= $(app
.navbar
.getElByPage($oldPageEl
));
6135 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPageEl
[0]) >= 0) {
6136 $oldPageEl
.addClass('stacked');
6137 $oldPageEl
.trigger('page:stack');
6138 if (separateNavbar
) {
6139 $oldNavbarInnerEl
.addClass('stacked');
6142 // Page remove event
6143 router
.pageCallback('beforeRemove', $oldPageEl
, $oldNavbarInner
&& $oldNavbarInner
.eq(index
), 'previous', undefined, options
);
6144 router
.removePage($oldPageEl
);
6145 if (separateNavbar
&& $oldNavbarInnerEl
.length
) {
6146 router
.removeNavbar($oldNavbarInnerEl
);
6150 } else if (options
.reloadPrevious
) {
6151 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPage
[0]) >= 0) {
6152 $oldPage
.addClass('stacked');
6153 $oldPage
.trigger('page:stack');
6154 if (separateNavbar
) {
6155 $oldNavbarInner
.addClass('stacked');
6158 // Page remove event
6159 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'previous', undefined, options
);
6160 router
.removePage($oldPage
);
6161 if (separateNavbar
&& $oldNavbarInner
&& $oldNavbarInner
.length
) {
6162 router
.removeNavbar($oldNavbarInner
);
6168 if (options
.route
.route
.tab
) {
6169 router
.tabLoad(options
.route
.route
.tab
, Utils
.extend({}, options
, {
6175 // Page init and before init events
6176 router
.pageCallback('init', $newPage
, $newNavbarInner
, newPagePosition
, reload
? newPagePosition
: 'current', options
, $oldPage
);
6178 if (options
.reloadCurrent
|| options
.reloadAll
) {
6179 router
.allowPageChange
= true;
6180 router
.pageCallback('beforeIn', $newPage
, $newNavbarInner
, newPagePosition
, 'current', options
);
6181 router
.pageCallback('afterIn', $newPage
, $newNavbarInner
, newPagePosition
, 'current', options
);
6182 if (options
.reloadCurrent
&& options
.clearPreviousHistory
) { router
.clearPreviousHistory(); }
6185 if (options
.reloadPrevious
) {
6186 router
.allowPageChange
= true;
6190 // Before animation event
6191 router
.pageCallback('beforeIn', $newPage
, $newNavbarInner
, 'next', 'current', options
);
6192 router
.pageCallback('beforeOut', $oldPage
, $oldNavbarInner
, 'current', 'previous', options
);
6195 function afterAnimation() {
6196 var pageClasses
= 'page-previous page-current page-next';
6197 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
6198 $newPage
.removeClass(pageClasses
).addClass('page-current').removeAttr('aria-hidden');
6199 $oldPage
.removeClass(pageClasses
).addClass('page-previous').attr('aria-hidden', 'true');
6200 if (dynamicNavbar
) {
6201 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current').removeAttr('aria-hidden');
6202 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-previous').attr('aria-hidden', 'true');
6204 // After animation event
6205 router
.allowPageChange
= true;
6206 router
.pageCallback('afterIn', $newPage
, $newNavbarInner
, 'next', 'current', options
);
6207 router
.pageCallback('afterOut', $oldPage
, $oldNavbarInner
, 'current', 'previous', options
);
6209 var keepOldPage
= app
.theme
=== 'ios' ? (router
.params
.preloadPreviousPage
|| router
.params
.iosSwipeBack
) : router
.params
.preloadPreviousPage
;
6211 if ($newPage
.hasClass('smart-select-page') || $newPage
.hasClass('photo-browser-page') || $newPage
.hasClass('autocomplete-page')) {
6216 if (router
.params
.stackPages
) {
6217 $oldPage
.addClass('stacked');
6218 $oldPage
.trigger('page:stack');
6219 if (separateNavbar
) {
6220 $oldNavbarInner
.addClass('stacked');
6222 } else if (!($newPage
.attr('data-name') && $newPage
.attr('data-name') === 'smart-select-page')) {
6224 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'previous', undefined, options
);
6225 router
.removePage($oldPage
);
6226 if (separateNavbar
&& $oldNavbarInner
.length
) {
6227 router
.removeNavbar($oldNavbarInner
);
6231 if (options
.clearPreviousHistory
) { router
.clearPreviousHistory(); }
6232 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
6234 if (router
.params
.pushState
) {
6235 History
.clearRouterQueue();
6238 function setPositionClasses() {
6239 var pageClasses
= 'page-previous page-current page-next';
6240 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
6241 $oldPage
.removeClass(pageClasses
).addClass('page-current').removeAttr('aria-hidden');
6242 $newPage
.removeClass(pageClasses
).addClass('page-next').removeAttr('aria-hidden');
6243 if (dynamicNavbar
) {
6244 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current').removeAttr('aria-hidden');
6245 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-next').removeAttr('aria-hidden');
6248 if (options
.animate
) {
6249 var delay
= router
.app
.theme
=== 'md' ? router
.params
.materialPageLoadDelay
: router
.params
.iosPageLoadDelay
;
6251 setTimeout(function () {
6252 setPositionClasses();
6253 router
.animate($oldPage
, $newPage
, $oldNavbarInner
, $newNavbarInner
, 'forward', function () {
6258 setPositionClasses();
6259 router
.animate($oldPage
, $newPage
, $oldNavbarInner
, $newNavbarInner
, 'forward', function () {
6268 function load(loadParams
, loadOptions
, ignorePageChange
) {
6269 if ( loadParams
=== void 0 ) loadParams
= {};
6270 if ( loadOptions
=== void 0 ) loadOptions
= {};
6273 if (!router
.allowPageChange
&& !ignorePageChange
) { return router
; }
6274 var params
= loadParams
;
6275 var options
= loadOptions
;
6276 var url
= params
.url
;
6277 var content
= params
.content
;
6279 var pageName
= params
.pageName
;
6280 var template
= params
.template
;
6281 var templateUrl
= params
.templateUrl
;
6282 var component
= params
.component
;
6283 var componentUrl
= params
.componentUrl
;
6285 if (!options
.reloadCurrent
6287 && options
.route
.route
6288 && options
.route
.route
.parentPath
6289 && router
.currentRoute
.route
6290 && router
.currentRoute
.route
.parentPath
=== options
.route
.route
.parentPath
) {
6291 // Do something nested
6292 if (options
.route
.url
=== router
.url
) {
6293 router
.allowPageChange
= true;
6296 // Check for same params
6297 var sameParams
= Object
.keys(options
.route
.params
).length
=== Object
.keys(router
.currentRoute
.params
).length
;
6299 // Check for equal params name
6300 Object
.keys(options
.route
.params
).forEach(function (paramName
) {
6302 !(paramName
in router
.currentRoute
.params
)
6303 || (router
.currentRoute
.params
[paramName
] !== options
.route
.params
[paramName
])
6310 if (options
.route
.route
.tab
) {
6311 return router
.tabLoad(options
.route
.route
.tab
, options
);
6319 && options
.route
.url
6320 && router
.url
=== options
.route
.url
6321 && !(options
.reloadCurrent
|| options
.reloadPrevious
)
6322 && !router
.params
.allowDuplicateUrls
6324 router
.allowPageChange
= true;
6328 if (!options
.route
&& url
) {
6329 options
.route
= router
.parseRouteUrl(url
);
6330 Utils
.extend(options
.route
, { route
: { url
: url
, path
: url
} });
6333 // Component Callbacks
6334 function resolve(pageEl
, newOptions
) {
6335 return router
.forward(pageEl
, Utils
.extend(options
, newOptions
));
6338 router
.allowPageChange
= true;
6342 if (url
|| templateUrl
|| componentUrl
) {
6343 router
.allowPageChange
= false;
6348 router
.forward(router
.getPageEl(content
), options
);
6349 } else if (template
|| templateUrl
) {
6350 // Parse template and send page element
6352 router
.pageTemplateLoader(template
, templateUrl
, options
, resolve
, reject
);
6354 router
.allowPageChange
= true;
6358 // Load page from specified HTMLElement or by page name in pages container
6359 router
.forward(router
.getPageEl(el
), options
);
6360 } else if (pageName
) {
6361 // Load page by page name in pages container
6362 router
.forward(router
.$el
.children((".page[data-name=\"" + pageName
+ "\"]")).eq(0), options
);
6363 } else if (component
|| componentUrl
) {
6364 // Load from component (F7/Vue/React/...)
6366 router
.pageComponentLoader(router
.el
, component
, componentUrl
, options
, resolve
, reject
);
6368 router
.allowPageChange
= true;
6377 router
.xhrRequest(url
, options
)
6378 .then(function (pageContent
) {
6379 router
.forward(router
.getPageEl(pageContent
), options
);
6381 .catch(function () {
6382 router
.allowPageChange
= true;
6387 function navigate(navigateParams
, navigateOptions
) {
6388 if ( navigateOptions
=== void 0 ) navigateOptions
= {};
6391 if (router
.swipeBackActive
) { return router
; }
6398 if (typeof navigateParams
=== 'string') {
6399 url
= navigateParams
;
6401 url
= navigateParams
.url
;
6402 createRoute
= navigateParams
.route
;
6403 name
= navigateParams
.name
;
6404 query
= navigateParams
.query
;
6405 params
= navigateParams
.params
;
6408 // find route by name
6409 route
= router
.findRouteByKey('name', name
);
6411 throw new Error(("Framework7: route with name \"" + name
+ "\" not found"));
6413 url
= router
.constructRouteUrl(route
, { params
: params
, query
: query
});
6415 return router
.navigate(url
, navigateOptions
);
6417 throw new Error(("Framework7: can't construct URL for route with name \"" + name
+ "\""));
6419 var app
= router
.app
;
6420 appRouterCheck(router
, 'navigate');
6421 if (url
=== '#' || url
=== '') {
6425 var navigateUrl
= url
.replace('./', '');
6426 if (navigateUrl
[0] !== '/' && navigateUrl
.indexOf('#') !== 0) {
6427 var currentPath
= router
.currentRoute
.parentPath
|| router
.currentRoute
.path
;
6428 navigateUrl
= ((currentPath
? (currentPath
+ "/") : '/') + navigateUrl
)
6429 .replace('///', '/')
6430 .replace('//', '/');
6433 route
= Utils
.extend(router
.parseRouteUrl(navigateUrl
), {
6434 route
: Utils
.extend({}, createRoute
),
6437 route
= router
.findMatchingRoute(navigateUrl
);
6444 if (route
.route
.redirect
) {
6445 return redirect
.call(router
, 'navigate', route
, navigateOptions
);
6450 if (route
.route
.options
) {
6451 Utils
.extend(options
, route
.route
.options
, navigateOptions
);
6453 Utils
.extend(options
, navigateOptions
);
6455 options
.route
= route
;
6457 if (options
&& options
.context
) {
6458 route
.context
= options
.context
;
6459 options
.route
.context
= options
.context
;
6462 function resolve() {
6463 var routerLoaded
= false;
6464 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
6465 if (route
.route
[modalLoadProp
] && !routerLoaded
) {
6466 routerLoaded
= true;
6467 router
.modalLoad(modalLoadProp
, route
, options
);
6470 if (route
.route
.keepAlive
&& route
.route
.keepAliveData
) {
6471 router
.load({ el
: route
.route
.keepAliveData
.pageEl
}, options
, false);
6472 routerLoaded
= true;
6474 ('url content component pageName el componentUrl template templateUrl').split(' ').forEach(function (pageLoadProp
) {
6477 if (route
.route
[pageLoadProp
] && !routerLoaded
) {
6478 routerLoaded
= true;
6479 router
.load(( obj
= {}, obj
[pageLoadProp
] = route
.route
[pageLoadProp
], obj
), options
, false);
6482 if (routerLoaded
) { return; }
6484 function asyncResolve(resolveParams
, resolveOptions
) {
6485 router
.allowPageChange
= false;
6486 var resolvedAsModal
= false;
6487 if (resolveOptions
&& resolveOptions
.context
) {
6488 if (!route
.context
) { route
.context
= resolveOptions
.context
; }
6489 else { route
.context
= Utils
.extend({}, route
.context
, resolveOptions
.context
); }
6490 options
.route
.context
= route
.context
;
6492 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
6493 if (resolveParams
[modalLoadProp
]) {
6494 resolvedAsModal
= true;
6495 var modalRoute
= Utils
.extend({}, route
, { route
: resolveParams
});
6496 router
.allowPageChange
= true;
6497 router
.modalLoad(modalLoadProp
, modalRoute
, Utils
.extend(options
, resolveOptions
));
6500 if (resolvedAsModal
) { return; }
6501 router
.load(resolveParams
, Utils
.extend(options
, resolveOptions
), true);
6503 function asyncReject() {
6504 router
.allowPageChange
= true;
6506 if (route
.route
.async
) {
6507 router
.allowPageChange
= false;
6509 route
.route
.async
.call(router
, options
.route
, router
.currentRoute
, asyncResolve
, asyncReject
);
6513 router
.allowPageChange
= true;
6516 processRouteQueue
.call(
6519 router
.currentRoute
,
6521 if (route
.route
.modules
) {
6523 .loadModules(Array
.isArray(route
.route
.modules
) ? route
.route
.modules
: [route
.route
.modules
])
6527 .catch(function () {
6543 function tabLoad(tabRoute
, loadOptions
) {
6544 if ( loadOptions
=== void 0 ) loadOptions
= {};
6547 var options
= Utils
.extend({
6548 animate
: router
.params
.animate
,
6558 if (options
.route
) {
6560 if (!options
.preload
&& options
.route
!== router
.currentRoute
) {
6561 previousRoute
= router
.previousRoute
;
6562 router
.currentRoute
= options
.route
;
6564 if (options
.preload
) {
6565 currentRoute
= options
.route
;
6566 previousRoute
= router
.currentRoute
;
6568 currentRoute
= router
.currentRoute
;
6569 if (!previousRoute
) { previousRoute
= router
.previousRoute
; }
6572 // Update Browser History
6573 if (router
.params
.pushState
&& options
.pushState
&& !options
.reloadPrevious
) {
6577 url
: options
.route
.url
,
6579 (router
.params
.pushStateRoot
|| '') + router
.params
.pushStateSeparator
+ options
.route
.url
6583 // Update Router History
6584 if (options
.history
) {
6585 router
.history
[Math
.max(router
.history
.length
- 1, 0)] = options
.route
.url
;
6586 router
.saveHistory();
6591 var $parentPageEl
= $(options
.parentPageEl
|| router
.currentPageEl
);
6593 if ($parentPageEl
.length
&& $parentPageEl
.find(("#" + (tabRoute
.id
))).length
) {
6594 tabEl
= $parentPageEl
.find(("#" + (tabRoute
.id
))).eq(0);
6595 } else if (router
.view
.selector
) {
6596 tabEl
= (router
.view
.selector
) + " #" + (tabRoute
.id
);
6598 tabEl
= "#" + (tabRoute
.id
);
6600 var tabShowResult
= router
.app
.tab
.show({
6602 animate
: options
.animate
,
6603 tabRoute
: options
.route
,
6606 var $newTabEl
= tabShowResult
.$newTabEl
;
6607 var $oldTabEl
= tabShowResult
.$oldTabEl
;
6608 var animated
= tabShowResult
.animated
;
6609 var onTabsChanged
= tabShowResult
.onTabsChanged
;
6611 if ($newTabEl
&& $newTabEl
.parents('.page').length
> 0 && options
.route
) {
6612 var tabParentPageData
= $newTabEl
.parents('.page')[0].f7Page
;
6613 if (tabParentPageData
&& options
.route
) {
6614 tabParentPageData
.route
= options
.route
;
6618 // Tab Content Loaded
6619 function onTabLoaded(contentEl
) {
6620 // Remove theme elements
6621 router
.removeThemeElements($newTabEl
);
6623 var tabEventTarget
= $newTabEl
;
6624 if (typeof contentEl
!== 'string') { tabEventTarget
= $(contentEl
); }
6626 tabEventTarget
.trigger('tab:init tab:mounted', tabRoute
);
6627 router
.emit('tabInit tabMounted', $newTabEl
[0], tabRoute
);
6629 if ($oldTabEl
&& $oldTabEl
.length
) {
6631 onTabsChanged(function () {
6632 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
6633 if (router
.params
.unloadTabContent
) {
6634 router
.tabRemove($oldTabEl
, $newTabEl
, tabRoute
);
6638 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
6639 if (router
.params
.unloadTabContent
) {
6640 router
.tabRemove($oldTabEl
, $newTabEl
, tabRoute
);
6646 if ($newTabEl
[0].f7RouterTabLoaded
) {
6647 if (!$oldTabEl
|| !$oldTabEl
.length
) { return router
; }
6649 onTabsChanged(function () {
6650 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
6653 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
6659 function loadTab(loadTabParams
, loadTabOptions
) {
6661 var url
= loadTabParams
.url
;
6662 var content
= loadTabParams
.content
;
6663 var el
= loadTabParams
.el
;
6664 var template
= loadTabParams
.template
;
6665 var templateUrl
= loadTabParams
.templateUrl
;
6666 var component
= loadTabParams
.component
;
6667 var componentUrl
= loadTabParams
.componentUrl
;
6668 // Component/Template Callbacks
6669 function resolve(contentEl
) {
6670 router
.allowPageChange
= true;
6671 if (!contentEl
) { return; }
6672 if (typeof contentEl
=== 'string') {
6673 $newTabEl
.html(contentEl
);
6676 if (contentEl
.f7Component
) {
6677 contentEl
.f7Component
.$mount(function (componentEl
) {
6678 $newTabEl
.append(componentEl
);
6681 $newTabEl
.append(contentEl
);
6684 $newTabEl
[0].f7RouterTabLoaded
= true;
6685 onTabLoaded(contentEl
);
6688 router
.allowPageChange
= true;
6694 } else if (template
|| templateUrl
) {
6696 router
.tabTemplateLoader(template
, templateUrl
, loadTabOptions
, resolve
, reject
);
6698 router
.allowPageChange
= true;
6703 } else if (component
|| componentUrl
) {
6704 // Load from component (F7/Vue/React/...)
6706 router
.tabComponentLoader($newTabEl
[0], component
, componentUrl
, loadTabOptions
, resolve
, reject
);
6708 router
.allowPageChange
= true;
6717 router
.xhrRequest(url
, loadTabOptions
)
6718 .then(function (tabContent
) {
6719 resolve(tabContent
);
6721 .catch(function () {
6722 router
.allowPageChange
= true;
6727 var hasContentLoadProp
;
6728 ('url content component el componentUrl template templateUrl').split(' ').forEach(function (tabLoadProp
) {
6731 if (tabRoute
[tabLoadProp
]) {
6732 hasContentLoadProp
= true;
6733 loadTab(( obj
= {}, obj
[tabLoadProp
] = tabRoute
[tabLoadProp
], obj
), options
);
6738 function asyncResolve(resolveParams
, resolveOptions
) {
6739 loadTab(resolveParams
, Utils
.extend(options
, resolveOptions
));
6741 function asyncReject() {
6742 router
.allowPageChange
= true;
6744 if (tabRoute
.async
) {
6745 tabRoute
.async
.call(router
, currentRoute
, previousRoute
, asyncResolve
, asyncReject
);
6746 } else if (!hasContentLoadProp
) {
6747 router
.allowPageChange
= true;
6752 function tabRemove($oldTabEl
, $newTabEl
, tabRoute
) {
6755 var hasTabComponentChild
;
6757 $oldTabEl
[0].f7RouterTabLoaded
= false;
6758 delete $oldTabEl
[0].f7RouterTabLoaded
;
6760 $oldTabEl
.children().each(function (index
, tabChild
) {
6761 if (tabChild
.f7Component
) {
6762 hasTabComponentChild
= true;
6763 $(tabChild
).trigger('tab:beforeremove', tabRoute
);
6764 tabChild
.f7Component
.$destroy();
6767 if (!hasTabComponentChild
) {
6768 $oldTabEl
.trigger('tab:beforeremove', tabRoute
);
6770 router
.emit('tabBeforeRemove', $oldTabEl
[0], $newTabEl
[0], tabRoute
);
6771 router
.removeTabContent($oldTabEl
[0], tabRoute
);
6774 function modalLoad(modalType
, route
, loadOptions
) {
6775 if ( loadOptions
=== void 0 ) loadOptions
= {};
6778 var app
= router
.app
;
6779 var isPanel
= modalType
=== 'panel';
6780 var modalOrPanel
= isPanel
? 'panel' : 'modal';
6782 var options
= Utils
.extend({
6783 animate
: router
.params
.animate
,
6789 var modalParams
= Utils
.extend({}, route
.route
[modalType
]);
6790 var modalRoute
= route
.route
;
6792 function onModalLoaded() {
6794 var modal
= app
[modalType
].create(modalParams
);
6795 modalRoute
.modalInstance
= modal
;
6797 var hasEl
= modal
.el
;
6799 function closeOnSwipeBack() {
6802 modal
.on((modalOrPanel
+ "Open"), function () {
6804 // Remove theme elements
6805 router
.removeThemeElements(modal
.el
);
6808 modal
.$el
.trigger(((modalType
.toLowerCase()) + ":init " + (modalType
.toLowerCase()) + ":mounted"), route
, modal
);
6809 router
.emit(((!isPanel
? 'modalInit' : '') + " " + modalType
+ "Init " + modalType
+ "Mounted"), modal
.el
, route
, modal
);
6811 router
.once('swipeBackMove', closeOnSwipeBack
);
6813 modal
.on((modalOrPanel
+ "Close"), function () {
6814 router
.off('swipeBackMove', closeOnSwipeBack
);
6815 if (!modal
.closeByRouter
) {
6820 modal
.on((modalOrPanel
+ "Closed"), function () {
6821 modal
.$el
.trigger(((modalType
.toLowerCase()) + ":beforeremove"), route
, modal
);
6822 modal
.emit(("" + (!isPanel
? 'modalBeforeRemove ' : '') + modalType
+ "BeforeRemove"), modal
.el
, route
, modal
);
6823 var modalComponent
= modal
.el
.f7Component
;
6824 if (modalComponent
) {
6825 modalComponent
.$destroy();
6827 Utils
.nextTick(function () {
6828 if (modalComponent
|| modalParams
.component
) {
6829 router
.removeModal(modal
.el
);
6833 delete modalRoute
.modalInstance
;
6837 if (options
.route
) {
6838 // Update Browser History
6839 if (router
.params
.pushState
&& options
.pushState
) {
6843 url
: options
.route
.url
,
6846 (router
.params
.pushStateRoot
|| '') + router
.params
.pushStateSeparator
+ options
.route
.url
6851 if (options
.route
!== router
.currentRoute
) {
6852 modal
.route
= Utils
.extend(options
.route
, { modal
: modal
});
6853 router
.currentRoute
= modal
.route
;
6856 // Update Router History
6857 if (options
.history
) {
6858 router
.history
.push(options
.route
.url
);
6859 router
.saveHistory();
6864 // Remove theme elements
6865 router
.removeThemeElements(modal
.el
);
6868 modal
.$el
.trigger(((modalType
.toLowerCase()) + ":init " + (modalType
.toLowerCase()) + ":mounted"), route
, modal
);
6869 router
.emit((modalOrPanel
+ "Init " + modalType
+ "Init " + modalType
+ "Mounted"), modal
.el
, route
, modal
);
6876 // Load Modal Content
6877 function loadModal(loadModalParams
, loadModalOptions
) {
6879 var url
= loadModalParams
.url
;
6880 var content
= loadModalParams
.content
;
6881 var template
= loadModalParams
.template
;
6882 var templateUrl
= loadModalParams
.templateUrl
;
6883 var component
= loadModalParams
.component
;
6884 var componentUrl
= loadModalParams
.componentUrl
;
6886 // Component/Template Callbacks
6887 function resolve(contentEl
) {
6889 if (typeof contentEl
=== 'string') {
6890 modalParams
.content
= contentEl
;
6891 } else if (contentEl
.f7Component
) {
6892 contentEl
.f7Component
.$mount(function (componentEl
) {
6893 modalParams
.el
= componentEl
;
6894 app
.root
.append(componentEl
);
6897 modalParams
.el
= contentEl
;
6903 router
.allowPageChange
= true;
6909 } else if (template
|| templateUrl
) {
6911 router
.modalTemplateLoader(template
, templateUrl
, loadModalOptions
, resolve
, reject
);
6913 router
.allowPageChange
= true;
6916 } else if (component
|| componentUrl
) {
6917 // Load from component (F7/Vue/React/...)
6919 router
.modalComponentLoader(app
.root
[0], component
, componentUrl
, loadModalOptions
, resolve
, reject
);
6921 router
.allowPageChange
= true;
6930 router
.xhrRequest(url
, loadModalOptions
)
6931 .then(function (modalContent
) {
6932 modalParams
.content
= modalContent
;
6935 .catch(function () {
6936 router
.allowPageChange
= true;
6944 ('url content component el componentUrl template templateUrl').split(' ').forEach(function (modalLoadProp
) {
6947 if (modalParams
[modalLoadProp
] && !foundLoadProp
) {
6948 foundLoadProp
= true;
6949 loadModal(( obj
= {}, obj
[modalLoadProp
] = modalParams
[modalLoadProp
], obj
), options
);
6952 if (!foundLoadProp
&& modalType
=== 'actions') {
6957 function asyncResolve(resolveParams
, resolveOptions
) {
6958 loadModal(resolveParams
, Utils
.extend(options
, resolveOptions
));
6960 function asyncReject() {
6961 router
.allowPageChange
= true;
6963 if (modalParams
.async
) {
6964 modalParams
.async
.call(router
, options
.route
, router
.currentRoute
, asyncResolve
, asyncReject
);
6968 function modalRemove(modal
) {
6969 Utils
.extend(modal
, { closeByRouter
: true });
6973 function backward(el
, backwardOptions
) {
6976 var app
= router
.app
;
6977 var view
= router
.view
;
6979 var options
= Utils
.extend({
6980 animate
: router
.params
.animate
,
6982 }, backwardOptions
);
6984 var dynamicNavbar
= router
.dynamicNavbar
;
6985 var separateNavbar
= router
.separateNavbar
;
6988 var $oldPage
= router
.$el
.children('.page-current');
6990 if ($newPage
.length
) {
6991 // Remove theme elements
6992 router
.removeThemeElements($newPage
);
6996 var $newNavbarInner
;
6997 var $oldNavbarInner
;
6999 if (dynamicNavbar
) {
7000 $newNavbarInner
= $newPage
.children('.navbar').children('.navbar-inner');
7001 if (separateNavbar
) {
7002 $navbarEl
= router
.$navbarEl
;
7003 if ($newNavbarInner
.length
> 0) {
7004 $newPage
.children('.navbar').remove();
7006 if ($newNavbarInner
.length
=== 0 && $newPage
[0] && $newPage
[0].f7Page
) {
7007 // Try from pageData
7008 $newNavbarInner
= $newPage
[0].f7Page
.$navbarEl
;
7010 $oldNavbarInner
= $navbarEl
.find('.navbar-current');
7012 $oldNavbarInner
= $oldPage
.children('.navbar').children('.navbar-inner');
7016 router
.allowPageChange
= false;
7017 if ($newPage
.length
=== 0 || $oldPage
.length
=== 0) {
7018 router
.allowPageChange
= true;
7022 // Remove theme elements
7023 router
.removeThemeElements($newPage
);
7025 // Save Keep Alive Cache
7026 if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !options
.route
.route
.keepAliveData
) {
7027 options
.route
.route
.keepAliveData
= {
7034 .addClass('page-previous')
7035 .removeClass('stacked')
7036 .removeAttr('aria-hidden')
7037 .trigger('page:unstack')
7038 .trigger('page:position', { position
: 'previous' });
7040 if (dynamicNavbar
&& $newNavbarInner
.length
> 0) {
7042 .addClass('navbar-previous')
7043 .removeClass('stacked')
7044 .removeAttr('aria-hidden');
7047 // Remove previous page in case of "forced"
7049 if (options
.force
) {
7050 if ($oldPage
.prev('.page-previous:not(.stacked)').length
> 0 || $oldPage
.prev('.page-previous').length
=== 0) {
7051 if (router
.history
.indexOf(options
.route
.url
) >= 0) {
7052 backIndex
= router
.history
.length
- router
.history
.indexOf(options
.route
.url
) - 1;
7053 router
.history
= router
.history
.slice(0, router
.history
.indexOf(options
.route
.url
) + 2);
7054 view
.history
= router
.history
;
7055 } else if (router
.history
[[router
.history
.length
- 2]]) {
7056 router
.history
[router
.history
.length
- 2] = options
.route
.url
;
7058 router
.history
.unshift(router
.url
);
7061 if (backIndex
&& router
.params
.stackPages
) {
7062 $oldPage
.prevAll('.page-previous').each(function (index
, pageToRemove
) {
7063 var $pageToRemove
= $(pageToRemove
);
7064 var $navbarToRemove
;
7065 if (separateNavbar
) {
7066 // $navbarToRemove = $oldNavbarInner.prevAll('.navbar-previous').eq(index);
7067 $navbarToRemove
= $(app
.navbar
.getElByPage($pageToRemove
));
7069 if ($pageToRemove
[0] !== $newPage
[0] && $pageToRemove
.index() > $newPage
.index()) {
7070 if (router
.initialPages
.indexOf($pageToRemove
[0]) >= 0) {
7071 $pageToRemove
.addClass('stacked');
7072 $pageToRemove
.trigger('page:stack');
7073 if (separateNavbar
) {
7074 $navbarToRemove
.addClass('stacked');
7077 router
.pageCallback('beforeRemove', $pageToRemove
, $navbarToRemove
, 'previous', undefined, options
);
7078 router
.removePage($pageToRemove
);
7079 if (separateNavbar
&& $navbarToRemove
.length
> 0) {
7080 router
.removeNavbar($navbarToRemove
);
7086 var $pageToRemove
= $oldPage
.prev('.page-previous:not(.stacked)');
7087 var $navbarToRemove
;
7088 if (separateNavbar
) {
7089 // $navbarToRemove = $oldNavbarInner.prev('.navbar-inner:not(.stacked)');
7090 $navbarToRemove
= $(app
.navbar
.getElByPage($pageToRemove
));
7092 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($pageToRemove
[0]) >= 0) {
7093 $pageToRemove
.addClass('stacked');
7094 $pageToRemove
.trigger('page:stack');
7095 $navbarToRemove
.addClass('stacked');
7096 } else if ($pageToRemove
.length
> 0) {
7097 router
.pageCallback('beforeRemove', $pageToRemove
, $navbarToRemove
, 'previous', undefined, options
);
7098 router
.removePage($pageToRemove
);
7099 if (separateNavbar
&& $navbarToRemove
.length
) {
7100 router
.removeNavbar($navbarToRemove
);
7108 var newPageInDom
= $newPage
.parents(doc
).length
> 0;
7109 var f7Component
= $newPage
[0].f7Component
;
7111 function insertPage() {
7112 if ($newPage
.next($oldPage
).length
=== 0) {
7113 if (!newPageInDom
&& f7Component
) {
7114 f7Component
.$mount(function (componentEl
) {
7115 $(componentEl
).insertBefore($oldPage
);
7118 $newPage
.insertBefore($oldPage
);
7121 if (separateNavbar
&& $newNavbarInner
.length
) {
7122 $newNavbarInner
.insertBefore($oldNavbarInner
);
7123 if ($oldNavbarInner
.length
> 0) {
7124 $newNavbarInner
.insertBefore($oldNavbarInner
);
7126 if (!router
.$navbarEl
.parents(doc
).length
) {
7127 router
.$el
.prepend(router
.$navbarEl
);
7129 $navbarEl
.append($newNavbarInner
);
7132 if (!newPageInDom
) {
7133 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7134 } else if (options
.route
&& options
.route
.route
&& options
.route
.route
.keepAlive
&& !$newPage
[0].f7PageMounted
) {
7135 $newPage
[0].f7PageMounted
= true;
7136 router
.pageCallback('mounted', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7140 if (options
.preload
) {
7144 if (options
.route
.route
.tab
) {
7145 router
.tabLoad(options
.route
.route
.tab
, Utils
.extend({}, options
, {
7151 // Page init and before init events
7152 router
.pageCallback('init', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7153 if ($newPage
.prevAll('.page-previous:not(.stacked)').length
> 0) {
7154 $newPage
.prevAll('.page-previous:not(.stacked)').each(function (index
, pageToRemove
) {
7155 var $pageToRemove
= $(pageToRemove
);
7156 var $navbarToRemove
;
7157 if (separateNavbar
) {
7158 // $navbarToRemove = $newNavbarInner.prevAll('.navbar-previous:not(.stacked)').eq(index);
7159 $navbarToRemove
= $(app
.navbar
.getElByPage($pageToRemove
));
7161 if (router
.params
.stackPages
&& router
.initialPages
.indexOf(pageToRemove
) >= 0) {
7162 $pageToRemove
.addClass('stacked');
7163 $pageToRemove
.trigger('page:stack');
7164 if (separateNavbar
) {
7165 $navbarToRemove
.addClass('stacked');
7168 router
.pageCallback('beforeRemove', $pageToRemove
, $navbarToRemove
, 'previous', undefined);
7169 router
.removePage($pageToRemove
);
7170 if (separateNavbar
&& $navbarToRemove
.length
) {
7171 router
.removeNavbar($navbarToRemove
);
7176 router
.allowPageChange
= true;
7181 if (!(Device
.ie
|| Device
.edge
|| (Device
.firefox
&& !Device
.ios
))) {
7182 if (router
.params
.pushState
&& options
.pushState
) {
7183 if (backIndex
) { History
.go(-backIndex
); }
7184 else { History
.back(); }
7189 if (router
.history
.length
=== 1) {
7190 router
.history
.unshift(router
.url
);
7192 router
.history
.pop();
7193 router
.saveHistory();
7195 // Current Page & Navbar
7196 router
.currentPageEl
= $newPage
[0];
7197 if (dynamicNavbar
&& $newNavbarInner
.length
) {
7198 router
.currentNavbarEl
= $newNavbarInner
[0];
7200 delete router
.currentNavbarEl
;
7204 router
.currentRoute
= options
.route
;
7207 if (Device
.ie
|| Device
.edge
|| (Device
.firefox
&& !Device
.ios
)) {
7208 if (router
.params
.pushState
&& options
.pushState
) {
7209 if (backIndex
) { History
.go(-backIndex
); }
7210 else { History
.back(); }
7218 if (options
.route
.route
.tab
) {
7219 router
.tabLoad(options
.route
.route
.tab
, Utils
.extend({}, options
, {
7225 // Page init and before init events
7226 router
.pageCallback('init', $newPage
, $newNavbarInner
, 'previous', 'current', options
, $oldPage
);
7228 // Before animation callback
7229 router
.pageCallback('beforeIn', $newPage
, $newNavbarInner
, 'previous', 'current', options
);
7230 router
.pageCallback('beforeOut', $oldPage
, $oldNavbarInner
, 'current', 'next', options
);
7233 function afterAnimation() {
7235 var pageClasses
= 'page-previous page-current page-next';
7236 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
7237 $newPage
.removeClass(pageClasses
).addClass('page-current').removeAttr('aria-hidden');
7238 $oldPage
.removeClass(pageClasses
).addClass('page-next').attr('aria-hidden', 'true');
7239 if (dynamicNavbar
) {
7240 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current').removeAttr('aria-hidden');
7241 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-next').attr('aria-hidden', 'true');
7244 // After animation event
7245 router
.pageCallback('afterIn', $newPage
, $newNavbarInner
, 'previous', 'current', options
);
7246 router
.pageCallback('afterOut', $oldPage
, $oldNavbarInner
, 'current', 'next', options
);
7249 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPage
[0]) >= 0) {
7250 $oldPage
.addClass('stacked');
7251 $oldPage
.trigger('page:stack');
7252 if (separateNavbar
) {
7253 $oldNavbarInner
.addClass('stacked');
7256 router
.pageCallback('beforeRemove', $oldPage
, $oldNavbarInner
, 'next', undefined, options
);
7257 router
.removePage($oldPage
);
7258 if (separateNavbar
&& $oldNavbarInner
.length
) {
7259 router
.removeNavbar($oldNavbarInner
);
7263 router
.allowPageChange
= true;
7264 router
.emit('routeChanged', router
.currentRoute
, router
.previousRoute
, router
);
7266 // Preload previous page
7267 var preloadPreviousPage
= app
.theme
=== 'ios' ? (router
.params
.preloadPreviousPage
|| router
.params
.iosSwipeBack
) : router
.params
.preloadPreviousPage
;
7268 if (preloadPreviousPage
&& router
.history
[router
.history
.length
- 2]) {
7269 router
.back(router
.history
[router
.history
.length
- 2], { preload
: true });
7271 if (router
.params
.pushState
) {
7272 History
.clearRouterQueue();
7276 function setPositionClasses() {
7277 var pageClasses
= 'page-previous page-current page-next';
7278 var navbarClasses
= 'navbar-previous navbar-current navbar-next';
7279 $oldPage
.removeClass(pageClasses
).addClass('page-current');
7280 $newPage
.removeClass(pageClasses
).addClass('page-previous').removeAttr('aria-hidden');
7281 if (dynamicNavbar
) {
7282 $oldNavbarInner
.removeClass(navbarClasses
).addClass('navbar-current');
7283 $newNavbarInner
.removeClass(navbarClasses
).addClass('navbar-previous').removeAttr('aria-hidden');
7287 if (options
.animate
) {
7288 setPositionClasses();
7289 router
.animate($oldPage
, $newPage
, $oldNavbarInner
, $newNavbarInner
, 'backward', function () {
7298 function loadBack(backParams
, backOptions
, ignorePageChange
) {
7301 if (!router
.allowPageChange
&& !ignorePageChange
) { return router
; }
7302 var params
= backParams
;
7303 var options
= backOptions
;
7304 var url
= params
.url
;
7305 var content
= params
.content
;
7307 var pageName
= params
.pageName
;
7308 var template
= params
.template
;
7309 var templateUrl
= params
.templateUrl
;
7310 var component
= params
.component
;
7311 var componentUrl
= params
.componentUrl
;
7315 && router
.url
=== options
.route
.url
7316 && !(options
.reloadCurrent
|| options
.reloadPrevious
)
7317 && !router
.params
.allowDuplicateUrls
7322 if (!options
.route
&& url
) {
7323 options
.route
= router
.parseRouteUrl(url
);
7326 // Component Callbacks
7327 function resolve(pageEl
, newOptions
) {
7328 return router
.backward(pageEl
, Utils
.extend(options
, newOptions
));
7331 router
.allowPageChange
= true;
7335 if (url
|| templateUrl
|| componentUrl
) {
7336 router
.allowPageChange
= false;
7341 router
.backward(router
.getPageEl(content
), options
);
7342 } else if (template
|| templateUrl
) {
7343 // Parse template and send page element
7345 router
.pageTemplateLoader(template
, templateUrl
, options
, resolve
, reject
);
7347 router
.allowPageChange
= true;
7351 // Load page from specified HTMLElement or by page name in pages container
7352 router
.backward(router
.getPageEl(el
), options
);
7353 } else if (pageName
) {
7354 // Load page by page name in pages container
7355 router
.backward(router
.$el
.children((".page[data-name=\"" + pageName
+ "\"]")).eq(0), options
);
7356 } else if (component
|| componentUrl
) {
7357 // Load from component (F7/Vue/React/...)
7359 router
.pageComponentLoader(router
.el
, component
, componentUrl
, options
, resolve
, reject
);
7361 router
.allowPageChange
= true;
7370 router
.xhrRequest(url
, options
)
7371 .then(function (pageContent
) {
7372 router
.backward(router
.getPageEl(pageContent
), options
);
7374 .catch(function () {
7375 router
.allowPageChange
= true;
7381 var args
= [], len
= arguments
.length
;
7382 while ( len
-- ) args
[ len
] = arguments
[ len
];
7385 if (router
.swipeBackActive
) { return router
; }
7387 var navigateOptions
;
7389 if (typeof args
[0] === 'object') {
7390 navigateOptions
= args
[0] || {};
7392 navigateUrl
= args
[0];
7393 navigateOptions
= args
[1] || {};
7396 var name
= navigateOptions
.name
;
7397 var params
= navigateOptions
.params
;
7398 var query
= navigateOptions
.query
;
7400 // find route by name
7401 route
= router
.findRouteByKey('name', name
);
7403 throw new Error(("Framework7: route with name \"" + name
+ "\" not found"));
7405 navigateUrl
= router
.constructRouteUrl(route
, { params
: params
, query
: query
});
7407 return router
.back(navigateUrl
, Utils
.extend({}, navigateOptions
, {
7413 throw new Error(("Framework7: can't construct URL for route with name \"" + name
+ "\""));
7416 var app
= router
.app
;
7417 appRouterCheck(router
, 'back');
7419 var currentRouteIsModal
= router
.currentRoute
.modal
;
7421 if (!currentRouteIsModal
) {
7422 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp
) {
7423 if (router
.currentRoute
.route
[modalLoadProp
]) {
7424 currentRouteIsModal
= true;
7425 modalType
= modalLoadProp
;
7429 if (currentRouteIsModal
) {
7430 var modalToClose
= router
.currentRoute
.modal
7431 || router
.currentRoute
.route
.modalInstance
7432 || app
[modalType
].get();
7433 var previousUrl
= router
.history
[router
.history
.length
- 2];
7435 // check if previous route is modal too
7436 if (modalToClose
&& modalToClose
.$el
) {
7437 var prevOpenedModals
= modalToClose
.$el
.prevAll('.modal-in');
7438 if (prevOpenedModals
.length
&& prevOpenedModals
[0].f7Modal
) {
7439 previousRoute
= prevOpenedModals
[0].f7Modal
.route
;
7442 if (!previousRoute
) {
7443 previousRoute
= router
.findMatchingRoute(previousUrl
);
7446 if (!previousRoute
&& previousUrl
) {
7449 path
: previousUrl
.split('?')[0],
7450 query
: Utils
.parseUrlQuery(previousUrl
),
7452 path
: previousUrl
.split('?')[0],
7457 if (!navigateUrl
|| navigateUrl
.replace(/[# ]/g, '').trim().length
=== 0) {
7458 if (!previousRoute
|| !modalToClose
) {
7462 var forceOtherUrl
= navigateOptions
.force
&& previousRoute
&& navigateUrl
;
7463 if (previousRoute
&& modalToClose
) {
7464 if (router
.params
.pushState
&& navigateOptions
.pushState
!== false) {
7467 router
.currentRoute
= previousRoute
;
7468 router
.history
.pop();
7469 router
.saveHistory();
7470 router
.modalRemove(modalToClose
);
7471 if (forceOtherUrl
) {
7472 router
.navigate(navigateUrl
, { reloadCurrent
: true });
7474 } else if (modalToClose
) {
7475 router
.modalRemove(modalToClose
);
7477 router
.navigate(navigateUrl
, { reloadCurrent
: true });
7482 var $previousPage
= router
.$el
.children('.page-current').prevAll('.page-previous').eq(0);
7483 if (!navigateOptions
.force
&& $previousPage
.length
> 0) {
7484 if (router
.params
.pushState
7485 && $previousPage
[0].f7Page
7486 && router
.history
[router
.history
.length
- 2] !== $previousPage
[0].f7Page
.route
.url
7489 router
.history
[router
.history
.length
- 2],
7490 Utils
.extend(navigateOptions
, { force
: true })
7495 var previousPageRoute
= $previousPage
[0].f7Page
.route
;
7496 processRouteQueue
.call(
7499 router
.currentRoute
,
7501 router
.loadBack({ el
: $previousPage
}, Utils
.extend(navigateOptions
, {
7502 route
: previousPageRoute
,
7512 if (navigateUrl
=== '#') {
7513 navigateUrl
= undefined;
7515 if (navigateUrl
&& navigateUrl
[0] !== '/' && navigateUrl
.indexOf('#') !== 0) {
7516 navigateUrl
= ((router
.path
|| '/') + navigateUrl
).replace('//', '/');
7518 if (!navigateUrl
&& router
.history
.length
> 1) {
7519 navigateUrl
= router
.history
[router
.history
.length
- 2];
7522 // Find route to load
7523 route
= router
.findMatchingRoute(navigateUrl
);
7528 path
: navigateUrl
.split('?')[0],
7529 query
: Utils
.parseUrlQuery(navigateUrl
),
7531 path
: navigateUrl
.split('?')[0],
7541 if (route
.route
.redirect
) {
7542 return redirect
.call(router
, 'back', route
, navigateOptions
);
7546 if (route
.route
.options
) {
7547 Utils
.extend(options
, route
.route
.options
, navigateOptions
);
7549 Utils
.extend(options
, navigateOptions
);
7551 options
.route
= route
;
7553 if (options
&& options
.context
) {
7554 route
.context
= options
.context
;
7555 options
.route
.context
= options
.context
;
7558 var backForceLoaded
;
7559 if (options
.force
&& router
.params
.stackPages
) {
7560 router
.$el
.children('.page-previous.stacked').each(function (index
, pageEl
) {
7561 if (pageEl
.f7Page
&& pageEl
.f7Page
.route
&& pageEl
.f7Page
.route
.url
=== route
.url
) {
7562 backForceLoaded
= true;
7563 router
.loadBack({ el
: pageEl
}, options
);
7566 if (backForceLoaded
) {
7570 function resolve() {
7571 var routerLoaded
= false;
7572 if (route
.route
.keepAlive
&& route
.route
.keepAliveData
) {
7573 router
.loadBack({ el
: route
.route
.keepAliveData
.pageEl
}, options
);
7574 routerLoaded
= true;
7576 ('url content component pageName el componentUrl template templateUrl').split(' ').forEach(function (pageLoadProp
) {
7579 if (route
.route
[pageLoadProp
] && !routerLoaded
) {
7580 routerLoaded
= true;
7581 router
.loadBack(( obj
= {}, obj
[pageLoadProp
] = route
.route
[pageLoadProp
], obj
), options
);
7584 if (routerLoaded
) { return; }
7586 function asyncResolve(resolveParams
, resolveOptions
) {
7587 router
.allowPageChange
= false;
7588 if (resolveOptions
&& resolveOptions
.context
) {
7589 if (!route
.context
) { route
.context
= resolveOptions
.context
; }
7590 else { route
.context
= Utils
.extend({}, route
.context
, resolveOptions
.context
); }
7591 options
.route
.context
= route
.context
;
7593 router
.loadBack(resolveParams
, Utils
.extend(options
, resolveOptions
), true);
7595 function asyncReject() {
7596 router
.allowPageChange
= true;
7598 if (route
.route
.async
) {
7599 router
.allowPageChange
= false;
7601 route
.route
.async
.call(router
, route
, router
.currentRoute
, asyncResolve
, asyncReject
);
7605 router
.allowPageChange
= true;
7608 if (options
.preload
) {
7611 processRouteQueue
.call(
7614 router
.currentRoute
,
7616 if (route
.route
.modules
) {
7618 .loadModules(Array
.isArray(route
.route
.modules
) ? route
.route
.modules
: [route
.route
.modules
])
7622 .catch(function () {
7639 function clearPreviousPages() {
7641 appRouterCheck(router
, 'clearPreviousPages');
7642 var app
= router
.app
;
7643 var separateNavbar
= router
.separateNavbar
;
7645 var $pagesToRemove
= router
.$el
7647 .filter(function (index
, pageInView
) {
7648 if (router
.currentRoute
&& (router
.currentRoute
.modal
|| router
.currentRoute
.panel
)) { return true; }
7649 return pageInView
!== router
.currentPageEl
;
7652 $pagesToRemove
.each(function (index
, pageEl
) {
7653 var $oldPageEl
= $(pageEl
);
7654 var $oldNavbarInnerEl
= $(app
.navbar
.getElByPage($oldPageEl
));
7655 if (router
.params
.stackPages
&& router
.initialPages
.indexOf($oldPageEl
[0]) >= 0) {
7656 $oldPageEl
.addClass('stacked');
7657 if (separateNavbar
) {
7658 $oldNavbarInnerEl
.addClass('stacked');
7661 // Page remove event
7662 router
.pageCallback('beforeRemove', $oldPageEl
, $oldNavbarInnerEl
, 'previous', undefined, {});
7663 router
.removePage($oldPageEl
);
7664 if (separateNavbar
&& $oldNavbarInnerEl
.length
) {
7665 router
.removeNavbar($oldNavbarInnerEl
);
7671 function clearPreviousHistory() {
7673 appRouterCheck(router
, 'clearPreviousHistory');
7674 var url
= router
.history
[router
.history
.length
- 1];
7676 router
.clearPreviousPages();
7678 router
.history
= [url
];
7679 router
.view
.history
= [url
];
7680 router
.saveHistory();
7683 var Router
= /*@__PURE__*/(function (Framework7Class
$$1) {
7684 function Router(app
, view
) {
7685 Framework7Class
$$1.call(this, {}, [typeof view
=== 'undefined' ? app
: view
]);
7689 router
.isAppRouter
= typeof view
=== 'undefined';
7691 if (router
.isAppRouter
) {
7693 Utils
.extend(false, router
, {
7695 params
: app
.params
.view
,
7696 routes
: app
.routes
|| [],
7701 Utils
.extend(false, router
, {
7705 params
: view
.params
,
7706 routes
: view
.routes
,
7709 $navbarEl
: view
.$navbarEl
,
7710 navbarEl
: view
.navbarEl
,
7711 history
: view
.history
,
7712 scrollHistory
: view
.scrollHistory
,
7714 dynamicNavbar
: app
.theme
=== 'ios' && view
.params
.iosDynamicNavbar
,
7715 separateNavbar
: app
.theme
=== 'ios' && view
.params
.iosDynamicNavbar
&& view
.params
.iosSeparateDynamicNavbar
,
7722 router
.useModules();
7725 router
.tempDom
= doc
.createElement('div');
7728 router
.allowPageChange
= true;
7731 var currentRoute
= {};
7732 var previousRoute
= {};
7733 Object
.defineProperty(router
, 'currentRoute', {
7736 set: function set(newRoute
) {
7737 if ( newRoute
=== void 0 ) newRoute
= {};
7739 previousRoute
= Utils
.extend({}, currentRoute
);
7740 currentRoute
= newRoute
;
7741 if (!currentRoute
) { return; }
7742 router
.url
= currentRoute
.url
;
7743 router
.emit('routeChange', newRoute
, previousRoute
, router
);
7745 get: function get() {
7746 return currentRoute
;
7749 Object
.defineProperty(router
, 'previousRoute', {
7752 get: function get() {
7753 return previousRoute
;
7755 set: function set(newRoute
) {
7756 previousRoute
= newRoute
;
7763 if ( Framework7Class
$$1 ) Router
.__proto__
= Framework7Class
$$1;
7764 Router
.prototype = Object
.create( Framework7Class
$$1 && Framework7Class
$$1.prototype );
7765 Router
.prototype.constructor = Router
;
7767 Router
.prototype.animatableNavElements
= function animatableNavElements (newNavbarInner
, oldNavbarInner
) {
7769 var dynamicNavbar
= router
.dynamicNavbar
;
7770 var animateIcon
= router
.params
.iosAnimateNavbarBackIcon
;
7774 function animatableNavEl(el
, navbarInner
) {
7776 var isSliding
= $el
.hasClass('sliding') || navbarInner
.hasClass('sliding');
7777 var isSubnavbar
= $el
.hasClass('subnavbar');
7778 var needsOpacityTransition
= isSliding
? !isSubnavbar
: true;
7779 var hasIcon
= isSliding
&& animateIcon
&& $el
.hasClass('left') && $el
.find('.back .icon').length
> 0;
7781 if (hasIcon
) { $iconEl
= $el
.find('.back .icon'); }
7786 leftOffset
: $el
[0].f7NavbarLeftOffset
,
7787 rightOffset
: $el
[0].f7NavbarRightOffset
,
7788 isSliding
: isSliding
,
7789 isSubnavbar
: isSubnavbar
,
7790 needsOpacityTransition
: needsOpacityTransition
,
7793 if (dynamicNavbar
) {
7796 newNavbarInner
.children('.left, .right, .title, .subnavbar').each(function (index
, navEl
) {
7797 newNavEls
.push(animatableNavEl(navEl
, newNavbarInner
));
7799 oldNavbarInner
.children('.left, .right, .title, .subnavbar').each(function (index
, navEl
) {
7800 oldNavEls
.push(animatableNavEl(navEl
, oldNavbarInner
));
7802 [oldNavEls
, newNavEls
].forEach(function (navEls
) {
7803 navEls
.forEach(function (navEl
) {
7805 var isSliding
= navEl
.isSliding
;
7806 var $el
= navEl
.$el
;
7807 var otherEls
= navEls
=== oldNavEls
? newNavEls
: oldNavEls
;
7808 if (!(isSliding
&& $el
.hasClass('title') && otherEls
)) { return; }
7809 otherEls
.forEach(function (otherNavEl
) {
7810 if (otherNavEl
.$el
.hasClass('left') && otherNavEl
.hasIcon
) {
7811 var iconTextEl
= otherNavEl
.$el
.find('.back span')[0];
7812 n
.leftOffset
+= iconTextEl
? iconTextEl
.offsetLeft
: 0;
7819 return { newNavEls
: newNavEls
, oldNavEls
: oldNavEls
};
7822 Router
.prototype.animateWithCSS
= function animateWithCSS (oldPage
, newPage
, oldNavbarInner
, newNavbarInner
, direction
, callback
) {
7824 var dynamicNavbar
= router
.dynamicNavbar
;
7825 var separateNavbar
= router
.separateNavbar
;
7826 var ios
= router
.app
.theme
=== 'ios';
7827 // Router Animation class
7828 var routerTransitionClass
= "router-transition-" + direction
+ " router-transition-css-" + direction
;
7832 var navbarWidth
= 0;
7834 if (ios
&& dynamicNavbar
) {
7835 if (!separateNavbar
) {
7836 navbarWidth
= newNavbarInner
[0].offsetWidth
;
7838 var navEls
= router
.animatableNavElements(newNavbarInner
, oldNavbarInner
);
7839 newNavEls
= navEls
.newNavEls
;
7840 oldNavEls
= navEls
.oldNavEls
;
7843 function animateNavbars(progress
) {
7844 if (ios
&& dynamicNavbar
) {
7845 newNavEls
.forEach(function (navEl
) {
7846 var $el
= navEl
.$el
;
7847 var offset
= direction
=== 'forward' ? navEl
.rightOffset
: navEl
.leftOffset
;
7848 if (navEl
.isSliding
) {
7849 $el
.transform(("translate3d(" + (offset
* (1 - progress
)) + "px,0,0)"));
7851 if (navEl
.hasIcon
) {
7852 if (direction
=== 'forward') {
7853 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
- navbarWidth
) * (1 - progress
)) + "px,0,0)"));
7855 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
+ (navbarWidth
/ 5)) * (1 - progress
)) + "px,0,0)"));
7859 oldNavEls
.forEach(function (navEl
) {
7860 var $el
= navEl
.$el
;
7861 var offset
= direction
=== 'forward' ? navEl
.leftOffset
: navEl
.rightOffset
;
7862 if (navEl
.isSliding
) {
7863 $el
.transform(("translate3d(" + (offset
* (progress
)) + "px,0,0)"));
7865 if (navEl
.hasIcon
) {
7866 if (direction
=== 'forward') {
7867 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
+ (navbarWidth
/ 5)) * (progress
)) + "px,0,0)"));
7869 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
- navbarWidth
) * (progress
)) + "px,0,0)"));
7876 // AnimationEnd Callback
7878 if (router
.dynamicNavbar
) {
7879 if (newNavbarInner
.hasClass('sliding')) {
7880 newNavbarInner
.find('.title, .left, .right, .left .icon, .subnavbar').transform('');
7882 newNavbarInner
.find('.sliding').transform('');
7884 if (oldNavbarInner
.hasClass('sliding')) {
7885 oldNavbarInner
.find('.title, .left, .right, .left .icon, .subnavbar').transform('');
7887 oldNavbarInner
.find('.sliding').transform('');
7890 router
.$el
.removeClass(routerTransitionClass
);
7891 if (callback
) { callback(); }
7894 (direction
=== 'forward' ? newPage
: oldPage
).animationEnd(function () {
7899 if (dynamicNavbar
) {
7902 Utils
.nextFrame(function () {
7903 // Add class, start animation
7905 router
.$el
.addClass(routerTransitionClass
);
7908 // Add class, start animation
7909 router
.$el
.addClass(routerTransitionClass
);
7913 Router
.prototype.animateWithJS
= function animateWithJS (oldPage
, newPage
, oldNavbarInner
, newNavbarInner
, direction
, callback
) {
7915 var dynamicNavbar
= router
.dynamicNavbar
;
7916 var separateNavbar
= router
.separateNavbar
;
7917 var ios
= router
.app
.theme
=== 'ios';
7918 var duration
= ios
? 400 : 250;
7919 var routerTransitionClass
= "router-transition-" + direction
+ " router-transition-js-" + direction
;
7921 var startTime
= null;
7926 var navbarWidth
= 0;
7928 if (ios
&& dynamicNavbar
) {
7929 if (!separateNavbar
) {
7930 navbarWidth
= newNavbarInner
[0].offsetWidth
;
7932 var navEls
= router
.animatableNavElements(newNavbarInner
, oldNavbarInner
);
7933 newNavEls
= navEls
.newNavEls
;
7934 oldNavEls
= navEls
.oldNavEls
;
7941 $shadowEl
= $('<div class="page-shadow-effect"></div>');
7942 $opacityEl
= $('<div class="page-opacity-effect"></div>');
7944 if (direction
=== 'forward') {
7945 newPage
.append($shadowEl
);
7946 oldPage
.append($opacityEl
);
7948 newPage
.append($opacityEl
);
7949 oldPage
.append($shadowEl
);
7952 var easing
= Utils
.bezier(0.25, 0.1, 0.25, 1);
7955 newPage
.transform('').css('opacity', '');
7956 oldPage
.transform('').css('opacity', '');
7959 $opacityEl
.remove();
7960 if (dynamicNavbar
) {
7961 newNavEls
.forEach(function (navEl
) {
7962 navEl
.$el
.transform('');
7963 navEl
.$el
.css('opacity', '');
7965 oldNavEls
.forEach(function (navEl
) {
7966 navEl
.$el
.transform('');
7967 navEl
.$el
.css('opacity', '');
7974 router
.$el
.removeClass(routerTransitionClass
);
7976 if (callback
) { callback(); }
7980 var time
= Utils
.now();
7981 if (!startTime
) { startTime
= time
; }
7982 var progress
= Math
.max(Math
.min((time
- startTime
) / duration
, 1), 0);
7983 var easeProgress
= easing(progress
);
7985 if (progress
>= 1) {
7988 var inverter
= router
.app
.rtl
? -1 : 1;
7990 if (direction
=== 'forward') {
7991 newPage
.transform(("translate3d(" + ((1 - easeProgress
) * 100 * inverter
) + "%,0,0)"));
7992 oldPage
.transform(("translate3d(" + (-easeProgress
* 20 * inverter
) + "%,0,0)"));
7993 $shadowEl
[0].style
.opacity
= easeProgress
;
7994 $opacityEl
[0].style
.opacity
= easeProgress
;
7996 newPage
.transform(("translate3d(" + (-(1 - easeProgress
) * 20 * inverter
) + "%,0,0)"));
7997 oldPage
.transform(("translate3d(" + (easeProgress
* 100 * inverter
) + "%,0,0)"));
7998 $shadowEl
[0].style
.opacity
= 1 - easeProgress
;
7999 $opacityEl
[0].style
.opacity
= 1 - easeProgress
;
8001 if (dynamicNavbar
) {
8002 newNavEls
.forEach(function (navEl
) {
8003 var $el
= navEl
.$el
;
8004 var offset
= direction
=== 'forward' ? navEl
.rightOffset
: navEl
.leftOffset
;
8005 if (navEl
.needsOpacityTransition
) {
8006 $el
[0].style
.opacity
= easeProgress
;
8008 if (navEl
.isSliding
) {
8009 $el
.transform(("translate3d(" + (offset
* (1 - easeProgress
)) + "px,0,0)"));
8011 if (navEl
.hasIcon
) {
8012 if (direction
=== 'forward') {
8013 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
- navbarWidth
) * (1 - easeProgress
)) + "px,0,0)"));
8015 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
+ (navbarWidth
/ 5)) * (1 - easeProgress
)) + "px,0,0)"));
8019 oldNavEls
.forEach(function (navEl
) {
8020 var $el
= navEl
.$el
;
8021 var offset
= direction
=== 'forward' ? navEl
.leftOffset
: navEl
.rightOffset
;
8022 if (navEl
.needsOpacityTransition
) {
8023 $el
[0].style
.opacity
= (1 - easeProgress
);
8025 if (navEl
.isSliding
) {
8026 $el
.transform(("translate3d(" + (offset
* (easeProgress
)) + "px,0,0)"));
8028 if (navEl
.hasIcon
) {
8029 if (direction
=== 'forward') {
8030 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
+ (navbarWidth
/ 5)) * (easeProgress
)) + "px,0,0)"));
8032 navEl
.$iconEl
.transform(("translate3d(" + ((-offset
- navbarWidth
) * (easeProgress
)) + "px,0,0)"));
8037 } else if (direction
=== 'forward') {
8038 newPage
.transform(("translate3d(0, " + ((1 - easeProgress
) * 56) + "px,0)"));
8039 newPage
.css('opacity', easeProgress
);
8041 oldPage
.transform(("translate3d(0, " + (easeProgress
* 56) + "px,0)"));
8042 oldPage
.css('opacity', 1 - easeProgress
);
8049 Utils
.requestAnimationFrame(render
);
8052 router
.$el
.addClass(routerTransitionClass
);
8054 Utils
.requestAnimationFrame(render
);
8057 Router
.prototype.animate
= function animate () {
8058 var args
= [], len
= arguments
.length
;
8059 while ( len
-- ) args
[ len
] = arguments
[ len
];
8061 // Args: oldPage, newPage, oldNavbarInner, newNavbarInner, direction, callback
8063 if (router
.params
.animateCustom
) {
8064 router
.params
.animateCustom
.apply(router
, args
);
8065 } else if (router
.params
.animateWithJS
) {
8066 router
.animateWithJS
.apply(router
, args
);
8068 router
.animateWithCSS
.apply(router
, args
);
8072 Router
.prototype.removeModal
= function removeModal (modalEl
) {
8074 router
.removeEl(modalEl
);
8076 // eslint-disable-next-line
8077 Router
.prototype.removeTabContent
= function removeTabContent (tabEl
) {
8078 var $tabEl
= $(tabEl
);
8082 Router
.prototype.removeNavbar
= function removeNavbar (el
) {
8084 router
.removeEl(el
);
8087 Router
.prototype.removePage
= function removePage (el
) {
8089 var f7Page
= $el
&& $el
[0] && $el
[0].f7Page
;
8091 if (f7Page
&& f7Page
.route
&& f7Page
.route
.route
&& f7Page
.route
.route
.keepAlive
) {
8095 router
.removeEl(el
);
8098 Router
.prototype.removeEl
= function removeEl (el
) {
8099 if (!el
) { return; }
8102 if ($el
.length
=== 0) { return; }
8103 $el
.find('.tab').each(function (tabIndex
, tabEl
) {
8104 $(tabEl
).children().each(function (index
, tabChild
) {
8105 if (tabChild
.f7Component
) {
8106 $(tabChild
).trigger('tab:beforeremove');
8107 tabChild
.f7Component
.$destroy();
8111 if ($el
[0].f7Component
&& $el
[0].f7Component
.$destroy
) {
8112 $el
[0].f7Component
.$destroy();
8114 if (!router
.params
.removeElements
) {
8117 if (router
.params
.removeElementsWithTimeout
) {
8118 setTimeout(function () {
8120 }, router
.params
.removeElementsTimeout
);
8126 Router
.prototype.getPageEl
= function getPageEl (content
) {
8128 if (typeof content
=== 'string') {
8129 router
.tempDom
.innerHTML
= content
;
8131 if ($(content
).hasClass('page')) {
8134 router
.tempDom
.innerHTML
= '';
8135 $(router
.tempDom
).append(content
);
8138 return router
.findElement('.page', router
.tempDom
);
8141 Router
.prototype.findElement
= function findElement (stringSelector
, container
, notStacked
) {
8143 var view
= router
.view
;
8144 var app
= router
.app
;
8147 var modalsSelector
= '.popup, .dialog, .popover, .actions-modal, .sheet-modal, .login-screen, .page';
8149 var $container
= $(container
);
8150 var selector
= stringSelector
;
8151 if (notStacked
) { selector
+= ':not(.stacked)'; }
8153 var found
= $container
8155 .filter(function (index
, el
) { return $(el
).parents(modalsSelector
).length
=== 0; });
8157 if (found
.length
> 1) {
8158 if (typeof view
.selector
=== 'string') {
8159 // Search in related view
8160 found
= $container
.find(((view
.selector
) + " " + selector
));
8162 if (found
.length
> 1) {
8163 // Search in main view
8164 found
= $container
.find(("." + (app
.params
.viewMainClass
) + " " + selector
));
8167 if (found
.length
=== 1) { return found
; }
8169 // Try to find not stacked
8170 if (!notStacked
) { found
= router
.findElement(selector
, $container
, true); }
8171 if (found
&& found
.length
=== 1) { return found
; }
8172 if (found
&& found
.length
> 1) { return $(found
[0]); }
8176 Router
.prototype.flattenRoutes
= function flattenRoutes (routes
) {
8178 if ( routes
=== void 0 ) routes
= this.routes
;
8180 var flattenedRoutes
= [];
8181 routes
.forEach(function (route
) {
8182 var hasTabRoutes
= false;
8183 if ('tabs' in route
&& route
.tabs
) {
8184 var mergedPathsRoutes
= route
.tabs
.map(function (tabRoute
) {
8185 var tRoute
= Utils
.extend({}, route
, {
8186 path
: (((route
.path
) + "/" + (tabRoute
.path
))).replace('///', '/').replace('//', '/'),
8187 parentPath
: route
.path
,
8191 delete tRoute
.routes
;
8194 hasTabRoutes
= true;
8195 flattenedRoutes
= flattenedRoutes
.concat(this$1.flattenRoutes(mergedPathsRoutes
));
8197 if ('routes' in route
) {
8198 var mergedPathsRoutes
$1 = route
.routes
.map(function (childRoute
) {
8199 var cRoute
= Utils
.extend({}, childRoute
);
8200 cRoute
.path
= (((route
.path
) + "/" + (cRoute
.path
))).replace('///', '/').replace('//', '/');
8204 flattenedRoutes
= flattenedRoutes
.concat(this$1.flattenRoutes(mergedPathsRoutes
$1));
8206 flattenedRoutes
= flattenedRoutes
.concat(route
, this$1.flattenRoutes(mergedPathsRoutes
$1));
8209 if (!('routes' in route
) && !('tabs' in route
&& route
.tabs
)) {
8210 flattenedRoutes
.push(route
);
8213 return flattenedRoutes
;
8216 // eslint-disable-next-line
8217 Router
.prototype.parseRouteUrl
= function parseRouteUrl (url
) {
8218 if (!url
) { return {}; }
8219 var query
= Utils
.parseUrlQuery(url
);
8220 var hash
= url
.split('#')[1];
8222 var path
= url
.split('#')[0].split('?')[0];
8232 // eslint-disable-next-line
8233 Router
.prototype.constructRouteUrl
= function constructRouteUrl (route
, ref
) {
8234 if ( ref
=== void 0 ) ref
= {};
8235 var params
= ref
.params
;
8236 var query
= ref
.query
;
8238 var path
= route
.path
;
8239 var toUrl
= pathToRegexp_1
.compile(path
);
8242 url
= toUrl(params
|| {});
8244 throw new Error(("Framework7: error constructing route URL from passed params:\nRoute: " + path
+ "\n" + (error
.toString())));
8248 if (typeof query
=== 'string') { url
+= "?" + query
; }
8249 else { url
+= "?" + (Utils
.serializeObject(query
)); }
8255 Router
.prototype.findTabRoute
= function findTabRoute (tabEl
) {
8257 var $tabEl
= $(tabEl
);
8258 var parentPath
= router
.currentRoute
.route
.parentPath
;
8259 var tabId
= $tabEl
.attr('id');
8260 var flattenedRoutes
= router
.flattenRoutes(router
.routes
);
8262 flattenedRoutes
.forEach(function (route
) {
8264 route
.parentPath
=== parentPath
8266 && route
.tab
.id
=== tabId
8268 foundTabRoute
= route
;
8271 return foundTabRoute
;
8274 Router
.prototype.findRouteByKey
= function findRouteByKey (key
, value
) {
8276 var routes
= router
.routes
;
8277 var flattenedRoutes
= router
.flattenRoutes(routes
);
8280 flattenedRoutes
.forEach(function (route
) {
8281 if (matchingRoute
) { return; }
8282 if (route
[key
] === value
) {
8283 matchingRoute
= route
;
8286 return matchingRoute
;
8289 Router
.prototype.findMatchingRoute
= function findMatchingRoute (url
) {
8290 if (!url
) { return undefined; }
8292 var routes
= router
.routes
;
8293 var flattenedRoutes
= router
.flattenRoutes(routes
);
8294 var ref
= router
.parseRouteUrl(url
);
8295 var path
= ref
.path
;
8296 var query
= ref
.query
;
8297 var hash
= ref
.hash
;
8298 var params
= ref
.params
;
8300 flattenedRoutes
.forEach(function (route
) {
8301 if (matchingRoute
) { return; }
8304 var pathsToMatch
= [route
.path
];
8306 if (typeof route
.alias
=== 'string') { pathsToMatch
.push(route
.alias
); }
8307 else if (Array
.isArray(route
.alias
)) {
8308 route
.alias
.forEach(function (aliasPath
) {
8309 pathsToMatch
.push(aliasPath
);
8315 pathsToMatch
.forEach(function (pathToMatch
) {
8316 if (matched
) { return; }
8317 matched
= pathToRegexp_1(pathToMatch
, keys
).exec(path
);
8321 keys
.forEach(function (keyObj
, index
) {
8322 if (typeof keyObj
.name
=== 'number') { return; }
8323 var paramValue
= matched
[index
+ 1];
8324 params
[keyObj
.name
] = paramValue
;
8328 if (route
.parentPath
) {
8329 parentPath
= path
.split('/').slice(0, route
.parentPath
.split('/').length
- 1).join('/');
8338 parentPath
: parentPath
,
8344 return matchingRoute
;
8347 // eslint-disable-next-line
8348 Router
.prototype.replaceRequestUrlParams
= function replaceRequestUrlParams (url
, options
) {
8349 if ( url
=== void 0 ) url
= '';
8350 if ( options
=== void 0 ) options
= {};
8352 var compiledUrl
= url
;
8353 if (typeof compiledUrl
=== 'string'
8354 && compiledUrl
.indexOf('{{') >= 0
8357 && options
.route
.params
8358 && Object
.keys(options
.route
.params
).length
8360 Object
.keys(options
.route
.params
).forEach(function (paramName
) {
8361 var regExp
= new RegExp(("{{" + paramName
+ "}}"), 'g');
8362 compiledUrl
= compiledUrl
.replace(regExp
, options
.route
.params
[paramName
] || '');
8368 Router
.prototype.removeFromXhrCache
= function removeFromXhrCache (url
) {
8370 var xhrCache
= router
.cache
.xhr
;
8372 for (var i
= 0; i
< xhrCache
.length
; i
+= 1) {
8373 if (xhrCache
[i
].url
=== url
) { index
= i
; }
8375 if (index
!== false) { xhrCache
.splice(index
, 1); }
8378 Router
.prototype.xhrRequest
= function xhrRequest (requestUrl
, options
) {
8380 var params
= router
.params
;
8381 var ignoreCache
= options
.ignoreCache
;
8382 var url
= requestUrl
;
8384 var hasQuery
= url
.indexOf('?') >= 0;
8385 if (params
.passRouteQueryToRequest
8388 && options
.route
.query
8389 && Object
.keys(options
.route
.query
).length
8391 url
+= "" + (hasQuery
? '&' : '?') + (Utils
.serializeObject(options
.route
.query
));
8395 if (params
.passRouteParamsToRequest
8398 && options
.route
.params
8399 && Object
.keys(options
.route
.params
).length
8401 url
+= "" + (hasQuery
? '&' : '?') + (Utils
.serializeObject(options
.route
.params
));
8405 if (url
.indexOf('{{') >= 0) {
8406 url
= router
.replaceRequestUrlParams(url
, options
);
8408 // should we ignore get params or not
8409 if (params
.xhrCacheIgnoreGetParameters
&& url
.indexOf('?') >= 0) {
8410 url
= url
.split('?')[0];
8412 return Utils
.promise(function (resolve
, reject
) {
8413 if (params
.xhrCache
&& !ignoreCache
&& url
.indexOf('nocache') < 0 && params
.xhrCacheIgnore
.indexOf(url
) < 0) {
8414 for (var i
= 0; i
< router
.cache
.xhr
.length
; i
+= 1) {
8415 var cachedUrl
= router
.cache
.xhr
[i
];
8416 if (cachedUrl
.url
=== url
) {
8418 if (Utils
.now() - cachedUrl
.time
< params
.xhrCacheDuration
) {
8420 resolve(cachedUrl
.content
);
8426 router
.xhr
= router
.app
.request({
8429 beforeSend
: function beforeSend(xhr
) {
8430 router
.emit('routerAjaxStart', xhr
, options
);
8432 complete
: function complete(xhr
, status
) {
8433 router
.emit('routerAjaxComplete', xhr
);
8434 if ((status
!== 'error' && status
!== 'timeout' && (xhr
.status
>= 200 && xhr
.status
< 300)) || xhr
.status
=== 0) {
8435 if (params
.xhrCache
&& xhr
.responseText
!== '') {
8436 router
.removeFromXhrCache(url
);
8437 router
.cache
.xhr
.push({
8440 content
: xhr
.responseText
,
8443 router
.emit('routerAjaxSuccess', xhr
, options
);
8444 resolve(xhr
.responseText
);
8446 router
.emit('routerAjaxError', xhr
, options
);
8450 error
: function error(xhr
) {
8451 router
.emit('routerAjaxError', xhr
, options
);
8458 // Remove theme elements
8459 Router
.prototype.removeThemeElements
= function removeThemeElements (el
) {
8461 var theme
= router
.app
.theme
;
8462 $(el
).find(("." + (theme
=== 'md' ? 'ios' : 'md') + "-only, .if-" + (theme
=== 'md' ? 'ios' : 'md'))).remove();
8465 Router
.prototype.templateLoader
= function templateLoader (template
, templateUrl
, options
, resolve
, reject
) {
8467 function compile(t
) {
8471 context
= options
.context
|| {};
8472 if (typeof context
=== 'function') { context
= context
.call(router
); }
8473 else if (typeof context
=== 'string') {
8475 context
= JSON
.parse(context
);
8481 if (typeof t
=== 'function') {
8482 compiledHtml
= t(context
);
8484 compiledHtml
= Template7
.compile(t
)(Utils
.extend({}, context
|| {}, {
8486 $root
: Utils
.extend({}, router
.app
.data
, router
.app
.methods
),
8487 $route
: options
.route
,
8490 ios
: router
.app
.theme
=== 'ios',
8491 md
: router
.app
.theme
=== 'md',
8499 resolve(compiledHtml
, { context
: context
});
8508 .xhrRequest(templateUrl
, options
)
8509 .then(function (templateContent
) {
8510 compile(templateContent
);
8512 .catch(function () {
8520 Router
.prototype.modalTemplateLoader
= function modalTemplateLoader (template
, templateUrl
, options
, resolve
, reject
) {
8522 return router
.templateLoader(template
, templateUrl
, options
, function (html
) {
8527 Router
.prototype.tabTemplateLoader
= function tabTemplateLoader (template
, templateUrl
, options
, resolve
, reject
) {
8529 return router
.templateLoader(template
, templateUrl
, options
, function (html
) {
8534 Router
.prototype.pageTemplateLoader
= function pageTemplateLoader (template
, templateUrl
, options
, resolve
, reject
) {
8536 return router
.templateLoader(template
, templateUrl
, options
, function (html
, newOptions
) {
8537 if ( newOptions
=== void 0 ) newOptions
= {};
8539 resolve(router
.getPageEl(html
), newOptions
);
8543 Router
.prototype.componentLoader
= function componentLoader (component
, componentUrl
, options
, resolve
, reject
) {
8544 if ( options
=== void 0 ) options
= {};
8547 var app
= router
.app
;
8548 var url
= typeof component
=== 'string' ? component
: componentUrl
;
8549 var compiledUrl
= router
.replaceRequestUrlParams(url
, options
);
8550 function compile(componentOptions
) {
8551 var context
= options
.context
|| {};
8552 if (typeof context
=== 'function') { context
= context
.call(router
); }
8553 else if (typeof context
=== 'string') {
8555 context
= JSON
.parse(context
);
8561 var extendContext
= Utils
.merge(
8565 $route
: options
.route
,
8568 ios
: app
.theme
=== 'ios',
8569 md
: app
.theme
=== 'md',
8573 var createdComponent
= app
.component
.create(componentOptions
, extendContext
);
8574 resolve(createdComponent
.el
);
8576 var cachedComponent
;
8578 router
.cache
.components
.forEach(function (cached
) {
8579 if (cached
.url
=== compiledUrl
) { cachedComponent
= cached
.component
; }
8582 if (compiledUrl
&& cachedComponent
) {
8583 compile(cachedComponent
);
8584 } else if (compiledUrl
&& !cachedComponent
) {
8591 .xhrRequest(url
, options
)
8592 .then(function (loadedComponent
) {
8593 var parsedComponent
= app
.component
.parse(loadedComponent
);
8594 router
.cache
.components
.push({
8596 component
: parsedComponent
,
8598 compile(parsedComponent
);
8600 .catch(function (err
) {
8609 Router
.prototype.modalComponentLoader
= function modalComponentLoader (rootEl
, component
, componentUrl
, options
, resolve
, reject
) {
8611 router
.componentLoader(component
, componentUrl
, options
, function (el
) {
8616 Router
.prototype.tabComponentLoader
= function tabComponentLoader (tabEl
, component
, componentUrl
, options
, resolve
, reject
) {
8618 router
.componentLoader(component
, componentUrl
, options
, function (el
) {
8623 Router
.prototype.pageComponentLoader
= function pageComponentLoader (routerEl
, component
, componentUrl
, options
, resolve
, reject
) {
8625 router
.componentLoader(component
, componentUrl
, options
, function (el
, newOptions
) {
8626 if ( newOptions
=== void 0 ) newOptions
= {};
8628 resolve(el
, newOptions
);
8632 Router
.prototype.getPageData
= function getPageData (pageEl
, navbarEl
, from, to
, route
, pageFromEl
) {
8633 if ( route
=== void 0 ) route
= {};
8636 var $pageEl
= $(pageEl
);
8637 var $navbarEl
= $(navbarEl
);
8638 var currentPage
= $pageEl
[0].f7Page
|| {};
8641 if ((from === 'next' && to
=== 'current') || (from === 'current' && to
=== 'previous')) { direction
= 'forward'; }
8642 if ((from === 'current' && to
=== 'next') || (from === 'previous' && to
=== 'current')) { direction
= 'backward'; }
8643 if (currentPage
&& !currentPage
.fromPage
) {
8644 var $pageFromEl
= $(pageFromEl
);
8645 if ($pageFromEl
.length
) {
8646 pageFrom
= $pageFromEl
[0].f7Page
;
8649 pageFrom
= currentPage
.pageFrom
|| pageFrom
;
8650 if (pageFrom
&& pageFrom
.pageFrom
) {
8651 pageFrom
.pageFrom
= null;
8661 $navbarEl
: $navbarEl
,
8662 navbarEl
: $navbarEl
[0],
8663 name
: $pageEl
.attr('data-name'),
8667 direction
: direction
,
8668 route
: currentPage
.route
? currentPage
.route
: route
,
8672 $pageEl
[0].f7Page
= page
;
8677 Router
.prototype.pageCallback
= function pageCallback (callback
, pageEl
, navbarEl
, from, to
, options
, pageFromEl
) {
8678 if ( options
=== void 0 ) options
= {};
8680 if (!pageEl
) { return; }
8682 var $pageEl
= $(pageEl
);
8683 if (!$pageEl
.length
) { return; }
8684 var route
= options
.route
;
8685 var restoreScrollTopOnBack
= router
.params
.restoreScrollTopOnBack
;
8686 var keepAlive
= $pageEl
[0].f7Page
&& $pageEl
[0].f7Page
.route
&& $pageEl
[0].f7Page
.route
.route
&& $pageEl
[0].f7Page
.route
.route
.keepAlive
;
8688 if (callback
=== 'beforeRemove' && keepAlive
) {
8689 callback
= 'beforeUnmount'; // eslint-disable-line
8692 var camelName
= "page" + (callback
[0].toUpperCase() + callback
.slice(1, callback
.length
));
8693 var colonName
= "page:" + (callback
.toLowerCase());
8696 if (callback
=== 'beforeRemove' && $pageEl
[0].f7Page
) {
8697 page
= Utils
.extend($pageEl
[0].f7Page
, { from: from, to
: to
, position
: from });
8699 page
= router
.getPageData(pageEl
, navbarEl
, from, to
, route
, pageFromEl
);
8701 page
.swipeBack
= !!options
.swipeBack
;
8703 var ref
= options
.route
? options
.route
.route
: {};
8704 var on
= ref
.on
; if ( on
=== void 0 ) on
= {};
8705 var once
= ref
.once
; if ( once
=== void 0 ) once
= {};
8707 Utils
.extend(on
, options
.on
);
8710 Utils
.extend(once
, options
.once
);
8713 function attachEvents() {
8714 if ($pageEl
[0].f7RouteEventsAttached
) { return; }
8715 $pageEl
[0].f7RouteEventsAttached
= true;
8716 if (on
&& Object
.keys(on
).length
> 0) {
8717 $pageEl
[0].f7RouteEventsOn
= on
;
8718 Object
.keys(on
).forEach(function (eventName
) {
8719 on
[eventName
] = on
[eventName
].bind(router
);
8720 $pageEl
.on(Utils
.eventNameToColonCase(eventName
), on
[eventName
]);
8723 if (once
&& Object
.keys(once
).length
> 0) {
8724 $pageEl
[0].f7RouteEventsOnce
= once
;
8725 Object
.keys(once
).forEach(function (eventName
) {
8726 once
[eventName
] = once
[eventName
].bind(router
);
8727 $pageEl
.once(Utils
.eventNameToColonCase(eventName
), once
[eventName
]);
8732 function detachEvents() {
8733 if (!$pageEl
[0].f7RouteEventsAttached
) { return; }
8734 if ($pageEl
[0].f7RouteEventsOn
) {
8735 Object
.keys($pageEl
[0].f7RouteEventsOn
).forEach(function (eventName
) {
8736 $pageEl
.off(Utils
.eventNameToColonCase(eventName
), $pageEl
[0].f7RouteEventsOn
[eventName
]);
8739 if ($pageEl
[0].f7RouteEventsOnce
) {
8740 Object
.keys($pageEl
[0].f7RouteEventsOnce
).forEach(function (eventName
) {
8741 $pageEl
.off(Utils
.eventNameToColonCase(eventName
), $pageEl
[0].f7RouteEventsOnce
[eventName
]);
8744 $pageEl
[0].f7RouteEventsAttached
= null;
8745 $pageEl
[0].f7RouteEventsOn
= null;
8746 $pageEl
[0].f7RouteEventsOnce
= null;
8747 delete $pageEl
[0].f7RouteEventsAttached
;
8748 delete $pageEl
[0].f7RouteEventsOn
;
8749 delete $pageEl
[0].f7RouteEventsOnce
;
8752 if (callback
=== 'mounted') {
8755 if (callback
=== 'init') {
8756 if (restoreScrollTopOnBack
&& (from === 'previous' || !from) && to
=== 'current' && router
.scrollHistory
[page
.route
.url
] && !$pageEl
.hasClass('no-restore-scroll')) {
8757 var $pageContent
= $pageEl
.find('.page-content');
8758 if ($pageContent
.length
> 0) {
8759 // eslint-disable-next-line
8760 $pageContent
= $pageContent
.filter(function (pageContentIndex
, pageContentEl
) {
8762 $(pageContentEl
).parents('.tab:not(.tab-active)').length
=== 0
8763 && !$(pageContentEl
).is('.tab:not(.tab-active)')
8767 $pageContent
.scrollTop(router
.scrollHistory
[page
.route
.url
]);
8770 if ($pageEl
[0].f7PageInitialized
) {
8771 $pageEl
.trigger('page:reinit', page
);
8772 router
.emit('pageReinit', page
);
8775 $pageEl
[0].f7PageInitialized
= true;
8777 if (restoreScrollTopOnBack
&& callback
=== 'beforeOut' && from === 'current' && to
=== 'previous') {
8778 // Save scroll position
8779 var $pageContent
$1 = $pageEl
.find('.page-content');
8780 if ($pageContent
$1.length
> 0) {
8781 // eslint-disable-next-line
8782 $pageContent
$1 = $pageContent
$1.filter(function (pageContentIndex
, pageContentEl
) {
8784 $(pageContentEl
).parents('.tab:not(.tab-active)').length
=== 0
8785 && !$(pageContentEl
).is('.tab:not(.tab-active)')
8789 router
.scrollHistory
[page
.route
.url
] = $pageContent
$1.scrollTop();
8791 if (restoreScrollTopOnBack
&& callback
=== 'beforeOut' && from === 'current' && to
=== 'next') {
8792 // Delete scroll position
8793 delete router
.scrollHistory
[page
.route
.url
];
8796 $pageEl
.trigger(colonName
, page
);
8797 router
.emit(camelName
, page
);
8799 if (callback
=== 'beforeRemove' || callback
=== 'beforeUnmount') {
8802 if ($pageEl
[0].f7Page
&& $pageEl
[0].f7Page
.navbarEl
) {
8803 delete $pageEl
[0].f7Page
.navbarEl
.f7Page
;
8805 $pageEl
[0].f7Page
= null;
8810 Router
.prototype.saveHistory
= function saveHistory () {
8812 router
.view
.history
= router
.history
;
8813 if (router
.params
.pushState
) {
8814 win
.localStorage
[("f7router-" + (router
.view
.id
) + "-history")] = JSON
.stringify(router
.history
);
8818 Router
.prototype.restoreHistory
= function restoreHistory () {
8820 if (router
.params
.pushState
&& win
.localStorage
[("f7router-" + (router
.view
.id
) + "-history")]) {
8821 router
.history
= JSON
.parse(win
.localStorage
[("f7router-" + (router
.view
.id
) + "-history")]);
8822 router
.view
.history
= router
.history
;
8826 Router
.prototype.clearHistory
= function clearHistory () {
8828 router
.history
= [];
8829 if (router
.view
) { router
.view
.history
= []; }
8830 router
.saveHistory();
8833 Router
.prototype.updateCurrentUrl
= function updateCurrentUrl (newUrl
) {
8835 appRouterCheck(router
, 'updateCurrentUrl');
8837 if (router
.history
.length
) {
8838 router
.history
[router
.history
.length
- 1] = newUrl
;
8840 router
.history
.push(newUrl
);
8843 // Update current route params
8844 var ref
= router
.parseRouteUrl(newUrl
);
8845 var query
= ref
.query
;
8846 var hash
= ref
.hash
;
8847 var params
= ref
.params
;
8849 var path
= ref
.path
;
8850 if (router
.currentRoute
) {
8851 Utils
.extend(router
.currentRoute
, {
8860 if (router
.params
.pushState
) {
8861 var pushStateRoot
= router
.params
.pushStateRoot
|| '';
8867 pushStateRoot
+ router
.params
.pushStateSeparator
+ newUrl
8872 router
.saveHistory();
8874 router
.emit('routeUrlUpdate', router
.currentRoute
, router
);
8877 Router
.prototype.init
= function init () {
8879 var app
= router
.app
;
8880 var view
= router
.view
;
8885 (view
&& router
.params
.iosSwipeBack
&& app
.theme
=== 'ios')
8886 || (view
&& router
.params
.mdSwipeBack
&& app
.theme
=== 'md')
8892 // Dynamic not separated navbbar
8893 if (router
.dynamicNavbar
&& !router
.separateNavbar
) {
8894 router
.$el
.addClass('router-dynamic-navbar-inside');
8897 var initUrl
= router
.params
.url
;
8898 var documentUrl
= doc
.location
.href
.split(doc
.location
.origin
)[1];
8899 var historyRestored
;
8900 var ref
= router
.params
;
8901 var pushState
= ref
.pushState
;
8902 var pushStateOnLoad
= ref
.pushStateOnLoad
;
8903 var pushStateSeparator
= ref
.pushStateSeparator
;
8904 var pushStateAnimateOnLoad
= ref
.pushStateAnimateOnLoad
;
8905 var ref
$1 = router
.params
;
8906 var pushStateRoot
= ref
$1.pushStateRoot
;
8907 if (win
.cordova
&& pushState
&& !pushStateSeparator
&& !pushStateRoot
&& doc
.location
.pathname
.indexOf('index.html')) {
8908 // eslint-disable-next-line
8909 console
.warn('Framework7: wrong or not complete pushState configuration, trying to guess pushStateRoot');
8910 pushStateRoot
= doc
.location
.pathname
.split('index.html')[0];
8913 if (!pushState
|| !pushStateOnLoad
) {
8915 initUrl
= documentUrl
;
8917 if (doc
.location
.search
&& initUrl
.indexOf('?') < 0) {
8918 initUrl
+= doc
.location
.search
;
8920 if (doc
.location
.hash
&& initUrl
.indexOf('#') < 0) {
8921 initUrl
+= doc
.location
.hash
;
8924 if (pushStateRoot
&& documentUrl
.indexOf(pushStateRoot
) >= 0) {
8925 documentUrl
= documentUrl
.split(pushStateRoot
)[1];
8926 if (documentUrl
=== '') { documentUrl
= '/'; }
8928 if (pushStateSeparator
.length
> 0 && documentUrl
.indexOf(pushStateSeparator
) >= 0) {
8929 initUrl
= documentUrl
.split(pushStateSeparator
)[1];
8931 initUrl
= documentUrl
;
8933 router
.restoreHistory();
8934 if (router
.history
.indexOf(initUrl
) >= 0) {
8935 router
.history
= router
.history
.slice(0, router
.history
.indexOf(initUrl
) + 1);
8936 } else if (router
.params
.url
=== initUrl
) {
8937 router
.history
= [initUrl
];
8938 } else if (History
.state
&& History
.state
[view
.id
] && History
.state
[view
.id
].url
=== router
.history
[router
.history
.length
- 1]) {
8939 initUrl
= router
.history
[router
.history
.length
- 1];
8941 router
.history
= [documentUrl
.split(pushStateSeparator
)[0] || '/', initUrl
];
8943 if (router
.history
.length
> 1) {
8944 historyRestored
= true;
8946 router
.history
= [];
8948 router
.saveHistory();
8951 if (router
.history
.length
> 1) {
8953 currentRoute
= router
.findMatchingRoute(router
.history
[0]);
8954 if (!currentRoute
) {
8955 currentRoute
= Utils
.extend(router
.parseRouteUrl(router
.history
[0]), {
8957 url
: router
.history
[0],
8958 path
: router
.history
[0].split('?')[0],
8964 currentRoute
= router
.findMatchingRoute(initUrl
);
8965 if (!currentRoute
) {
8966 currentRoute
= Utils
.extend(router
.parseRouteUrl(initUrl
), {
8969 path
: initUrl
.split('?')[0],
8975 if (router
.params
.stackPages
) {
8976 router
.$el
.children('.page').each(function (index
, pageEl
) {
8977 var $pageEl
= $(pageEl
);
8978 router
.initialPages
.push($pageEl
[0]);
8979 if (router
.separateNavbar
&& $pageEl
.children('.navbar').length
> 0) {
8980 router
.initialNavbars
.push($pageEl
.children('.navbar').find('.navbar-inner')[0]);
8985 if (router
.$el
.children('.page:not(.stacked)').length
=== 0 && initUrl
) {
8986 // No pages presented in DOM, reload new page
8987 router
.navigate(initUrl
, {
8989 reloadCurrent
: true,
8993 // Init current DOM page
8995 router
.currentRoute
= currentRoute
;
8996 router
.$el
.children('.page:not(.stacked)').each(function (index
, pageEl
) {
8997 var $pageEl
= $(pageEl
);
8999 $pageEl
.addClass('page-current');
9000 if (router
.separateNavbar
) {
9001 $navbarInnerEl
= $pageEl
.children('.navbar').children('.navbar-inner');
9002 if ($navbarInnerEl
.length
> 0) {
9003 if (!router
.$navbarEl
.parents(doc
).length
) {
9004 router
.$el
.prepend(router
.$navbarEl
);
9006 router
.$navbarEl
.append($navbarInnerEl
);
9007 $pageEl
.children('.navbar').remove();
9009 router
.$navbarEl
.addClass('navbar-hidden');
9013 route
: router
.currentRoute
,
9015 if (router
.currentRoute
&& router
.currentRoute
.route
&& router
.currentRoute
.route
.options
) {
9016 Utils
.extend(initOptions
, router
.currentRoute
.route
.options
);
9018 router
.currentPageEl
= $pageEl
[0];
9019 if (router
.dynamicNavbar
&& $navbarInnerEl
.length
) {
9020 router
.currentNavbarEl
= $navbarInnerEl
[0];
9022 router
.removeThemeElements($pageEl
);
9023 if (router
.dynamicNavbar
&& $navbarInnerEl
.length
) {
9024 router
.removeThemeElements($navbarInnerEl
);
9026 if (initOptions
.route
.route
.tab
) {
9028 router
.tabLoad(initOptions
.route
.route
.tab
, Utils
.extend({}, initOptions
));
9030 router
.pageCallback('init', $pageEl
, $navbarInnerEl
, 'current', undefined, initOptions
);
9032 if (historyRestored
) {
9033 router
.navigate(initUrl
, {
9037 animate
: pushStateAnimateOnLoad
,
9039 pageAfterIn
: function pageAfterIn() {
9040 if (router
.history
.length
> 2) {
9041 router
.back({ preload
: true });
9047 if (!historyRestored
&& !hasTabRoute
) {
9048 router
.history
.push(initUrl
);
9049 router
.saveHistory();
9052 if (initUrl
&& pushState
&& pushStateOnLoad
&& (!History
.state
|| !History
.state
[view
.id
])) {
9053 History
.initViewState(view
.id
, {
9057 router
.emit('local::init routerInit', router
);
9060 Router
.prototype.destroy
= function destroy () {
9063 router
.emit('local::destroy routerDestroy', router
);
9065 // Delete props & methods
9066 Object
.keys(router
).forEach(function (routerProp
) {
9067 router
[routerProp
] = null;
9068 delete router
[routerProp
];
9075 }(Framework7Class
));
9078 Router
.prototype.forward
= forward
;
9079 Router
.prototype.load
= load
;
9080 Router
.prototype.navigate
= navigate
;
9081 Router
.prototype.refreshPage
= refreshPage
;
9083 Router
.prototype.tabLoad
= tabLoad
;
9084 Router
.prototype.tabRemove
= tabRemove
;
9086 Router
.prototype.modalLoad
= modalLoad
;
9087 Router
.prototype.modalRemove
= modalRemove
;
9089 Router
.prototype.backward
= backward
;
9090 Router
.prototype.loadBack
= loadBack
;
9091 Router
.prototype.back
= back
;
9092 // Clear previoius pages from the DOM
9093 Router
.prototype.clearPreviousPages
= clearPreviousPages
;
9095 Router
.prototype.clearPreviousHistory
= clearPreviousHistory
;
9109 create
: function create() {
9110 var instance
= this;
9113 if (instance
.params
.router
) {
9114 instance
.router
= new Router(instance
.app
, instance
);
9118 instance
.router
= new Router(instance
);
9123 var View
= /*@__PURE__*/(function (Framework7Class
$$1) {
9124 function View(appInstance
, el
, viewParams
) {
9125 if ( viewParams
=== void 0 ) viewParams
= {};
9127 Framework7Class
$$1.call(this, viewParams
, [appInstance
]);
9129 var app
= appInstance
;
9138 // Default View params
9139 view
.params
= Utils
.extend(defaults
, app
.params
.view
, viewParams
);
9142 if (view
.params
.routes
.length
> 0) {
9143 view
.routes
= view
.params
.routes
;
9145 view
.routes
= [].concat(app
.routes
, view
.params
.routesAdd
);
9150 if (typeof el
=== 'string') { selector
= el
; }
9152 // Supposed to be HTMLElement or Dom7
9153 selector
= ($el
.attr('id') ? ("#" + ($el
.attr('id'))) : '') + ($el
.attr('class') ? ("." + ($el
.attr('class').replace(/ /g
, '.').replace('.active', ''))) : '');
9158 if (app
.theme
=== 'ios' && view
.params
.iosDynamicNavbar
&& view
.params
.iosSeparateDynamicNavbar
) {
9159 $navbarEl
= $el
.children('.navbar').eq(0);
9160 if ($navbarEl
.length
=== 0) {
9161 $navbarEl
= $('<div class="navbar"></div>');
9166 Utils
.extend(false, view
, {
9170 name
: view
.params
.name
,
9171 main
: view
.params
.main
|| $el
.hasClass('view-main'),
9172 $navbarEl
: $navbarEl
,
9173 navbarEl
: $navbarEl
? $navbarEl
[0] : undefined,
9180 $el
[0].f7View
= view
;
9186 app
.views
.push(view
);
9188 app
.views
.main
= view
;
9191 app
.views
[view
.name
] = view
;
9195 view
.index
= app
.views
.indexOf(view
);
9200 viewId
= "view_" + (view
.name
);
9201 } else if (view
.main
) {
9202 viewId
= 'view_main';
9204 viewId
= "view_" + (view
.index
);
9209 if (app
.initialized
) {
9212 app
.on('init', function () {
9220 if ( Framework7Class
$$1 ) View
.__proto__
= Framework7Class
$$1;
9221 View
.prototype = Object
.create( Framework7Class
$$1 && Framework7Class
$$1.prototype );
9222 View
.prototype.constructor = View
;
9224 View
.prototype.destroy
= function destroy () {
9228 view
.$el
.trigger('view:beforedestroy', view
);
9229 view
.emit('local::beforeDestroy viewBeforeDestroy', view
);
9232 app
.views
.main
= null;
9233 delete app
.views
.main
;
9234 } else if (view
.name
) {
9235 app
.views
[view
.name
] = null;
9236 delete app
.views
[view
.name
];
9238 view
.$el
[0].f7View
= null;
9239 delete view
.$el
[0].f7View
;
9241 app
.views
.splice(app
.views
.indexOf(view
), 1);
9244 if (view
.params
.router
&& view
.router
) {
9245 view
.router
.destroy();
9248 view
.emit('local::destroy viewDestroy', view
);
9250 // Delete props & methods
9251 Object
.keys(view
).forEach(function (viewProp
) {
9252 view
[viewProp
] = null;
9253 delete view
[viewProp
];
9259 View
.prototype.init
= function init () {
9261 if (view
.params
.router
) {
9263 view
.$el
.trigger('view:init', view
);
9264 view
.emit('local::init viewInit', view
);
9269 }(Framework7Class
));
9274 function initClicks(app
) {
9275 function handleClicks(e
) {
9276 var $clickedEl
= $(e
.target
);
9277 var $clickedLinkEl
= $clickedEl
.closest('a');
9278 var isLink
= $clickedLinkEl
.length
> 0;
9279 var url
= isLink
&& $clickedLinkEl
.attr('href');
9280 var isTabLink
= isLink
&& $clickedLinkEl
.hasClass('tab-link') && ($clickedLinkEl
.attr('data-tab') || (url
&& url
.indexOf('#') === 0));
9282 // Check if link is external
9284 // eslint-disable-next-line
9285 if ($clickedLinkEl
.is(app
.params
.clicks
.externalLinks
) || (url
&& url
.indexOf('javascript:') >= 0)) {
9286 var target
= $clickedLinkEl
.attr('target');
9290 && win
.cordova
.InAppBrowser
9291 && (target
=== '_system' || target
=== '_blank')
9294 win
.cordova
.InAppBrowser
.open(url
, target
);
9301 Object
.keys(app
.modules
).forEach(function (moduleName
) {
9302 var moduleClicks
= app
.modules
[moduleName
].clicks
;
9303 if (!moduleClicks
) { return; }
9304 Object
.keys(moduleClicks
).forEach(function (clickSelector
) {
9305 var matchingClickedElement
= $clickedEl
.closest(clickSelector
).eq(0);
9306 if (matchingClickedElement
.length
> 0) {
9307 moduleClicks
[clickSelector
].call(app
, matchingClickedElement
, matchingClickedElement
.dataset());
9313 var clickedLinkData
= {};
9316 clickedLinkData
= $clickedLinkEl
.dataset();
9318 var validUrl
= url
&& url
.length
> 0 && url
!== '#' && !isTabLink
;
9319 if (validUrl
|| $clickedLinkEl
.hasClass('back')) {
9321 if (clickedLinkData
.view
) {
9322 view
= $(clickedLinkData
.view
)[0].f7View
;
9324 view
= $clickedEl
.parents('.view')[0] && $clickedEl
.parents('.view')[0].f7View
;
9325 if (!$clickedLinkEl
.hasClass('back') && view
&& view
.params
.linksView
) {
9326 if (typeof view
.params
.linksView
=== 'string') { view
= $(view
.params
.linksView
)[0].f7View
; }
9327 else if (view
.params
.linksView
instanceof View
) { view
= view
.params
.linksView
; }
9331 if (app
.views
.main
) { view
= app
.views
.main
; }
9333 if (!view
|| !view
.router
) { return; }
9334 if (clickedLinkData
.context
&& typeof clickedLinkData
.context
=== 'string') {
9336 clickedLinkData
.context
= JSON
.parse(clickedLinkData
.context
);
9338 // something wrong there
9341 if ($clickedLinkEl
[0].f7RouteProps
) {
9342 clickedLinkData
.props
= $clickedLinkEl
[0].f7RouteProps
;
9344 if ($clickedLinkEl
.hasClass('back')) { view
.router
.back(url
, clickedLinkData
); }
9345 else { view
.router
.navigate(url
, clickedLinkData
); }
9349 app
.on('click', handleClicks
);
9351 // Prevent scrolling on overlays
9352 function preventScrolling(e
) {
9355 if (Support
.touch
&& !Device
.android
) {
9356 var activeListener
= Support
.passiveListener
? { passive
: false, capture
: false } : false;
9357 $(doc
).on((app
.params
.touch
.fastClicks
? 'touchstart' : 'touchmove'), '.panel-backdrop, .dialog-backdrop, .preloader-backdrop, .popup-backdrop, .searchbar-backdrop', preventScrolling
, activeListener
);
9360 var ClicksModule
= {
9365 externalLinks
: '.external',
9369 init
: function init() {
9376 var HistoryModule
= {
9382 init
: function init() {
9388 var keyPrefix
= 'f7storage-';
9390 get: function get(key
) {
9391 return Utils
.promise(function (resolve
, reject
) {
9393 var value
= JSON
.parse(win
.localStorage
.getItem(("" + keyPrefix
+ key
)));
9400 set: function set(key
, value
) {
9401 return Utils
.promise(function (resolve
, reject
) {
9403 win
.localStorage
.setItem(("" + keyPrefix
+ key
), JSON
.stringify(value
));
9410 remove
: function remove(key
) {
9411 return Utils
.promise(function (resolve
, reject
) {
9413 win
.localStorage
.removeItem(("" + keyPrefix
+ key
));
9420 clear
: function clear() {
9423 length
: function length() {
9426 keys
: function keys() {
9427 return Utils
.promise(function (resolve
, reject
) {
9429 var keys
= Object
.keys(win
.localStorage
)
9430 .filter(function (keyName
) { return keyName
.indexOf(keyPrefix
) === 0; })
9431 .map(function (keyName
) { return keyName
.replace(keyPrefix
, ''); });
9438 forEach
: function forEach(callback
) {
9439 return Utils
.promise(function (resolve
, reject
) {
9441 Object
.keys(win
.localStorage
)
9442 .filter(function (keyName
) { return keyName
.indexOf(keyPrefix
) === 0; })
9443 .forEach(function (keyName
, index
) {
9444 var key
= keyName
.replace(keyPrefix
, '');
9445 Storage
.get(key
).then(function (value
) {
9446 callback(key
, value
, index
);
9457 var StorageModule
= {
9465 function vnode(sel
, data
, children
, text
, elm
) {
9466 var key
= data
=== undefined ? undefined : data
.key
;
9467 return { sel
: sel
, data
: data
, children
: children
,
9468 text
: text
, elm
: elm
, key
: key
};
9471 var array
= Array
.isArray
;
9472 function primitive(s
) {
9473 return typeof s
=== 'string' || typeof s
=== 'number';
9476 function addNS(data
, children
, sel
) {
9477 data
.ns
= 'http://www.w3.org/2000/svg';
9478 if (sel
!== 'foreignObject' && children
!== undefined) {
9479 for (var i
= 0; i
< children
.length
; ++i
) {
9480 var childData
= children
[i
].data
;
9481 if (childData
!== undefined) {
9482 addNS(childData
, children
[i
].children
, children
[i
].sel
);
9487 function h(sel
, b
, c
) {
9488 var data
= {}, children
, text
, i
;
9489 if (c
!== undefined) {
9494 else if (primitive(c
)) {
9497 else if (c
&& c
.sel
) {
9501 else if (b
!== undefined) {
9505 else if (primitive(b
)) {
9508 else if (b
&& b
.sel
) {
9515 if (array(children
)) {
9516 for (i
= 0; i
< children
.length
; ++i
) {
9517 if (primitive(children
[i
]))
9518 { children
[i
] = vnode(undefined, undefined, undefined, children
[i
], undefined); }
9521 if (sel
[0] === 's' && sel
[1] === 'v' && sel
[2] === 'g' &&
9522 (sel
.length
=== 3 || sel
[3] === '.' || sel
[3] === '#')) {
9523 addNS(data
, children
, sel
);
9525 return vnode(sel
, data
, children
, text
, undefined);
9528 /* eslint no-use-before-define: "off" */
9530 var selfClosing
= 'area base br col command embed hr img input keygen link menuitem meta param source track wbr'.split(' ');
9531 var propsAttrs
= 'hidden checked disabled readonly selected autocomplete autofocus autoplay required multiple value'.split(' ');
9532 var booleanProps
= 'hidden checked disabled readonly selected autocomplete autofocus autoplay required multiple readOnly'.split(' ');
9533 var tempDom
= doc
.createElement('div');
9535 function getHooks(data
, app
, initial
, isRoot
) {
9537 if (!data
|| !data
.attrs
|| !data
.attrs
.class) { return hooks
; }
9538 var classNames
= data
.attrs
.class;
9543 classNames
.split(' ').forEach(function (className
) {
9545 insert
.push
.apply(insert
, app
.getVnodeHooks('insert', className
));
9547 destroy
.push
.apply(destroy
, app
.getVnodeHooks('destroy', className
));
9548 update
.push
.apply(update
, app
.getVnodeHooks('update', className
));
9549 postpatch
.push
.apply(postpatch
, app
.getVnodeHooks('postpatch', className
));
9552 if (isRoot
&& !initial
) {
9553 postpatch
.push(function (oldVnode
, vnode
) {
9554 var vn
= vnode
|| oldVnode
;
9555 if (!vn
) { return; }
9556 if (vn
.data
&& vn
.data
.context
&& vn
.data
.context
.$options
.updated
) {
9557 vn
.data
.context
.$options
.updated();
9561 if (insert
.length
=== 0 && destroy
.length
=== 0 && update
.length
=== 0 && postpatch
.length
=== 0) {
9564 if (insert
.length
) {
9565 hooks
.insert = function (vnode
) {
9566 insert
.forEach(function (f
) { return f(vnode
); });
9569 if (destroy
.length
) {
9570 hooks
.destroy = function (vnode
) {
9571 destroy
.forEach(function (f
) { return f(vnode
); });
9574 if (update
.length
) {
9575 hooks
.update = function (oldVnode
, vnode
) {
9576 update
.forEach(function (f
) { return f(oldVnode
, vnode
); });
9579 if (postpatch
.length
) {
9580 hooks
.postpatch = function (oldVnode
, vnode
) {
9581 postpatch
.forEach(function (f
) { return f(oldVnode
, vnode
); });
9587 function getEventHandler(handlerString
, context
, ref
) {
9588 if ( ref
=== void 0 ) ref
= {};
9589 var stop
= ref
.stop
;
9590 var prevent
= ref
.prevent
;
9591 var once
= ref
.once
;
9597 var customArgs
= [];
9598 var needMethodBind
= true;
9600 if (handlerString
.indexOf('(') < 0) {
9601 methodName
= handlerString
;
9603 methodName
= handlerString
.split('(')[0];
9605 if (methodName
.indexOf('.') >= 0) {
9606 methodName
.split('.').forEach(function (path
, pathIndex
) {
9607 if (pathIndex
=== 0 && path
=== 'this') { return; }
9608 if (pathIndex
=== 0 && path
=== 'window') {
9609 // eslint-disable-next-line
9611 needMethodBind
= false;
9614 if (!method
) { method
= context
; }
9615 if (method
[path
]) { method
= method
[path
]; }
9617 throw new Error(("Framework7: Component doesn't have method \"" + (methodName
.split('.').slice(0, pathIndex
+ 1).join('.')) + "\""));
9621 if (!context
[methodName
]) {
9622 throw new Error(("Framework7: Component doesn't have method \"" + methodName
+ "\""));
9624 method
= context
[methodName
];
9626 if (needMethodBind
) {
9627 method
= method
.bind(context
);
9630 function handler() {
9631 var args
= [], len
= arguments
.length
;
9632 while ( len
-- ) args
[ len
] = arguments
[ len
];
9635 if (once
&& fired
) { return; }
9636 if (stop
) { e
.stopPropagation(); }
9637 if (prevent
) { e
.preventDefault(); }
9640 if (handlerString
.indexOf('(') < 0) {
9643 handlerString
.split('(')[1].split(')')[0].split(',').forEach(function (argument
) {
9644 var arg
= argument
.trim();
9645 // eslint-disable-next-line
9646 if (!isNaN(arg
)) { arg
= parseFloat(arg
); }
9647 else if (arg
=== 'true') { arg
= true; }
9648 else if (arg
=== 'false') { arg
= false; }
9649 else if (arg
=== 'null') { arg
= null; }
9650 else if (arg
=== 'undefined') { arg
= undefined; }
9651 else if (arg
[0] === '"') { arg
= arg
.replace(/"/g, ''); }
9652 else if (arg[0] === '\'') { arg = arg.replace(/'/g, ''); }
9653 else if (arg.indexOf('.') > 0) {
9655 arg.split('.').forEach(function (path) {
9656 if (!deepArg) { deepArg = context; }
9657 deepArg = deepArg[path];
9663 customArgs.push(arg);
9667 method.apply(void 0, customArgs);
9673 function getData(el, context, app, initial, isRoot) {
9677 var attributes = el.attributes;
9678 Array.prototype.forEach.call(attributes, function (attr) {
9679 var attrName = attr.name;
9680 var attrValue = attr.value;
9681 if (propsAttrs.indexOf(attrName) >= 0) {
9683 if (!data.props) { data.props = {}; }
9684 if (attrName === 'readonly') {
9685 attrName = 'readOnly';
9687 if (booleanProps.indexOf(attrName) >= 0) {
9688 // eslint-disable-next-line
9689 data.props[attrName] = attrValue === false ? false : true;
9691 data.props[attrName] = attrValue;
9693 } else if (attrName === 'key') {
9695 data.key = attrValue;
9696 } else if (attrName.indexOf('@') === 0) {
9698 if (!data.on) { data.on = {}; }
9699 var eventName = attrName.substr(1);
9701 var prevent = false;
9703 if (eventName.indexOf('.') >= 0) {
9704 eventName.split('.').forEach(function (eventNamePart, eventNameIndex) {
9705 if (eventNameIndex === 0) { eventName = eventNamePart; }
9707 if (eventNamePart === 'stop') { stop = true; }
9708 if (eventNamePart === 'prevent') { prevent = true; }
9709 if (eventNamePart === 'once') { once = true; }
9713 data.on[eventName] = getEventHandler(attrValue, context, { stop: stop, prevent: prevent, once: once });
9714 } else if (attrName === 'style') {
9716 if (attrValue.indexOf('{') >= 0 && attrValue.indexOf('}') >= 0) {
9718 data.style = JSON.parse(attrValue);
9720 if (!data.attrs) { data.attrs = {}; }
9721 data.attrs.style = attrValue;
9724 if (!data.attrs) { data.attrs = {}; }
9725 data.attrs.style = attrValue;
9728 // Rest of attribures
9729 if (!data.attrs) { data.attrs = {}; }
9730 data.attrs[attrName] = attrValue;
9733 if (attrName === 'id' && !data.key && !isRoot) {
9734 data.key = attrValue;
9738 var hooks = getHooks(data, app, initial, isRoot);
9739 hooks.prepatch = function (oldVnode, vnode) {
9740 if (!oldVnode || !vnode) { return; }
9741 if (oldVnode && oldVnode.data && oldVnode.data.props) {
9742 Object.keys(oldVnode.data.props).forEach(function (key) {
9743 if (booleanProps.indexOf(key) < 0) { return; }
9744 if (!vnode.data) { vnode.data = {}; }
9745 if (!vnode.data.props) { vnode.data.props = {}; }
9746 if (oldVnode.data.props[key] === true && !(key in vnode.data.props)) {
9747 vnode.data.props[key] = false;
9758 function getChildren(el, context, app, initial) {
9760 var nodes = el.childNodes;
9761 for (var i = 0; i < nodes.length; i += 1) {
9762 var childNode = nodes[i];
9763 var child = elementToVNode(childNode, context, app, initial);
9765 children.push(child);
9771 function elementToVNode(el, context, app, initial, isRoot) {
9772 if (el.nodeType === 1) {
9774 var tagName = el.nodeName.toLowerCase();
9777 getData(el, context, app, initial, isRoot),
9778 selfClosing.indexOf(tagName) >= 0 ? [] : getChildren(el, context, app, initial)
9781 if (el.nodeType === 3) {
9783 return el.textContent;
9788 function vdom (html, context, app, initial) {
9789 if ( html === void 0 ) html = '';
9792 tempDom.innerHTML = html.trim();
9796 for (var i = 0; i < tempDom.childNodes.length; i += 1) {
9797 if (!rootEl && tempDom.childNodes[i].nodeType === 1) {
9798 rootEl = tempDom.childNodes[i];
9801 var result = elementToVNode(rootEl, context, app, initial, true);
9804 tempDom.innerHTML = '';
9809 function createElement(tagName) {
9810 return document.createElement(tagName);
9812 function createElementNS(namespaceURI, qualifiedName) {
9813 return document.createElementNS(namespaceURI, qualifiedName);
9815 function createTextNode(text) {
9816 return document.createTextNode(text);
9818 function createComment(text) {
9819 return document.createComment(text);
9821 function insertBefore$1(parentNode, newNode, referenceNode) {
9822 parentNode.insertBefore(newNode, referenceNode);
9824 function removeChild(node, child) {
9825 if (!node) { return; }
9826 node.removeChild(child);
9828 function appendChild(node, child) {
9829 node.appendChild(child);
9831 function parentNode(node) {
9832 return node.parentNode;
9834 function nextSibling(node) {
9835 return node.nextSibling;
9837 function tagName(elm) {
9840 function setTextContent(node, text) {
9841 node.textContent = text;
9843 function getTextContent(node) {
9844 return node.textContent;
9846 function isElement(node) {
9847 return node.nodeType === 1;
9849 function isText(node) {
9850 return node.nodeType === 3;
9852 function isComment(node) {
9853 return node.nodeType === 8;
9856 createElement: createElement,
9857 createElementNS: createElementNS,
9858 createTextNode: createTextNode,
9859 createComment: createComment,
9860 insertBefore: insertBefore$1,
9861 removeChild: removeChild,
9862 appendChild: appendChild,
9863 parentNode: parentNode,
9864 nextSibling: nextSibling,
9866 setTextContent: setTextContent,
9867 getTextContent: getTextContent,
9868 isElement: isElement,
9870 isComment: isComment,
9873 function isUndef(s) { return s === undefined; }
9874 function isDef(s) { return s !== undefined; }
9875 var emptyNode = vnode('', {}, [], undefined, undefined);
9876 function sameVnode(vnode1, vnode2) {
9877 return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;
9879 function isVnode(vnode$$1) {
9880 return vnode$$1.sel !== undefined;
9882 function createKeyToOldIdx(children, beginIdx, endIdx) {
9883 var i, map = {}, key, ch;
9884 for (i = beginIdx; i <= endIdx; ++i) {
9888 if (key !== undefined)
9894 var hooks = ['create', 'update', 'remove', 'destroy', 'pre', 'post'];
9895 function init$1(modules, domApi) {
9897 var api = domApi !== undefined ? domApi : htmlDomApi;
9898 for (i = 0; i < hooks.length; ++i) {
9900 for (j = 0; j < modules.length; ++j) {
9901 var hook = modules[j][hooks[i]];
9902 if (hook !== undefined) {
9903 cbs[hooks[i]].push(hook);
9907 function emptyNodeAt(elm) {
9908 var id = elm.id ? '#' + elm.id : '';
9909 var c = elm.className ? '.' + elm.className.split(' ').join('.') : '';
9910 return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm);
9912 function createRmCb(childElm, listeners) {
9913 return function rmCb() {
9914 if (--listeners === 0) {
9915 var parent_1 = api.parentNode(childElm);
9916 api.removeChild(parent_1, childElm);
9920 function createElm(vnode$$1, insertedVnodeQueue) {
9921 var i, data = vnode$$1.data;
9922 if (data !== undefined) {
9923 if (isDef(i = data.hook) && isDef(i = i.init)) {
9925 data = vnode$$1.data;
9928 var children = vnode$$1.children, sel = vnode$$1.sel;
9930 if (isUndef(vnode$$1.text)) {
9933 vnode$$1.elm = api.createComment(vnode$$1.text);
9935 else if (sel !== undefined) {
9937 var hashIdx = sel.indexOf('#');
9938 var dotIdx = sel.indexOf('.', hashIdx);
9939 var hash = hashIdx > 0 ? hashIdx : sel.length;
9940 var dot = dotIdx > 0 ? dotIdx : sel.length;
9941 var tag = hashIdx !== -1 || dotIdx !== -1 ? sel.slice(0, Math.min(hash, dot)) : sel;
9942 var elm = vnode$$1.elm = isDef(data) && isDef(i = data.ns) ? api.createElementNS(i, tag)
9943 : api.createElement(tag);
9945 { elm.setAttribute('id', sel.slice(hash + 1, dot)); }
9947 { elm.setAttribute('class', sel.slice(dot + 1).replace(/\./g, ' ')); }
9948 for (i = 0; i < cbs.create.length; ++i)
9949 { cbs.create[i](emptyNode, vnode$$1); }
9950 if (array(children)) {
9951 for (i = 0; i < children.length; ++i) {
9952 var ch = children[i];
9954 api.appendChild(elm, createElm(ch, insertedVnodeQueue));
9958 else if (primitive(vnode$$1.text)) {
9959 api.appendChild(elm, api.createTextNode(vnode$$1.text));
9961 i = vnode$$1.data.hook; // Reuse variable
9964 { i.create(emptyNode, vnode$$1); }
9966 { insertedVnodeQueue.push(vnode$$1); }
9970 vnode$$1.elm = api.createTextNode(vnode$$1.text);
9972 return vnode$$1.elm;
9974 function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
9975 for (; startIdx <= endIdx; ++startIdx) {
9976 var ch = vnodes[startIdx];
9978 api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before);
9982 function invokeDestroyHook(vnode$$1) {
9983 var i, j, data = vnode$$1.data;
9984 if (data !== undefined) {
9985 if (isDef(i = data.hook) && isDef(i = i.destroy))
9987 for (i = 0; i < cbs.destroy.length; ++i)
9988 { cbs.destroy[i](vnode$$1); }
9989 if (vnode$$1.children !== undefined) {
9990 for (j = 0; j < vnode$$1.children.length; ++j) {
9991 i = vnode$$1.children[j];
9992 if (i != null && typeof i !== "string
") {
9993 invokeDestroyHook(i);
9999 function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
10000 for (; startIdx <= endIdx; ++startIdx) {
10001 var i_1 = void 0, listeners = void 0, rm = void 0, ch = vnodes[startIdx];
10003 if (isDef(ch.sel)) {
10004 invokeDestroyHook(ch);
10005 listeners = cbs.remove.length + 1;
10006 rm = createRmCb(ch.elm, listeners);
10007 for (i_1 = 0; i_1 < cbs.remove.length; ++i_1)
10008 { cbs.remove[i_1](ch, rm); }
10009 if (isDef(i_1 = ch.data) && isDef(i_1 = i_1.hook) && isDef(i_1 = i_1.remove)) {
10017 api.removeChild(parentElm, ch.elm);
10022 function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {
10023 var oldStartIdx = 0, newStartIdx = 0;
10024 var oldEndIdx = oldCh.length - 1;
10025 var oldStartVnode = oldCh[0];
10026 var oldEndVnode = oldCh[oldEndIdx];
10027 var newEndIdx = newCh.length - 1;
10028 var newStartVnode = newCh[0];
10029 var newEndVnode = newCh[newEndIdx];
10034 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
10035 if (oldStartVnode == null) {
10036 oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
10038 else if (oldEndVnode == null) {
10039 oldEndVnode = oldCh[--oldEndIdx];
10041 else if (newStartVnode == null) {
10042 newStartVnode = newCh[++newStartIdx];
10044 else if (newEndVnode == null) {
10045 newEndVnode = newCh[--newEndIdx];
10047 else if (sameVnode(oldStartVnode, newStartVnode)) {
10048 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);
10049 oldStartVnode = oldCh[++oldStartIdx];
10050 newStartVnode = newCh[++newStartIdx];
10052 else if (sameVnode(oldEndVnode, newEndVnode)) {
10053 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);
10054 oldEndVnode = oldCh[--oldEndIdx];
10055 newEndVnode = newCh[--newEndIdx];
10057 else if (sameVnode(oldStartVnode, newEndVnode)) {
10058 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);
10059 api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));
10060 oldStartVnode = oldCh[++oldStartIdx];
10061 newEndVnode = newCh[--newEndIdx];
10063 else if (sameVnode(oldEndVnode, newStartVnode)) {
10064 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);
10065 api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
10066 oldEndVnode = oldCh[--oldEndIdx];
10067 newStartVnode = newCh[++newStartIdx];
10070 if (oldKeyToIdx === undefined) {
10071 oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
10073 idxInOld = oldKeyToIdx[newStartVnode.key];
10074 if (isUndef(idxInOld)) {
10075 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
10076 newStartVnode = newCh[++newStartIdx];
10079 elmToMove = oldCh[idxInOld];
10080 if (elmToMove.sel !== newStartVnode.sel) {
10081 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
10084 patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
10085 oldCh[idxInOld] = undefined;
10086 api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
10088 newStartVnode = newCh[++newStartIdx];
10092 if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
10093 if (oldStartIdx > oldEndIdx) {
10094 before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
10095 addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
10098 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
10102 function patchVnode(oldVnode, vnode$$1, insertedVnodeQueue) {
10104 if (isDef(i = vnode$$1.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {
10105 i(oldVnode, vnode$$1);
10107 var elm = vnode$$1.elm = oldVnode.elm;
10108 var oldCh = oldVnode.children;
10109 var ch = vnode$$1.children;
10110 if (oldVnode === vnode$$1)
10112 if (vnode$$1.data !== undefined) {
10113 for (i = 0; i < cbs.update.length; ++i)
10114 { cbs.update[i](oldVnode, vnode$$1); }
10115 i = vnode$$1.data.hook;
10116 if (isDef(i) && isDef(i = i.update))
10117 { i(oldVnode, vnode$$1); }
10119 if (isUndef(vnode$$1.text)) {
10120 if (isDef(oldCh) && isDef(ch)) {
10122 { updateChildren(elm, oldCh, ch, insertedVnodeQueue); }
10124 else if (isDef(ch)) {
10125 if (isDef(oldVnode.text))
10126 { api.setTextContent(elm, ''); }
10127 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
10129 else if (isDef(oldCh)) {
10130 removeVnodes(elm, oldCh, 0, oldCh.length - 1);
10132 else if (isDef(oldVnode.text)) {
10133 api.setTextContent(elm, '');
10136 else if (oldVnode.text !== vnode$$1.text) {
10137 api.setTextContent(elm, vnode$$1.text);
10139 if (isDef(hook) && isDef(i = hook.postpatch)) {
10140 i(oldVnode, vnode$$1);
10143 return function patch(oldVnode, vnode$$1) {
10144 var i, elm, parent;
10145 var insertedVnodeQueue = [];
10146 for (i = 0; i < cbs.pre.length; ++i)
10148 if (!isVnode(oldVnode)) {
10149 oldVnode = emptyNodeAt(oldVnode);
10151 if (sameVnode(oldVnode, vnode$$1)) {
10152 patchVnode(oldVnode, vnode$$1, insertedVnodeQueue);
10155 elm = oldVnode.elm;
10156 parent = api.parentNode(elm);
10157 createElm(vnode$$1, insertedVnodeQueue);
10158 if (parent !== null) {
10159 api.insertBefore(parent, vnode$$1.elm, api.nextSibling(elm));
10160 removeVnodes(parent, [oldVnode], 0, 0);
10163 for (i = 0; i < insertedVnodeQueue.length; ++i) {
10164 insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]);
10166 for (i = 0; i < cbs.post.length; ++i)
10172 var xlinkNS = 'http://www.w3.org/1999/xlink';
10173 var xmlNS = 'http://www.w3.org/XML/1998/namespace';
10174 var colonChar = 58;
10176 function updateAttrs(oldVnode, vnode) {
10177 var key, elm = vnode.elm, oldAttrs = oldVnode.data.attrs, attrs = vnode.data.attrs;
10178 if (!oldAttrs && !attrs)
10180 if (oldAttrs === attrs)
10182 oldAttrs = oldAttrs || {};
10183 attrs = attrs || {};
10184 // update modified attributes, add new attributes
10185 for (key in attrs) {
10186 var cur = attrs[key];
10187 var old = oldAttrs[key];
10189 if (cur === true) {
10190 elm.setAttribute(key, "");
10192 else if (cur === false) {
10193 elm.removeAttribute(key);
10196 if (key.charCodeAt(0) !== xChar) {
10197 elm.setAttribute(key, cur);
10199 else if (key.charCodeAt(3) === colonChar) {
10200 // Assume xml namespace
10201 elm.setAttributeNS(xmlNS, key, cur);
10203 else if (key.charCodeAt(5) === colonChar) {
10204 // Assume xlink namespace
10205 elm.setAttributeNS(xlinkNS, key, cur);
10208 elm.setAttribute(key, cur);
10213 // remove removed attributes
10214 // use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value)
10215 // the other option is to remove all attributes with value == undefined
10216 for (key in oldAttrs) {
10217 if (!(key in attrs)) {
10218 elm.removeAttribute(key);
10222 var attributesModule = { create: updateAttrs, update: updateAttrs };
10224 function updateProps(oldVnode, vnode) {
10225 var key, cur, old, elm = vnode.elm, oldProps = oldVnode.data.props, props = vnode.data.props;
10226 if (!oldProps && !props)
10228 if (oldProps === props)
10230 oldProps = oldProps || {};
10231 props = props || {};
10232 for (key in oldProps) {
10237 for (key in props) {
10239 old = oldProps[key];
10240 if (old !== cur && (key !== 'value' || elm[key] !== cur)) {
10245 var propsModule = { create: updateProps, update: updateProps };
10247 var raf = (typeof window !== 'undefined' && window.requestAnimationFrame) || setTimeout;
10248 var nextFrame = function (fn) { raf(function () { raf(fn); }); };
10249 function setNextFrame(obj, prop, val) {
10250 nextFrame(function () { obj[prop] = val; });
10252 function updateStyle(oldVnode, vnode) {
10253 var cur, name, elm = vnode.elm, oldStyle = oldVnode.data.style, style = vnode.data.style;
10254 if (!oldStyle && !style)
10256 if (oldStyle === style)
10258 oldStyle = oldStyle || {};
10259 style = style || {};
10260 var oldHasDel = 'delayed' in oldStyle;
10261 for (name in oldStyle) {
10262 if (!style[name]) {
10263 if (name[0] === '-' && name[1] === '-') {
10264 elm.style.removeProperty(name);
10267 elm.style[name] = '';
10271 for (name in style) {
10273 if (name === 'delayed' && style.delayed) {
10274 for (var name2 in style.delayed) {
10275 cur = style.delayed[name2];
10276 if (!oldHasDel || cur !== oldStyle.delayed[name2]) {
10277 setNextFrame(elm.style, name2, cur);
10281 else if (name !== 'remove' && cur !== oldStyle[name]) {
10282 if (name[0] === '-' && name[1] === '-') {
10283 elm.style.setProperty(name, cur);
10286 elm.style[name] = cur;
10291 function applyDestroyStyle(vnode) {
10292 var style, name, elm = vnode.elm, s = vnode.data.style;
10293 if (!s || !(style = s.destroy))
10295 for (name in style) {
10296 elm.style[name] = style[name];
10299 function applyRemoveStyle(vnode, rm) {
10300 var s = vnode.data.style;
10301 if (!s || !s.remove) {
10305 var name, elm = vnode.elm, i = 0, compStyle, style = s.remove, amount = 0, applied = [];
10306 for (name in style) {
10307 applied.push(name);
10308 elm.style[name] = style[name];
10310 compStyle = getComputedStyle(elm);
10311 var props = compStyle['transition-property'].split(', ');
10312 for (; i < props.length; ++i) {
10313 if (applied.indexOf(props[i]) !== -1)
10316 elm.addEventListener('transitionend', function (ev) {
10317 if (ev.target === elm)
10323 var styleModule = {
10324 create: updateStyle,
10325 update: updateStyle,
10326 destroy: applyDestroyStyle,
10327 remove: applyRemoveStyle
10330 function invokeHandler(handler, event, args) {
10331 if (typeof handler === 'function') {
10332 // call function handler
10333 handler.apply(void 0, [ event ].concat( args ));
10336 function handleEvent(event, args, vnode) {
10337 var name = event.type;
10338 var on = vnode.data.on;
10339 // call event handler(s) if exists
10340 if (on && on[name]) {
10341 invokeHandler(on[name], event, args, vnode);
10344 function createListener() {
10345 return function handler(event) {
10346 var args = [], len = arguments.length - 1;
10347 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
10349 handleEvent(event, args, handler.vnode);
10352 function updateEvents(oldVnode, vnode) {
10353 var oldOn = oldVnode.data.on;
10354 var oldListener = oldVnode.listener;
10355 var oldElm = oldVnode.elm;
10356 var on = vnode && vnode.data.on;
10357 var elm = (vnode && vnode.elm);
10358 // optimization for reused immutable handlers
10359 if (oldOn === on) {
10362 // remove existing listeners which no longer used
10363 if (oldOn && oldListener) {
10364 // if element changed or deleted we remove all existing listeners unconditionally
10366 Object.keys(oldOn).forEach(function (name) {
10367 $(oldElm).off(name, oldListener);
10370 Object.keys(oldOn).forEach(function (name) {
10372 $(oldElm).off(name, oldListener);
10377 // add new listeners which has not already attached
10379 // reuse existing listener or create new
10380 var listener = oldVnode.listener || createListener();
10381 vnode.listener = listener;
10382 // update vnode for listener
10383 listener.vnode = vnode;
10384 // if element changed or added we add all needed listeners unconditionally
10386 Object.keys(on).forEach(function (name) {
10387 $(elm).on(name, listener);
10390 Object.keys(on).forEach(function (name) {
10391 if (!oldOn[name]) {
10392 $(elm).on(name, listener);
10399 var eventListenersModule = {
10400 create: updateEvents,
10401 update: updateEvents,
10402 destroy: updateEvents,
10405 /* eslint import/no-named-as-default: off */
10407 var patch = init$1([
10411 eventListenersModule ]);
10413 var Framework7Component = function Framework7Component(app, options, extendContext) {
10414 if ( extendContext === void 0 ) extendContext = {};
10416 var id = Utils.id();
10417 var self = Utils.merge(
10425 $options: Utils.extend({ id: id }, options),
10428 var $options = self.$options;
10430 // Root data and methods
10431 Object.defineProperty(self, '$root', {
10433 configurable: true,
10434 get: function get() {
10435 var root = Utils.merge({}, app.data, app.methods);
10436 if (win && win.Proxy) {
10437 root = new win.Proxy(root, {
10438 set: function set(target, name, val) {
10439 app.data[name] = val;
10441 deleteProperty: function deleteProperty(target, name) {
10442 delete app.data[name];
10443 delete app.methods[name];
10445 has: function has(target, name) {
10446 return (name in app.data || name in app.methods);
10452 set: function set() {},
10456 ('beforeCreate created beforeMount mounted beforeDestroy destroyed updated').split(' ').forEach(function (cycleKey) {
10457 if ($options[cycleKey]) { $options[cycleKey] = $options[cycleKey].bind(self); }
10460 if ($options.data) {
10461 $options.data = $options.data.bind(self);
10463 Utils.extend(self, $options.data());
10465 if ($options.render) { $options.render = $options.render.bind(self); }
10466 if ($options.methods) {
10467 Object.keys($options.methods).forEach(function (methodName) {
10468 self[methodName] = $options.methods[methodName].bind(self);
10474 Object.keys($options.on).forEach(function (eventName) {
10475 $options.on[eventName] = $options.on[eventName].bind(self);
10478 if ($options.once) {
10479 Object.keys($options.once).forEach(function (eventName) {
10480 $options.once[eventName] = $options.once[eventName].bind(self);
10484 // Before create hook
10485 if ($options.beforeCreate) { $options.beforeCreate(); }
10488 var html = self.$render();
10491 if (html && typeof html === 'string') {
10492 html = html.trim();
10493 self.$vnode = vdom(html, self, app, true);
10494 self.el = doc.createElement('div');
10495 patch(self.el, self.$vnode);
10499 self.$el = $(self.el);
10501 // Set styles scope ID
10502 if ($options.style) {
10503 self.$styleEl = doc.createElement('style');
10504 self.$styleEl.innerHTML = $options.style;
10505 if ($options.styleScoped) {
10506 self.el.setAttribute(("data
-f7
-" + ($options.id)), '');
10510 self.$attachEvents();
10512 // Created callback
10513 if ($options.created) { $options.created(); }
10515 // Store component instance
10516 self.el.f7Component = self;
10521 Framework7Component.prototype.$attachEvents = function $attachEvents () {
10523 var $options = self.$options;
10524 var $el = self.$el;
10526 Object.keys($options.on).forEach(function (eventName) {
10527 $el.on(Utils.eventNameToColonCase(eventName), $options.on[eventName]);
10530 if ($options.once) {
10531 Object.keys($options.once).forEach(function (eventName) {
10532 $el.once(Utils.eventNameToColonCase(eventName), $options.once[eventName]);
10537 Framework7Component.prototype.$detachEvents = function $detachEvents () {
10539 var $options = self.$options;
10540 var $el = self.$el;
10542 Object.keys($options.on).forEach(function (eventName) {
10543 $el.off(Utils.eventNameToColonCase(eventName), $options.on[eventName]);
10546 if ($options.once) {
10547 Object.keys($options.once).forEach(function (eventName) {
10548 $el.off(Utils.eventNameToColonCase(eventName), $options.once[eventName]);
10553 Framework7Component.prototype.$render = function $render () {
10555 var $options = self.$options;
10557 if ($options.render) {
10558 html = $options.render();
10559 } else if ($options.template) {
10560 if (typeof $options.template === 'string') {
10562 html = Template7.compile($options.template)(self);
10567 // Supposed to be function
10568 html = $options.template(self);
10574 Framework7Component.prototype.$forceUpdate = function $forceUpdate () {
10576 var html = self.$render();
10579 if (html && typeof html === 'string') {
10580 html = html.trim();
10581 var newVNode = vdom(html, self, self.$app);
10582 self.$vnode = patch(self.$vnode, newVNode);
10586 Framework7Component.prototype.$setState = function $setState (mergeState) {
10588 Utils.merge(self, mergeState);
10589 self.$forceUpdate();
10592 Framework7Component.prototype.$mount = function $mount (mountMethod) {
10594 if (self.$options.beforeMount) { self.$options.beforeMount(); }
10595 if (self.$styleEl) { $('head').append(self.$styleEl); }
10596 if (mountMethod) { mountMethod(self.el); }
10597 if (self.$options.mounted) { self.$options.mounted(); }
10600 Framework7Component.prototype.$destroy = function $destroy () {
10602 if (self.$options.beforeDestroy) { self.$options.beforeDestroy(); }
10603 if (self.$styleEl) { $(self.$styleEl).remove(); }
10604 self.$detachEvents();
10605 if (self.$options.destroyed) { self.$options.destroyed(); }
10606 // Delete component instance
10607 if (self.el && self.el.f7Component) {
10608 self.el.f7Component = null;
10609 delete self.el.f7Component;
10611 // Patch with empty node
10613 self.$vnode = patch(self.$vnode, { sel: self.$vnode.sel, data: {} });
10615 Utils.deleteProps(self);
10618 function parseComponent(componentString) {
10619 var id = Utils.id();
10620 var callbackCreateName = "f7_component_create_callback_
" + id;
10621 var callbackRenderName = "f7_component_render_callback_
" + id;
10625 var hasTemplate = componentString.match(/<template([ ]?)([a-z0-9-]*)>/);
10626 var templateType = hasTemplate[2] || 't7';
10628 template = componentString
10629 .split(/<template[ ]?[a-z0-9-]*>/)
10630 .filter(function (item, index) { return index > 0; })
10631 .join('<template>')
10632 .split('</template>')
10633 .filter(function (item, index, arr) { return index < arr.length - 1; })
10634 .join('</template>')
10635 .replace(/{{#raw}}([ \n]*)<template/g, '{{#raw}}<template')
10636 .replace(/\/template>([ \n]*){{\/raw}}/g, '/template>{{/raw}}')
10637 .replace(/([ \n])<template/g, '$1{{#raw}}<template')
10638 .replace(/\/template>([ \n])/g, '/template>{{/raw}}$1');
10643 var styleScoped = false;
10645 if (componentString.indexOf('<style>') >= 0) {
10646 style = componentString.split('<style>')[1].split('</style>')[0];
10647 } else if (componentString.indexOf('<style scoped>') >= 0) {
10648 styleScoped = true;
10649 style = componentString.split('<style scoped>')[1].split('</style>')[0];
10650 style = style.split('\n').map(function (line) {
10651 var trimmedLine = line.trim();
10652 if (trimmedLine.indexOf('@') === 0) { return line; }
10653 if (line.indexOf('{') >= 0) {
10654 if (line.indexOf('{{this}}') >= 0) {
10655 return line.replace('{{this}}', ("[data
-f7
-" + id + "]"));
10657 return ("[data
-f7
-" + id + "] " + (line.trim()));
10666 if (componentString.indexOf('<script>') >= 0) {
10667 var scripts = componentString.split('<script>');
10668 scriptContent = scripts[scripts.length - 1].split('</script>')[0].trim();
10670 scriptContent = 'return {}';
10672 if (!scriptContent || !scriptContent.trim()) { scriptContent = 'return {}'; }
10674 scriptContent = "window
." + callbackCreateName + " = function () {" + scriptContent + "}";
10676 // Insert Script El
10677 scriptEl = doc.createElement('script');
10678 scriptEl.innerHTML = scriptContent;
10679 $('head').append(scriptEl);
10681 var component = win[callbackCreateName]();
10683 // Remove Script El
10684 $(scriptEl).remove();
10685 win[callbackCreateName] = null;
10686 delete win[callbackCreateName];
10689 if (!component.template && !component.render) {
10690 component.template = template;
10691 component.templateType = templateType;
10693 if (component.template) {
10694 if (component.templateType === 't7') {
10695 component.template = Template7.compile(component.template);
10697 if (component.templateType === 'es') {
10698 var renderContent = "window
." + callbackRenderName + " = function () {\n return function render() {\n return `" + (component.template) + "`;\n }\n }";
10699 scriptEl = doc.createElement('script');
10700 scriptEl.innerHTML = renderContent;
10701 $('head').append(scriptEl);
10703 component.render = win[callbackRenderName]();
10705 // Remove Script El
10706 $(scriptEl).remove();
10707 win[callbackRenderName] = null;
10708 delete win[callbackRenderName];
10714 component.style = style;
10715 component.styleScoped = styleScoped;
10723 var ComponentModule = {
10725 create: function create() {
10728 parse: function parse(componentString) {
10729 return parseComponent(componentString);
10731 create: function create(options, extendContext) {
10732 return new Framework7Component(app, options, extendContext);
10739 hide: function hide() {
10740 $('html').removeClass('with-statusbar');
10741 if (Device.cordova && win.StatusBar) {
10742 win.StatusBar.hide();
10745 show: function show() {
10746 if (Device.cordova && win.StatusBar) {
10747 win.StatusBar.show();
10748 Utils.nextTick(function () {
10749 if (Device.needsStatusbarOverlay()) {
10750 $('html').addClass('with-statusbar');
10755 $('html').addClass('with-statusbar');
10757 onClick: function onClick() {
10760 if ($('.popup.modal-in').length > 0) {
10761 // Check for opened popup
10762 pageContent = $('.popup.modal-in').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
10763 } else if ($('.panel.panel-active').length > 0) {
10764 // Check for opened panel
10765 pageContent = $('.panel.panel-active').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
10766 } else if ($('.views > .view.tab-active').length > 0) {
10767 // View in tab bar app layout
10768 pageContent = $('.views > .view.tab-active').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
10769 } else if ($('.views').length > 0) {
10770 pageContent = $('.views').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
10772 pageContent = app.root.children('.view').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
10775 if (pageContent && pageContent.length > 0) {
10777 if (pageContent.hasClass('tab')) {
10778 pageContent = pageContent.parent('.tabs').children('.page-content.tab-active');
10780 if (pageContent.length > 0) { pageContent.scrollTop(0, 300); }
10783 setTextColor: function setTextColor(color) {
10784 if (Device.cordova && win.StatusBar) {
10785 if (color === 'white') {
10786 win.StatusBar.styleLightContent();
10788 win.StatusBar.styleDefault();
10792 setIosTextColor: function setIosTextColor(color) {
10793 if (!Device.ios) { return; }
10794 Statusbar.setTextColor(color);
10796 setBackgroundColor: function setBackgroundColor(color) {
10797 $('.statusbar').css('background-color', color);
10798 if (Device.cordova && win.StatusBar) {
10799 win.StatusBar.backgroundColorByHexString(color);
10802 isVisible: function isVisible() {
10803 if (Device.cordova && win.StatusBar) {
10804 return win.StatusBar.isVisible;
10808 overlaysWebView: function overlaysWebView(overlays) {
10809 if ( overlays === void 0 ) overlays = true;
10811 if (Device.cordova && win.StatusBar) {
10812 win.StatusBar.overlaysWebView(overlays);
10814 $('html').addClass('with-statusbar');
10816 $('html').removeClass('with-statusbar');
10820 iosOverlaysWebView: function iosOverlaysWebView(overlays) {
10821 if (!Device.ios) { return; }
10822 Statusbar.overlaysWebView(overlays);
10824 checkOverlay: function checkOverlay() {
10825 if (Device.needsStatusbarOverlay()) {
10826 $('html').addClass('with-statusbar');
10828 $('html').removeClass('with-statusbar');
10831 init: function init() {
10833 var params = app.params.statusbar;
10834 if (!params.enabled) { return; }
10836 if (params.overlay === 'auto') {
10837 if (Device.needsStatusbarOverlay()) {
10838 $('html').addClass('with-statusbar');
10840 $('html').removeClass('with-statusbar');
10843 if (Device.ios && (Device.cordova || Device.webView)) {
10844 if (win.orientation === 0) {
10845 app.once('resize', function () {
10846 Statusbar.checkOverlay();
10850 $(doc).on('resume', function () {
10851 Statusbar.checkOverlay();
10854 app.on(Device.ios ? 'orientationchange' : 'orientationchange resize', function () {
10855 Statusbar.checkOverlay();
10858 } else if (params.overlay === true) {
10859 $('html').addClass('with-statusbar');
10860 } else if (params.overlay === false) {
10861 $('html').removeClass('with-statusbar');
10864 if (Device.cordova && win.StatusBar) {
10865 if (params.scrollTopOnClick) {
10866 $(win).on('statusTap', Statusbar.onClick.bind(app));
10869 if (params.iosOverlaysWebView) {
10870 win.StatusBar.overlaysWebView(true);
10872 win.StatusBar.overlaysWebView(false);
10874 if (params.iosTextColor === 'white') {
10875 win.StatusBar.styleLightContent();
10877 win.StatusBar.styleDefault();
10880 if (Device.android) {
10881 if (params.androidOverlaysWebView) {
10882 win.StatusBar.overlaysWebView(true);
10884 win.StatusBar.overlaysWebView(false);
10886 if (params.androidTextColor === 'white') {
10887 win.StatusBar.styleLightContent();
10889 win.StatusBar.styleDefault();
10893 if (params.iosBackgroundColor && Device.ios) {
10894 Statusbar.setBackgroundColor(params.iosBackgroundColor);
10896 if ((params.materialBackgroundColor || params.androidBackgroundColor) && Device.android) {
10897 Statusbar.setBackgroundColor(params.materialBackgroundColor || params.androidBackgroundColor);
10902 var Statusbar$1 = {
10908 scrollTopOnClick: true,
10910 iosOverlaysWebView: true,
10911 iosTextColor: 'black',
10912 iosBackgroundColor: null,
10914 androidOverlaysWebView: false,
10915 androidTextColor: 'black',
10916 androidBackgroundColor: null,
10919 create: function create() {
10921 Utils.extend(app, {
10923 checkOverlay: Statusbar.checkOverlay,
10924 hide: Statusbar.hide,
10925 show: Statusbar.show,
10926 overlaysWebView: Statusbar.overlaysWebView,
10927 setTextColor: Statusbar.setTextColor,
10928 setBackgroundColor: Statusbar.setBackgroundColor,
10929 isVisible: Statusbar.isVisible,
10930 init: Statusbar.init.bind(app),
10932 iosOverlaysWebView: Statusbar.iosOverlaysWebView,
10933 setIosTextColor: Statusbar.iosSetTextColor,
10938 init: function init() {
10940 Statusbar.init.call(app);
10944 '.statusbar': function onStatusbarClick() {
10946 if (!app.params.statusbar.enabled) { return; }
10947 if (!app.params.statusbar.scrollTopOnClick) { return; }
10948 Statusbar.onClick.call(app);
10953 function getCurrentView(app) {
10954 var popoverView = $('.popover.modal-in .view');
10955 var popupView = $('.popup.modal-in .view');
10956 var panelView = $('.panel.panel-active .view');
10957 var appViews = $('.views');
10958 if (appViews.length === 0) { appViews = app.root; }
10959 // Find active view as tab
10960 var appView = appViews.children('.view');
10961 // Propably in tabs or split view
10962 if (appView.length > 1) {
10963 if (appView.hasClass('tab')) {
10965 appView = appViews.children('.view.tab-active');
10968 if (popoverView.length > 0 && popoverView[0].f7View) { return popoverView[0].f7View; }
10969 if (popupView.length > 0 && popupView[0].f7View) { return popupView[0].f7View; }
10970 if (panelView.length > 0 && panelView[0].f7View) { return panelView[0].f7View; }
10971 if (appView.length > 0) {
10972 if (appView.length === 1 && appView[0].f7View) { return appView[0].f7View; }
10973 if (appView.length > 1) {
10974 return app.views.main;
10990 xhrCacheIgnore: [],
10991 xhrCacheIgnoreGetParameters: false,
10992 xhrCacheDuration: 1000 * 60 * 10, // Ten minutes
10993 preloadPreviousPage: true,
10994 allowDuplicateUrls: false,
10995 reloadPages: false,
10996 removeElements: true,
10997 removeElementsWithTimeout: false,
10998 removeElementsTimeout: 0,
10999 restoreScrollTopOnBack: true,
11000 unloadTabContent: true,
11001 passRouteQueryToRequest: true,
11002 passRouteParamsToRequest: false,
11004 iosSwipeBack: true,
11005 iosSwipeBackAnimateShadow: true,
11006 iosSwipeBackAnimateOpacity: true,
11007 iosSwipeBackActiveArea: 30,
11008 iosSwipeBackThreshold: 0,
11009 mdSwipeBack: false,
11010 mdSwipeBackAnimateShadow: true,
11011 mdSwipeBackAnimateOpacity: false,
11012 mdSwipeBackActiveArea: 30,
11013 mdSwipeBackThreshold: 0,
11016 pushStateRoot: undefined,
11017 pushStateAnimate: true,
11018 pushStateAnimateOnLoad: false,
11019 pushStateSeparator: '#!',
11020 pushStateOnLoad: true,
11023 animateWithJS: false,
11024 // iOS Dynamic Navbar
11025 iosDynamicNavbar: true,
11026 iosSeparateDynamicNavbar: true,
11027 // Animate iOS Navbar Back Icon
11028 iosAnimateNavbarBackIcon: true,
11030 iosPageLoadDelay: 0,
11031 materialPageLoadDelay: 0,
11033 routesBeforeEnter: null,
11034 routesBeforeLeave: null,
11040 create: function create() {
11042 Utils.extend(app, {
11043 views: Utils.extend([], {
11044 create: function create(el, params) {
11045 return new View(app, el, params);
11047 get: function get(viewEl) {
11048 var $viewEl = $(viewEl);
11049 if ($viewEl.length && $viewEl[0].f7View) { return $viewEl[0].f7View; }
11054 Object.defineProperty(app.views, 'current', {
11056 configurable: true,
11057 get: function get() {
11058 return getCurrentView(app);
11062 app.view = app.views;
11065 init: function init() {
11067 $('.view-init').each(function (index, viewEl) {
11068 if (viewEl.f7View) { return; }
11069 var viewParams = $(viewEl).dataset();
11070 app.views.create(viewEl, viewParams);
11073 modalOpen: function modalOpen(modal) {
11075 modal.$el.find('.view-init').each(function (index, viewEl) {
11076 if (viewEl.f7View) { return; }
11077 var viewParams = $(viewEl).dataset();
11078 app.views.create(viewEl, viewParams);
11081 modalBeforeDestroy: function modalBeforeDestroy(modal) {
11082 if (!modal || !modal.$el) { return; }
11083 modal.$el.find('.view-init').each(function (index, viewEl) {
11084 var view = viewEl.f7View;
11085 if (!view) { return; }
11093 size: function size(el) {
11095 if (app.theme !== 'ios') { return; }
11097 if ($el.hasClass('navbar')) {
11098 $el = $el.children('.navbar-inner').each(function (index, navbarEl) {
11099 app.navbar.size(navbarEl);
11104 $el.hasClass('stacked')
11105 || $el.parents('.stacked').length > 0
11106 || $el.parents('.tab:not(.tab-active)').length > 0
11107 || $el.parents('.popup:not(.modal-in)').length > 0
11111 var $viewEl = $el.parents('.view').eq(0);
11112 var left = app.rtl ? $el.children('.right') : $el.children('.left');
11113 var right = app.rtl ? $el.children('.left') : $el.children('.right');
11114 var title = $el.children('.title');
11115 var subnavbar = $el.children('.subnavbar');
11116 var noLeft = left.length === 0;
11117 var noRight = right.length === 0;
11118 var leftWidth = noLeft ? 0 : left.outerWidth(true);
11119 var rightWidth = noRight ? 0 : right.outerWidth(true);
11120 var titleWidth = title.outerWidth(true);
11121 var navbarStyles = $el.styles();
11122 var navbarWidth = $el[0].offsetWidth;
11123 var navbarInnerWidth = navbarWidth - parseInt(navbarStyles.paddingLeft, 10) - parseInt(navbarStyles.paddingRight, 10);
11124 var isPrevious = $el.hasClass('navbar-previous');
11125 var sliding = $el.hasClass('sliding');
11129 var separateNavbar;
11130 var separateNavbarRightOffset = 0;
11131 var separateNavbarLeftOffset = 0;
11133 if ($viewEl.length > 0 && $viewEl[0].f7View) {
11134 router = $viewEl[0].f7View.router;
11135 dynamicNavbar = router && router.dynamicNavbar;
11136 separateNavbar = router && router.separateNavbar;
11137 if (!separateNavbar) {
11138 separateNavbarRightOffset = navbarWidth;
11139 separateNavbarLeftOffset = navbarWidth / 5;
11146 currLeft = navbarInnerWidth - titleWidth;
11151 if (!noLeft && !noRight) {
11152 currLeft = ((navbarInnerWidth - rightWidth - titleWidth) + leftWidth) / 2;
11154 var requiredLeft = (navbarInnerWidth - titleWidth) / 2;
11155 if (navbarInnerWidth - leftWidth - rightWidth > titleWidth) {
11156 if (requiredLeft < leftWidth) {
11157 requiredLeft = leftWidth;
11159 if (requiredLeft + titleWidth > navbarInnerWidth - rightWidth) {
11160 requiredLeft = navbarInnerWidth - rightWidth - titleWidth;
11162 diff = requiredLeft - currLeft;
11168 var inverter = app.rtl ? -1 : 1;
11170 if (dynamicNavbar) {
11171 if (title.hasClass('sliding') || (title.length > 0 && sliding)) {
11172 var titleLeftOffset = (-(currLeft + diff) * inverter) + separateNavbarLeftOffset;
11173 var titleRightOffset = ((navbarInnerWidth - currLeft - diff - titleWidth) * inverter) - separateNavbarRightOffset;
11176 if (router && router.params.iosAnimateNavbarBackIcon) {
11177 var activeNavbarBackLink = $el.parent().find('.navbar-current').children('.left.sliding').find('.back .icon ~ span');
11178 if (activeNavbarBackLink.length > 0) {
11179 titleLeftOffset += activeNavbarBackLink[0].offsetLeft;
11183 title[0].f7NavbarLeftOffset = titleLeftOffset;
11184 title[0].f7NavbarRightOffset = titleRightOffset;
11186 if (!noLeft && (left.hasClass('sliding') || sliding)) {
11188 left[0].f7NavbarLeftOffset = (-(navbarInnerWidth - left[0].offsetWidth) / 2) * inverter;
11189 left[0].f7NavbarRightOffset = leftWidth * inverter;
11191 left[0].f7NavbarLeftOffset = -leftWidth + separateNavbarLeftOffset;
11192 left[0].f7NavbarRightOffset = ((navbarInnerWidth - left[0].offsetWidth) / 2) - separateNavbarRightOffset;
11193 if (router && router.params.iosAnimateNavbarBackIcon && left.find('.back .icon').length > 0) {
11194 left[0].f7NavbarRightOffset -= left.find('.back .icon')[0].offsetWidth;
11198 if (!noRight && (right.hasClass('sliding') || sliding)) {
11200 right[0].f7NavbarLeftOffset = -rightWidth * inverter;
11201 right[0].f7NavbarRightOffset = ((navbarInnerWidth - right[0].offsetWidth) / 2) * inverter;
11203 right[0].f7NavbarLeftOffset = (-(navbarInnerWidth - right[0].offsetWidth) / 2) + separateNavbarLeftOffset;
11204 right[0].f7NavbarRightOffset = rightWidth - separateNavbarRightOffset;
11207 if (subnavbar.length && (subnavbar.hasClass('sliding') || sliding)) {
11208 subnavbar[0].f7NavbarLeftOffset = app.rtl ? subnavbar[0].offsetWidth : (-subnavbar[0].offsetWidth + separateNavbarLeftOffset);
11209 subnavbar[0].f7NavbarRightOffset = (-subnavbar[0].f7NavbarLeftOffset - separateNavbarRightOffset) + separateNavbarLeftOffset;
11214 if (app.params.navbar.iosCenterTitle) {
11215 var titleLeft = diff;
11216 if (app.rtl && noLeft && noRight && title.length > 0) { titleLeft = -titleLeft; }
11217 title.css({ left: (titleLeft + "px
") });
11220 hide: function hide(el, animate) {
11221 if ( animate === void 0 ) animate = true;
11224 if ($el.hasClass('navbar-inner')) { $el = $el.parents('.navbar'); }
11225 if (!$el.length) { return; }
11226 if ($el.hasClass('navbar-hidden')) { return; }
11227 var className = "navbar
-hidden
" + (animate ? ' navbar-transitioning' : '');
11228 $el.transitionEnd(function () {
11229 $el.removeClass('navbar-transitioning');
11231 $el.addClass(className);
11233 show: function show(el, animate) {
11234 if ( el === void 0 ) el = '.navbar-hidden';
11235 if ( animate === void 0 ) animate = true;
11238 if ($el.hasClass('navbar-inner')) { $el = $el.parents('.navbar'); }
11239 if (!$el.length) { return; }
11240 if (!$el.hasClass('navbar-hidden')) { return; }
11242 $el.addClass('navbar-transitioning');
11243 $el.transitionEnd(function () {
11244 $el.removeClass('navbar-transitioning');
11247 $el.removeClass('navbar-hidden');
11249 getElByPage: function getElByPage(page) {
11253 if (page.$navbarEl || page.$el) {
11255 $pageEl = page.$el;
11258 if ($pageEl.length > 0) { pageData = $pageEl[0].f7Page; }
11260 if (pageData && pageData.$navbarEl && pageData.$navbarEl.length > 0) {
11261 $navbarEl = pageData.$navbarEl;
11262 } else if ($pageEl) {
11263 $navbarEl = $pageEl.children('.navbar').children('.navbar-inner');
11265 if (!$navbarEl || ($navbarEl && $navbarEl.length === 0)) { return undefined; }
11266 return $navbarEl[0];
11268 getPageByEl: function getPageByEl(navbarInnerEl) {
11269 var $navbarInnerEl = $(navbarInnerEl);
11270 if ($navbarInnerEl.hasClass('navbar')) {
11271 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner');
11272 if ($navbarInnerEl.length > 1) { return undefined; }
11274 if ($navbarInnerEl.parents('.page').length) {
11275 return $navbarInnerEl.parents('.page')[0];
11278 $navbarInnerEl.parents('.view').find('.page').each(function (index, el) {
11279 if (el && el.f7Page && el.f7Page.navbarEl && $navbarInnerEl[0] === el.f7Page.navbarEl) {
11285 initHideNavbarOnScroll: function initHideNavbarOnScroll(pageEl, navbarInnerEl) {
11287 var $pageEl = $(pageEl);
11288 var $navbarEl = $(navbarInnerEl || app.navbar.getElByPage(pageEl)).closest('.navbar');
11290 var previousScrollTop;
11291 var currentScrollTop;
11298 function handleScroll() {
11299 var scrollContent = this;
11300 if ($pageEl.hasClass('page-previous')) { return; }
11301 currentScrollTop = scrollContent.scrollTop;
11302 scrollHeight = scrollContent.scrollHeight;
11303 offsetHeight = scrollContent.offsetHeight;
11304 reachEnd = currentScrollTop + offsetHeight >= scrollHeight;
11305 navbarHidden = $navbarEl.hasClass('navbar-hidden');
11308 if (app.params.navbar.showOnPageScrollEnd) {
11311 } else if (previousScrollTop > currentScrollTop) {
11312 if (app.params.navbar.showOnPageScrollTop || currentScrollTop <= 44) {
11317 } else if (currentScrollTop > 44) {
11323 if (action === 'show' && navbarHidden) {
11324 app.navbar.show($navbarEl);
11325 navbarHidden = false;
11326 } else if (action === 'hide' && !navbarHidden) {
11327 app.navbar.hide($navbarEl);
11328 navbarHidden = true;
11331 previousScrollTop = currentScrollTop;
11333 $pageEl.on('scroll', '.page-content', handleScroll, true);
11334 $pageEl[0].f7ScrollNavbarHandler = handleScroll;
11339 create: function create() {
11341 Utils.extend(app, {
11343 size: Navbar.size.bind(app),
11344 hide: Navbar.hide.bind(app),
11345 show: Navbar.show.bind(app),
11346 getElByPage: Navbar.getElByPage.bind(app),
11347 getPageByEl: Navbar.getPageByEl.bind(app),
11348 initHideNavbarOnScroll: Navbar.initHideNavbarOnScroll.bind(app),
11354 scrollTopOnTitleClick: true,
11355 iosCenterTitle: true,
11356 hideOnPageScroll: false,
11357 showOnPageScrollEnd: true,
11358 showOnPageScrollTop: true,
11362 'panelBreakpoint resize': function onResize() {
11364 if (app.theme !== 'ios') { return; }
11365 $('.navbar').each(function (index, navbarEl) {
11366 app.navbar.size(navbarEl);
11369 pageBeforeRemove: function pageBeforeRemove(page) {
11370 if (page.$el[0].f7ScrollNavbarHandler) {
11371 page.$el.off('scroll', '.page-content', page.$el[0].f7ScrollNavbarHandler, true);
11374 pageBeforeIn: function pageBeforeIn(page) {
11376 if (app.theme !== 'ios') { return; }
11378 var view = page.$el.parents('.view')[0].f7View;
11379 var navbarInnerEl = app.navbar.getElByPage(page);
11380 if (!navbarInnerEl) {
11381 $navbarEl = page.$el.parents('.view').children('.navbar');
11383 $navbarEl = $(navbarInnerEl).parents('.navbar');
11385 if (page.$el.hasClass('no-navbar') || (view.router.dynamicNavbar && !navbarInnerEl)) {
11386 var animate = !!(page.pageFrom && page.router.history.length > 0);
11387 app.navbar.hide($navbarEl, animate);
11389 app.navbar.show($navbarEl);
11392 pageReinit: function pageReinit(page) {
11394 if (app.theme !== 'ios') { return; }
11395 var $navbarEl = $(app.navbar.getElByPage(page));
11396 if (!$navbarEl || $navbarEl.length === 0) { return; }
11397 app.navbar.size($navbarEl);
11399 pageInit: function pageInit(page) {
11401 var $navbarEl = $(app.navbar.getElByPage(page));
11402 if (!$navbarEl || $navbarEl.length === 0) { return; }
11403 if (app.theme === 'ios') {
11404 app.navbar.size($navbarEl);
11407 app.params.navbar.hideOnPageScroll
11408 || page.$el.find('.hide-navbar-on-scroll').length
11409 || page.$el.hasClass('hide-navbar-on-scroll')
11410 || page.$el.find('.hide-bars-on-scroll').length
11411 || page.$el.hasClass('hide-bars-on-scroll')
11414 page.$el.find('.keep-navbar-on-scroll').length
11415 || page.$el.hasClass('keep-navbar-on-scroll')
11416 || page.$el.find('.keep-bars-on-scroll').length
11417 || page.$el.hasClass('keep-bars-on-scroll')
11421 app.navbar.initHideNavbarOnScroll(page.el, $navbarEl[0]);
11424 modalOpen: function modalOpen(modal) {
11426 if (app.theme !== 'ios') { return; }
11427 modal.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
11428 app.navbar.size(navbarEl);
11431 panelOpen: function panelOpen(panel) {
11433 if (app.theme !== 'ios') { return; }
11434 panel.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
11435 app.navbar.size(navbarEl);
11438 panelSwipeOpen: function panelSwipeOpen(panel) {
11440 if (app.theme !== 'ios') { return; }
11441 panel.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
11442 app.navbar.size(navbarEl);
11445 tabShow: function tabShow(tabEl) {
11447 $(tabEl).find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
11448 app.navbar.size(navbarEl);
11453 '.navbar .title': function onTitleClick($clickedEl) {
11455 if (!app.params.navbar.scrollTopOnTitleClick) { return; }
11456 if ($clickedEl.closest('a').length > 0) {
11460 // Find active page
11461 var navbar = $clickedEl.parents('.navbar');
11464 pageContent = navbar.parents('.page-content');
11466 if (pageContent.length === 0) {
11468 if (navbar.parents('.page').length > 0) {
11469 pageContent = navbar.parents('.page').find('.page-content');
11472 if (pageContent.length === 0) {
11473 if (navbar.nextAll('.page-current:not(.stacked)').length > 0) {
11474 pageContent = navbar.nextAll('.page-current:not(.stacked)').find('.page-content');
11478 if (pageContent && pageContent.length > 0) {
11480 if (pageContent.hasClass('tab')) {
11481 pageContent = pageContent.parent('.tabs').children('.page-content.tab-active');
11483 if (pageContent.length > 0) { pageContent.scrollTop(0, 300); }
11489 postpatch: function postpatch(vnode) {
11491 if (app.theme !== 'ios') { return; }
11492 app.navbar.size(vnode.elm);
11499 setHighlight: function setHighlight(tabbarEl) {
11501 if (app.theme !== 'md') { return; }
11503 var $tabbarEl = $(tabbarEl);
11505 if ($tabbarEl.length === 0 || !($tabbarEl.hasClass('tabbar') || $tabbarEl.hasClass('tabbar-labels'))) { return; }
11507 var $highlightEl = $tabbarEl.find('.tab-link-highlight');
11508 var tabLinksCount = $tabbarEl.find('.tab-link').length;
11509 if (tabLinksCount === 0) {
11510 $highlightEl.remove();
11514 if ($highlightEl.length === 0) {
11515 $tabbarEl.children('.toolbar-inner').append('<span class="tab
-link
-highlight
"></span>');
11516 $highlightEl = $tabbarEl.find('.tab-link-highlight');
11517 } else if ($highlightEl.next().length) {
11518 $tabbarEl.children('.toolbar-inner').append($highlightEl);
11521 var $activeLink = $tabbarEl.find('.tab-link-active');
11522 var highlightWidth;
11523 var highlightTranslate;
11525 if ($tabbarEl.hasClass('tabbar-scrollable') && $activeLink && $activeLink[0]) {
11526 highlightWidth = ($activeLink[0].offsetWidth) + "px
";
11527 highlightTranslate = ($activeLink[0].offsetLeft) + "px
";
11529 var activeIndex = $activeLink.index();
11530 highlightWidth = (100 / tabLinksCount) + "%";
11531 highlightTranslate = ((app.rtl ? -activeIndex : activeIndex) * 100) + "%";
11534 Utils.nextFrame(function () {
11536 .css('width', highlightWidth)
11537 .transform(("translate3d(" + highlightTranslate + ",0,0)"));
11540 init: function init(tabbarEl) {
11542 app.toolbar.setHighlight(tabbarEl);
11544 hide: function hide(el, animate) {
11545 if ( animate === void 0 ) animate = true;
11548 if ($el.hasClass('toolbar-hidden')) { return; }
11549 var className = "toolbar
-hidden
" + (animate ? ' toolbar-transitioning' : '');
11550 $el.transitionEnd(function () {
11551 $el.removeClass('toolbar-transitioning');
11553 $el.addClass(className);
11555 show: function show(el, animate) {
11556 if ( animate === void 0 ) animate = true;
11559 if (!$el.hasClass('toolbar-hidden')) { return; }
11561 $el.addClass('toolbar-transitioning');
11562 $el.transitionEnd(function () {
11563 $el.removeClass('toolbar-transitioning');
11566 $el.removeClass('toolbar-hidden');
11568 initHideToolbarOnScroll: function initHideToolbarOnScroll(pageEl) {
11570 var $pageEl = $(pageEl);
11571 var $toolbarEl = $pageEl.parents('.view').children('.toolbar');
11572 if ($toolbarEl.length === 0) {
11573 $toolbarEl = $pageEl.find('.toolbar');
11575 if ($toolbarEl.length === 0) {
11576 $toolbarEl = $pageEl.parents('.views').children('.tabbar, .tabbar-labels');
11578 if ($toolbarEl.length === 0) {
11582 var previousScrollTop;
11583 var currentScrollTop;
11590 function handleScroll() {
11591 var scrollContent = this;
11592 if ($pageEl.hasClass('page-previous')) { return; }
11593 currentScrollTop = scrollContent.scrollTop;
11594 scrollHeight = scrollContent.scrollHeight;
11595 offsetHeight = scrollContent.offsetHeight;
11596 reachEnd = currentScrollTop + offsetHeight >= scrollHeight;
11597 toolbarHidden = $toolbarEl.hasClass('toolbar-hidden');
11600 if (app.params.toolbar.showOnPageScrollEnd) {
11603 } else if (previousScrollTop > currentScrollTop) {
11604 if (app.params.toolbar.showOnPageScrollTop || currentScrollTop <= 44) {
11609 } else if (currentScrollTop > 44) {
11615 if (action === 'show' && toolbarHidden) {
11616 app.toolbar.show($toolbarEl);
11617 toolbarHidden = false;
11618 } else if (action === 'hide' && !toolbarHidden) {
11619 app.toolbar.hide($toolbarEl);
11620 toolbarHidden = true;
11623 previousScrollTop = currentScrollTop;
11625 $pageEl.on('scroll', '.page-content', handleScroll, true);
11626 $pageEl[0].f7ScrollToolbarHandler = handleScroll;
11631 create: function create() {
11633 Utils.extend(app, {
11635 hide: Toolbar.hide.bind(app),
11636 show: Toolbar.show.bind(app),
11637 setHighlight: Toolbar.setHighlight.bind(app),
11638 initHideToolbarOnScroll: Toolbar.initHideToolbarOnScroll.bind(app),
11639 init: Toolbar.init.bind(app),
11645 hideOnPageScroll: false,
11646 showOnPageScrollEnd: true,
11647 showOnPageScrollTop: true,
11651 pageBeforeRemove: function pageBeforeRemove(page) {
11652 if (page.$el[0].f7ScrollToolbarHandler) {
11653 page.$el.off('scroll', '.page-content', page.$el[0].f7ScrollToolbarHandler, true);
11656 pageBeforeIn: function pageBeforeIn(page) {
11658 var $toolbarEl = page.$el.parents('.view').children('.toolbar');
11659 if ($toolbarEl.length === 0) {
11660 $toolbarEl = page.$el.parents('.views').children('.tabbar, .tabbar-labels');
11662 if ($toolbarEl.length === 0) {
11663 $toolbarEl = page.$el.find('.toolbar');
11665 if ($toolbarEl.length === 0) {
11668 if (page.$el.hasClass('no-toolbar')) {
11669 app.toolbar.hide($toolbarEl);
11671 app.toolbar.show($toolbarEl);
11674 pageInit: function pageInit(page) {
11676 page.$el.find('.tabbar, .tabbar-labels').each(function (index, tabbarEl) {
11677 app.toolbar.init(tabbarEl);
11680 app.params.toolbar.hideOnPageScroll
11681 || page.$el.find('.hide-toolbar-on-scroll').length
11682 || page.$el.hasClass('hide-toolbar-on-scroll')
11683 || page.$el.find('.hide-bars-on-scroll').length
11684 || page.$el.hasClass('hide-bars-on-scroll')
11687 page.$el.find('.keep-toolbar-on-scroll').length
11688 || page.$el.hasClass('keep-toolbar-on-scroll')
11689 || page.$el.find('.keep-bars-on-scroll').length
11690 || page.$el.hasClass('keep-bars-on-scroll')
11694 app.toolbar.initHideToolbarOnScroll(page.el);
11697 init: function init() {
11699 app.root.find('.tabbar, .tabbar-labels').each(function (index, tabbarEl) {
11700 app.toolbar.init(tabbarEl);
11709 pageInit: function pageInit(page) {
11710 if (page.$navbarEl && page.$navbarEl.length && page.$navbarEl.find('.subnavbar').length) {
11711 page.$el.addClass('page-with-subnavbar');
11713 if (page.$el.find('.subnavbar').length) {
11714 page.$el.addClass('page-with-subnavbar');
11720 var TouchRipple = function TouchRipple($el, x, y) {
11722 if (!$el) { return undefined; }
11723 var box = $el[0].getBoundingClientRect();
11728 var width = box.width;
11729 var height = box.height;
11730 var diameter = Math.max((Math.pow( ((Math.pow( height, 2 )) + (Math.pow( width, 2 ))), 0.5 )), 48);
11732 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
>"));
11734 $el.prepend(ripple.$rippleWaveEl);
11736 /* eslint no-underscore-dangle: ["error
", { "allow
": ["_clientLeft
"] }] */
11737 // ripple._clientLeft = ripple.$rippleWaveEl[0].clientLeft;
11738 ripple.rippleTransform = "translate3d(" + (-center.x + (width / 2)) + "px
, " + (-center.y + (height / 2)) + "px
, 0) scale(1)";
11740 Utils.nextFrame(function () {
11741 if (!ripple || !ripple.$rippleWaveEl) { return; }
11742 ripple.$rippleWaveEl.transform(ripple.rippleTransform);
11748 TouchRipple.prototype.onRemove = function onRemove () {
11750 if (ripple.$rippleWaveEl) {
11751 ripple.$rippleWaveEl.remove();
11753 Object.keys(ripple).forEach(function (key) {
11754 ripple[key] = null;
11755 delete ripple[key];
11760 TouchRipple.prototype.remove = function remove () {
11762 if (ripple.removing) { return; }
11763 var $rippleWaveEl = this.$rippleWaveEl;
11764 var rippleTransform = this.rippleTransform;
11765 var removeTimeout = Utils.nextTick(function () {
11768 ripple.removing = true;
11770 .addClass('ripple-wave-fill')
11771 .transform(rippleTransform.replace('scale(1)', 'scale(1.01)'))
11772 .transitionEnd(function () {
11773 clearTimeout(removeTimeout);
11774 Utils.nextFrame(function () {
11776 .addClass('ripple-wave-out')
11777 .transform(rippleTransform.replace('scale(1)', 'scale(1.01)'));
11779 removeTimeout = Utils.nextTick(function () {
11783 $rippleWaveEl.transitionEnd(function () {
11784 clearTimeout(removeTimeout);
11791 var TouchRipple$1 = {
11792 name: 'touch-ripple',
11794 TouchRipple: TouchRipple,
11796 create: function create() {
11798 app.touchRipple = {
11799 create: function create() {
11800 var args = [], len = arguments.length;
11801 while ( len-- ) args[ len ] = arguments[ len ];
11803 return new (Function.prototype.bind.apply( TouchRipple, [ null ].concat( args) ));
11809 var openedModals = [];
11810 var dialogsQueue = [];
11811 function clearDialogsQueue() {
11812 if (dialogsQueue.length === 0) { return; }
11813 var dialog = dialogsQueue.shift();
11816 var Modal = /*@__PURE__*/(function (Framework7Class$$1) {
11817 function Modal(app, params) {
11818 Framework7Class$$1.call(this, params, [app]);
11824 // Extend defaults with modules params
11825 modal.useModulesParams(defaults);
11827 modal.params = Utils.extend(defaults, params);
11828 modal.opened = false;
11831 modal.useModules();
11836 if ( Framework7Class$$1 ) Modal.__proto__ = Framework7Class$$1;
11837 Modal.prototype = Object.create( Framework7Class$$1 && Framework7Class$$1.prototype );
11838 Modal.prototype.constructor = Modal;
11840 Modal.prototype.onOpen = function onOpen () {
11842 modal.opened = true;
11843 openedModals.push(modal);
11844 $('html').addClass(("with-modal
-" + (modal.type.toLowerCase())));
11845 modal.$el.trigger(("modal
:open
" + (modal.type.toLowerCase()) + ":open
"), modal);
11846 modal.emit(("local
::open modalOpen
" + (modal.type) + "Open
"), modal);
11849 Modal.prototype.onOpened = function onOpened () {
11851 modal.$el.trigger(("modal
:opened
" + (modal.type.toLowerCase()) + ":opened
"), modal);
11852 modal.emit(("local
::opened modalOpened
" + (modal.type) + "Opened
"), modal);
11855 Modal.prototype.onClose = function onClose () {
11857 modal.opened = false;
11858 if (!modal.type || !modal.$el) { return; }
11859 openedModals.splice(openedModals.indexOf(modal), 1);
11860 $('html').removeClass(("with-modal
-" + (modal.type.toLowerCase())));
11861 modal.$el.trigger(("modal
:close
" + (modal.type.toLowerCase()) + ":close
"), modal);
11862 modal.emit(("local
::close modalClose
" + (modal.type) + "Close
"), modal);
11865 Modal.prototype.onClosed = function onClosed () {
11867 if (!modal.type || !modal.$el) { return; }
11868 modal.$el.removeClass('modal-out');
11870 modal.$el.trigger(("modal
:closed
" + (modal.type.toLowerCase()) + ":closed
"), modal);
11871 modal.emit(("local
::closed modalClosed
" + (modal.type) + "Closed
"), modal);
11874 Modal.prototype.open = function open (animateModal) {
11876 var app = modal.app;
11877 var $el = modal.$el;
11878 var $backdropEl = modal.$backdropEl;
11879 var type = modal.type;
11880 var animate = true;
11881 if (typeof animateModal !== 'undefined') { animate = animateModal; }
11882 else if (typeof modal.params.animate !== 'undefined') {
11883 animate = modal.params.animate;
11886 if (!$el || $el.hasClass('modal-in')) {
11890 if (type === 'dialog' && app.params.modal.queueDialogs) {
11892 if ($('.dialog.modal-in').length > 0) {
11893 pushToQueue = true;
11894 } else if (openedModals.length > 0) {
11895 openedModals.forEach(function (openedModal) {
11896 if (openedModal.type === 'dialog') { pushToQueue = true; }
11900 dialogsQueue.push(modal);
11905 var $modalParentEl = $el.parent();
11906 var wasInDom = $el.parents(doc).length > 0;
11907 if (app.params.modal.moveToRoot && !$modalParentEl.is(app.root)) {
11908 app.root.append($el);
11909 modal.once((type + "Closed
"), function () {
11911 $modalParentEl.append($el);
11920 // Set Dialog offset
11921 if (type === 'dialog') {
11923 marginTop: ((-Math.round($el.outerHeight() / 2)) + "px
"),
11928 /* eslint no-underscore-dangle: ["error
", { "allow
": ["_clientLeft
"] }] */
11929 modal._clientLeft = $el[0].clientLeft;
11932 function transitionEnd() {
11933 if ($el.hasClass('modal-out')) {
11935 } else if ($el.hasClass('modal-in')) {
11941 $backdropEl.removeClass('not-animated');
11942 $backdropEl.addClass('backdrop-in');
11945 .animationEnd(function () {
11949 .transitionEnd(function () {
11953 .removeClass('modal-out not-animated')
11954 .addClass('modal-in');
11958 $backdropEl.addClass('backdrop-in not-animated');
11960 $el.removeClass('modal-out').addClass('modal-in not-animated');
11968 Modal.prototype.close = function close (animateModal) {
11970 var $el = modal.$el;
11971 var $backdropEl = modal.$backdropEl;
11973 var animate = true;
11974 if (typeof animateModal !== 'undefined') { animate = animateModal; }
11975 else if (typeof modal.params.animate !== 'undefined') {
11976 animate = modal.params.animate;
11979 if (!$el || !$el.hasClass('modal-in')) {
11985 var needToHideBackdrop = true;
11986 if (modal.type === 'popup') {
11987 modal.$el.prevAll('.popup.modal-in').each(function (index, popupEl) {
11988 var popupInstance = popupEl.f7Modal;
11989 if (!popupInstance) { return; }
11991 popupInstance.params.closeByBackdropClick
11992 && popupInstance.params.backdrop
11993 && popupInstance.backdropEl === modal.backdropEl
11995 needToHideBackdrop = false;
11999 if (needToHideBackdrop) {
12000 $backdropEl[animate ? 'removeClass' : 'addClass']('not-animated');
12001 $backdropEl.removeClass('backdrop-in');
12006 $el[animate ? 'removeClass' : 'addClass']('not-animated');
12007 function transitionEnd() {
12008 if ($el.hasClass('modal-out')) {
12010 } else if ($el.hasClass('modal-in')) {
12016 .animationEnd(function () {
12020 .transitionEnd(function () {
12024 .removeClass('modal-in')
12025 .addClass('modal-out');
12030 .addClass('not-animated')
12031 .removeClass('modal-in')
12032 .addClass('modal-out');
12038 if (modal.type === 'dialog') {
12039 clearDialogsQueue();
12045 Modal.prototype.destroy = function destroy () {
12047 if (modal.destroyed) { return; }
12048 modal.emit(("local
::beforeDestroy modalBeforeDestroy
" + (modal.type) + "BeforeDestroy
"), modal);
12050 modal.$el.trigger(("modal
:beforedestroy
" + (modal.type.toLowerCase()) + ":beforedestroy
"), modal);
12051 if (modal.$el.length && modal.$el[0].f7Modal) {
12052 delete modal.$el[0].f7Modal;
12055 Utils.deleteProps(modal);
12056 modal.destroyed = true;
12060 }(Framework7Class));
12062 var CustomModal = /*@__PURE__*/(function (Modal$$1) {
12063 function CustomModal(app, params) {
12064 var extendedParams = Utils.extend({
12066 closeByBackdropClick: true,
12070 // Extends with open/close Modal methods;
12071 Modal$$1.call(this, app, extendedParams);
12073 var customModal = this;
12075 customModal.params = extendedParams;
12079 if (!customModal.params.el) {
12080 $el = $(customModal.params.content);
12082 $el = $(customModal.params.el);
12085 if ($el && $el.length > 0 && $el[0].f7Modal) {
12086 return $el[0].f7Modal;
12089 if ($el.length === 0) {
12090 return customModal.destroy();
12093 if (customModal.params.backdrop) {
12094 $backdropEl = app.root.children('.custom-modal-backdrop');
12095 if ($backdropEl.length === 0) {
12096 $backdropEl = $('<div class="custom
-modal
-backdrop
"></div>');
12097 app.root.append($backdropEl);
12101 function handleClick(e) {
12102 if (!customModal || customModal.destroyed) { return; }
12103 if ($backdropEl && e.target === $backdropEl[0]) {
12104 customModal.close();
12108 customModal.on('customModalOpened', function () {
12109 if (customModal.params.closeByBackdropClick && customModal.params.backdrop) {
12110 app.on('click', handleClick);
12113 customModal.on('customModalClose', function () {
12114 if (customModal.params.closeByBackdropClick && customModal.params.backdrop) {
12115 app.off('click', handleClick);
12119 Utils.extend(customModal, {
12123 $backdropEl: $backdropEl,
12124 backdropEl: $backdropEl && $backdropEl[0],
12125 type: 'customModal',
12128 $el[0].f7Modal = customModal;
12130 return customModal;
12133 if ( Modal$$1 ) CustomModal.__proto__ = Modal$$1;
12134 CustomModal.prototype = Object.create( Modal$$1 && Modal$$1.prototype );
12135 CustomModal.prototype.constructor = CustomModal;
12137 return CustomModal;
12144 CustomModal: CustomModal,
12146 create: function create() {
12148 app.customModal = {
12149 create: function create(params) {
12150 return new CustomModal(app, params);
12157 queueDialogs: true,
12163 if (typeof window !== 'undefined') {
12165 if (!window.Template7) { window.Template7 = Template7; }
12168 if (!window.Dom7) { window.Dom7 = $; }
12172 // Install Core Modules & Components