]> git.proxmox.com Git - framework7.git/blob - framework7/js/framework7.js
0f0ade88828c9d99e7755c38a9b583379135406f
[framework7.git] / framework7 / js / framework7.js
1 /**
2 * Framework7 4.0.5
3 * Full featured mobile HTML framework for building iOS & Android apps
4 * http://framework7.io/
5 *
6 * Copyright 2014-2019 Vladimir Kharlampidi
7 *
8 * Released under the MIT License
9 *
10 * Released on: February 14, 2019
11 */
12
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';
18
19 /**
20 * Template7 1.4.1
21 * Mobile-first HTML template engine
22 *
23 * http://www.idangero.us/template7/
24 *
25 * Copyright 2019, Vladimir Kharlampidi
26 * The iDangero.us
27 * http://www.idangero.us/
28 *
29 * Licensed under MIT
30 *
31 * Released on: February 5, 2019
32 */
33
34 var t7ctx;
35 if (typeof window !== 'undefined') {
36 t7ctx = window;
37 } else if (typeof global !== 'undefined') {
38 t7ctx = global;
39 } else {
40 t7ctx = undefined;
41 }
42
43 var Template7Context = t7ctx;
44
45 var Template7Utils = {
46 quoteSingleRexExp: new RegExp('\'', 'g'),
47 quoteDoubleRexExp: new RegExp('"', 'g'),
48 isFunction: function isFunction(func) {
49 return typeof func === 'function';
50 },
51 escape: function escape(string) {
52 if ( string === void 0 ) string = '';
53
54 return string
55 .replace(/&/g, '&')
56 .replace(/</g, '&lt;')
57 .replace(/>/g, '&gt;')
58 .replace(/"/g, '&quot;')
59 .replace(/'/g, '&#039;');
60 },
61 helperToSlices: function helperToSlices(string) {
62 var quoteDoubleRexExp = Template7Utils.quoteDoubleRexExp;
63 var quoteSingleRexExp = Template7Utils.quoteSingleRexExp;
64 var helperParts = string.replace(/[{}#}]/g, '').trim().split(' ');
65 var slices = [];
66 var shiftIndex;
67 var i;
68 var j;
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 ? '"' : '\'';
77 // Plain String
78 if (part.match(blockQuoteRegExp).length === 2) {
79 // One word string
80 slices.push(part);
81 } else {
82 // Find closed Index
83 shiftIndex = 0;
84 for (j = i + 1; j < helperParts.length; j += 1) {
85 part += " " + (helperParts[j]);
86 if (helperParts[j].indexOf(openingQuote) >= 0) {
87 shiftIndex = j;
88 slices.push(part);
89 break;
90 }
91 }
92 if (shiftIndex) { i = shiftIndex; }
93 }
94 } else if (part.indexOf('=') > 0) {
95 // Hash
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 ? '"' : '\'';
102 }
103 if (hashContent.match(blockQuoteRegExp).length !== 2) {
104 shiftIndex = 0;
105 for (j = i + 1; j < helperParts.length; j += 1) {
106 hashContent += " " + (helperParts[j]);
107 if (helperParts[j].indexOf(openingQuote) >= 0) {
108 shiftIndex = j;
109 break;
110 }
111 }
112 if (shiftIndex) { i = shiftIndex; }
113 }
114 var hash = [hashName, hashContent.replace(blockQuoteRegExp, '')];
115 slices.push(hash);
116 } else {
117 // Plain variable
118 slices.push(part);
119 }
120 }
121 return slices;
122 },
123 stringToBlocks: function stringToBlocks(string) {
124 var blocks = [];
125 var i;
126 var j;
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) {
133 blocks.push({
134 type: 'plain',
135 content: block,
136 });
137 } else {
138 if (block.indexOf('{/') >= 0) {
139 continue;
140 }
141 block = block
142 .replace(/{{([#/])*([ ])*/, '{{$1')
143 .replace(/([ ])*}}/, '}}');
144 if (block.indexOf('{#') < 0 && block.indexOf(' ') < 0 && block.indexOf('else') < 0) {
145 // Simple variable
146 blocks.push({
147 type: 'variable',
148 contextName: block.replace(/[{}]/g, ''),
149 });
150 continue;
151 }
152 // Helpers
153 var helperSlices = Template7Utils.helperToSlices(block);
154 var helperName = helperSlices[0];
155 var isPartial = helperName === '>';
156 var helperContext = [];
157 var helperHash = {};
158 for (j = 1; j < helperSlices.length; j += 1) {
159 var slice = helperSlices[j];
160 if (Array.isArray(slice)) {
161 // Hash
162 helperHash[slice[0]] = slice[1] === 'false' ? false : slice[1];
163 } else {
164 helperContext.push(slice);
165 }
166 }
167
168 if (block.indexOf('{#') >= 0) {
169 // Condition/Helper
170 var helperContent = '';
171 var elseContent = '';
172 var toSkip = 0;
173 var shiftIndex = (void 0);
174 var foundClosed = false;
175 var foundElse = false;
176 var depth = 0;
177 for (j = i + 1; j < stringBlocks.length; j += 1) {
178 if (stringBlocks[j].indexOf('{{#') >= 0) {
179 depth += 1;
180 }
181 if (stringBlocks[j].indexOf('{{/') >= 0) {
182 depth -= 1;
183 }
184 if (stringBlocks[j].indexOf(("{{#" + helperName)) >= 0) {
185 helperContent += stringBlocks[j];
186 if (foundElse) { elseContent += stringBlocks[j]; }
187 toSkip += 1;
188 } else if (stringBlocks[j].indexOf(("{{/" + helperName)) >= 0) {
189 if (toSkip > 0) {
190 toSkip -= 1;
191 helperContent += stringBlocks[j];
192 if (foundElse) { elseContent += stringBlocks[j]; }
193 } else {
194 shiftIndex = j;
195 foundClosed = true;
196 break;
197 }
198 } else if (stringBlocks[j].indexOf('else') >= 0 && depth === 0) {
199 foundElse = true;
200 } else {
201 if (!foundElse) { helperContent += stringBlocks[j]; }
202 if (foundElse) { elseContent += stringBlocks[j]; }
203 }
204 }
205 if (foundClosed) {
206 if (shiftIndex) { i = shiftIndex; }
207 if (helperName === 'raw') {
208 blocks.push({
209 type: 'plain',
210 content: helperContent,
211 });
212 } else {
213 blocks.push({
214 type: 'helper',
215 helperName: helperName,
216 contextName: helperContext,
217 content: helperContent,
218 inverseContent: elseContent,
219 hash: helperHash,
220 });
221 }
222 }
223 } else if (block.indexOf(' ') > 0) {
224 if (isPartial) {
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, '')) + "\""; }
229 }
230 }
231 blocks.push({
232 type: 'helper',
233 helperName: helperName,
234 contextName: helperContext,
235 hash: helperHash,
236 });
237 }
238 }
239 }
240 return blocks;
241 },
242 parseJsVariable: function parseJsVariable(expression, replace, object) {
243 return expression.split(/([+ \-*/^()&=|<>!%:?])/g).reduce(function (arr, part) {
244 if (!part) {
245 return arr;
246 }
247 if (part.indexOf(replace) < 0) {
248 arr.push(part);
249 return arr;
250 }
251 if (!object) {
252 arr.push(JSON.stringify(''));
253 return arr;
254 }
255
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; }
261 });
262 }
263 if (typeof variable === 'string') {
264 variable = JSON.stringify(variable);
265 }
266 if (variable === undefined) { variable = 'undefined'; }
267
268 arr.push(variable);
269 return arr;
270 }, []).join('');
271 },
272 parseJsParents: function parseJsParents(expression, parents) {
273 return expression.split(/([+ \-*^()&=|<>!%:?])/g).reduce(function (arr, part) {
274 if (!part) {
275 return arr;
276 }
277
278 if (part.indexOf('../') < 0) {
279 arr.push(part);
280 return arr;
281 }
282
283 if (!parents || parents.length === 0) {
284 arr.push(JSON.stringify(''));
285 return arr;
286 }
287
288 var levelsUp = part.split('../').length - 1;
289 var parentData = levelsUp > parents.length ? parents[parents.length - 1] : parents[levelsUp - 1];
290
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'; }
296 });
297 if (variable === false || variable === true) {
298 arr.push(JSON.stringify(variable));
299 return arr;
300 }
301 if (variable === null || variable === 'undefined') {
302 arr.push(JSON.stringify(''));
303 return arr;
304 }
305 arr.push(JSON.stringify(variable));
306 return arr;
307 }, []).join('');
308 },
309 getCompileVar: function getCompileVar(name, ctx, data) {
310 if ( data === void 0 ) data = 'data_1';
311
312 var variable = ctx;
313 var parts;
314 var levelsUp = 0;
315 var newDepth;
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) {
325 variable = 'root';
326 parts = name.split('@root.')[1].split('.');
327 } else {
328 parts = name.split('.');
329 }
330 for (var i = 0; i < parts.length; i += 1) {
331 var part = parts[i];
332 if (part.indexOf('@') === 0) {
333 var dataLevel = data.split('_')[1];
334 if (levelsUp > 0) {
335 dataLevel = newDepth;
336 }
337 if (i > 0) {
338 variable += "[(data_" + dataLevel + " && data_" + dataLevel + "." + (part.replace('@', '')) + ")]";
339 } else {
340 variable = "(data_" + dataLevel + " && data_" + dataLevel + "." + (part.replace('@', '')) + ")";
341 }
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);
346 } else {
347 variable += "." + part;
348 }
349 }
350 return variable;
351 },
352 getCompiledArguments: function getCompiledArguments(contextArray, ctx, data) {
353 var arr = [];
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]); }
357 else {
358 arr.push(Template7Utils.getCompileVar(contextArray[i], ctx, data));
359 }
360 }
361
362 return arr.join(', ');
363 },
364 };
365
366 /* eslint no-eval: "off" */
367
368 var Template7Helpers = {
369 _partial: function _partial(partialName, options) {
370 var ctx = this;
371 var p = Template7Class.partials[partialName];
372 if (!p || (p && !p.template)) { return ''; }
373 if (!p.compiled) {
374 p.compiled = new Template7Class(p.template).compile();
375 }
376 Object.keys(options.hash).forEach(function (hashName) {
377 ctx[hashName] = options.hash[hashName];
378 });
379 return p.compiled(ctx, options.data, options.root);
380 },
381 escape: function escape(context) {
382 if (typeof context !== 'string') {
383 throw new Error('Template7: Passed context to "escape" helper should be a string');
384 }
385 return Template7Utils.escape(context);
386 },
387 if: function if$1(context, options) {
388 var ctx = context;
389 if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }
390 if (ctx) {
391 return options.fn(this, options.data);
392 }
393
394 return options.inverse(this, options.data);
395 },
396 unless: function unless(context, options) {
397 var ctx = context;
398 if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }
399 if (!ctx) {
400 return options.fn(this, options.data);
401 }
402
403 return options.inverse(this, options.data);
404 },
405 each: function each(context, options) {
406 var ctx = context;
407 var ret = '';
408 var i = 0;
409 if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }
410 if (Array.isArray(ctx)) {
411 if (options.hash.reverse) {
412 ctx = ctx.reverse();
413 }
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 });
416 }
417 if (options.hash.reverse) {
418 ctx = ctx.reverse();
419 }
420 } else {
421 // eslint-disable-next-line
422 for (var key in ctx) {
423 i += 1;
424 ret += options.fn(ctx[key], { key: key });
425 }
426 }
427 if (i > 0) { return ret; }
428 return options.inverse(this);
429 },
430 with: function with$1(context, options) {
431 var ctx = context;
432 if (Template7Utils.isFunction(ctx)) { ctx = context.call(this); }
433 return options.fn(ctx);
434 },
435 join: function join(context, options) {
436 var ctx = context;
437 if (Template7Utils.isFunction(ctx)) { ctx = ctx.call(this); }
438 return ctx.join(options.hash.delimiter || options.hash.delimeter);
439 },
440 js: function js(expression, options) {
441 var data = options.data;
442 var func;
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');
448 execute = execute
449 .replace(re1, JSON.stringify(data[prop]))
450 .replace(re2, JSON.stringify(data[prop]));
451 }
452 });
453 if (options.root && execute.indexOf('@root') >= 0) {
454 execute = Template7Utils.parseJsVariable(execute, '@root', options.root);
455 }
456 if (execute.indexOf('@global') >= 0) {
457 execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global);
458 }
459 if (execute.indexOf('../') >= 0) {
460 execute = Template7Utils.parseJsParents(execute, options.parents);
461 }
462 if (execute.indexOf('return') >= 0) {
463 func = "(function(){" + execute + "})";
464 } else {
465 func = "(function(){return (" + execute + ")})";
466 }
467 return eval(func).call(this);
468 },
469 js_if: function js_if(expression, options) {
470 var data = options.data;
471 var func;
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');
477 execute = execute
478 .replace(re1, JSON.stringify(data[prop]))
479 .replace(re2, JSON.stringify(data[prop]));
480 }
481 });
482 if (options.root && execute.indexOf('@root') >= 0) {
483 execute = Template7Utils.parseJsVariable(execute, '@root', options.root);
484 }
485 if (execute.indexOf('@global') >= 0) {
486 execute = Template7Utils.parseJsVariable(execute, '@global', Template7Context.Template7.global);
487 }
488 if (execute.indexOf('../') >= 0) {
489 execute = Template7Utils.parseJsParents(execute, options.parents);
490 }
491 if (execute.indexOf('return') >= 0) {
492 func = "(function(){" + execute + "})";
493 } else {
494 func = "(function(){return (" + execute + ")})";
495 }
496 var condition = eval(func).call(this);
497 if (condition) {
498 return options.fn(this, options.data);
499 }
500
501 return options.inverse(this, options.data);
502 },
503 };
504 Template7Helpers.js_compare = Template7Helpers.js_if;
505
506 var Template7Options = {};
507 var Template7Partials = {};
508
509 var Template7Class = function Template7Class(template) {
510 var t = this;
511 t.template = template;
512 };
513
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;
518
519 var t = this;
520 if (t.compiled) { return t.compiled; }
521
522 if (typeof template !== 'string') {
523 throw new Error('Template7: Template must be a string');
524 }
525 var stringToBlocks = Template7Utils.stringToBlocks;
526 var getCompileVar = Template7Utils.getCompileVar;
527 var getCompiledArguments = Template7Utils.getCompiledArguments;
528
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 ''; };
534 }
535
536 function getCompileFn(block, newDepth) {
537 if (block.content) { return t.compile(block.content, newDepth); }
538 return function empty() { return ''; };
539 }
540 function getCompileInverse(block, newDepth) {
541 if (block.inverseContent) { return t.compile(block.inverseContent, newDepth); }
542 return function empty() { return ''; };
543 }
544
545 var resultString = '';
546 if (depth === 1) {
547 resultString += "(function (" + ctx + ", " + data + ", root) {\n";
548 } else {
549 resultString += "(function (" + ctx + ", " + data + ") {\n";
550 }
551 if (depth === 1) {
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';
556 }
557 resultString += 'var r = \'\';\n';
558 var i;
559 for (i = 0; i < blocks.length; i += 1) {
560 var block = blocks[i];
561 // Plain block
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, '\\' + '\'')) + "';";
565 continue;
566 }
567 var variable = (void 0);
568 var compiledArguments = (void 0);
569 // Variable block
570 if (block.type === 'variable') {
571 variable = getCompileVar(block.contextName, ctx, data);
572 resultString += "r += c(" + variable + ", " + ctx + ");";
573 }
574 // Helpers block
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;
582 }
583 parents = "[" + parentsString + "]";
584 } else {
585 parents = "[" + ctx + "]";
586 }
587 var dynamicHelper = (void 0);
588 if (block.helperName.indexOf('[') === 0) {
589 block.helperName = getCompileVar(block.helperName.replace(/[[\]]/g, ''), ctx, data);
590 dynamicHelper = true;
591 }
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) + "\""));
597 } else {
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 += '}}';
605 }
606 }
607 }
608 resultString += '\nreturn r;})';
609
610 if (depth === 1) {
611 // eslint-disable-next-line
612 t.compiled = eval(resultString);
613 return t.compiled;
614 }
615 return resultString;
616 };
617 staticAccessors.options.get = function () {
618 return Template7Options;
619 };
620 staticAccessors.partials.get = function () {
621 return Template7Partials;
622 };
623 staticAccessors.helpers.get = function () {
624 return Template7Helpers;
625 };
626
627 Object.defineProperties( Template7Class, staticAccessors );
628
629 function Template7() {
630 var args = [], len = arguments.length;
631 while ( len-- ) args[ len ] = arguments[ len ];
632
633 var template = args[0];
634 var data = args[1];
635 if (args.length === 2) {
636 var instance = new Template7Class(template);
637 var rendered = instance.compile()(data);
638 instance = null;
639 return (rendered);
640 }
641 return new Template7Class(template);
642 }
643 Template7.registerHelper = function registerHelper(name, fn) {
644 Template7Class.helpers[name] = fn;
645 };
646 Template7.unregisterHelper = function unregisterHelper(name) {
647 Template7Class.helpers[name] = undefined;
648 delete Template7Class.helpers[name];
649 };
650 Template7.registerPartial = function registerPartial(name, template) {
651 Template7Class.partials[name] = { template: template };
652 };
653 Template7.unregisterPartial = function unregisterPartial(name) {
654 if (Template7Class.partials[name]) {
655 Template7Class.partials[name] = undefined;
656 delete Template7Class.partials[name];
657 }
658 };
659 Template7.compile = function compile(template, options) {
660 var instance = new Template7Class(template, options);
661 return instance.compile();
662 };
663
664 Template7.options = Template7Class.options;
665 Template7.helpers = Template7Class.helpers;
666 Template7.partials = Template7Class.partials;
667
668 /**
669 * SSR Window 1.0.1
670 * Better handling for window object in SSR environment
671 * https://github.com/nolimits4web/ssr-window
672 *
673 * Copyright 2018, Vladimir Kharlampidi
674 *
675 * Licensed under MIT
676 *
677 * Released on: July 18, 2018
678 */
679 var doc = (typeof document === 'undefined') ? {
680 body: {},
681 addEventListener: function addEventListener() {},
682 removeEventListener: function removeEventListener() {},
683 activeElement: {
684 blur: function blur() {},
685 nodeName: '',
686 },
687 querySelector: function querySelector() {
688 return null;
689 },
690 querySelectorAll: function querySelectorAll() {
691 return [];
692 },
693 getElementById: function getElementById() {
694 return null;
695 },
696 createEvent: function createEvent() {
697 return {
698 initEvent: function initEvent() {},
699 };
700 },
701 createElement: function createElement() {
702 return {
703 children: [],
704 childNodes: [],
705 style: {},
706 setAttribute: function setAttribute() {},
707 getElementsByTagName: function getElementsByTagName() {
708 return [];
709 },
710 };
711 },
712 location: { hash: '' },
713 } : document; // eslint-disable-line
714
715 var win = (typeof window === 'undefined') ? {
716 document: doc,
717 navigator: {
718 userAgent: '',
719 },
720 location: {},
721 history: {},
722 CustomEvent: function CustomEvent() {
723 return this;
724 },
725 addEventListener: function addEventListener() {},
726 removeEventListener: function removeEventListener() {},
727 getComputedStyle: function getComputedStyle() {
728 return {
729 getPropertyValue: function getPropertyValue() {
730 return '';
731 },
732 };
733 },
734 Image: function Image() {},
735 Date: function Date() {},
736 screen: {},
737 setTimeout: function setTimeout() {},
738 clearTimeout: function clearTimeout() {},
739 } : window; // eslint-disable-line
740
741 /**
742 * Dom7 2.1.3
743 * Minimalistic JavaScript library for DOM manipulation, with a jQuery-compatible API
744 * http://framework7.io/docs/dom.html
745 *
746 * Copyright 2019, Vladimir Kharlampidi
747 * The iDangero.us
748 * http://www.idangero.us/
749 *
750 * Licensed under MIT
751 *
752 * Released on: February 11, 2019
753 */
754
755 var Dom7 = function Dom7(arr) {
756 var self = this;
757 // Create array-like object
758 for (var i = 0; i < arr.length; i += 1) {
759 self[i] = arr[i];
760 }
761 self.length = arr.length;
762 // Return collection with methods
763 return this;
764 };
765
766 function $(selector, context) {
767 var arr = [];
768 var i = 0;
769 if (selector && !context) {
770 if (selector instanceof Dom7) {
771 return selector;
772 }
773 }
774 if (selector) {
775 // String
776 if (typeof selector === 'string') {
777 var els;
778 var tempParent;
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]);
791 }
792 } else {
793 if (!context && selector[0] === '#' && !selector.match(/[ .<>:~]/)) {
794 // Pure ID selector
795 els = [doc.getElementById(selector.trim().split('#')[1])];
796 } else {
797 // Other selectors
798 els = (context || doc).querySelectorAll(selector.trim());
799 }
800 for (i = 0; i < els.length; i += 1) {
801 if (els[i]) { arr.push(els[i]); }
802 }
803 }
804 } else if (selector.nodeType || selector === win || selector === doc) {
805 // Node/element
806 arr.push(selector);
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]);
811 }
812 }
813 }
814 return new Dom7(arr);
815 }
816
817 $.fn = Dom7.prototype;
818 $.Class = Dom7;
819 $.Dom7 = Dom7;
820
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]); }
825 }
826 return uniqueArray;
827 }
828 function toCamelCase(string) {
829 return string.toLowerCase().replace(/-(.)/g, function (match, group1) { return group1.toUpperCase(); });
830 }
831
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);
836 }
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);
841 }
842
843 // Classes and attributes
844 function addClass(className) {
845 if (typeof className === 'undefined') {
846 return this;
847 }
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]); }
852 }
853 }
854 return this;
855 }
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]); }
861 }
862 }
863 return this;
864 }
865 function hasClass(className) {
866 if (!this[0]) { return false; }
867 return this[0].classList.contains(className);
868 }
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]); }
874 }
875 }
876 return this;
877 }
878 function attr(attrs, value) {
879 var arguments$1 = arguments;
880
881 if (arguments.length === 1 && typeof attrs === 'string') {
882 // Get attr
883 if (this[0]) { return this[0].getAttribute(attrs); }
884 return undefined;
885 }
886
887 // Set attrs
888 for (var i = 0; i < this.length; i += 1) {
889 if (arguments$1.length === 2) {
890 // String
891 this[i].setAttribute(attrs, value);
892 } else {
893 // Object
894 // eslint-disable-next-line
895 for (var attrName in attrs) {
896 this[i][attrName] = attrs[attrName];
897 this[i].setAttribute(attrName, attrs[attrName]);
898 }
899 }
900 }
901 return this;
902 }
903 // eslint-disable-next-line
904 function removeAttr(attr) {
905 for (var i = 0; i < this.length; i += 1) {
906 this[i].removeAttribute(attr);
907 }
908 return this;
909 }
910 // eslint-disable-next-line
911 function prop(props, value) {
912 var arguments$1 = arguments;
913
914 if (arguments.length === 1 && typeof props === 'string') {
915 // Get prop
916 if (this[0]) { return this[0][props]; }
917 } else {
918 // Set props
919 for (var i = 0; i < this.length; i += 1) {
920 if (arguments$1.length === 2) {
921 // String
922 this[i][props] = value;
923 } else {
924 // Object
925 // eslint-disable-next-line
926 for (var propName in props) {
927 this[i][propName] = props[propName];
928 }
929 }
930 }
931 return this;
932 }
933 }
934 function data(key, value) {
935 var el;
936 if (typeof value === 'undefined') {
937 el = this[0];
938 // Get value
939 if (el) {
940 if (el.dom7ElementDataStorage && (key in el.dom7ElementDataStorage)) {
941 return el.dom7ElementDataStorage[key];
942 }
943
944 var dataKey = el.getAttribute(("data-" + key));
945 if (dataKey) {
946 return dataKey;
947 }
948 return undefined;
949 }
950 return undefined;
951 }
952
953 // Set value
954 for (var i = 0; i < this.length; i += 1) {
955 el = this[i];
956 if (!el.dom7ElementDataStorage) { el.dom7ElementDataStorage = {}; }
957 el.dom7ElementDataStorage[key] = value;
958 }
959 return this;
960 }
961 function removeData(key) {
962 for (var i = 0; i < this.length; i += 1) {
963 var el = this[i];
964 if (el.dom7ElementDataStorage && el.dom7ElementDataStorage[key]) {
965 el.dom7ElementDataStorage[key] = null;
966 delete el.dom7ElementDataStorage[key];
967 }
968 }
969 }
970 function dataset() {
971 var el = this[0];
972 if (!el) { return undefined; }
973 var dataset = {}; // eslint-disable-line
974 if (el.dataset) {
975 // eslint-disable-next-line
976 for (var dataKey in el.dataset) {
977 dataset[dataKey] = el.dataset[dataKey];
978 }
979 } else {
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;
985 }
986 }
987 }
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; }
993 }
994 return dataset;
995 }
996 function val(value) {
997 var dom = this;
998 if (typeof value === 'undefined') {
999 if (dom[0]) {
1000 if (dom[0].multiple && dom[0].nodeName.toLowerCase() === 'select') {
1001 var values = [];
1002 for (var i = 0; i < dom[0].selectedOptions.length; i += 1) {
1003 values.push(dom[0].selectedOptions[i].value);
1004 }
1005 return values;
1006 }
1007 return dom[0].value;
1008 }
1009 return undefined;
1010 }
1011
1012 for (var i$1 = 0; i$1 < dom.length; i$1 += 1) {
1013 var el = dom[i$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;
1017 }
1018 } else {
1019 el.value = value;
1020 }
1021 }
1022 return dom;
1023 }
1024 // Transforms
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;
1031 }
1032 return this;
1033 }
1034 function transition(duration) {
1035 if (typeof duration !== 'string') {
1036 duration = duration + "ms"; // eslint-disable-line
1037 }
1038 for (var i = 0; i < this.length; i += 1) {
1039 var elStyle = this[i].style;
1040 elStyle.webkitTransitionDuration = duration;
1041 elStyle.transitionDuration = duration;
1042 }
1043 return this;
1044 }
1045 // Events
1046 function on() {
1047 var assign;
1048
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;
1058 }
1059 if (!capture) { capture = false; }
1060
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);
1067 }
1068 if ($(target).is(targetSelector)) { listener.apply(target, eventData); }
1069 else {
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); }
1073 }
1074 }
1075 }
1076 function handleEvent(e) {
1077 var eventData = e && e.target ? e.target.dom7EventData || [] : [];
1078 if (eventData.indexOf(e) < 0) {
1079 eventData.unshift(e);
1080 }
1081 listener.apply(this, eventData);
1082 }
1083 var events = eventType.split(' ');
1084 var j;
1085 for (var i = 0; i < this.length; i += 1) {
1086 var el = this[i];
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({
1093 listener: listener,
1094 proxyListener: handleEvent,
1095 });
1096 el.addEventListener(event, handleEvent, capture);
1097 }
1098 } else {
1099 // Live events
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({
1105 listener: listener,
1106 proxyListener: handleLiveEvent,
1107 });
1108 el.addEventListener(event$1, handleLiveEvent, capture);
1109 }
1110 }
1111 }
1112 return this;
1113 }
1114 function off() {
1115 var assign;
1116
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;
1126 }
1127 if (!capture) { capture = false; }
1128
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) {
1133 var el = this[j];
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];
1139 }
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 && handler.listener && handler.listener.dom7proxy && handler.listener.dom7proxy === listener) {
1147 el.removeEventListener(event, handler.proxyListener, capture);
1148 handlers.splice(k, 1);
1149 } else if (!listener) {
1150 el.removeEventListener(event, handler.proxyListener, capture);
1151 handlers.splice(k, 1);
1152 }
1153 }
1154 }
1155 }
1156 }
1157 return this;
1158 }
1159 function once() {
1160 var assign;
1161
1162 var args = [], len = arguments.length;
1163 while ( len-- ) args[ len ] = arguments[ len ];
1164 var dom = this;
1165 var eventName = args[0];
1166 var targetSelector = args[1];
1167 var listener = args[2];
1168 var capture = args[3];
1169 if (typeof args[1] === 'function') {
1170 (assign = args, eventName = assign[0], listener = assign[1], capture = assign[2]);
1171 targetSelector = undefined;
1172 }
1173 function onceHandler() {
1174 var eventArgs = [], len = arguments.length;
1175 while ( len-- ) eventArgs[ len ] = arguments[ len ];
1176
1177 listener.apply(this, eventArgs);
1178 dom.off(eventName, targetSelector, onceHandler, capture);
1179 if (onceHandler.dom7proxy) {
1180 delete onceHandler.dom7proxy;
1181 }
1182 }
1183 onceHandler.dom7proxy = listener;
1184 return dom.on(eventName, targetSelector, onceHandler, capture);
1185 }
1186 function trigger() {
1187 var args = [], len = arguments.length;
1188 while ( len-- ) args[ len ] = arguments[ len ];
1189
1190 var events = args[0].split(' ');
1191 var eventData = args[1];
1192 for (var i = 0; i < events.length; i += 1) {
1193 var event = events[i];
1194 for (var j = 0; j < this.length; j += 1) {
1195 var el = this[j];
1196 var evt = (void 0);
1197 try {
1198 evt = new win.CustomEvent(event, {
1199 detail: eventData,
1200 bubbles: true,
1201 cancelable: true,
1202 });
1203 } catch (e) {
1204 evt = doc.createEvent('Event');
1205 evt.initEvent(event, true, true);
1206 evt.detail = eventData;
1207 }
1208 // eslint-disable-next-line
1209 el.dom7EventData = args.filter(function (data, dataIndex) { return dataIndex > 0; });
1210 el.dispatchEvent(evt);
1211 el.dom7EventData = [];
1212 delete el.dom7EventData;
1213 }
1214 }
1215 return this;
1216 }
1217 function transitionEnd(callback) {
1218 var events = ['webkitTransitionEnd', 'transitionend'];
1219 var dom = this;
1220 var i;
1221 function fireCallBack(e) {
1222 /* jshint validthis:true */
1223 if (e.target !== this) { return; }
1224 callback.call(this, e);
1225 for (i = 0; i < events.length; i += 1) {
1226 dom.off(events[i], fireCallBack);
1227 }
1228 }
1229 if (callback) {
1230 for (i = 0; i < events.length; i += 1) {
1231 dom.on(events[i], fireCallBack);
1232 }
1233 }
1234 return this;
1235 }
1236 function animationEnd(callback) {
1237 var events = ['webkitAnimationEnd', 'animationend'];
1238 var dom = this;
1239 var i;
1240 function fireCallBack(e) {
1241 if (e.target !== this) { return; }
1242 callback.call(this, e);
1243 for (i = 0; i < events.length; i += 1) {
1244 dom.off(events[i], fireCallBack);
1245 }
1246 }
1247 if (callback) {
1248 for (i = 0; i < events.length; i += 1) {
1249 dom.on(events[i], fireCallBack);
1250 }
1251 }
1252 return this;
1253 }
1254 // Sizing/Styles
1255 function width() {
1256 if (this[0] === win) {
1257 return win.innerWidth;
1258 }
1259
1260 if (this.length > 0) {
1261 return parseFloat(this.css('width'));
1262 }
1263
1264 return null;
1265 }
1266 function outerWidth(includeMargins) {
1267 if (this.length > 0) {
1268 if (includeMargins) {
1269 // eslint-disable-next-line
1270 var styles = this.styles();
1271 return this[0].offsetWidth + parseFloat(styles.getPropertyValue('margin-right')) + parseFloat(styles.getPropertyValue('margin-left'));
1272 }
1273 return this[0].offsetWidth;
1274 }
1275 return null;
1276 }
1277 function height() {
1278 if (this[0] === win) {
1279 return win.innerHeight;
1280 }
1281
1282 if (this.length > 0) {
1283 return parseFloat(this.css('height'));
1284 }
1285
1286 return null;
1287 }
1288 function outerHeight(includeMargins) {
1289 if (this.length > 0) {
1290 if (includeMargins) {
1291 // eslint-disable-next-line
1292 var styles = this.styles();
1293 return this[0].offsetHeight + parseFloat(styles.getPropertyValue('margin-top')) + parseFloat(styles.getPropertyValue('margin-bottom'));
1294 }
1295 return this[0].offsetHeight;
1296 }
1297 return null;
1298 }
1299 function offset() {
1300 if (this.length > 0) {
1301 var el = this[0];
1302 var box = el.getBoundingClientRect();
1303 var body = doc.body;
1304 var clientTop = el.clientTop || body.clientTop || 0;
1305 var clientLeft = el.clientLeft || body.clientLeft || 0;
1306 var scrollTop = el === win ? win.scrollY : el.scrollTop;
1307 var scrollLeft = el === win ? win.scrollX : el.scrollLeft;
1308 return {
1309 top: (box.top + scrollTop) - clientTop,
1310 left: (box.left + scrollLeft) - clientLeft,
1311 };
1312 }
1313
1314 return null;
1315 }
1316 function hide() {
1317 for (var i = 0; i < this.length; i += 1) {
1318 this[i].style.display = 'none';
1319 }
1320 return this;
1321 }
1322 function show() {
1323 for (var i = 0; i < this.length; i += 1) {
1324 var el = this[i];
1325 if (el.style.display === 'none') {
1326 el.style.display = '';
1327 }
1328 if (win.getComputedStyle(el, null).getPropertyValue('display') === 'none') {
1329 // Still not visible
1330 el.style.display = 'block';
1331 }
1332 }
1333 return this;
1334 }
1335 function styles() {
1336 if (this[0]) { return win.getComputedStyle(this[0], null); }
1337 return {};
1338 }
1339 function css(props, value) {
1340 var i;
1341 if (arguments.length === 1) {
1342 if (typeof props === 'string') {
1343 if (this[0]) { return win.getComputedStyle(this[0], null).getPropertyValue(props); }
1344 } else {
1345 for (i = 0; i < this.length; i += 1) {
1346 // eslint-disable-next-line
1347 for (var prop in props) {
1348 this[i].style[prop] = props[prop];
1349 }
1350 }
1351 return this;
1352 }
1353 }
1354 if (arguments.length === 2 && typeof props === 'string') {
1355 for (i = 0; i < this.length; i += 1) {
1356 this[i].style[props] = value;
1357 }
1358 return this;
1359 }
1360 return this;
1361 }
1362
1363 // Dom manipulation
1364 function toArray() {
1365 var arr = [];
1366 for (var i = 0; i < this.length; i += 1) {
1367 arr.push(this[i]);
1368 }
1369 return arr;
1370 }
1371 // Iterate over the collection passing elements to `callback`
1372 function each(callback) {
1373 // Don't bother continuing without a callback
1374 if (!callback) { return this; }
1375 // Iterate over the current collection
1376 for (var i = 0; i < this.length; i += 1) {
1377 // If the callback returns false
1378 if (callback.call(this[i], i, this[i]) === false) {
1379 // End the loop early
1380 return this;
1381 }
1382 }
1383 // Return `this` to allow chained DOM operations
1384 return this;
1385 }
1386 function forEach(callback) {
1387 // Don't bother continuing without a callback
1388 if (!callback) { return this; }
1389 // Iterate over the current collection
1390 for (var i = 0; i < this.length; i += 1) {
1391 // If the callback returns false
1392 if (callback.call(this[i], this[i], i) === false) {
1393 // End the loop early
1394 return this;
1395 }
1396 }
1397 // Return `this` to allow chained DOM operations
1398 return this;
1399 }
1400 function filter(callback) {
1401 var matchedItems = [];
1402 var dom = this;
1403 for (var i = 0; i < dom.length; i += 1) {
1404 if (callback.call(dom[i], i, dom[i])) { matchedItems.push(dom[i]); }
1405 }
1406 return new Dom7(matchedItems);
1407 }
1408 function map(callback) {
1409 var modifiedItems = [];
1410 var dom = this;
1411 for (var i = 0; i < dom.length; i += 1) {
1412 modifiedItems.push(callback.call(dom[i], i, dom[i]));
1413 }
1414 return new Dom7(modifiedItems);
1415 }
1416 // eslint-disable-next-line
1417 function html(html) {
1418 if (typeof html === 'undefined') {
1419 return this[0] ? this[0].innerHTML : undefined;
1420 }
1421
1422 for (var i = 0; i < this.length; i += 1) {
1423 this[i].innerHTML = html;
1424 }
1425 return this;
1426 }
1427 // eslint-disable-next-line
1428 function text(text) {
1429 if (typeof text === 'undefined') {
1430 if (this[0]) {
1431 return this[0].textContent.trim();
1432 }
1433 return null;
1434 }
1435
1436 for (var i = 0; i < this.length; i += 1) {
1437 this[i].textContent = text;
1438 }
1439 return this;
1440 }
1441 function is(selector) {
1442 var el = this[0];
1443 var compareWith;
1444 var i;
1445 if (!el || typeof selector === 'undefined') { return false; }
1446 if (typeof selector === 'string') {
1447 if (el.matches) { return el.matches(selector); }
1448 else if (el.webkitMatchesSelector) { return el.webkitMatchesSelector(selector); }
1449 else if (el.msMatchesSelector) { return el.msMatchesSelector(selector); }
1450
1451 compareWith = $(selector);
1452 for (i = 0; i < compareWith.length; i += 1) {
1453 if (compareWith[i] === el) { return true; }
1454 }
1455 return false;
1456 } else if (selector === doc) { return el === doc; }
1457 else if (selector === win) { return el === win; }
1458
1459 if (selector.nodeType || selector instanceof Dom7) {
1460 compareWith = selector.nodeType ? [selector] : selector;
1461 for (i = 0; i < compareWith.length; i += 1) {
1462 if (compareWith[i] === el) { return true; }
1463 }
1464 return false;
1465 }
1466 return false;
1467 }
1468 function indexOf(el) {
1469 for (var i = 0; i < this.length; i += 1) {
1470 if (this[i] === el) { return i; }
1471 }
1472 return -1;
1473 }
1474 function index() {
1475 var child = this[0];
1476 var i;
1477 if (child) {
1478 i = 0;
1479 // eslint-disable-next-line
1480 while ((child = child.previousSibling) !== null) {
1481 if (child.nodeType === 1) { i += 1; }
1482 }
1483 return i;
1484 }
1485 return undefined;
1486 }
1487 // eslint-disable-next-line
1488 function eq(index) {
1489 if (typeof index === 'undefined') { return this; }
1490 var length = this.length;
1491 var returnIndex;
1492 if (index > length - 1) {
1493 return new Dom7([]);
1494 }
1495 if (index < 0) {
1496 returnIndex = length + index;
1497 if (returnIndex < 0) { return new Dom7([]); }
1498 return new Dom7([this[returnIndex]]);
1499 }
1500 return new Dom7([this[index]]);
1501 }
1502 function append() {
1503 var args = [], len = arguments.length;
1504 while ( len-- ) args[ len ] = arguments[ len ];
1505
1506 var newChild;
1507
1508 for (var k = 0; k < args.length; k += 1) {
1509 newChild = args[k];
1510 for (var i = 0; i < this.length; i += 1) {
1511 if (typeof newChild === 'string') {
1512 var tempDiv = doc.createElement('div');
1513 tempDiv.innerHTML = newChild;
1514 while (tempDiv.firstChild) {
1515 this[i].appendChild(tempDiv.firstChild);
1516 }
1517 } else if (newChild instanceof Dom7) {
1518 for (var j = 0; j < newChild.length; j += 1) {
1519 this[i].appendChild(newChild[j]);
1520 }
1521 } else {
1522 this[i].appendChild(newChild);
1523 }
1524 }
1525 }
1526
1527 return this;
1528 }
1529 // eslint-disable-next-line
1530 function appendTo(parent) {
1531 $(parent).append(this);
1532 return this;
1533 }
1534 function prepend(newChild) {
1535 var i;
1536 var j;
1537 for (i = 0; i < this.length; i += 1) {
1538 if (typeof newChild === 'string') {
1539 var tempDiv = doc.createElement('div');
1540 tempDiv.innerHTML = newChild;
1541 for (j = tempDiv.childNodes.length - 1; j >= 0; j -= 1) {
1542 this[i].insertBefore(tempDiv.childNodes[j], this[i].childNodes[0]);
1543 }
1544 } else if (newChild instanceof Dom7) {
1545 for (j = 0; j < newChild.length; j += 1) {
1546 this[i].insertBefore(newChild[j], this[i].childNodes[0]);
1547 }
1548 } else {
1549 this[i].insertBefore(newChild, this[i].childNodes[0]);
1550 }
1551 }
1552 return this;
1553 }
1554 // eslint-disable-next-line
1555 function prependTo(parent) {
1556 $(parent).prepend(this);
1557 return this;
1558 }
1559 function insertBefore(selector) {
1560 var before = $(selector);
1561 for (var i = 0; i < this.length; i += 1) {
1562 if (before.length === 1) {
1563 before[0].parentNode.insertBefore(this[i], before[0]);
1564 } else if (before.length > 1) {
1565 for (var j = 0; j < before.length; j += 1) {
1566 before[j].parentNode.insertBefore(this[i].cloneNode(true), before[j]);
1567 }
1568 }
1569 }
1570 }
1571 function insertAfter(selector) {
1572 var after = $(selector);
1573 for (var i = 0; i < this.length; i += 1) {
1574 if (after.length === 1) {
1575 after[0].parentNode.insertBefore(this[i], after[0].nextSibling);
1576 } else if (after.length > 1) {
1577 for (var j = 0; j < after.length; j += 1) {
1578 after[j].parentNode.insertBefore(this[i].cloneNode(true), after[j].nextSibling);
1579 }
1580 }
1581 }
1582 }
1583 function next(selector) {
1584 if (this.length > 0) {
1585 if (selector) {
1586 if (this[0].nextElementSibling && $(this[0].nextElementSibling).is(selector)) {
1587 return new Dom7([this[0].nextElementSibling]);
1588 }
1589 return new Dom7([]);
1590 }
1591
1592 if (this[0].nextElementSibling) { return new Dom7([this[0].nextElementSibling]); }
1593 return new Dom7([]);
1594 }
1595 return new Dom7([]);
1596 }
1597 function nextAll(selector) {
1598 var nextEls = [];
1599 var el = this[0];
1600 if (!el) { return new Dom7([]); }
1601 while (el.nextElementSibling) {
1602 var next = el.nextElementSibling; // eslint-disable-line
1603 if (selector) {
1604 if ($(next).is(selector)) { nextEls.push(next); }
1605 } else { nextEls.push(next); }
1606 el = next;
1607 }
1608 return new Dom7(nextEls);
1609 }
1610 function prev(selector) {
1611 if (this.length > 0) {
1612 var el = this[0];
1613 if (selector) {
1614 if (el.previousElementSibling && $(el.previousElementSibling).is(selector)) {
1615 return new Dom7([el.previousElementSibling]);
1616 }
1617 return new Dom7([]);
1618 }
1619
1620 if (el.previousElementSibling) { return new Dom7([el.previousElementSibling]); }
1621 return new Dom7([]);
1622 }
1623 return new Dom7([]);
1624 }
1625 function prevAll(selector) {
1626 var prevEls = [];
1627 var el = this[0];
1628 if (!el) { return new Dom7([]); }
1629 while (el.previousElementSibling) {
1630 var prev = el.previousElementSibling; // eslint-disable-line
1631 if (selector) {
1632 if ($(prev).is(selector)) { prevEls.push(prev); }
1633 } else { prevEls.push(prev); }
1634 el = prev;
1635 }
1636 return new Dom7(prevEls);
1637 }
1638 function siblings(selector) {
1639 return this.nextAll(selector).add(this.prevAll(selector));
1640 }
1641 function parent(selector) {
1642 var parents = []; // eslint-disable-line
1643 for (var i = 0; i < this.length; i += 1) {
1644 if (this[i].parentNode !== null) {
1645 if (selector) {
1646 if ($(this[i].parentNode).is(selector)) { parents.push(this[i].parentNode); }
1647 } else {
1648 parents.push(this[i].parentNode);
1649 }
1650 }
1651 }
1652 return $(unique(parents));
1653 }
1654 function parents(selector) {
1655 var parents = []; // eslint-disable-line
1656 for (var i = 0; i < this.length; i += 1) {
1657 var parent = this[i].parentNode; // eslint-disable-line
1658 while (parent) {
1659 if (selector) {
1660 if ($(parent).is(selector)) { parents.push(parent); }
1661 } else {
1662 parents.push(parent);
1663 }
1664 parent = parent.parentNode;
1665 }
1666 }
1667 return $(unique(parents));
1668 }
1669 function closest(selector) {
1670 var closest = this; // eslint-disable-line
1671 if (typeof selector === 'undefined') {
1672 return new Dom7([]);
1673 }
1674 if (!closest.is(selector)) {
1675 closest = closest.parents(selector).eq(0);
1676 }
1677 return closest;
1678 }
1679 function find(selector) {
1680 var foundElements = [];
1681 for (var i = 0; i < this.length; i += 1) {
1682 var found = this[i].querySelectorAll(selector);
1683 for (var j = 0; j < found.length; j += 1) {
1684 foundElements.push(found[j]);
1685 }
1686 }
1687 return new Dom7(foundElements);
1688 }
1689 function children(selector) {
1690 var children = []; // eslint-disable-line
1691 for (var i = 0; i < this.length; i += 1) {
1692 var childNodes = this[i].childNodes;
1693
1694 for (var j = 0; j < childNodes.length; j += 1) {
1695 if (!selector) {
1696 if (childNodes[j].nodeType === 1) { children.push(childNodes[j]); }
1697 } else if (childNodes[j].nodeType === 1 && $(childNodes[j]).is(selector)) {
1698 children.push(childNodes[j]);
1699 }
1700 }
1701 }
1702 return new Dom7(unique(children));
1703 }
1704 function remove() {
1705 for (var i = 0; i < this.length; i += 1) {
1706 if (this[i].parentNode) { this[i].parentNode.removeChild(this[i]); }
1707 }
1708 return this;
1709 }
1710 function detach() {
1711 return this.remove();
1712 }
1713 function add() {
1714 var args = [], len = arguments.length;
1715 while ( len-- ) args[ len ] = arguments[ len ];
1716
1717 var dom = this;
1718 var i;
1719 var j;
1720 for (i = 0; i < args.length; i += 1) {
1721 var toAdd = $(args[i]);
1722 for (j = 0; j < toAdd.length; j += 1) {
1723 dom[dom.length] = toAdd[j];
1724 dom.length += 1;
1725 }
1726 }
1727 return dom;
1728 }
1729 function empty() {
1730 for (var i = 0; i < this.length; i += 1) {
1731 var el = this[i];
1732 if (el.nodeType === 1) {
1733 for (var j = 0; j < el.childNodes.length; j += 1) {
1734 if (el.childNodes[j].parentNode) {
1735 el.childNodes[j].parentNode.removeChild(el.childNodes[j]);
1736 }
1737 }
1738 el.textContent = '';
1739 }
1740 }
1741 return this;
1742 }
1743
1744 var Methods = /*#__PURE__*/Object.freeze({
1745 addClass: addClass,
1746 removeClass: removeClass,
1747 hasClass: hasClass,
1748 toggleClass: toggleClass,
1749 attr: attr,
1750 removeAttr: removeAttr,
1751 prop: prop,
1752 data: data,
1753 removeData: removeData,
1754 dataset: dataset,
1755 val: val,
1756 transform: transform,
1757 transition: transition,
1758 on: on,
1759 off: off,
1760 once: once,
1761 trigger: trigger,
1762 transitionEnd: transitionEnd,
1763 animationEnd: animationEnd,
1764 width: width,
1765 outerWidth: outerWidth,
1766 height: height,
1767 outerHeight: outerHeight,
1768 offset: offset,
1769 hide: hide,
1770 show: show,
1771 styles: styles,
1772 css: css,
1773 toArray: toArray,
1774 each: each,
1775 forEach: forEach,
1776 filter: filter,
1777 map: map,
1778 html: html,
1779 text: text,
1780 is: is,
1781 indexOf: indexOf,
1782 index: index,
1783 eq: eq,
1784 append: append,
1785 appendTo: appendTo,
1786 prepend: prepend,
1787 prependTo: prependTo,
1788 insertBefore: insertBefore,
1789 insertAfter: insertAfter,
1790 next: next,
1791 nextAll: nextAll,
1792 prev: prev,
1793 prevAll: prevAll,
1794 siblings: siblings,
1795 parent: parent,
1796 parents: parents,
1797 closest: closest,
1798 find: find,
1799 children: children,
1800 remove: remove,
1801 detach: detach,
1802 add: add,
1803 empty: empty
1804 });
1805
1806 function scrollTo() {
1807 var assign;
1808
1809 var args = [], len = arguments.length;
1810 while ( len-- ) args[ len ] = arguments[ len ];
1811 var left = args[0];
1812 var top = args[1];
1813 var duration = args[2];
1814 var easing = args[3];
1815 var callback = args[4];
1816 if (args.length === 4 && typeof easing === 'function') {
1817 callback = easing;
1818 (assign = args, left = assign[0], top = assign[1], duration = assign[2], callback = assign[3], easing = assign[4]);
1819 }
1820 if (typeof easing === 'undefined') { easing = 'swing'; }
1821
1822 return this.each(function animate() {
1823 var el = this;
1824 var currentTop;
1825 var currentLeft;
1826 var maxTop;
1827 var maxLeft;
1828 var newTop;
1829 var newLeft;
1830 var scrollTop; // eslint-disable-line
1831 var scrollLeft; // eslint-disable-line
1832 var animateTop = top > 0 || top === 0;
1833 var animateLeft = left > 0 || left === 0;
1834 if (typeof easing === 'undefined') {
1835 easing = 'swing';
1836 }
1837 if (animateTop) {
1838 currentTop = el.scrollTop;
1839 if (!duration) {
1840 el.scrollTop = top;
1841 }
1842 }
1843 if (animateLeft) {
1844 currentLeft = el.scrollLeft;
1845 if (!duration) {
1846 el.scrollLeft = left;
1847 }
1848 }
1849 if (!duration) { return; }
1850 if (animateTop) {
1851 maxTop = el.scrollHeight - el.offsetHeight;
1852 newTop = Math.max(Math.min(top, maxTop), 0);
1853 }
1854 if (animateLeft) {
1855 maxLeft = el.scrollWidth - el.offsetWidth;
1856 newLeft = Math.max(Math.min(left, maxLeft), 0);
1857 }
1858 var startTime = null;
1859 if (animateTop && newTop === currentTop) { animateTop = false; }
1860 if (animateLeft && newLeft === currentLeft) { animateLeft = false; }
1861 function render(time) {
1862 if ( time === void 0 ) time = new Date().getTime();
1863
1864 if (startTime === null) {
1865 startTime = time;
1866 }
1867 var progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
1868 var easeProgress = easing === 'linear' ? progress : (0.5 - (Math.cos(progress * Math.PI) / 2));
1869 var done;
1870 if (animateTop) { scrollTop = currentTop + (easeProgress * (newTop - currentTop)); }
1871 if (animateLeft) { scrollLeft = currentLeft + (easeProgress * (newLeft - currentLeft)); }
1872 if (animateTop && newTop > currentTop && scrollTop >= newTop) {
1873 el.scrollTop = newTop;
1874 done = true;
1875 }
1876 if (animateTop && newTop < currentTop && scrollTop <= newTop) {
1877 el.scrollTop = newTop;
1878 done = true;
1879 }
1880 if (animateLeft && newLeft > currentLeft && scrollLeft >= newLeft) {
1881 el.scrollLeft = newLeft;
1882 done = true;
1883 }
1884 if (animateLeft && newLeft < currentLeft && scrollLeft <= newLeft) {
1885 el.scrollLeft = newLeft;
1886 done = true;
1887 }
1888
1889 if (done) {
1890 if (callback) { callback(); }
1891 return;
1892 }
1893 if (animateTop) { el.scrollTop = scrollTop; }
1894 if (animateLeft) { el.scrollLeft = scrollLeft; }
1895 requestAnimationFrame(render);
1896 }
1897 requestAnimationFrame(render);
1898 });
1899 }
1900 // scrollTop(top, duration, easing, callback) {
1901 function scrollTop() {
1902 var assign;
1903
1904 var args = [], len = arguments.length;
1905 while ( len-- ) args[ len ] = arguments[ len ];
1906 var top = args[0];
1907 var duration = args[1];
1908 var easing = args[2];
1909 var callback = args[3];
1910 if (args.length === 3 && typeof easing === 'function') {
1911 (assign = args, top = assign[0], duration = assign[1], callback = assign[2], easing = assign[3]);
1912 }
1913 var dom = this;
1914 if (typeof top === 'undefined') {
1915 if (dom.length > 0) { return dom[0].scrollTop; }
1916 return null;
1917 }
1918 return dom.scrollTo(undefined, top, duration, easing, callback);
1919 }
1920 function scrollLeft() {
1921 var assign;
1922
1923 var args = [], len = arguments.length;
1924 while ( len-- ) args[ len ] = arguments[ len ];
1925 var left = args[0];
1926 var duration = args[1];
1927 var easing = args[2];
1928 var callback = args[3];
1929 if (args.length === 3 && typeof easing === 'function') {
1930 (assign = args, left = assign[0], duration = assign[1], callback = assign[2], easing = assign[3]);
1931 }
1932 var dom = this;
1933 if (typeof left === 'undefined') {
1934 if (dom.length > 0) { return dom[0].scrollLeft; }
1935 return null;
1936 }
1937 return dom.scrollTo(left, undefined, duration, easing, callback);
1938 }
1939
1940 var Scroll = /*#__PURE__*/Object.freeze({
1941 scrollTo: scrollTo,
1942 scrollTop: scrollTop,
1943 scrollLeft: scrollLeft
1944 });
1945
1946 function animate(initialProps, initialParams) {
1947 var els = this;
1948 var a = {
1949 props: Object.assign({}, initialProps),
1950 params: Object.assign({
1951 duration: 300,
1952 easing: 'swing', // or 'linear'
1953 /* Callbacks
1954 begin(elements)
1955 complete(elements)
1956 progress(elements, complete, remaining, start, tweenValue)
1957 */
1958 }, initialParams),
1959
1960 elements: els,
1961 animating: false,
1962 que: [],
1963
1964 easingProgress: function easingProgress(easing, progress) {
1965 if (easing === 'swing') {
1966 return 0.5 - (Math.cos(progress * Math.PI) / 2);
1967 }
1968 if (typeof easing === 'function') {
1969 return easing(progress);
1970 }
1971 return progress;
1972 },
1973 stop: function stop() {
1974 if (a.frameId) {
1975 cancelAnimationFrame(a.frameId);
1976 }
1977 a.animating = false;
1978 a.elements.each(function (index, el) {
1979 var element = el;
1980 delete element.dom7AnimateInstance;
1981 });
1982 a.que = [];
1983 },
1984 done: function done(complete) {
1985 a.animating = false;
1986 a.elements.each(function (index, el) {
1987 var element = el;
1988 delete element.dom7AnimateInstance;
1989 });
1990 if (complete) { complete(els); }
1991 if (a.que.length > 0) {
1992 var que = a.que.shift();
1993 a.animate(que[0], que[1]);
1994 }
1995 },
1996 animate: function animate(props, params) {
1997 if (a.animating) {
1998 a.que.push([props, params]);
1999 return a;
2000 }
2001 var elements = [];
2002
2003 // Define & Cache Initials & Units
2004 a.elements.each(function (index, el) {
2005 var initialFullValue;
2006 var initialValue;
2007 var unit;
2008 var finalValue;
2009 var finalFullValue;
2010
2011 if (!el.dom7AnimateInstance) { a.elements[index].dom7AnimateInstance = a; }
2012
2013 elements[index] = {
2014 container: el,
2015 };
2016 Object.keys(props).forEach(function (prop) {
2017 initialFullValue = win.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');
2018 initialValue = parseFloat(initialFullValue);
2019 unit = initialFullValue.replace(initialValue, '');
2020 finalValue = parseFloat(props[prop]);
2021 finalFullValue = props[prop] + unit;
2022 elements[index][prop] = {
2023 initialFullValue: initialFullValue,
2024 initialValue: initialValue,
2025 unit: unit,
2026 finalValue: finalValue,
2027 finalFullValue: finalFullValue,
2028 currentValue: initialValue,
2029 };
2030 });
2031 });
2032
2033 var startTime = null;
2034 var time;
2035 var elementsDone = 0;
2036 var propsDone = 0;
2037 var done;
2038 var began = false;
2039
2040 a.animating = true;
2041
2042 function render() {
2043 time = new Date().getTime();
2044 var progress;
2045 var easeProgress;
2046 // let el;
2047 if (!began) {
2048 began = true;
2049 if (params.begin) { params.begin(els); }
2050 }
2051 if (startTime === null) {
2052 startTime = time;
2053 }
2054 if (params.progress) {
2055 // eslint-disable-next-line
2056 params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), ((startTime + params.duration) - time < 0 ? 0 : (startTime + params.duration) - time), startTime);
2057 }
2058
2059 elements.forEach(function (element) {
2060 var el = element;
2061 if (done || el.done) { return; }
2062 Object.keys(props).forEach(function (prop) {
2063 if (done || el.done) { return; }
2064 progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);
2065 easeProgress = a.easingProgress(params.easing, progress);
2066 var ref = el[prop];
2067 var initialValue = ref.initialValue;
2068 var finalValue = ref.finalValue;
2069 var unit = ref.unit;
2070 el[prop].currentValue = initialValue + (easeProgress * (finalValue - initialValue));
2071 var currentValue = el[prop].currentValue;
2072
2073 if (
2074 (finalValue > initialValue && currentValue >= finalValue) ||
2075 (finalValue < initialValue && currentValue <= finalValue)) {
2076 el.container.style[prop] = finalValue + unit;
2077 propsDone += 1;
2078 if (propsDone === Object.keys(props).length) {
2079 el.done = true;
2080 elementsDone += 1;
2081 }
2082 if (elementsDone === elements.length) {
2083 done = true;
2084 }
2085 }
2086 if (done) {
2087 a.done(params.complete);
2088 return;
2089 }
2090 el.container.style[prop] = currentValue + unit;
2091 });
2092 });
2093 if (done) { return; }
2094 // Then call
2095 a.frameId = requestAnimationFrame(render);
2096 }
2097 a.frameId = requestAnimationFrame(render);
2098 return a;
2099 },
2100 };
2101
2102 if (a.elements.length === 0) {
2103 return els;
2104 }
2105
2106 var animateInstance;
2107 for (var i = 0; i < a.elements.length; i += 1) {
2108 if (a.elements[i].dom7AnimateInstance) {
2109 animateInstance = a.elements[i].dom7AnimateInstance;
2110 } else { a.elements[i].dom7AnimateInstance = a; }
2111 }
2112 if (!animateInstance) {
2113 animateInstance = a;
2114 }
2115
2116 if (initialProps === 'stop') {
2117 animateInstance.stop();
2118 } else {
2119 animateInstance.animate(a.props, a.params);
2120 }
2121
2122 return els;
2123 }
2124
2125 function stop() {
2126 var els = this;
2127 for (var i = 0; i < els.length; i += 1) {
2128 if (els[i].dom7AnimateInstance) {
2129 els[i].dom7AnimateInstance.stop();
2130 }
2131 }
2132 }
2133
2134 var Animate = /*#__PURE__*/Object.freeze({
2135 animate: animate,
2136 stop: stop
2137 });
2138
2139 var noTrigger = ('resize scroll').split(' ');
2140 function eventShortcut(name) {
2141 var ref;
2142
2143 var args = [], len = arguments.length - 1;
2144 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
2145 if (typeof args[0] === 'undefined') {
2146 for (var i = 0; i < this.length; i += 1) {
2147 if (noTrigger.indexOf(name) < 0) {
2148 if (name in this[i]) { this[i][name](); }
2149 else {
2150 $(this[i]).trigger(name);
2151 }
2152 }
2153 }
2154 return this;
2155 }
2156 return (ref = this).on.apply(ref, [ name ].concat( args ));
2157 }
2158
2159 function click() {
2160 var args = [], len = arguments.length;
2161 while ( len-- ) args[ len ] = arguments[ len ];
2162
2163 return eventShortcut.bind(this).apply(void 0, [ 'click' ].concat( args ));
2164 }
2165 function blur() {
2166 var args = [], len = arguments.length;
2167 while ( len-- ) args[ len ] = arguments[ len ];
2168
2169 return eventShortcut.bind(this).apply(void 0, [ 'blur' ].concat( args ));
2170 }
2171 function focus() {
2172 var args = [], len = arguments.length;
2173 while ( len-- ) args[ len ] = arguments[ len ];
2174
2175 return eventShortcut.bind(this).apply(void 0, [ 'focus' ].concat( args ));
2176 }
2177 function focusin() {
2178 var args = [], len = arguments.length;
2179 while ( len-- ) args[ len ] = arguments[ len ];
2180
2181 return eventShortcut.bind(this).apply(void 0, [ 'focusin' ].concat( args ));
2182 }
2183 function focusout() {
2184 var args = [], len = arguments.length;
2185 while ( len-- ) args[ len ] = arguments[ len ];
2186
2187 return eventShortcut.bind(this).apply(void 0, [ 'focusout' ].concat( args ));
2188 }
2189 function keyup() {
2190 var args = [], len = arguments.length;
2191 while ( len-- ) args[ len ] = arguments[ len ];
2192
2193 return eventShortcut.bind(this).apply(void 0, [ 'keyup' ].concat( args ));
2194 }
2195 function keydown() {
2196 var args = [], len = arguments.length;
2197 while ( len-- ) args[ len ] = arguments[ len ];
2198
2199 return eventShortcut.bind(this).apply(void 0, [ 'keydown' ].concat( args ));
2200 }
2201 function keypress() {
2202 var args = [], len = arguments.length;
2203 while ( len-- ) args[ len ] = arguments[ len ];
2204
2205 return eventShortcut.bind(this).apply(void 0, [ 'keypress' ].concat( args ));
2206 }
2207 function submit() {
2208 var args = [], len = arguments.length;
2209 while ( len-- ) args[ len ] = arguments[ len ];
2210
2211 return eventShortcut.bind(this).apply(void 0, [ 'submit' ].concat( args ));
2212 }
2213 function change() {
2214 var args = [], len = arguments.length;
2215 while ( len-- ) args[ len ] = arguments[ len ];
2216
2217 return eventShortcut.bind(this).apply(void 0, [ 'change' ].concat( args ));
2218 }
2219 function mousedown() {
2220 var args = [], len = arguments.length;
2221 while ( len-- ) args[ len ] = arguments[ len ];
2222
2223 return eventShortcut.bind(this).apply(void 0, [ 'mousedown' ].concat( args ));
2224 }
2225 function mousemove() {
2226 var args = [], len = arguments.length;
2227 while ( len-- ) args[ len ] = arguments[ len ];
2228
2229 return eventShortcut.bind(this).apply(void 0, [ 'mousemove' ].concat( args ));
2230 }
2231 function mouseup() {
2232 var args = [], len = arguments.length;
2233 while ( len-- ) args[ len ] = arguments[ len ];
2234
2235 return eventShortcut.bind(this).apply(void 0, [ 'mouseup' ].concat( args ));
2236 }
2237 function mouseenter() {
2238 var args = [], len = arguments.length;
2239 while ( len-- ) args[ len ] = arguments[ len ];
2240
2241 return eventShortcut.bind(this).apply(void 0, [ 'mouseenter' ].concat( args ));
2242 }
2243 function mouseleave() {
2244 var args = [], len = arguments.length;
2245 while ( len-- ) args[ len ] = arguments[ len ];
2246
2247 return eventShortcut.bind(this).apply(void 0, [ 'mouseleave' ].concat( args ));
2248 }
2249 function mouseout() {
2250 var args = [], len = arguments.length;
2251 while ( len-- ) args[ len ] = arguments[ len ];
2252
2253 return eventShortcut.bind(this).apply(void 0, [ 'mouseout' ].concat( args ));
2254 }
2255 function mouseover() {
2256 var args = [], len = arguments.length;
2257 while ( len-- ) args[ len ] = arguments[ len ];
2258
2259 return eventShortcut.bind(this).apply(void 0, [ 'mouseover' ].concat( args ));
2260 }
2261 function touchstart() {
2262 var args = [], len = arguments.length;
2263 while ( len-- ) args[ len ] = arguments[ len ];
2264
2265 return eventShortcut.bind(this).apply(void 0, [ 'touchstart' ].concat( args ));
2266 }
2267 function touchend() {
2268 var args = [], len = arguments.length;
2269 while ( len-- ) args[ len ] = arguments[ len ];
2270
2271 return eventShortcut.bind(this).apply(void 0, [ 'touchend' ].concat( args ));
2272 }
2273 function touchmove() {
2274 var args = [], len = arguments.length;
2275 while ( len-- ) args[ len ] = arguments[ len ];
2276
2277 return eventShortcut.bind(this).apply(void 0, [ 'touchmove' ].concat( args ));
2278 }
2279 function resize() {
2280 var args = [], len = arguments.length;
2281 while ( len-- ) args[ len ] = arguments[ len ];
2282
2283 return eventShortcut.bind(this).apply(void 0, [ 'resize' ].concat( args ));
2284 }
2285 function scroll() {
2286 var args = [], len = arguments.length;
2287 while ( len-- ) args[ len ] = arguments[ len ];
2288
2289 return eventShortcut.bind(this).apply(void 0, [ 'scroll' ].concat( args ));
2290 }
2291
2292 var eventShortcuts = /*#__PURE__*/Object.freeze({
2293 click: click,
2294 blur: blur,
2295 focus: focus,
2296 focusin: focusin,
2297 focusout: focusout,
2298 keyup: keyup,
2299 keydown: keydown,
2300 keypress: keypress,
2301 submit: submit,
2302 change: change,
2303 mousedown: mousedown,
2304 mousemove: mousemove,
2305 mouseup: mouseup,
2306 mouseenter: mouseenter,
2307 mouseleave: mouseleave,
2308 mouseout: mouseout,
2309 mouseover: mouseover,
2310 touchstart: touchstart,
2311 touchend: touchend,
2312 touchmove: touchmove,
2313 resize: resize,
2314 scroll: scroll
2315 });
2316
2317 [Methods, Scroll, Animate, eventShortcuts].forEach(function (group) {
2318 Object.keys(group).forEach(function (methodName) {
2319 $.fn[methodName] = group[methodName];
2320 });
2321 });
2322
2323 /**
2324 * https://github.com/gre/bezier-easing
2325 * BezierEasing - use bezier curve for transition easing function
2326 * by Gaëtan Renaudeau 2014 - 2015 – MIT License
2327 */
2328
2329 /* eslint-disable */
2330
2331 // These values are established by empiricism with tests (tradeoff: performance VS precision)
2332 var NEWTON_ITERATIONS = 4;
2333 var NEWTON_MIN_SLOPE = 0.001;
2334 var SUBDIVISION_PRECISION = 0.0000001;
2335 var SUBDIVISION_MAX_ITERATIONS = 10;
2336
2337 var kSplineTableSize = 11;
2338 var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0);
2339
2340 var float32ArraySupported = typeof Float32Array === 'function';
2341
2342 function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; }
2343 function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; }
2344 function C (aA1) { return 3.0 * aA1; }
2345
2346 // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
2347 function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; }
2348
2349 // Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2.
2350 function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); }
2351
2352 function binarySubdivide (aX, aA, aB, mX1, mX2) {
2353 var currentX, currentT, i = 0;
2354 do {
2355 currentT = aA + (aB - aA) / 2.0;
2356 currentX = calcBezier(currentT, mX1, mX2) - aX;
2357 if (currentX > 0.0) {
2358 aB = currentT;
2359 } else {
2360 aA = currentT;
2361 }
2362 } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
2363 return currentT;
2364 }
2365
2366 function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) {
2367 for (var i = 0; i < NEWTON_ITERATIONS; ++i) {
2368 var currentSlope = getSlope(aGuessT, mX1, mX2);
2369 if (currentSlope === 0.0) {
2370 return aGuessT;
2371 }
2372 var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
2373 aGuessT -= currentX / currentSlope;
2374 }
2375 return aGuessT;
2376 }
2377
2378 function bezier (mX1, mY1, mX2, mY2) {
2379 if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) {
2380 throw new Error('bezier x values must be in [0, 1] range');
2381 }
2382
2383 // Precompute samples table
2384 var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
2385 if (mX1 !== mY1 || mX2 !== mY2) {
2386 for (var i = 0; i < kSplineTableSize; ++i) {
2387 sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2);
2388 }
2389 }
2390
2391 function getTForX (aX) {
2392 var intervalStart = 0.0;
2393 var currentSample = 1;
2394 var lastSample = kSplineTableSize - 1;
2395
2396 for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) {
2397 intervalStart += kSampleStepSize;
2398 }
2399 --currentSample;
2400
2401 // Interpolate to provide an initial guess for t
2402 var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]);
2403 var guessForT = intervalStart + dist * kSampleStepSize;
2404
2405 var initialSlope = getSlope(guessForT, mX1, mX2);
2406 if (initialSlope >= NEWTON_MIN_SLOPE) {
2407 return newtonRaphsonIterate(aX, guessForT, mX1, mX2);
2408 } else if (initialSlope === 0.0) {
2409 return guessForT;
2410 } else {
2411 return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2);
2412 }
2413 }
2414
2415 return function BezierEasing (x) {
2416 if (mX1 === mY1 && mX2 === mY2) {
2417 return x; // linear
2418 }
2419 // Because JavaScript number are imprecise, we should guarantee the extremes are right.
2420 if (x === 0) {
2421 return 0;
2422 }
2423 if (x === 1) {
2424 return 1;
2425 }
2426 return calcBezier(getTForX(x), mY1, mY2);
2427 };
2428 }
2429
2430 /* eslint no-control-regex: "off" */
2431
2432 // Remove Diacritics
2433 var defaultDiacriticsRemovalap = [
2434 { 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' },
2435 { base: 'AA', letters: '\uA732' },
2436 { base: 'AE', letters: '\u00C6\u01FC\u01E2' },
2437 { base: 'AO', letters: '\uA734' },
2438 { base: 'AU', letters: '\uA736' },
2439 { base: 'AV', letters: '\uA738\uA73A' },
2440 { base: 'AY', letters: '\uA73C' },
2441 { base: 'B', letters: '\u0042\u24B7\uFF22\u1E02\u1E04\u1E06\u0243\u0182\u0181' },
2442 { base: 'C', letters: '\u0043\u24B8\uFF23\u0106\u0108\u010A\u010C\u00C7\u1E08\u0187\u023B\uA73E' },
2443 { base: 'D', letters: '\u0044\u24B9\uFF24\u1E0A\u010E\u1E0C\u1E10\u1E12\u1E0E\u0110\u018B\u018A\u0189\uA779' },
2444 { base: 'DZ', letters: '\u01F1\u01C4' },
2445 { base: 'Dz', letters: '\u01F2\u01C5' },
2446 { 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' },
2447 { base: 'F', letters: '\u0046\u24BB\uFF26\u1E1E\u0191\uA77B' },
2448 { base: 'G', letters: '\u0047\u24BC\uFF27\u01F4\u011C\u1E20\u011E\u0120\u01E6\u0122\u01E4\u0193\uA7A0\uA77D\uA77E' },
2449 { base: 'H', letters: '\u0048\u24BD\uFF28\u0124\u1E22\u1E26\u021E\u1E24\u1E28\u1E2A\u0126\u2C67\u2C75\uA78D' },
2450 { base: 'I', letters: '\u0049\u24BE\uFF29\u00CC\u00CD\u00CE\u0128\u012A\u012C\u0130\u00CF\u1E2E\u1EC8\u01CF\u0208\u020A\u1ECA\u012E\u1E2C\u0197' },
2451 { base: 'J', letters: '\u004A\u24BF\uFF2A\u0134\u0248' },
2452 { base: 'K', letters: '\u004B\u24C0\uFF2B\u1E30\u01E8\u1E32\u0136\u1E34\u0198\u2C69\uA740\uA742\uA744\uA7A2' },
2453 { base: 'L', letters: '\u004C\u24C1\uFF2C\u013F\u0139\u013D\u1E36\u1E38\u013B\u1E3C\u1E3A\u0141\u023D\u2C62\u2C60\uA748\uA746\uA780' },
2454 { base: 'LJ', letters: '\u01C7' },
2455 { base: 'Lj', letters: '\u01C8' },
2456 { base: 'M', letters: '\u004D\u24C2\uFF2D\u1E3E\u1E40\u1E42\u2C6E\u019C' },
2457 { base: 'N', letters: '\u004E\u24C3\uFF2E\u01F8\u0143\u00D1\u1E44\u0147\u1E46\u0145\u1E4A\u1E48\u0220\u019D\uA790\uA7A4' },
2458 { base: 'NJ', letters: '\u01CA' },
2459 { base: 'Nj', letters: '\u01CB' },
2460 { 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' },
2461 { base: 'OI', letters: '\u01A2' },
2462 { base: 'OO', letters: '\uA74E' },
2463 { base: 'OU', letters: '\u0222' },
2464 { base: 'OE', letters: '\u008C\u0152' },
2465 { base: 'oe', letters: '\u009C\u0153' },
2466 { base: 'P', letters: '\u0050\u24C5\uFF30\u1E54\u1E56\u01A4\u2C63\uA750\uA752\uA754' },
2467 { base: 'Q', letters: '\u0051\u24C6\uFF31\uA756\uA758\u024A' },
2468 { base: 'R', letters: '\u0052\u24C7\uFF32\u0154\u1E58\u0158\u0210\u0212\u1E5A\u1E5C\u0156\u1E5E\u024C\u2C64\uA75A\uA7A6\uA782' },
2469 { base: 'S', letters: '\u0053\u24C8\uFF33\u1E9E\u015A\u1E64\u015C\u1E60\u0160\u1E66\u1E62\u1E68\u0218\u015E\u2C7E\uA7A8\uA784' },
2470 { base: 'T', letters: '\u0054\u24C9\uFF34\u1E6A\u0164\u1E6C\u021A\u0162\u1E70\u1E6E\u0166\u01AC\u01AE\u023E\uA786' },
2471 { base: 'TZ', letters: '\uA728' },
2472 { 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' },
2473 { base: 'V', letters: '\u0056\u24CB\uFF36\u1E7C\u1E7E\u01B2\uA75E\u0245' },
2474 { base: 'VY', letters: '\uA760' },
2475 { base: 'W', letters: '\u0057\u24CC\uFF37\u1E80\u1E82\u0174\u1E86\u1E84\u1E88\u2C72' },
2476 { base: 'X', letters: '\u0058\u24CD\uFF38\u1E8A\u1E8C' },
2477 { base: 'Y', letters: '\u0059\u24CE\uFF39\u1EF2\u00DD\u0176\u1EF8\u0232\u1E8E\u0178\u1EF6\u1EF4\u01B3\u024E\u1EFE' },
2478 { base: 'Z', letters: '\u005A\u24CF\uFF3A\u0179\u1E90\u017B\u017D\u1E92\u1E94\u01B5\u0224\u2C7F\u2C6B\uA762' },
2479 { 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' },
2480 { base: 'aa', letters: '\uA733' },
2481 { base: 'ae', letters: '\u00E6\u01FD\u01E3' },
2482 { base: 'ao', letters: '\uA735' },
2483 { base: 'au', letters: '\uA737' },
2484 { base: 'av', letters: '\uA739\uA73B' },
2485 { base: 'ay', letters: '\uA73D' },
2486 { base: 'b', letters: '\u0062\u24D1\uFF42\u1E03\u1E05\u1E07\u0180\u0183\u0253' },
2487 { base: 'c', letters: '\u0063\u24D2\uFF43\u0107\u0109\u010B\u010D\u00E7\u1E09\u0188\u023C\uA73F\u2184' },
2488 { base: 'd', letters: '\u0064\u24D3\uFF44\u1E0B\u010F\u1E0D\u1E11\u1E13\u1E0F\u0111\u018C\u0256\u0257\uA77A' },
2489 { base: 'dz', letters: '\u01F3\u01C6' },
2490 { 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' },
2491 { base: 'f', letters: '\u0066\u24D5\uFF46\u1E1F\u0192\uA77C' },
2492 { base: 'g', letters: '\u0067\u24D6\uFF47\u01F5\u011D\u1E21\u011F\u0121\u01E7\u0123\u01E5\u0260\uA7A1\u1D79\uA77F' },
2493 { base: 'h', letters: '\u0068\u24D7\uFF48\u0125\u1E23\u1E27\u021F\u1E25\u1E29\u1E2B\u1E96\u0127\u2C68\u2C76\u0265' },
2494 { base: 'hv', letters: '\u0195' },
2495 { base: 'i', letters: '\u0069\u24D8\uFF49\u00EC\u00ED\u00EE\u0129\u012B\u012D\u00EF\u1E2F\u1EC9\u01D0\u0209\u020B\u1ECB\u012F\u1E2D\u0268\u0131' },
2496 { base: 'j', letters: '\u006A\u24D9\uFF4A\u0135\u01F0\u0249' },
2497 { base: 'k', letters: '\u006B\u24DA\uFF4B\u1E31\u01E9\u1E33\u0137\u1E35\u0199\u2C6A\uA741\uA743\uA745\uA7A3' },
2498 { base: 'l', letters: '\u006C\u24DB\uFF4C\u0140\u013A\u013E\u1E37\u1E39\u013C\u1E3D\u1E3B\u017F\u0142\u019A\u026B\u2C61\uA749\uA781\uA747' },
2499 { base: 'lj', letters: '\u01C9' },
2500 { base: 'm', letters: '\u006D\u24DC\uFF4D\u1E3F\u1E41\u1E43\u0271\u026F' },
2501 { base: 'n', letters: '\u006E\u24DD\uFF4E\u01F9\u0144\u00F1\u1E45\u0148\u1E47\u0146\u1E4B\u1E49\u019E\u0272\u0149\uA791\uA7A5' },
2502 { base: 'nj', letters: '\u01CC' },
2503 { 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' },
2504 { base: 'oi', letters: '\u01A3' },
2505 { base: 'ou', letters: '\u0223' },
2506 { base: 'oo', letters: '\uA74F' },
2507 { base: 'p', letters: '\u0070\u24DF\uFF50\u1E55\u1E57\u01A5\u1D7D\uA751\uA753\uA755' },
2508 { base: 'q', letters: '\u0071\u24E0\uFF51\u024B\uA757\uA759' },
2509 { base: 'r', letters: '\u0072\u24E1\uFF52\u0155\u1E59\u0159\u0211\u0213\u1E5B\u1E5D\u0157\u1E5F\u024D\u027D\uA75B\uA7A7\uA783' },
2510 { base: 's', letters: '\u0073\u24E2\uFF53\u00DF\u015B\u1E65\u015D\u1E61\u0161\u1E67\u1E63\u1E69\u0219\u015F\u023F\uA7A9\uA785\u1E9B' },
2511 { base: 't', letters: '\u0074\u24E3\uFF54\u1E6B\u1E97\u0165\u1E6D\u021B\u0163\u1E71\u1E6F\u0167\u01AD\u0288\u2C66\uA787' },
2512 { base: 'tz', letters: '\uA729' },
2513 { 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' },
2514 { base: 'v', letters: '\u0076\u24E5\uFF56\u1E7D\u1E7F\u028B\uA75F\u028C' },
2515 { base: 'vy', letters: '\uA761' },
2516 { base: 'w', letters: '\u0077\u24E6\uFF57\u1E81\u1E83\u0175\u1E87\u1E85\u1E98\u1E89\u2C73' },
2517 { base: 'x', letters: '\u0078\u24E7\uFF58\u1E8B\u1E8D' },
2518 { base: 'y', letters: '\u0079\u24E8\uFF59\u1EF3\u00FD\u0177\u1EF9\u0233\u1E8F\u00FF\u1EF7\u1E99\u1EF5\u01B4\u024F\u1EFF' },
2519 { base: 'z', letters: '\u007A\u24E9\uFF5A\u017A\u1E91\u017C\u017E\u1E93\u1E95\u01B6\u0225\u0240\u2C6C\uA763' } ];
2520
2521 var diacriticsMap = {};
2522 for (var i = 0; i < defaultDiacriticsRemovalap.length; i += 1) {
2523 var letters = defaultDiacriticsRemovalap[i].letters;
2524 for (var j = 0; j < letters.length; j += 1) {
2525 diacriticsMap[letters[j]] = defaultDiacriticsRemovalap[i].base;
2526 }
2527 }
2528
2529 var uniqueNumber = 1;
2530
2531 var Utils = {
2532 uniqueNumber: function uniqueNumber$1() {
2533 uniqueNumber += 1;
2534 return uniqueNumber;
2535 },
2536 id: function id(mask, map) {
2537 if ( mask === void 0 ) mask = 'xxxxxxxxxx';
2538 if ( map === void 0 ) map = '0123456789abcdef';
2539
2540 var length = map.length;
2541 return mask.replace(/x/g, function () { return map[Math.floor((Math.random() * length))]; });
2542 },
2543 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(),
2544 iosPreloaderContent: ("\n <span class=\"preloader-inner\">\n " + (Array.from({ length: 12 }).map(function () { return '<span class="preloader-inner-line"></span>'; }).join('')) + "\n </span>\n ").trim(),
2545 eventNameToColonCase: function eventNameToColonCase(eventName) {
2546 var hasColon;
2547 return eventName.split('').map(function (char, index) {
2548 if (char.match(/[A-Z]/) && index !== 0 && !hasColon) {
2549 hasColon = true;
2550 return (":" + (char.toLowerCase()));
2551 }
2552 return char.toLowerCase();
2553 }).join('');
2554 },
2555 deleteProps: function deleteProps(obj) {
2556 var object = obj;
2557 Object.keys(object).forEach(function (key) {
2558 try {
2559 object[key] = null;
2560 } catch (e) {
2561 // no setter for object
2562 }
2563 try {
2564 delete object[key];
2565 } catch (e) {
2566 // something got wrong
2567 }
2568 });
2569 },
2570 bezier: function bezier$1() {
2571 var args = [], len = arguments.length;
2572 while ( len-- ) args[ len ] = arguments[ len ];
2573
2574 return bezier.apply(void 0, args);
2575 },
2576 nextTick: function nextTick(callback, delay) {
2577 if ( delay === void 0 ) delay = 0;
2578
2579 return setTimeout(callback, delay);
2580 },
2581 nextFrame: function nextFrame(callback) {
2582 return Utils.requestAnimationFrame(function () {
2583 Utils.requestAnimationFrame(callback);
2584 });
2585 },
2586 now: function now() {
2587 return Date.now();
2588 },
2589 requestAnimationFrame: function requestAnimationFrame(callback) {
2590 return win.requestAnimationFrame(callback);
2591 },
2592 cancelAnimationFrame: function cancelAnimationFrame(id) {
2593 return win.cancelAnimationFrame(id);
2594 },
2595 removeDiacritics: function removeDiacritics(str) {
2596 return str.replace(/[^\u0000-\u007E]/g, function (a) { return diacriticsMap[a] || a; });
2597 },
2598 parseUrlQuery: function parseUrlQuery(url) {
2599 var query = {};
2600 var urlToParse = url || win.location.href;
2601 var i;
2602 var params;
2603 var param;
2604 var length;
2605 if (typeof urlToParse === 'string' && urlToParse.length) {
2606 urlToParse = urlToParse.indexOf('?') > -1 ? urlToParse.replace(/\S*\?/, '') : '';
2607 params = urlToParse.split('&').filter(function (paramsPart) { return paramsPart !== ''; });
2608 length = params.length;
2609
2610 for (i = 0; i < length; i += 1) {
2611 param = params[i].replace(/#\S+/g, '').split('=');
2612 query[decodeURIComponent(param[0])] = typeof param[1] === 'undefined' ? undefined : decodeURIComponent(param.slice(1).join('=')) || '';
2613 }
2614 }
2615 return query;
2616 },
2617 getTranslate: function getTranslate(el, axis) {
2618 if ( axis === void 0 ) axis = 'x';
2619
2620 var matrix;
2621 var curTransform;
2622 var transformMatrix;
2623
2624 var curStyle = win.getComputedStyle(el, null);
2625
2626 if (win.WebKitCSSMatrix) {
2627 curTransform = curStyle.transform || curStyle.webkitTransform;
2628 if (curTransform.split(',').length > 6) {
2629 curTransform = curTransform.split(', ').map(function (a) { return a.replace(',', '.'); }).join(', ');
2630 }
2631 // Some old versions of Webkit choke when 'none' is passed; pass
2632 // empty string instead in this case
2633 transformMatrix = new win.WebKitCSSMatrix(curTransform === 'none' ? '' : curTransform);
2634 } else {
2635 transformMatrix = curStyle.MozTransform || curStyle.OTransform || curStyle.MsTransform || curStyle.msTransform || curStyle.transform || curStyle.getPropertyValue('transform').replace('translate(', 'matrix(1, 0, 0, 1,');
2636 matrix = transformMatrix.toString().split(',');
2637 }
2638
2639 if (axis === 'x') {
2640 // Latest Chrome and webkits Fix
2641 if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m41; }
2642 // Crazy IE10 Matrix
2643 else if (matrix.length === 16) { curTransform = parseFloat(matrix[12]); }
2644 // Normal Browsers
2645 else { curTransform = parseFloat(matrix[4]); }
2646 }
2647 if (axis === 'y') {
2648 // Latest Chrome and webkits Fix
2649 if (win.WebKitCSSMatrix) { curTransform = transformMatrix.m42; }
2650 // Crazy IE10 Matrix
2651 else if (matrix.length === 16) { curTransform = parseFloat(matrix[13]); }
2652 // Normal Browsers
2653 else { curTransform = parseFloat(matrix[5]); }
2654 }
2655 return curTransform || 0;
2656 },
2657 serializeObject: function serializeObject(obj, parents) {
2658 if ( parents === void 0 ) parents = [];
2659
2660 if (typeof obj === 'string') { return obj; }
2661 var resultArray = [];
2662 var separator = '&';
2663 var newParents;
2664 function varName(name) {
2665 if (parents.length > 0) {
2666 var parentParts = '';
2667 for (var j = 0; j < parents.length; j += 1) {
2668 if (j === 0) { parentParts += parents[j]; }
2669 else { parentParts += "[" + (encodeURIComponent(parents[j])) + "]"; }
2670 }
2671 return (parentParts + "[" + (encodeURIComponent(name)) + "]");
2672 }
2673 return encodeURIComponent(name);
2674 }
2675 function varValue(value) {
2676 return encodeURIComponent(value);
2677 }
2678 Object.keys(obj).forEach(function (prop) {
2679 var toPush;
2680 if (Array.isArray(obj[prop])) {
2681 toPush = [];
2682 for (var i = 0; i < obj[prop].length; i += 1) {
2683 if (!Array.isArray(obj[prop][i]) && typeof obj[prop][i] === 'object') {
2684 newParents = parents.slice();
2685 newParents.push(prop);
2686 newParents.push(String(i));
2687 toPush.push(Utils.serializeObject(obj[prop][i], newParents));
2688 } else {
2689 toPush.push(((varName(prop)) + "[]=" + (varValue(obj[prop][i]))));
2690 }
2691 }
2692 if (toPush.length > 0) { resultArray.push(toPush.join(separator)); }
2693 } else if (obj[prop] === null || obj[prop] === '') {
2694 resultArray.push(((varName(prop)) + "="));
2695 } else if (typeof obj[prop] === 'object') {
2696 // Object, convert to named array
2697 newParents = parents.slice();
2698 newParents.push(prop);
2699 toPush = Utils.serializeObject(obj[prop], newParents);
2700 if (toPush !== '') { resultArray.push(toPush); }
2701 } else if (typeof obj[prop] !== 'undefined' && obj[prop] !== '') {
2702 // Should be string or plain value
2703 resultArray.push(((varName(prop)) + "=" + (varValue(obj[prop]))));
2704 } else if (obj[prop] === '') { resultArray.push(varName(prop)); }
2705 });
2706 return resultArray.join(separator);
2707 },
2708 isObject: function isObject(o) {
2709 return typeof o === 'object' && o !== null && o.constructor && o.constructor === Object;
2710 },
2711 merge: function merge() {
2712 var args = [], len$1 = arguments.length;
2713 while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];
2714
2715 var to = args[0];
2716 args.splice(0, 1);
2717 var from = args;
2718
2719 for (var i = 0; i < from.length; i += 1) {
2720 var nextSource = args[i];
2721 if (nextSource !== undefined && nextSource !== null) {
2722 var keysArray = Object.keys(Object(nextSource));
2723 for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
2724 var nextKey = keysArray[nextIndex];
2725 var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
2726 if (desc !== undefined && desc.enumerable) {
2727 to[nextKey] = nextSource[nextKey];
2728 }
2729 }
2730 }
2731 }
2732 return to;
2733 },
2734 extend: function extend() {
2735 var args = [], len$1 = arguments.length;
2736 while ( len$1-- ) args[ len$1 ] = arguments[ len$1 ];
2737
2738 var deep = true;
2739 var to;
2740 var from;
2741 if (typeof args[0] === 'boolean') {
2742 deep = args[0];
2743 to = args[1];
2744 args.splice(0, 2);
2745 from = args;
2746 } else {
2747 to = args[0];
2748 args.splice(0, 1);
2749 from = args;
2750 }
2751 for (var i = 0; i < from.length; i += 1) {
2752 var nextSource = args[i];
2753 if (nextSource !== undefined && nextSource !== null) {
2754 var keysArray = Object.keys(Object(nextSource));
2755 for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
2756 var nextKey = keysArray[nextIndex];
2757 var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
2758 if (desc !== undefined && desc.enumerable) {
2759 if (!deep) {
2760 to[nextKey] = nextSource[nextKey];
2761 } else if (Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
2762 Utils.extend(to[nextKey], nextSource[nextKey]);
2763 } else if (!Utils.isObject(to[nextKey]) && Utils.isObject(nextSource[nextKey])) {
2764 to[nextKey] = {};
2765 Utils.extend(to[nextKey], nextSource[nextKey]);
2766 } else {
2767 to[nextKey] = nextSource[nextKey];
2768 }
2769 }
2770 }
2771 }
2772 }
2773 return to;
2774 },
2775 colorHexToRgb: function colorHexToRgb(hex) {
2776 var h = hex.replace(/^#?([a-f\d])([a-f\d])([a-f\d])$/i, function (m, r, g, b) { return r + r + g + g + b + b; });
2777 var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(h);
2778 return result
2779 ? result.slice(1).map(function (n) { return parseInt(n, 16); })
2780 : null;
2781 },
2782 colorRgbToHex: function colorRgbToHex(r, g, b) {
2783 var result = [r, g, b].map(function (n) {
2784 var hex = n.toString(16);
2785 return hex.length === 1 ? ("0" + hex) : hex;
2786 }).join('');
2787 return ("#" + result);
2788 },
2789 colorRgbToHsl: function colorRgbToHsl(r, g, b) {
2790 r /= 255; // eslint-disable-line
2791 g /= 255; // eslint-disable-line
2792 b /= 255; // eslint-disable-line
2793 var max = Math.max(r, g, b);
2794 var min = Math.min(r, g, b);
2795 var d = max - min;
2796 var h;
2797 if (d === 0) { h = 0; }
2798 else if (max === r) { h = ((g - b) / d) % 6; }
2799 else if (max === g) { h = (b - r) / d + 2; }
2800 else if (max === b) { h = (r - g) / d + 4; }
2801 var l = (min + max) / 2;
2802 var s = d === 0 ? 0 : d / (1 - Math.abs(2 * l - 1));
2803 return [h * 60, s, l];
2804 },
2805 colorHslToRgb: function colorHslToRgb(h, s, l) {
2806 var c = (1 - Math.abs(2 * l - 1)) * s;
2807 var hp = h / 60;
2808 var x = c * (1 - Math.abs((hp % 2) - 1));
2809 var rgb1;
2810 if (Number.isNaN(h) || typeof h === 'undefined') {
2811 rgb1 = [0, 0, 0];
2812 } else if (hp <= 1) { rgb1 = [c, x, 0]; }
2813 else if (hp <= 2) { rgb1 = [x, c, 0]; }
2814 else if (hp <= 3) { rgb1 = [0, c, x]; }
2815 else if (hp <= 4) { rgb1 = [0, x, c]; }
2816 else if (hp <= 5) { rgb1 = [x, 0, c]; }
2817 else if (hp <= 6) { rgb1 = [c, 0, x]; }
2818 var m = l - (c / 2);
2819 return rgb1.map(function (n) { return Math.max(0, Math.min(255, Math.round(255 * (n + m)))); });
2820 },
2821 colorThemeCSSProperties: function colorThemeCSSProperties() {
2822 var args = [], len = arguments.length;
2823 while ( len-- ) args[ len ] = arguments[ len ];
2824
2825 var hex;
2826 var rgb;
2827 if (args.length === 1) {
2828 hex = args[0];
2829 rgb = Utils.colorHexToRgb(hex);
2830 } else if (args.length === 3) {
2831 rgb = args;
2832 hex = Utils.colorRgbToHex.apply(Utils, rgb);
2833 }
2834 if (!rgb) { return {}; }
2835 var hsl = Utils.colorRgbToHsl.apply(Utils, rgb);
2836 var hslShade = [hsl[0], hsl[1], Math.max(0, (hsl[2] - 0.08))];
2837 var hslTint = [hsl[0], hsl[1], Math.max(0, (hsl[2] + 0.08))];
2838 var shade = Utils.colorRgbToHex.apply(Utils, Utils.colorHslToRgb.apply(Utils, hslShade));
2839 var tint = Utils.colorRgbToHex.apply(Utils, Utils.colorHslToRgb.apply(Utils, hslTint));
2840 return {
2841 '--f7-theme-color': hex,
2842 '--f7-theme-color-rgb': rgb.join(', '),
2843 '--f7-theme-color-shade': shade,
2844 '--f7-theme-color-tint': tint,
2845 };
2846 },
2847 };
2848
2849 var Device = (function Device() {
2850 var platform = win.navigator.platform;
2851 var ua = win.navigator.userAgent;
2852
2853 var device = {
2854 ios: false,
2855 android: false,
2856 androidChrome: false,
2857 desktop: false,
2858 windowsPhone: false,
2859 iphone: false,
2860 iphoneX: false,
2861 ipod: false,
2862 ipad: false,
2863 edge: false,
2864 ie: false,
2865 firefox: false,
2866 macos: false,
2867 windows: false,
2868 cordova: !!(win.cordova || win.phonegap),
2869 phonegap: !!(win.cordova || win.phonegap),
2870 };
2871
2872 var screenWidth = win.screen.width;
2873 var screenHeight = win.screen.height;
2874
2875 var windowsPhone = ua.match(/(Windows Phone);?[\s\/]+([\d.]+)?/); // eslint-disable-line
2876 var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/); // eslint-disable-line
2877 var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
2878 var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
2879 var iphone = !ipad && ua.match(/(iPhone\sOS|iOS)\s([\d_]+)/);
2880 var iphoneX = iphone && (
2881 (screenWidth === 375 && screenHeight === 812) // X/XS
2882 || (screenWidth === 414 && screenHeight === 896) // XR / XS Max
2883 );
2884 var ie = ua.indexOf('MSIE ') >= 0 || ua.indexOf('Trident/') >= 0;
2885 var edge = ua.indexOf('Edge/') >= 0;
2886 var firefox = ua.indexOf('Gecko/') >= 0 && ua.indexOf('Firefox/') >= 0;
2887 var macos = platform === 'MacIntel';
2888 var windows = platform === 'Win32';
2889
2890 device.ie = ie;
2891 device.edge = edge;
2892 device.firefox = firefox;
2893
2894 // Windows
2895 if (windowsPhone) {
2896 device.os = 'windows';
2897 device.osVersion = windowsPhone[2];
2898 device.windowsPhone = true;
2899 }
2900 // Android
2901 if (android && !windows) {
2902 device.os = 'android';
2903 device.osVersion = android[2];
2904 device.android = true;
2905 device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0;
2906 }
2907 if (ipad || iphone || ipod) {
2908 device.os = 'ios';
2909 device.ios = true;
2910 }
2911 // iOS
2912 if (iphone && !ipod) {
2913 device.osVersion = iphone[2].replace(/_/g, '.');
2914 device.iphone = true;
2915 device.iphoneX = iphoneX;
2916 }
2917 if (ipad) {
2918 device.osVersion = ipad[2].replace(/_/g, '.');
2919 device.ipad = true;
2920 }
2921 if (ipod) {
2922 device.osVersion = ipod[3] ? ipod[3].replace(/_/g, '.') : null;
2923 device.iphone = true;
2924 }
2925 // iOS 8+ changed UA
2926 if (device.ios && device.osVersion && ua.indexOf('Version/') >= 0) {
2927 if (device.osVersion.split('.')[0] === '10') {
2928 device.osVersion = ua.toLowerCase().split('version/')[1].split(' ')[0];
2929 }
2930 }
2931
2932 // Webview
2933 device.webView = !!((iphone || ipad || ipod) && (ua.match(/.*AppleWebKit(?!.*Safari)/i) || win.navigator.standalone))
2934 || (win.matchMedia && win.matchMedia('(display-mode: standalone)').matches);
2935 device.webview = device.webView;
2936 device.standalone = device.webView;
2937
2938 // Desktop
2939 device.desktop = !(device.os || device.android || device.webView);
2940 if (device.desktop) {
2941 device.macos = macos;
2942 device.windows = windows;
2943 }
2944
2945 // Minimal UI
2946 if (device.os && device.os === 'ios') {
2947 var osVersionArr = device.osVersion.split('.');
2948 var metaViewport = doc.querySelector('meta[name="viewport"]');
2949 device.minimalUi = !device.webView
2950 && (ipod || iphone)
2951 && (osVersionArr[0] * 1 === 7 ? osVersionArr[1] * 1 >= 1 : osVersionArr[0] * 1 > 7)
2952 && metaViewport && metaViewport.getAttribute('content').indexOf('minimal-ui') >= 0;
2953 }
2954
2955 // Meta statusbar
2956 var metaStatusbar = doc.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');
2957
2958 // Check for status bar and fullscreen app mode
2959 device.needsStatusbarOverlay = function needsStatusbarOverlay() {
2960 if (device.standalone && device.ios && metaStatusbar && metaStatusbar.content === 'black-translucent') {
2961 return true;
2962 }
2963 if ((device.webView || (device.android && device.cordova)) && (win.innerWidth * win.innerHeight === win.screen.width * win.screen.height)) {
2964 if (device.iphoneX && (win.orientation === 90 || win.orientation === -90)) {
2965 return false;
2966 }
2967 return true;
2968 }
2969 return false;
2970 };
2971 device.statusbar = device.needsStatusbarOverlay();
2972
2973 // Pixel Ratio
2974 device.pixelRatio = win.devicePixelRatio || 1;
2975
2976 // Export object
2977 return device;
2978 }());
2979
2980 var EventsClass = function EventsClass(parents) {
2981 if ( parents === void 0 ) parents = [];
2982
2983 var self = this;
2984 self.eventsParents = parents;
2985 self.eventsListeners = {};
2986 };
2987
2988 EventsClass.prototype.on = function on (events, handler, priority) {
2989 var self = this;
2990 if (typeof handler !== 'function') { return self; }
2991 var method = priority ? 'unshift' : 'push';
2992 events.split(' ').forEach(function (event) {
2993 if (!self.eventsListeners[event]) { self.eventsListeners[event] = []; }
2994 self.eventsListeners[event][method](handler);
2995 });
2996 return self;
2997 };
2998
2999 EventsClass.prototype.once = function once (events, handler, priority) {
3000 var self = this;
3001 if (typeof handler !== 'function') { return self; }
3002 function onceHandler() {
3003 var args = [], len = arguments.length;
3004 while ( len-- ) args[ len ] = arguments[ len ];
3005
3006 handler.apply(self, args);
3007 self.off(events, onceHandler);
3008 if (onceHandler.f7proxy) {
3009 delete onceHandler.f7proxy;
3010 }
3011 }
3012 onceHandler.f7proxy = handler;
3013 return self.on(events, onceHandler, priority);
3014 };
3015
3016 EventsClass.prototype.off = function off (events, handler) {
3017 var self = this;
3018 if (!self.eventsListeners) { return self; }
3019 events.split(' ').forEach(function (event) {
3020 if (typeof handler === 'undefined') {
3021 self.eventsListeners[event] = [];
3022 } else if (self.eventsListeners[event]) {
3023 self.eventsListeners[event].forEach(function (eventHandler, index) {
3024 if (eventHandler === handler || (eventHandler.f7proxy && eventHandler.f7proxy === handler)) {
3025 self.eventsListeners[event].splice(index, 1);
3026 }
3027 });
3028 }
3029 });
3030 return self;
3031 };
3032
3033 EventsClass.prototype.emit = function emit () {
3034 var args = [], len = arguments.length;
3035 while ( len-- ) args[ len ] = arguments[ len ];
3036
3037 var self = this;
3038 if (!self.eventsListeners) { return self; }
3039 var events;
3040 var data;
3041 var context;
3042 var eventsParents;
3043 if (typeof args[0] === 'string' || Array.isArray(args[0])) {
3044 events = args[0];
3045 data = args.slice(1, args.length);
3046 context = self;
3047 eventsParents = self.eventsParents;
3048 } else {
3049 events = args[0].events;
3050 data = args[0].data;
3051 context = args[0].context || self;
3052 eventsParents = args[0].local ? [] : args[0].parents || self.eventsParents;
3053 }
3054 var eventsArray = Array.isArray(events) ? events : events.split(' ');
3055 var localEvents = eventsArray.map(function (eventName) { return eventName.replace('local::', ''); });
3056 var parentEvents = eventsArray.filter(function (eventName) { return eventName.indexOf('local::') < 0; });
3057
3058 localEvents.forEach(function (event) {
3059 if (self.eventsListeners && self.eventsListeners[event]) {
3060 var handlers = [];
3061 self.eventsListeners[event].forEach(function (eventHandler) {
3062 handlers.push(eventHandler);
3063 });
3064 handlers.forEach(function (eventHandler) {
3065 eventHandler.apply(context, data);
3066 });
3067 }
3068 });
3069 if (eventsParents && eventsParents.length > 0) {
3070 eventsParents.forEach(function (eventsParent) {
3071 eventsParent.emit.apply(eventsParent, [ parentEvents ].concat( data ));
3072 });
3073 }
3074 return self;
3075 };
3076
3077 var Framework7Class = /*@__PURE__*/(function (EventsClass$$1) {
3078 function Framework7Class(params, parents) {
3079 if ( params === void 0 ) params = {};
3080 if ( parents === void 0 ) parents = [];
3081
3082 EventsClass$$1.call(this, parents);
3083 var self = this;
3084 self.params = params;
3085
3086 if (self.params && self.params.on) {
3087 Object.keys(self.params.on).forEach(function (eventName) {
3088 self.on(eventName, self.params.on[eventName]);
3089 });
3090 }
3091 }
3092
3093 if ( EventsClass$$1 ) Framework7Class.__proto__ = EventsClass$$1;
3094 Framework7Class.prototype = Object.create( EventsClass$$1 && EventsClass$$1.prototype );
3095 Framework7Class.prototype.constructor = Framework7Class;
3096
3097 var staticAccessors = { components: { configurable: true } };
3098
3099 // eslint-disable-next-line
3100 Framework7Class.prototype.useModuleParams = function useModuleParams (module, instanceParams) {
3101 if (module.params) {
3102 var originalParams = {};
3103 Object.keys(module.params).forEach(function (paramKey) {
3104 if (typeof instanceParams[paramKey] === 'undefined') { return; }
3105 originalParams[paramKey] = Utils.extend({}, instanceParams[paramKey]);
3106 });
3107 Utils.extend(instanceParams, module.params);
3108 Object.keys(originalParams).forEach(function (paramKey) {
3109 Utils.extend(instanceParams[paramKey], originalParams[paramKey]);
3110 });
3111 }
3112 };
3113
3114 Framework7Class.prototype.useModulesParams = function useModulesParams (instanceParams) {
3115 var instance = this;
3116 if (!instance.modules) { return; }
3117 Object.keys(instance.modules).forEach(function (moduleName) {
3118 var module = instance.modules[moduleName];
3119 // Extend params
3120 if (module.params) {
3121 Utils.extend(instanceParams, module.params);
3122 }
3123 });
3124 };
3125
3126 Framework7Class.prototype.useModule = function useModule (moduleName, moduleParams) {
3127 if ( moduleName === void 0 ) moduleName = '';
3128 if ( moduleParams === void 0 ) moduleParams = {};
3129
3130 var instance = this;
3131 if (!instance.modules) { return; }
3132 var module = typeof moduleName === 'string' ? instance.modules[moduleName] : moduleName;
3133 if (!module) { return; }
3134
3135 // Extend instance methods and props
3136 if (module.instance) {
3137 Object.keys(module.instance).forEach(function (modulePropName) {
3138 var moduleProp = module.instance[modulePropName];
3139 if (typeof moduleProp === 'function') {
3140 instance[modulePropName] = moduleProp.bind(instance);
3141 } else {
3142 instance[modulePropName] = moduleProp;
3143 }
3144 });
3145 }
3146 // Add event listeners
3147 if (module.on && instance.on) {
3148 Object.keys(module.on).forEach(function (moduleEventName) {
3149 instance.on(moduleEventName, module.on[moduleEventName]);
3150 });
3151 }
3152 // Add vnode hooks
3153 if (module.vnode) {
3154 if (!instance.vnodeHooks) { instance.vnodeHooks = {}; }
3155 Object.keys(module.vnode).forEach(function (vnodeId) {
3156 Object.keys(module.vnode[vnodeId]).forEach(function (hookName) {
3157 var handler = module.vnode[vnodeId][hookName];
3158 if (!instance.vnodeHooks[hookName]) { instance.vnodeHooks[hookName] = {}; }
3159 if (!instance.vnodeHooks[hookName][vnodeId]) { instance.vnodeHooks[hookName][vnodeId] = []; }
3160 instance.vnodeHooks[hookName][vnodeId].push(handler.bind(instance));
3161 });
3162 });
3163 }
3164 // Module create callback
3165 if (module.create) {
3166 module.create.bind(instance)(moduleParams);
3167 }
3168 };
3169
3170 Framework7Class.prototype.useModules = function useModules (modulesParams) {
3171 if ( modulesParams === void 0 ) modulesParams = {};
3172
3173 var instance = this;
3174 if (!instance.modules) { return; }
3175 Object.keys(instance.modules).forEach(function (moduleName) {
3176 var moduleParams = modulesParams[moduleName] || {};
3177 instance.useModule(moduleName, moduleParams);
3178 });
3179 };
3180
3181 staticAccessors.components.set = function (components) {
3182 var Class = this;
3183 if (!Class.use) { return; }
3184 Class.use(components);
3185 };
3186
3187 Framework7Class.installModule = function installModule (module) {
3188 var params = [], len = arguments.length - 1;
3189 while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];
3190
3191 var Class = this;
3192 if (!Class.prototype.modules) { Class.prototype.modules = {}; }
3193 var name = module.name || (((Object.keys(Class.prototype.modules).length) + "_" + (Utils.now())));
3194 Class.prototype.modules[name] = module;
3195 // Prototype
3196 if (module.proto) {
3197 Object.keys(module.proto).forEach(function (key) {
3198 Class.prototype[key] = module.proto[key];
3199 });
3200 }
3201 // Class
3202 if (module.static) {
3203 Object.keys(module.static).forEach(function (key) {
3204 Class[key] = module.static[key];
3205 });
3206 }
3207 // Callback
3208 if (module.install) {
3209 module.install.apply(Class, params);
3210 }
3211 return Class;
3212 };
3213
3214 Framework7Class.use = function use (module) {
3215 var params = [], len = arguments.length - 1;
3216 while ( len-- > 0 ) params[ len ] = arguments[ len + 1 ];
3217
3218 var Class = this;
3219 if (Array.isArray(module)) {
3220 module.forEach(function (m) { return Class.installModule(m); });
3221 return Class;
3222 }
3223 return Class.installModule.apply(Class, [ module ].concat( params ));
3224 };
3225
3226 Object.defineProperties( Framework7Class, staticAccessors );
3227
3228 return Framework7Class;
3229 }(EventsClass));
3230
3231 function ConstructorMethods (parameters) {
3232 if ( parameters === void 0 ) parameters = {};
3233
3234 var defaultSelector = parameters.defaultSelector;
3235 var constructor = parameters.constructor;
3236 var domProp = parameters.domProp;
3237 var app = parameters.app;
3238 var addMethods = parameters.addMethods;
3239 var methods = {
3240 create: function create() {
3241 var args = [], len = arguments.length;
3242 while ( len-- ) args[ len ] = arguments[ len ];
3243
3244 if (app) { return new (Function.prototype.bind.apply( constructor, [ null ].concat( [app], args) )); }
3245 return new (Function.prototype.bind.apply( constructor, [ null ].concat( args) ));
3246 },
3247 get: function get(el) {
3248 if ( el === void 0 ) el = defaultSelector;
3249
3250 if (el instanceof constructor) { return el; }
3251 var $el = $(el);
3252 if ($el.length === 0) { return undefined; }
3253 return $el[0][domProp];
3254 },
3255 destroy: function destroy(el) {
3256 var instance = methods.get(el);
3257 if (instance && instance.destroy) { return instance.destroy(); }
3258 return undefined;
3259 },
3260 };
3261 if (addMethods && Array.isArray(addMethods)) {
3262 addMethods.forEach(function (methodName) {
3263 methods[methodName] = function (el) {
3264 if ( el === void 0 ) el = defaultSelector;
3265 var args = [], len = arguments.length - 1;
3266 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
3267
3268 var instance = methods.get(el);
3269 if (instance && instance[methodName]) { return instance[methodName].apply(instance, args); }
3270 return undefined;
3271 };
3272 });
3273 }
3274 return methods;
3275 }
3276
3277 function ModalMethods (parameters) {
3278 if ( parameters === void 0 ) parameters = {};
3279
3280 var defaultSelector = parameters.defaultSelector;
3281 var constructor = parameters.constructor;
3282 var app = parameters.app;
3283 var methods = Utils.extend(
3284 ConstructorMethods({
3285 defaultSelector: defaultSelector,
3286 constructor: constructor,
3287 app: app,
3288 domProp: 'f7Modal',
3289 }),
3290 {
3291 open: function open(el, animate) {
3292 var $el = $(el);
3293 var instance = $el[0].f7Modal;
3294 if (!instance) { instance = new constructor(app, { el: $el }); }
3295 return instance.open(animate);
3296 },
3297 close: function close(el, animate) {
3298 if ( el === void 0 ) el = defaultSelector;
3299
3300 var $el = $(el);
3301 if ($el.length === 0) { return undefined; }
3302 var instance = $el[0].f7Modal;
3303 if (!instance) { instance = new constructor(app, { el: $el }); }
3304 return instance.close(animate);
3305 },
3306 }
3307 );
3308 return methods;
3309 }
3310
3311 var fetchedModules = [];
3312 function loadModule(moduleToLoad) {
3313 var Framework7 = this;
3314 return new Promise(function (resolve, reject) {
3315 var app = Framework7.instance;
3316 var modulePath;
3317 var moduleObj;
3318 var moduleFunc;
3319 if (!moduleToLoad) {
3320 reject(new Error('Framework7: Lazy module must be specified'));
3321 return;
3322 }
3323
3324 function install(module) {
3325 Framework7.use(module);
3326
3327 if (app) {
3328 app.useModuleParams(module, app.params);
3329 app.useModule(module);
3330 }
3331 }
3332
3333 if (typeof moduleToLoad === 'string') {
3334 var matchNamePattern = moduleToLoad.match(/([a-z0-9-]*)/i);
3335 if (moduleToLoad.indexOf('.') < 0 && matchNamePattern && matchNamePattern[0].length === moduleToLoad.length) {
3336 if (!app || (app && !app.params.lazyModulesPath)) {
3337 reject(new Error('Framework7: "lazyModulesPath" app parameter must be specified to fetch module by name'));
3338 return;
3339 }
3340 modulePath = (app.params.lazyModulesPath) + "/" + moduleToLoad + ".js";
3341 } else {
3342 modulePath = moduleToLoad;
3343 }
3344 } else if (typeof moduleToLoad === 'function') {
3345 moduleFunc = moduleToLoad;
3346 } else {
3347 // considering F7-Plugin object
3348 moduleObj = moduleToLoad;
3349 }
3350
3351 if (moduleFunc) {
3352 var module = moduleFunc(Framework7, false);
3353 if (!module) {
3354 reject(new Error('Framework7: Can\'t find Framework7 component in specified component function'));
3355 return;
3356 }
3357 // Check if it was added
3358 if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
3359 resolve();
3360 return;
3361 }
3362 // Install It
3363 install(module);
3364
3365 resolve();
3366 }
3367 if (moduleObj) {
3368 var module$1 = moduleObj;
3369 if (!module$1) {
3370 reject(new Error('Framework7: Can\'t find Framework7 component in specified component'));
3371 return;
3372 }
3373 // Check if it was added
3374 if (Framework7.prototype.modules && Framework7.prototype.modules[module$1.name]) {
3375 resolve();
3376 return;
3377 }
3378 // Install It
3379 install(module$1);
3380
3381 resolve();
3382 }
3383 if (modulePath) {
3384 if (fetchedModules.indexOf(modulePath) >= 0) {
3385 resolve();
3386 return;
3387 }
3388 fetchedModules.push(modulePath);
3389 var scriptLoad = new Promise(function (resolveScript, rejectScript) {
3390 Framework7.request.get(
3391 modulePath,
3392 function (scriptContent) {
3393 var id = Utils.id();
3394 var callbackLoadName = "f7_component_loader_callback_" + id;
3395
3396 var scriptEl = document.createElement('script');
3397 scriptEl.innerHTML = "window." + callbackLoadName + " = function (Framework7, Framework7AutoInstallComponent) {return " + (scriptContent.trim()) + "}";
3398 $('head').append(scriptEl);
3399
3400 var componentLoader = window[callbackLoadName];
3401 delete window[callbackLoadName];
3402 $(scriptEl).remove();
3403
3404 var module = componentLoader(Framework7, false);
3405
3406 if (!module) {
3407 rejectScript(new Error(("Framework7: Can't find Framework7 component in " + modulePath + " file")));
3408 return;
3409 }
3410
3411 // Check if it was added
3412 if (Framework7.prototype.modules && Framework7.prototype.modules[module.name]) {
3413 resolveScript();
3414 return;
3415 }
3416
3417 // Install It
3418 install(module);
3419
3420 resolveScript();
3421 },
3422 function (xhr, status) {
3423 rejectScript(xhr, status);
3424 }
3425 );
3426 });
3427 var styleLoad = new Promise(function (resolveStyle) {
3428 Framework7.request.get(
3429 modulePath.replace('.js', app.rtl ? '.rtl.css' : '.css'),
3430 function (styleContent) {
3431 var styleEl = document.createElement('style');
3432 styleEl.innerHTML = styleContent;
3433 $('head').append(styleEl);
3434
3435 resolveStyle();
3436 },
3437 function () {
3438 resolveStyle();
3439 }
3440 );
3441 });
3442
3443 Promise.all([scriptLoad, styleLoad]).then(function () {
3444 resolve();
3445 }).catch(function (err) {
3446 reject(err);
3447 });
3448 }
3449 });
3450 }
3451
3452 var Framework7 = /*@__PURE__*/(function (Framework7Class$$1) {
3453 function Framework7(params) {
3454 Framework7Class$$1.call(this, params);
3455 if (Framework7.instance) {
3456 throw new Error('Framework7 is already initialized and can\'t be initialized more than once');
3457 }
3458
3459 var passedParams = Utils.extend({}, params);
3460
3461 // App Instance
3462 var app = this;
3463
3464 Framework7.instance = app;
3465
3466 // Default
3467 var defaults = {
3468 version: '1.0.0',
3469 id: 'io.framework7.testapp',
3470 root: 'body',
3471 theme: 'auto',
3472 language: win.navigator.language,
3473 routes: [],
3474 name: 'Framework7',
3475 lazyModulesPath: null,
3476 initOnDeviceReady: true,
3477 init: true,
3478 };
3479
3480 // Extend defaults with modules params
3481 app.useModulesParams(defaults);
3482
3483 // Extend defaults with passed params
3484 app.params = Utils.extend(defaults, params);
3485
3486 var $rootEl = $(app.params.root);
3487
3488 Utils.extend(app, {
3489 // App Id
3490 id: app.params.id,
3491 // App Name
3492 name: app.params.name,
3493 // App version
3494 version: app.params.version,
3495 // Routes
3496 routes: app.params.routes,
3497 // Lang
3498 language: app.params.language,
3499 // Root
3500 root: $rootEl,
3501 // RTL
3502 rtl: $rootEl.css('direction') === 'rtl',
3503 // Theme
3504 theme: (function getTheme() {
3505 if (app.params.theme === 'auto') {
3506 return Device.ios ? 'ios' : 'md';
3507 }
3508 return app.params.theme;
3509 }()),
3510 // Initially passed parameters
3511 passedParams: passedParams,
3512 });
3513
3514 // Save Root
3515 if (app.root && app.root[0]) {
3516 app.root[0].f7 = app;
3517 }
3518
3519 // Install Modules
3520 app.useModules();
3521
3522 // Init Data & Methods
3523 app.initData();
3524
3525 // Init
3526 if (app.params.init) {
3527 if (Device.cordova && app.params.initOnDeviceReady) {
3528 $(doc).on('deviceready', function () {
3529 app.init();
3530 });
3531 } else {
3532 app.init();
3533 }
3534 }
3535 // Return app instance
3536 return app;
3537 }
3538
3539 if ( Framework7Class$$1 ) Framework7.__proto__ = Framework7Class$$1;
3540 Framework7.prototype = Object.create( Framework7Class$$1 && Framework7Class$$1.prototype );
3541 Framework7.prototype.constructor = Framework7;
3542
3543 var prototypeAccessors = { $: { configurable: true },t7: { configurable: true } };
3544 var staticAccessors = { Dom7: { configurable: true },$: { configurable: true },Template7: { configurable: true },Class: { configurable: true },Events: { configurable: true } };
3545
3546 Framework7.prototype.initData = function initData () {
3547 var app = this;
3548
3549 // Data
3550 app.data = {};
3551 if (app.params.data && typeof app.params.data === 'function') {
3552 Utils.extend(app.data, app.params.data.bind(app)());
3553 } else if (app.params.data) {
3554 Utils.extend(app.data, app.params.data);
3555 }
3556 // Methods
3557 app.methods = {};
3558 if (app.params.methods) {
3559 Object.keys(app.params.methods).forEach(function (methodName) {
3560 if (typeof app.params.methods[methodName] === 'function') {
3561 app.methods[methodName] = app.params.methods[methodName].bind(app);
3562 } else {
3563 app.methods[methodName] = app.params.methods[methodName];
3564 }
3565 });
3566 }
3567 };
3568
3569 Framework7.prototype.init = function init () {
3570 var app = this;
3571 if (app.initialized) { return app; }
3572
3573 app.root.addClass('framework7-initializing');
3574
3575 // RTL attr
3576 if (app.rtl) {
3577 $('html').attr('dir', 'rtl');
3578 }
3579
3580 // Root class
3581 app.root.addClass('framework7-root');
3582
3583 // Theme class
3584 $('html').removeClass('ios md').addClass(app.theme);
3585
3586 // Init class
3587 Utils.nextFrame(function () {
3588 app.root.removeClass('framework7-initializing');
3589 });
3590 // Emit, init other modules
3591 app.initialized = true;
3592 app.emit('init');
3593
3594 return app;
3595 };
3596
3597 // eslint-disable-next-line
3598 Framework7.prototype.loadModule = function loadModule$$1 () {
3599 var args = [], len = arguments.length;
3600 while ( len-- ) args[ len ] = arguments[ len ];
3601
3602 return Framework7.loadModule.apply(Framework7, args);
3603 };
3604
3605 // eslint-disable-next-line
3606 Framework7.prototype.loadModules = function loadModules () {
3607 var args = [], len = arguments.length;
3608 while ( len-- ) args[ len ] = arguments[ len ];
3609
3610 return Framework7.loadModules.apply(Framework7, args);
3611 };
3612
3613 Framework7.prototype.getVnodeHooks = function getVnodeHooks (hook, id) {
3614 var app = this;
3615 if (!app.vnodeHooks || !app.vnodeHooks[hook]) { return []; }
3616 return app.vnodeHooks[hook][id] || [];
3617 };
3618
3619 // eslint-disable-next-line
3620 prototypeAccessors.$.get = function () {
3621 return $;
3622 };
3623 // eslint-disable-next-line
3624 prototypeAccessors.t7.get = function () {
3625 return Template7;
3626 };
3627
3628 staticAccessors.Dom7.get = function () {
3629 return $;
3630 };
3631
3632 staticAccessors.$.get = function () {
3633 return $;
3634 };
3635
3636 staticAccessors.Template7.get = function () {
3637 return Template7;
3638 };
3639
3640 staticAccessors.Class.get = function () {
3641 return Framework7Class$$1;
3642 };
3643
3644 staticAccessors.Events.get = function () {
3645 return EventsClass;
3646 };
3647
3648 Object.defineProperties( Framework7.prototype, prototypeAccessors );
3649 Object.defineProperties( Framework7, staticAccessors );
3650
3651 return Framework7;
3652 }(Framework7Class));
3653
3654 Framework7.ModalMethods = ModalMethods;
3655 Framework7.ConstructorMethods = ConstructorMethods;
3656
3657 Framework7.loadModule = loadModule;
3658 Framework7.loadModules = function loadModules(modules) {
3659 return Promise.all(modules.map(function (module) { return Framework7.loadModule(module); }));
3660 };
3661
3662 var DeviceModule = {
3663 name: 'device',
3664 proto: {
3665 device: Device,
3666 },
3667 static: {
3668 device: Device,
3669 },
3670 on: {
3671 init: function init() {
3672 var classNames = [];
3673 var html = doc.querySelector('html');
3674 var metaStatusbar = doc.querySelector('meta[name="apple-mobile-web-app-status-bar-style"]');
3675 if (!html) { return; }
3676 if (Device.standalone && Device.ios && metaStatusbar && metaStatusbar.content === 'black-translucent') {
3677 classNames.push('device-full-viewport');
3678 }
3679
3680 // Pixel Ratio
3681 classNames.push(("device-pixel-ratio-" + (Math.floor(Device.pixelRatio))));
3682 if (Device.pixelRatio >= 2) {
3683 classNames.push('device-retina');
3684 }
3685 // OS classes
3686 if (Device.os) {
3687 classNames.push(
3688 ("device-" + (Device.os)),
3689 ("device-" + (Device.os) + "-" + (Device.osVersion.split('.')[0])),
3690 ("device-" + (Device.os) + "-" + (Device.osVersion.replace(/\./g, '-')))
3691 );
3692 if (Device.os === 'ios') {
3693 var major = parseInt(Device.osVersion.split('.')[0], 10);
3694 for (var i = major - 1; i >= 6; i -= 1) {
3695 classNames.push(("device-ios-gt-" + i));
3696 }
3697 if (Device.iphoneX) {
3698 classNames.push('device-iphone-x');
3699 }
3700 }
3701 } else if (Device.desktop) {
3702 classNames.push('device-desktop');
3703 if (Device.macos) { classNames.push('device-macos'); }
3704 else if (Device.windows) { classNames.push('device-windows'); }
3705 }
3706 if (Device.cordova || Device.phonegap) {
3707 classNames.push('device-cordova');
3708 }
3709
3710 // Add html classes
3711 classNames.forEach(function (className) {
3712 html.classList.add(className);
3713 });
3714 },
3715 },
3716 };
3717
3718 var Support = (function Support() {
3719 var testDiv = doc.createElement('div');
3720
3721 return {
3722 touch: (function checkTouch() {
3723 return !!((win.navigator.maxTouchPoints > 0) || ('ontouchstart' in win) || (win.DocumentTouch && doc instanceof win.DocumentTouch));
3724 }()),
3725
3726 pointerEvents: !!(win.navigator.pointerEnabled || win.PointerEvent || ('maxTouchPoints' in win.navigator)),
3727 prefixedPointerEvents: !!win.navigator.msPointerEnabled,
3728
3729 transition: (function checkTransition() {
3730 var style = testDiv.style;
3731 return ('transition' in style || 'webkitTransition' in style || 'MozTransition' in style);
3732 }()),
3733 transforms3d: (win.Modernizr && win.Modernizr.csstransforms3d === true) || (function checkTransforms3d() {
3734 var style = testDiv.style;
3735 return ('webkitPerspective' in style || 'MozPerspective' in style || 'OPerspective' in style || 'MsPerspective' in style || 'perspective' in style);
3736 }()),
3737
3738 flexbox: (function checkFlexbox() {
3739 var div = doc.createElement('div').style;
3740 var styles = ('alignItems webkitAlignItems webkitBoxAlign msFlexAlign mozBoxAlign webkitFlexDirection msFlexDirection mozBoxDirection mozBoxOrient webkitBoxDirection webkitBoxOrient').split(' ');
3741 for (var i = 0; i < styles.length; i += 1) {
3742 if (styles[i] in div) { return true; }
3743 }
3744 return false;
3745 }()),
3746
3747 observer: (function checkObserver() {
3748 return ('MutationObserver' in win || 'WebkitMutationObserver' in win);
3749 }()),
3750
3751 passiveListener: (function checkPassiveListener() {
3752 var supportsPassive = false;
3753 try {
3754 var opts = Object.defineProperty({}, 'passive', {
3755 // eslint-disable-next-line
3756 get: function get() {
3757 supportsPassive = true;
3758 },
3759 });
3760 win.addEventListener('testPassiveListener', null, opts);
3761 } catch (e) {
3762 // No support
3763 }
3764 return supportsPassive;
3765 }()),
3766
3767 gestures: (function checkGestures() {
3768 return 'ongesturestart' in win;
3769 }()),
3770
3771 intersectionObserver: (function checkObserver() {
3772 return ('IntersectionObserver' in win);
3773 }()),
3774 };
3775 }());
3776
3777 var SupportModule = {
3778 name: 'support',
3779 proto: {
3780 support: Support,
3781 },
3782 static: {
3783 support: Support,
3784 },
3785 on: {
3786 init: function init() {
3787 var html = doc.querySelector('html');
3788 if (!html) { return; }
3789 var classNames = [];
3790 // Add html classes
3791 classNames.forEach(function (className) {
3792 html.classList.add(className);
3793 });
3794 },
3795 },
3796 };
3797
3798 var UtilsModule = {
3799 name: 'utils',
3800 proto: {
3801 utils: Utils,
3802 },
3803 static: {
3804 utils: Utils,
3805 },
3806 };
3807
3808 var ResizeModule = {
3809 name: 'resize',
3810 instance: {
3811 getSize: function getSize() {
3812 var app = this;
3813 if (!app.root[0]) { return { width: 0, height: 0, left: 0, top: 0 }; }
3814 var offset = app.root.offset();
3815 var ref = [app.root[0].offsetWidth, app.root[0].offsetHeight, offset.left, offset.top];
3816 var width = ref[0];
3817 var height = ref[1];
3818 var left = ref[2];
3819 var top = ref[3];
3820 app.width = width;
3821 app.height = height;
3822 app.left = left;
3823 app.top = top;
3824 return { width: width, height: height, left: left, top: top };
3825 },
3826 },
3827 on: {
3828 init: function init() {
3829 var app = this;
3830
3831 // Get Size
3832 app.getSize();
3833
3834 // Emit resize
3835 win.addEventListener('resize', function () {
3836 app.emit('resize');
3837 }, false);
3838
3839 // Emit orientationchange
3840 win.addEventListener('orientationchange', function () {
3841 app.emit('orientationchange');
3842 });
3843 },
3844 orientationchange: function orientationchange() {
3845 var app = this;
3846 if (app.device && app.device.minimalUi) {
3847 if (win.orientation === 90 || win.orientation === -90) {
3848 doc.body.scrollTop = 0;
3849 }
3850 }
3851 // Fix iPad weird body scroll
3852 if (app.device.ipad) {
3853 doc.body.scrollLeft = 0;
3854 setTimeout(function () {
3855 doc.body.scrollLeft = 0;
3856 }, 0);
3857 }
3858 },
3859 resize: function resize() {
3860 var app = this;
3861 app.getSize();
3862 },
3863 },
3864 };
3865
3866 var globals = {};
3867 var jsonpRequests = 0;
3868
3869 function Request(requestOptions) {
3870 var globalsNoCallbacks = Utils.extend({}, globals);
3871 ('beforeCreate beforeOpen beforeSend error complete success statusCode').split(' ').forEach(function (callbackName) {
3872 delete globalsNoCallbacks[callbackName];
3873 });
3874 var defaults = Utils.extend({
3875 url: win.location.toString(),
3876 method: 'GET',
3877 data: false,
3878 async: true,
3879 cache: true,
3880 user: '',
3881 password: '',
3882 headers: {},
3883 xhrFields: {},
3884 statusCode: {},
3885 processData: true,
3886 dataType: 'text',
3887 contentType: 'application/x-www-form-urlencoded',
3888 timeout: 0,
3889 }, globalsNoCallbacks);
3890
3891 var options = Utils.extend({}, defaults, requestOptions);
3892 var proceedRequest;
3893
3894 // Function to run XHR callbacks and events
3895 function fireCallback(callbackName) {
3896 var data = [], len = arguments.length - 1;
3897 while ( len-- > 0 ) data[ len ] = arguments[ len + 1 ];
3898
3899 /*
3900 Callbacks:
3901 beforeCreate (options),
3902 beforeOpen (xhr, options),
3903 beforeSend (xhr, options),
3904 error (xhr, status),
3905 complete (xhr, stautus),
3906 success (response, status, xhr),
3907 statusCode ()
3908 */
3909 var globalCallbackValue;
3910 var optionCallbackValue;
3911 if (globals[callbackName]) {
3912 globalCallbackValue = globals[callbackName].apply(globals, data);
3913 }
3914 if (options[callbackName]) {
3915 optionCallbackValue = options[callbackName].apply(options, data);
3916 }
3917 if (typeof globalCallbackValue !== 'boolean') { globalCallbackValue = true; }
3918 if (typeof optionCallbackValue !== 'boolean') { optionCallbackValue = true; }
3919 return (globalCallbackValue && optionCallbackValue);
3920 }
3921
3922 // Before create callback
3923 proceedRequest = fireCallback('beforeCreate', options);
3924 if (proceedRequest === false) { return undefined; }
3925
3926 // For jQuery guys
3927 if (options.type) { options.method = options.type; }
3928
3929 // Parameters Prefix
3930 var paramsPrefix = options.url.indexOf('?') >= 0 ? '&' : '?';
3931
3932 // UC method
3933 var method = options.method.toUpperCase();
3934
3935 // Data to modify GET URL
3936 if ((method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') && options.data) {
3937 var stringData;
3938 if (typeof options.data === 'string') {
3939 // Should be key=value string
3940 if (options.data.indexOf('?') >= 0) { stringData = options.data.split('?')[1]; }
3941 else { stringData = options.data; }
3942 } else {
3943 // Should be key=value object
3944 stringData = Utils.serializeObject(options.data);
3945 }
3946 if (stringData.length) {
3947 options.url += paramsPrefix + stringData;
3948 if (paramsPrefix === '?') { paramsPrefix = '&'; }
3949 }
3950 }
3951
3952 // JSONP
3953 if (options.dataType === 'json' && options.url.indexOf('callback=') >= 0) {
3954 var callbackName = "f7jsonp_" + (Date.now() + ((jsonpRequests += 1)));
3955 var abortTimeout;
3956 var callbackSplit = options.url.split('callback=');
3957 var requestUrl = (callbackSplit[0]) + "callback=" + callbackName;
3958 if (callbackSplit[1].indexOf('&') >= 0) {
3959 var addVars = callbackSplit[1].split('&').filter(function (el) { return el.indexOf('=') > 0; }).join('&');
3960 if (addVars.length > 0) { requestUrl += "&" + addVars; }
3961 }
3962
3963 // Create script
3964 var script = doc.createElement('script');
3965 script.type = 'text/javascript';
3966 script.onerror = function onerror() {
3967 clearTimeout(abortTimeout);
3968 fireCallback('error', null, 'scripterror');
3969 fireCallback('complete', null, 'scripterror');
3970 };
3971 script.src = requestUrl;
3972
3973 // Handler
3974 win[callbackName] = function jsonpCallback(data) {
3975 clearTimeout(abortTimeout);
3976 fireCallback('success', data);
3977 script.parentNode.removeChild(script);
3978 script = null;
3979 delete win[callbackName];
3980 };
3981 doc.querySelector('head').appendChild(script);
3982
3983 if (options.timeout > 0) {
3984 abortTimeout = setTimeout(function () {
3985 script.parentNode.removeChild(script);
3986 script = null;
3987 fireCallback('error', null, 'timeout');
3988 }, options.timeout);
3989 }
3990
3991 return undefined;
3992 }
3993
3994 // Cache for GET/HEAD requests
3995 if (method === 'GET' || method === 'HEAD' || method === 'OPTIONS' || method === 'DELETE') {
3996 if (options.cache === false) {
3997 options.url += paramsPrefix + "_nocache" + (Date.now());
3998 }
3999 }
4000
4001 // Create XHR
4002 var xhr = new XMLHttpRequest();
4003
4004 // Save Request URL
4005 xhr.requestUrl = options.url;
4006 xhr.requestParameters = options;
4007
4008 // Before open callback
4009 proceedRequest = fireCallback('beforeOpen', xhr, options);
4010 if (proceedRequest === false) { return xhr; }
4011
4012 // Open XHR
4013 xhr.open(method, options.url, options.async, options.user, options.password);
4014
4015 // Create POST Data
4016 var postData = null;
4017
4018 if ((method === 'POST' || method === 'PUT' || method === 'PATCH') && options.data) {
4019 if (options.processData) {
4020 var postDataInstances = [ArrayBuffer, Blob, Document, FormData];
4021 // Post Data
4022 if (postDataInstances.indexOf(options.data.constructor) >= 0) {
4023 postData = options.data;
4024 } else {
4025 // POST Headers
4026 var boundary = "---------------------------" + (Date.now().toString(16));
4027
4028 if (options.contentType === 'multipart/form-data') {
4029 xhr.setRequestHeader('Content-Type', ("multipart/form-data; boundary=" + boundary));
4030 } else {
4031 xhr.setRequestHeader('Content-Type', options.contentType);
4032 }
4033 postData = '';
4034 var data$1 = Utils.serializeObject(options.data);
4035 if (options.contentType === 'multipart/form-data') {
4036 data$1 = data$1.split('&');
4037 var newData = [];
4038 for (var i = 0; i < data$1.length; i += 1) {
4039 newData.push(("Content-Disposition: form-data; name=\"" + (data$1[i].split('=')[0]) + "\"\r\n\r\n" + (data$1[i].split('=')[1]) + "\r\n"));
4040 }
4041 postData = "--" + boundary + "\r\n" + (newData.join(("--" + boundary + "\r\n"))) + "--" + boundary + "--\r\n";
4042 } else if (options.contentType === 'application/json') {
4043 postData = JSON.stringify(options.data);
4044 } else {
4045 postData = data$1;
4046 }
4047 }
4048 } else {
4049 postData = options.data;
4050 xhr.setRequestHeader('Content-Type', options.contentType);
4051 }
4052 }
4053
4054 // Additional headers
4055 if (options.headers) {
4056 Object.keys(options.headers).forEach(function (headerName) {
4057 xhr.setRequestHeader(headerName, options.headers[headerName]);
4058 });
4059 }
4060
4061 // Check for crossDomain
4062 if (typeof options.crossDomain === 'undefined') {
4063 // eslint-disable-next-line
4064 options.crossDomain = /^([\w-]+:)?\/\/([^\/]+)/.test(options.url) && RegExp.$2 !== win.location.host;
4065 }
4066
4067 if (!options.crossDomain) {
4068 xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
4069 }
4070
4071 if (options.xhrFields) {
4072 Utils.extend(xhr, options.xhrFields);
4073 }
4074
4075 var xhrTimeout;
4076
4077 // Handle XHR
4078 xhr.onload = function onload() {
4079 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4080 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 0) {
4081 var responseData;
4082 if (options.dataType === 'json') {
4083 var parseError;
4084 try {
4085 responseData = JSON.parse(xhr.responseText);
4086 } catch (err) {
4087 parseError = true;
4088 }
4089 if (!parseError) {
4090 fireCallback('success', responseData, xhr.status, xhr);
4091 } else {
4092 fireCallback('error', xhr, 'parseerror');
4093 }
4094 } else {
4095 responseData = xhr.responseType === 'text' || xhr.responseType === '' ? xhr.responseText : xhr.response;
4096 fireCallback('success', responseData, xhr.status, xhr);
4097 }
4098 } else {
4099 fireCallback('error', xhr, xhr.status);
4100 }
4101 if (options.statusCode) {
4102 if (globals.statusCode && globals.statusCode[xhr.status]) { globals.statusCode[xhr.status](xhr); }
4103 if (options.statusCode[xhr.status]) { options.statusCode[xhr.status](xhr); }
4104 }
4105 fireCallback('complete', xhr, xhr.status);
4106 };
4107
4108 xhr.onerror = function onerror() {
4109 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4110 fireCallback('error', xhr, xhr.status);
4111 fireCallback('complete', xhr, 'error');
4112 };
4113
4114 // Timeout
4115 if (options.timeout > 0) {
4116 xhr.onabort = function onabort() {
4117 if (xhrTimeout) { clearTimeout(xhrTimeout); }
4118 };
4119 xhrTimeout = setTimeout(function () {
4120 xhr.abort();
4121 fireCallback('error', xhr, 'timeout');
4122 fireCallback('complete', xhr, 'timeout');
4123 }, options.timeout);
4124 }
4125
4126 // Ajax start callback
4127 proceedRequest = fireCallback('beforeSend', xhr, options);
4128 if (proceedRequest === false) { return xhr; }
4129
4130 // Send XHR
4131 xhr.send(postData);
4132
4133 // Return XHR object
4134 return xhr;
4135 }
4136 function RequestShortcut(method) {
4137 var assign, assign$1;
4138
4139 var args = [], len = arguments.length - 1;
4140 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
4141 var ref = [];
4142 var url = ref[0];
4143 var data = ref[1];
4144 var success = ref[2];
4145 var error = ref[3];
4146 var dataType = ref[4];
4147 if (typeof args[1] === 'function') {
4148 (assign = args, url = assign[0], success = assign[1], error = assign[2], dataType = assign[3]);
4149 } else {
4150 (assign$1 = args, url = assign$1[0], data = assign$1[1], success = assign$1[2], error = assign$1[3], dataType = assign$1[4]);
4151 }
4152 [success, error].forEach(function (callback) {
4153 if (typeof callback === 'string') {
4154 dataType = callback;
4155 if (callback === success) { success = undefined; }
4156 else { error = undefined; }
4157 }
4158 });
4159 dataType = dataType || (method === 'json' || method === 'postJSON' ? 'json' : undefined);
4160 var requestOptions = {
4161 url: url,
4162 method: method === 'post' || method === 'postJSON' ? 'POST' : 'GET',
4163 data: data,
4164 success: success,
4165 error: error,
4166 dataType: dataType,
4167 };
4168 if (method === 'postJSON') {
4169 Utils.extend(requestOptions, {
4170 contentType: 'application/json',
4171 processData: false,
4172 crossDomain: true,
4173 data: typeof data === 'string' ? data : JSON.stringify(data),
4174 });
4175 }
4176 return Request(requestOptions);
4177 }
4178 function RequestShortcutPromise(method) {
4179 var args = [], len = arguments.length - 1;
4180 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
4181
4182 var url = args[0];
4183 var data = args[1];
4184 var dataType = args[2];
4185 return new Promise(function (resolve, reject) {
4186 RequestShortcut(
4187 method,
4188 url,
4189 data,
4190 function (response) {
4191 resolve(response);
4192 },
4193 function (xhr, status) {
4194 reject(status);
4195 },
4196 dataType
4197 );
4198 });
4199 }
4200 Object.assign(Request, {
4201 get: function () {
4202 var args = [], len = arguments.length;
4203 while ( len-- ) args[ len ] = arguments[ len ];
4204
4205 return RequestShortcut.apply(void 0, [ 'get' ].concat( args ));
4206 },
4207 post: function () {
4208 var args = [], len = arguments.length;
4209 while ( len-- ) args[ len ] = arguments[ len ];
4210
4211 return RequestShortcut.apply(void 0, [ 'post' ].concat( args ));
4212 },
4213 json: function () {
4214 var args = [], len = arguments.length;
4215 while ( len-- ) args[ len ] = arguments[ len ];
4216
4217 return RequestShortcut.apply(void 0, [ 'json' ].concat( args ));
4218 },
4219 getJSON: function () {
4220 var args = [], len = arguments.length;
4221 while ( len-- ) args[ len ] = arguments[ len ];
4222
4223 return RequestShortcut.apply(void 0, [ 'json' ].concat( args ));
4224 },
4225 postJSON: function () {
4226 var args = [], len = arguments.length;
4227 while ( len-- ) args[ len ] = arguments[ len ];
4228
4229 return RequestShortcut.apply(void 0, [ 'postJSON' ].concat( args ));
4230 },
4231 });
4232
4233 Request.promise = function requestPromise(requestOptions) {
4234 return new Promise(function (resolve, reject) {
4235 Request(Object.assign(requestOptions, {
4236 success: function success(data) {
4237 resolve(data);
4238 },
4239 error: function error(xhr, status) {
4240 reject(status);
4241 },
4242 }));
4243 });
4244 };
4245 Object.assign(Request.promise, {
4246 get: function () {
4247 var args = [], len = arguments.length;
4248 while ( len-- ) args[ len ] = arguments[ len ];
4249
4250 return RequestShortcutPromise.apply(void 0, [ 'get' ].concat( args ));
4251 },
4252 post: function () {
4253 var args = [], len = arguments.length;
4254 while ( len-- ) args[ len ] = arguments[ len ];
4255
4256 return RequestShortcutPromise.apply(void 0, [ 'post' ].concat( args ));
4257 },
4258 json: function () {
4259 var args = [], len = arguments.length;
4260 while ( len-- ) args[ len ] = arguments[ len ];
4261
4262 return RequestShortcutPromise.apply(void 0, [ 'json' ].concat( args ));
4263 },
4264 getJSON: function () {
4265 var args = [], len = arguments.length;
4266 while ( len-- ) args[ len ] = arguments[ len ];
4267
4268 return RequestShortcutPromise.apply(void 0, [ 'json' ].concat( args ));
4269 },
4270 postJSON: function () {
4271 var args = [], len = arguments.length;
4272 while ( len-- ) args[ len ] = arguments[ len ];
4273
4274 return RequestShortcutPromise.apply(void 0, [ 'postJSON' ].concat( args ));
4275 },
4276 });
4277
4278 Request.setup = function setup(options) {
4279 if (options.type && !options.method) {
4280 Utils.extend(options, { method: options.type });
4281 }
4282 Utils.extend(globals, options);
4283 };
4284
4285 /* eslint no-param-reassign: "off" */
4286
4287 var RequestModule = {
4288 name: 'request',
4289 proto: {
4290 request: Request,
4291 },
4292 static: {
4293 request: Request,
4294 },
4295 };
4296
4297 function initTouch() {
4298 var app = this;
4299 var params = app.params.touch;
4300 var useRipple = params[((app.theme) + "TouchRipple")];
4301
4302 if (Device.ios && Device.webView) {
4303 // Strange hack required for iOS 8 webview to work on inputs
4304 win.addEventListener('touchstart', function () {});
4305 }
4306
4307 var touchStartX;
4308 var touchStartY;
4309 var touchStartTime;
4310 var targetElement;
4311 var trackClick;
4312 var activeSelection;
4313 var scrollParent;
4314 var lastClickTime;
4315 var isMoved;
4316 var tapHoldFired;
4317 var tapHoldTimeout;
4318 var preventClick;
4319
4320 var activableElement;
4321 var activeTimeout;
4322
4323 var needsFastClick;
4324 var needsFastClickTimeOut;
4325
4326 var rippleWave;
4327 var rippleTarget;
4328 var rippleTimeout;
4329
4330 function findActivableElement(el) {
4331 var target = $(el);
4332 var parents = target.parents(params.activeStateElements);
4333 var activable;
4334 if (target.is(params.activeStateElements)) {
4335 activable = target;
4336 }
4337 if (parents.length > 0) {
4338 activable = activable ? activable.add(parents) : parents;
4339 }
4340 return activable || target;
4341 }
4342
4343 function isInsideScrollableViewLight(el) {
4344 var pageContent = el.parents('.page-content');
4345 return pageContent.length > 0;
4346 }
4347 function isInsideScrollableView(el) {
4348 var pageContent = el.parents('.page-content');
4349
4350 if (pageContent.length === 0) {
4351 return false;
4352 }
4353
4354 // This event handler covers the "tap to stop scrolling".
4355 if (pageContent.prop('scrollHandlerSet') !== 'yes') {
4356 pageContent.on('scroll', function () {
4357 clearTimeout(activeTimeout);
4358 clearTimeout(rippleTimeout);
4359 });
4360 pageContent.prop('scrollHandlerSet', 'yes');
4361 }
4362
4363 return true;
4364 }
4365 function addActive() {
4366 if (!activableElement) { return; }
4367 activableElement.addClass('active-state');
4368 }
4369 function removeActive() {
4370 if (!activableElement) { return; }
4371 activableElement.removeClass('active-state');
4372 activableElement = null;
4373 }
4374 function isFormElement(el) {
4375 var nodes = ('input select textarea label').split(' ');
4376 if (el.nodeName && nodes.indexOf(el.nodeName.toLowerCase()) >= 0) { return true; }
4377 return false;
4378 }
4379 function androidNeedsBlur(el) {
4380 var noBlur = ('button input textarea select').split(' ');
4381 if (doc.activeElement && el !== doc.activeElement && doc.activeElement !== doc.body) {
4382 if (noBlur.indexOf(el.nodeName.toLowerCase()) >= 0) {
4383 return false;
4384 }
4385 return true;
4386 }
4387 return false;
4388 }
4389 function targetNeedsFastClick(el) {
4390 /*
4391 if (
4392 Device.ios
4393 &&
4394 (
4395 Device.osVersion.split('.')[0] > 9
4396 ||
4397 (Device.osVersion.split('.')[0] * 1 === 9 && Device.osVersion.split('.')[1] >= 1)
4398 )
4399 ) {
4400 return false;
4401 }
4402 */
4403 var $el = $(el);
4404 if (el.nodeName.toLowerCase() === 'input' && (el.type === 'file' || el.type === 'range')) { return false; }
4405 if (el.nodeName.toLowerCase() === 'select' && Device.android) { return false; }
4406 if ($el.hasClass('no-fastclick') || $el.parents('.no-fastclick').length > 0) { return false; }
4407 if (params.fastClicksExclude && $el.closest(params.fastClicksExclude).length > 0) { return false; }
4408
4409 return true;
4410 }
4411 function targetNeedsFocus(el) {
4412 if (doc.activeElement === el) {
4413 return false;
4414 }
4415 var tag = el.nodeName.toLowerCase();
4416 var skipInputs = ('button checkbox file image radio submit').split(' ');
4417 if (el.disabled || el.readOnly) { return false; }
4418 if (tag === 'textarea') { return true; }
4419 if (tag === 'select') {
4420 if (Device.android) { return false; }
4421 return true;
4422 }
4423 if (tag === 'input' && skipInputs.indexOf(el.type) < 0) { return true; }
4424 return false;
4425 }
4426 function targetNeedsPrevent(el) {
4427 var $el = $(el);
4428 var prevent = true;
4429 if ($el.is('label') || $el.parents('label').length > 0) {
4430 if (Device.android) {
4431 prevent = false;
4432 } else if (Device.ios && $el.is('input')) {
4433 prevent = true;
4434 } else { prevent = false; }
4435 }
4436 return prevent;
4437 }
4438
4439 // Ripple handlers
4440 function findRippleElement(el) {
4441 var rippleElements = params.touchRippleElements;
4442 var $el = $(el);
4443 if ($el.is(rippleElements)) {
4444 if ($el.hasClass('no-ripple')) {
4445 return false;
4446 }
4447 return $el;
4448 }
4449 if ($el.parents(rippleElements).length > 0) {
4450 var rippleParent = $el.parents(rippleElements).eq(0);
4451 if (rippleParent.hasClass('no-ripple')) {
4452 return false;
4453 }
4454 return rippleParent;
4455 }
4456 return false;
4457 }
4458 function createRipple($el, x, y) {
4459 if (!$el) { return; }
4460 rippleWave = app.touchRipple.create($el, x, y);
4461 }
4462
4463 function removeRipple() {
4464 if (!rippleWave) { return; }
4465 rippleWave.remove();
4466 rippleWave = undefined;
4467 rippleTarget = undefined;
4468 }
4469 function rippleTouchStart(el) {
4470 rippleTarget = findRippleElement(el);
4471 if (!rippleTarget || rippleTarget.length === 0) {
4472 rippleTarget = undefined;
4473 return;
4474 }
4475 var inScrollable = params.fastClicks
4476 ? isInsideScrollableView(rippleTarget)
4477 : isInsideScrollableViewLight(rippleTarget);
4478
4479 if (!inScrollable) {
4480 createRipple(rippleTarget, touchStartX, touchStartY);
4481 } else {
4482 rippleTimeout = setTimeout(function () {
4483 createRipple(rippleTarget, touchStartX, touchStartY);
4484 }, 80);
4485 }
4486 }
4487 function rippleTouchMove() {
4488 clearTimeout(rippleTimeout);
4489 removeRipple();
4490 }
4491 function rippleTouchEnd() {
4492 if (rippleWave) {
4493 removeRipple();
4494 } else if (rippleTarget && !isMoved) {
4495 clearTimeout(rippleTimeout);
4496 createRipple(rippleTarget, touchStartX, touchStartY);
4497 setTimeout(removeRipple, 0);
4498 } else {
4499 removeRipple();
4500 }
4501 }
4502
4503 // Mouse Handlers
4504 function handleMouseDown(e) {
4505 findActivableElement(e.target).addClass('active-state');
4506 if ('which' in e && e.which === 3) {
4507 setTimeout(function () {
4508 $('.active-state').removeClass('active-state');
4509 }, 0);
4510 }
4511 if (useRipple) {
4512 touchStartX = e.pageX;
4513 touchStartY = e.pageY;
4514 rippleTouchStart(e.target, e.pageX, e.pageY);
4515 }
4516 }
4517 function handleMouseMove() {
4518 $('.active-state').removeClass('active-state');
4519 if (useRipple) {
4520 rippleTouchMove();
4521 }
4522 }
4523 function handleMouseUp() {
4524 $('.active-state').removeClass('active-state');
4525 if (useRipple) {
4526 rippleTouchEnd();
4527 }
4528 }
4529
4530 // Send Click
4531 function sendClick(e) {
4532 var touch = e.changedTouches[0];
4533 var evt = doc.createEvent('MouseEvents');
4534 var eventType = 'click';
4535 if (Device.android && targetElement.nodeName.toLowerCase() === 'select') {
4536 eventType = 'mousedown';
4537 }
4538 evt.initMouseEvent(eventType, true, true, win, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
4539 evt.forwardedTouchEvent = true;
4540
4541 if (app.device.ios && win.navigator.standalone) {
4542 // Fix the issue happens in iOS home screen apps where the wrong element is selected during a momentum scroll.
4543 // Upon tapping, we give the scrolling time to stop, then we grab the element based where the user tapped.
4544 setTimeout(function () {
4545 targetElement = doc.elementFromPoint(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
4546 targetElement.dispatchEvent(evt);
4547 }, 10);
4548 } else {
4549 targetElement.dispatchEvent(evt);
4550 }
4551 }
4552
4553 // Touch Handlers
4554 function handleTouchStart(e) {
4555 var this$1 = this;
4556
4557 isMoved = false;
4558 tapHoldFired = false;
4559 if (e.targetTouches.length > 1) {
4560 if (activableElement) { removeActive(); }
4561 return true;
4562 }
4563 if (e.touches.length > 1 && activableElement) {
4564 removeActive();
4565 }
4566 if (params.tapHold) {
4567 if (tapHoldTimeout) { clearTimeout(tapHoldTimeout); }
4568 tapHoldTimeout = setTimeout(function () {
4569 if (e && e.touches && e.touches.length > 1) { return; }
4570 tapHoldFired = true;
4571 e.preventDefault();
4572 $(e.target).trigger('taphold');
4573 }, params.tapHoldDelay);
4574 }
4575 if (needsFastClickTimeOut) { clearTimeout(needsFastClickTimeOut); }
4576 needsFastClick = targetNeedsFastClick(e.target);
4577
4578 if (!needsFastClick) {
4579 trackClick = false;
4580 return true;
4581 }
4582 if (Device.ios || (Device.android && 'getSelection' in win)) {
4583 var selection = win.getSelection();
4584 if (
4585 selection.rangeCount
4586 && selection.focusNode !== doc.body
4587 && (!selection.isCollapsed || doc.activeElement === selection.focusNode)
4588 ) {
4589 activeSelection = true;
4590 return true;
4591 }
4592
4593 activeSelection = false;
4594 }
4595 if (Device.android) {
4596 if (androidNeedsBlur(e.target)) {
4597 doc.activeElement.blur();
4598 }
4599 }
4600
4601 trackClick = true;
4602 targetElement = e.target;
4603 touchStartTime = (new Date()).getTime();
4604 touchStartX = e.targetTouches[0].pageX;
4605 touchStartY = e.targetTouches[0].pageY;
4606
4607 // Detect scroll parent
4608 if (Device.ios) {
4609 scrollParent = undefined;
4610 $(targetElement).parents().each(function () {
4611 var parent = this$1;
4612 if (parent.scrollHeight > parent.offsetHeight && !scrollParent) {
4613 scrollParent = parent;
4614 scrollParent.f7ScrollTop = scrollParent.scrollTop;
4615 }
4616 });
4617 }
4618 if ((touchStartTime - lastClickTime) < params.fastClicksDelayBetweenClicks) {
4619 e.preventDefault();
4620 }
4621
4622 if (params.activeState) {
4623 activableElement = findActivableElement(targetElement);
4624 activeTimeout = setTimeout(addActive, 0);
4625 }
4626 if (useRipple) {
4627 rippleTouchStart(targetElement, touchStartX, touchStartY);
4628 }
4629 return true;
4630 }
4631 function handleTouchMove(e) {
4632 if (!trackClick) { return; }
4633 var distance = params.fastClicksDistanceThreshold;
4634 if (distance) {
4635 var pageX = e.targetTouches[0].pageX;
4636 var pageY = e.targetTouches[0].pageY;
4637 if (Math.abs(pageX - touchStartX) > distance || Math.abs(pageY - touchStartY) > distance) {
4638 isMoved = true;
4639 }
4640 } else {
4641 isMoved = true;
4642 }
4643 if (isMoved) {
4644 trackClick = false;
4645 targetElement = null;
4646 isMoved = true;
4647 if (params.tapHold) {
4648 clearTimeout(tapHoldTimeout);
4649 }
4650 if (params.activeState) {
4651 clearTimeout(activeTimeout);
4652 removeActive();
4653 }
4654 if (useRipple) {
4655 rippleTouchMove();
4656 }
4657 }
4658 }
4659 function handleTouchEnd(e) {
4660 clearTimeout(activeTimeout);
4661 clearTimeout(tapHoldTimeout);
4662
4663 var touchEndTime = (new Date()).getTime();
4664
4665 if (!trackClick) {
4666 if (!activeSelection && needsFastClick) {
4667 if (!(Device.android && !e.cancelable) && e.cancelable) {
4668 e.preventDefault();
4669 }
4670 }
4671 if (params.activeState) { removeActive(); }
4672 if (useRipple) {
4673 rippleTouchEnd();
4674 }
4675 return true;
4676 }
4677
4678 if (doc.activeElement === e.target) {
4679 if (params.activeState) { removeActive(); }
4680 if (useRipple) {
4681 rippleTouchEnd();
4682 }
4683 return true;
4684 }
4685
4686 if (!activeSelection) {
4687 e.preventDefault();
4688 }
4689
4690 if ((touchEndTime - lastClickTime) < params.fastClicksDelayBetweenClicks) {
4691 setTimeout(removeActive, 0);
4692 if (useRipple) {
4693 rippleTouchEnd();
4694 }
4695 return true;
4696 }
4697
4698 lastClickTime = touchEndTime;
4699
4700 trackClick = false;
4701
4702 if (Device.ios && scrollParent) {
4703 if (scrollParent.scrollTop !== scrollParent.f7ScrollTop) {
4704 return false;
4705 }
4706 }
4707
4708 // Add active-state here because, in a very fast tap, the timeout didn't
4709 // have the chance to execute. Removing active-state in a timeout gives
4710 // the chance to the animation execute.
4711 if (params.activeState) {
4712 addActive();
4713 setTimeout(removeActive, 0);
4714 }
4715 // Remove Ripple
4716 if (useRipple) {
4717 rippleTouchEnd();
4718 }
4719
4720 // Trigger focus when required
4721 if (targetNeedsFocus(targetElement)) {
4722 if (Device.ios && Device.webView) {
4723 targetElement.focus();
4724 return false;
4725 }
4726
4727 targetElement.focus();
4728 }
4729
4730 // Blur active elements
4731 if (doc.activeElement && targetElement !== doc.activeElement && doc.activeElement !== doc.body && targetElement.nodeName.toLowerCase() !== 'label') {
4732 doc.activeElement.blur();
4733 }
4734
4735 // Send click
4736 e.preventDefault();
4737 if (params.tapHoldPreventClicks && tapHoldFired) {
4738 return false;
4739 }
4740 sendClick(e);
4741 return false;
4742 }
4743 function handleTouchCancel() {
4744 trackClick = false;
4745 targetElement = null;
4746
4747 // Remove Active State
4748 clearTimeout(activeTimeout);
4749 clearTimeout(tapHoldTimeout);
4750 if (params.activeState) {
4751 removeActive();
4752 }
4753
4754 // Remove Ripple
4755 if (useRipple) {
4756 rippleTouchEnd();
4757 }
4758 }
4759
4760 function handleClick(e) {
4761 var allowClick = false;
4762 if (trackClick) {
4763 targetElement = null;
4764 trackClick = false;
4765 return true;
4766 }
4767 if ((e.target.type === 'submit' && e.detail === 0) || e.target.type === 'file') {
4768 return true;
4769 }
4770 if (!targetElement) {
4771 if (!isFormElement(e.target)) {
4772 allowClick = true;
4773 }
4774 }
4775 if (!needsFastClick) {
4776 allowClick = true;
4777 }
4778 if (doc.activeElement === targetElement) {
4779 allowClick = true;
4780 }
4781 if (e.forwardedTouchEvent) {
4782 allowClick = true;
4783 }
4784 if (!e.cancelable) {
4785 allowClick = true;
4786 }
4787 if (params.tapHold && params.tapHoldPreventClicks && tapHoldFired) {
4788 allowClick = false;
4789 }
4790 if (!allowClick) {
4791 e.stopImmediatePropagation();
4792 e.stopPropagation();
4793 if (targetElement) {
4794 if (targetNeedsPrevent(targetElement) || isMoved) {
4795 e.preventDefault();
4796 }
4797 } else {
4798 e.preventDefault();
4799 }
4800 targetElement = null;
4801 }
4802 needsFastClickTimeOut = setTimeout(function () {
4803 needsFastClick = false;
4804 }, (Device.ios || Device.androidChrome ? 100 : 400));
4805
4806 if (params.tapHold) {
4807 tapHoldTimeout = setTimeout(function () {
4808 tapHoldFired = false;
4809 }, (Device.ios || Device.androidChrome ? 100 : 400));
4810 }
4811
4812 return allowClick;
4813 }
4814
4815 function handleTouchStartLight(e) {
4816 isMoved = false;
4817 tapHoldFired = false;
4818 preventClick = false;
4819 if (e.targetTouches.length > 1) {
4820 if (activableElement) { removeActive(); }
4821 return true;
4822 }
4823 if (e.touches.length > 1 && activableElement) {
4824 removeActive();
4825 }
4826 if (params.tapHold) {
4827 if (tapHoldTimeout) { clearTimeout(tapHoldTimeout); }
4828 tapHoldTimeout = setTimeout(function () {
4829 if (e && e.touches && e.touches.length > 1) { return; }
4830 tapHoldFired = true;
4831 e.preventDefault();
4832 preventClick = true;
4833 $(e.target).trigger('taphold');
4834 }, params.tapHoldDelay);
4835 }
4836 targetElement = e.target;
4837 touchStartX = e.targetTouches[0].pageX;
4838 touchStartY = e.targetTouches[0].pageY;
4839
4840 if (params.activeState) {
4841 activableElement = findActivableElement(targetElement);
4842 if (!isInsideScrollableViewLight(activableElement)) {
4843 addActive();
4844 } else {
4845 activeTimeout = setTimeout(addActive, 80);
4846 }
4847 }
4848 if (useRipple) {
4849 rippleTouchStart(targetElement, touchStartX, touchStartY);
4850 }
4851 return true;
4852 }
4853 function handleTouchMoveLight(e) {
4854 var distance = params.fastClicks ? params.fastClicksDistanceThreshold : 0;
4855 if (distance) {
4856 var pageX = e.targetTouches[0].pageX;
4857 var pageY = e.targetTouches[0].pageY;
4858 if (Math.abs(pageX - touchStartX) > distance || Math.abs(pageY - touchStartY) > distance) {
4859 isMoved = true;
4860 }
4861 } else {
4862 isMoved = true;
4863 }
4864 if (isMoved) {
4865 preventClick = true;
4866 if (params.tapHold) {
4867 clearTimeout(tapHoldTimeout);
4868 }
4869 if (params.activeState) {
4870 clearTimeout(activeTimeout);
4871 removeActive();
4872 }
4873 if (useRipple) {
4874 rippleTouchMove();
4875 }
4876 }
4877 }
4878 function handleTouchEndLight(e) {
4879 clearTimeout(activeTimeout);
4880 clearTimeout(tapHoldTimeout);
4881 if (doc.activeElement === e.target) {
4882 if (params.activeState) { removeActive(); }
4883 if (useRipple) {
4884 rippleTouchEnd();
4885 }
4886 return true;
4887 }
4888 if (params.activeState) {
4889 addActive();
4890 setTimeout(removeActive, 0);
4891 }
4892 if (useRipple) {
4893 rippleTouchEnd();
4894 }
4895 if ((params.tapHoldPreventClicks && tapHoldFired) || preventClick) {
4896 if (e.cancelable) { e.preventDefault(); }
4897 preventClick = true;
4898 return false;
4899 }
4900 return true;
4901 }
4902 function handleClickLight(e) {
4903 var localPreventClick = preventClick;
4904 if (targetElement && e.target !== targetElement) {
4905 localPreventClick = true;
4906 }
4907 if (params.tapHold && params.tapHoldPreventClicks && tapHoldFired) {
4908 localPreventClick = true;
4909 }
4910 if (localPreventClick) {
4911 e.stopImmediatePropagation();
4912 e.stopPropagation();
4913 e.preventDefault();
4914 }
4915
4916 if (params.tapHold) {
4917 tapHoldTimeout = setTimeout(
4918 function () {
4919 tapHoldFired = false;
4920 },
4921 (Device.ios || Device.androidChrome ? 100 : 400)
4922 );
4923 }
4924 preventClick = false;
4925 targetElement = null;
4926
4927 return !localPreventClick;
4928 }
4929
4930 function emitAppTouchEvent(name, e) {
4931 app.emit({
4932 events: name,
4933 data: [e],
4934 });
4935 }
4936 function appClick(e) {
4937 emitAppTouchEvent('click', e);
4938 }
4939 function appTouchStartActive(e) {
4940 emitAppTouchEvent('touchstart touchstart:active', e);
4941 }
4942 function appTouchMoveActive(e) {
4943 emitAppTouchEvent('touchmove touchmove:active', e);
4944 }
4945 function appTouchEndActive(e) {
4946 emitAppTouchEvent('touchend touchend:active', e);
4947 }
4948 function appTouchStartPassive(e) {
4949 emitAppTouchEvent('touchstart:passive', e);
4950 }
4951 function appTouchMovePassive(e) {
4952 emitAppTouchEvent('touchmove:passive', e);
4953 }
4954 function appTouchEndPassive(e) {
4955 emitAppTouchEvent('touchend:passive', e);
4956 }
4957
4958 var passiveListener = Support.passiveListener ? { passive: true } : false;
4959 var activeListener = Support.passiveListener ? { passive: false } : false;
4960
4961 doc.addEventListener('click', appClick, true);
4962
4963 if (Support.passiveListener) {
4964 doc.addEventListener(app.touchEvents.start, appTouchStartActive, activeListener);
4965 doc.addEventListener(app.touchEvents.move, appTouchMoveActive, activeListener);
4966 doc.addEventListener(app.touchEvents.end, appTouchEndActive, activeListener);
4967
4968 doc.addEventListener(app.touchEvents.start, appTouchStartPassive, passiveListener);
4969 doc.addEventListener(app.touchEvents.move, appTouchMovePassive, passiveListener);
4970 doc.addEventListener(app.touchEvents.end, appTouchEndPassive, passiveListener);
4971 } else {
4972 doc.addEventListener(app.touchEvents.start, function (e) {
4973 appTouchStartActive(e);
4974 appTouchStartPassive(e);
4975 }, false);
4976 doc.addEventListener(app.touchEvents.move, function (e) {
4977 appTouchMoveActive(e);
4978 appTouchMovePassive(e);
4979 }, false);
4980 doc.addEventListener(app.touchEvents.end, function (e) {
4981 appTouchEndActive(e);
4982 appTouchEndPassive(e);
4983 }, false);
4984 }
4985
4986 if (Support.touch) {
4987 if (params.fastClicks) {
4988 app.on('click', handleClick);
4989 app.on('touchstart', handleTouchStart);
4990 app.on('touchmove', handleTouchMove);
4991 app.on('touchend', handleTouchEnd);
4992 } else {
4993 app.on('click', handleClickLight);
4994 app.on('touchstart', handleTouchStartLight);
4995 app.on('touchmove', handleTouchMoveLight);
4996 app.on('touchend', handleTouchEndLight);
4997 }
4998
4999 doc.addEventListener('touchcancel', handleTouchCancel, { passive: true });
5000 } else if (params.activeState) {
5001 app.on('touchstart', handleMouseDown);
5002 app.on('touchmove', handleMouseMove);
5003 app.on('touchend', handleMouseUp);
5004 }
5005 doc.addEventListener('contextmenu', function (e) {
5006 if (params.disableContextMenu && (Device.ios || Device.android || Device.cordova)) {
5007 e.preventDefault();
5008 }
5009 if (useRipple) {
5010 if (activableElement) { removeActive(); }
5011 rippleTouchEnd();
5012 }
5013 });
5014 }
5015
5016 var TouchModule = {
5017 name: 'touch',
5018 params: {
5019 touch: {
5020 // Fast clicks
5021 fastClicks: false,
5022 fastClicksDistanceThreshold: 10,
5023 fastClicksDelayBetweenClicks: 50,
5024 fastClicksExclude: '', // CSS selector
5025 // ContextMenu
5026 disableContextMenu: false,
5027 // Tap Hold
5028 tapHold: false,
5029 tapHoldDelay: 750,
5030 tapHoldPreventClicks: true,
5031 // Active State
5032 activeState: true,
5033 activeStateElements: 'a, button, label, span, .actions-button, .stepper-button, .stepper-button-plus, .stepper-button-minus, .card-expandable, .menu-item',
5034 mdTouchRipple: true,
5035 iosTouchRipple: false,
5036 touchRippleElements: '.ripple, .link, .item-link, .list-button, .links-list a, .button, button, .input-clear-button, .dialog-button, .tab-link, .item-radio, .item-checkbox, .actions-button, .searchbar-disable-button, .fab a, .checkbox, .radio, .data-table .sortable-cell:not(.input-cell), .notification-close-button, .stepper-button, .stepper-button-minus, .stepper-button-plus, .menu-item-content',
5037 },
5038 },
5039 instance: {
5040 touchEvents: {
5041 start: Support.touch ? 'touchstart' : 'mousedown',
5042 move: Support.touch ? 'touchmove' : 'mousemove',
5043 end: Support.touch ? 'touchend' : 'mouseup',
5044 },
5045 },
5046 on: {
5047 init: initTouch,
5048 },
5049 };
5050
5051 /**
5052 * Expose `pathToRegexp`.
5053 */
5054 var pathToRegexp_1 = pathToRegexp;
5055 var parse_1 = parse;
5056 var compile_1 = compile;
5057 var tokensToFunction_1 = tokensToFunction;
5058 var tokensToRegExp_1 = tokensToRegExp;
5059
5060 /**
5061 * Default configs.
5062 */
5063 var DEFAULT_DELIMITER = '/';
5064
5065 /**
5066 * The main path matching regexp utility.
5067 *
5068 * @type {RegExp}
5069 */
5070 var PATH_REGEXP = new RegExp([
5071 // Match escaped characters that would otherwise appear in future matches.
5072 // This allows the user to escape special characters that won't transform.
5073 '(\\\\.)',
5074 // Match Express-style parameters and un-named parameters with a prefix
5075 // and optional suffixes. Matches appear as:
5076 //
5077 // ":test(\\d+)?" => ["test", "\d+", undefined, "?"]
5078 // "(\\d+)" => [undefined, undefined, "\d+", undefined]
5079 '(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?'
5080 ].join('|'), 'g');
5081
5082 /**
5083 * Parse a string for the raw tokens.
5084 *
5085 * @param {string} str
5086 * @param {Object=} options
5087 * @return {!Array}
5088 */
5089 function parse (str, options) {
5090 var tokens = [];
5091 var key = 0;
5092 var index = 0;
5093 var path = '';
5094 var defaultDelimiter = (options && options.delimiter) || DEFAULT_DELIMITER;
5095 var whitelist = (options && options.whitelist) || undefined;
5096 var pathEscaped = false;
5097 var res;
5098
5099 while ((res = PATH_REGEXP.exec(str)) !== null) {
5100 var m = res[0];
5101 var escaped = res[1];
5102 var offset = res.index;
5103 path += str.slice(index, offset);
5104 index = offset + m.length;
5105
5106 // Ignore already escaped sequences.
5107 if (escaped) {
5108 path += escaped[1];
5109 pathEscaped = true;
5110 continue
5111 }
5112
5113 var prev = '';
5114 var name = res[2];
5115 var capture = res[3];
5116 var group = res[4];
5117 var modifier = res[5];
5118
5119 if (!pathEscaped && path.length) {
5120 var k = path.length - 1;
5121 var c = path[k];
5122 var matches = whitelist ? whitelist.indexOf(c) > -1 : true;
5123
5124 if (matches) {
5125 prev = c;
5126 path = path.slice(0, k);
5127 }
5128 }
5129
5130 // Push the current path onto the tokens.
5131 if (path) {
5132 tokens.push(path);
5133 path = '';
5134 pathEscaped = false;
5135 }
5136
5137 var repeat = modifier === '+' || modifier === '*';
5138 var optional = modifier === '?' || modifier === '*';
5139 var pattern = capture || group;
5140 var delimiter = prev || defaultDelimiter;
5141
5142 tokens.push({
5143 name: name || key++,
5144 prefix: prev,
5145 delimiter: delimiter,
5146 optional: optional,
5147 repeat: repeat,
5148 pattern: pattern
5149 ? escapeGroup(pattern)
5150 : '[^' + escapeString(delimiter === defaultDelimiter ? delimiter : (delimiter + defaultDelimiter)) + ']+?'
5151 });
5152 }
5153
5154 // Push any remaining characters.
5155 if (path || index < str.length) {
5156 tokens.push(path + str.substr(index));
5157 }
5158
5159 return tokens
5160 }
5161
5162 /**
5163 * Compile a string to a template function for the path.
5164 *
5165 * @param {string} str
5166 * @param {Object=} options
5167 * @return {!function(Object=, Object=)}
5168 */
5169 function compile (str, options) {
5170 return tokensToFunction(parse(str, options))
5171 }
5172
5173 /**
5174 * Expose a method for transforming tokens into the path function.
5175 */
5176 function tokensToFunction (tokens) {
5177 // Compile all the tokens into regexps.
5178 var matches = new Array(tokens.length);
5179
5180 // Compile all the patterns before compilation.
5181 for (var i = 0; i < tokens.length; i++) {
5182 if (typeof tokens[i] === 'object') {
5183 matches[i] = new RegExp('^(?:' + tokens[i].pattern + ')$');
5184 }
5185 }
5186
5187 return function (data, options) {
5188 var path = '';
5189 var encode = (options && options.encode) || encodeURIComponent;
5190
5191 for (var i = 0; i < tokens.length; i++) {
5192 var token = tokens[i];
5193
5194 if (typeof token === 'string') {
5195 path += token;
5196 continue
5197 }
5198
5199 var value = data ? data[token.name] : undefined;
5200 var segment;
5201
5202 if (Array.isArray(value)) {
5203 if (!token.repeat) {
5204 throw new TypeError('Expected "' + token.name + '" to not repeat, but got array')
5205 }
5206
5207 if (value.length === 0) {
5208 if (token.optional) { continue }
5209
5210 throw new TypeError('Expected "' + token.name + '" to not be empty')
5211 }
5212
5213 for (var j = 0; j < value.length; j++) {
5214 segment = encode(value[j], token);
5215
5216 if (!matches[i].test(segment)) {
5217 throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '"')
5218 }
5219
5220 path += (j === 0 ? token.prefix : token.delimiter) + segment;
5221 }
5222
5223 continue
5224 }
5225
5226 if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
5227 segment = encode(String(value), token);
5228
5229 if (!matches[i].test(segment)) {
5230 throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but got "' + segment + '"')
5231 }
5232
5233 path += token.prefix + segment;
5234 continue
5235 }
5236
5237 if (token.optional) { continue }
5238
5239 throw new TypeError('Expected "' + token.name + '" to be ' + (token.repeat ? 'an array' : 'a string'))
5240 }
5241
5242 return path
5243 }
5244 }
5245
5246 /**
5247 * Escape a regular expression string.
5248 *
5249 * @param {string} str
5250 * @return {string}
5251 */
5252 function escapeString (str) {
5253 return str.replace(/([.+*?=^!:${}()[\]|/\\])/g, '\\$1')
5254 }
5255
5256 /**
5257 * Escape the capturing group by escaping special characters and meaning.
5258 *
5259 * @param {string} group
5260 * @return {string}
5261 */
5262 function escapeGroup (group) {
5263 return group.replace(/([=!:$/()])/g, '\\$1')
5264 }
5265
5266 /**
5267 * Get the flags for a regexp from the options.
5268 *
5269 * @param {Object} options
5270 * @return {string}
5271 */
5272 function flags (options) {
5273 return options && options.sensitive ? '' : 'i'
5274 }
5275
5276 /**
5277 * Pull out keys from a regexp.
5278 *
5279 * @param {!RegExp} path
5280 * @param {Array=} keys
5281 * @return {!RegExp}
5282 */
5283 function regexpToRegexp (path, keys) {
5284 if (!keys) { return path }
5285
5286 // Use a negative lookahead to match only capturing groups.
5287 var groups = path.source.match(/\((?!\?)/g);
5288
5289 if (groups) {
5290 for (var i = 0; i < groups.length; i++) {
5291 keys.push({
5292 name: i,
5293 prefix: null,
5294 delimiter: null,
5295 optional: false,
5296 repeat: false,
5297 pattern: null
5298 });
5299 }
5300 }
5301
5302 return path
5303 }
5304
5305 /**
5306 * Transform an array into a regexp.
5307 *
5308 * @param {!Array} path
5309 * @param {Array=} keys
5310 * @param {Object=} options
5311 * @return {!RegExp}
5312 */
5313 function arrayToRegexp (path, keys, options) {
5314 var parts = [];
5315
5316 for (var i = 0; i < path.length; i++) {
5317 parts.push(pathToRegexp(path[i], keys, options).source);
5318 }
5319
5320 return new RegExp('(?:' + parts.join('|') + ')', flags(options))
5321 }
5322
5323 /**
5324 * Create a path regexp from string input.
5325 *
5326 * @param {string} path
5327 * @param {Array=} keys
5328 * @param {Object=} options
5329 * @return {!RegExp}
5330 */
5331 function stringToRegexp (path, keys, options) {
5332 return tokensToRegExp(parse(path, options), keys, options)
5333 }
5334
5335 /**
5336 * Expose a function for taking tokens and returning a RegExp.
5337 *
5338 * @param {!Array} tokens
5339 * @param {Array=} keys
5340 * @param {Object=} options
5341 * @return {!RegExp}
5342 */
5343 function tokensToRegExp (tokens, keys, options) {
5344 options = options || {};
5345
5346 var strict = options.strict;
5347 var start = options.start !== false;
5348 var end = options.end !== false;
5349 var delimiter = options.delimiter || DEFAULT_DELIMITER;
5350 var endsWith = [].concat(options.endsWith || []).map(escapeString).concat('$').join('|');
5351 var route = start ? '^' : '';
5352
5353 // Iterate over the tokens and create our regexp string.
5354 for (var i = 0; i < tokens.length; i++) {
5355 var token = tokens[i];
5356
5357 if (typeof token === 'string') {
5358 route += escapeString(token);
5359 } else {
5360 var capture = token.repeat
5361 ? '(?:' + token.pattern + ')(?:' + escapeString(token.delimiter) + '(?:' + token.pattern + '))*'
5362 : token.pattern;
5363
5364 if (keys) { keys.push(token); }
5365
5366 if (token.optional) {
5367 if (!token.prefix) {
5368 route += '(' + capture + ')?';
5369 } else {
5370 route += '(?:' + escapeString(token.prefix) + '(' + capture + '))?';
5371 }
5372 } else {
5373 route += escapeString(token.prefix) + '(' + capture + ')';
5374 }
5375 }
5376 }
5377
5378 if (end) {
5379 if (!strict) { route += '(?:' + escapeString(delimiter) + ')?'; }
5380
5381 route += endsWith === '$' ? '$' : '(?=' + endsWith + ')';
5382 } else {
5383 var endToken = tokens[tokens.length - 1];
5384 var isEndDelimited = typeof endToken === 'string'
5385 ? endToken[endToken.length - 1] === delimiter
5386 : endToken === undefined;
5387
5388 if (!strict) { route += '(?:' + escapeString(delimiter) + '(?=' + endsWith + '))?'; }
5389 if (!isEndDelimited) { route += '(?=' + escapeString(delimiter) + '|' + endsWith + ')'; }
5390 }
5391
5392 return new RegExp(route, flags(options))
5393 }
5394
5395 /**
5396 * Normalize the given path string, returning a regular expression.
5397 *
5398 * An empty array can be passed in for the keys, which will hold the
5399 * placeholder key descriptions. For example, using `/user/:id`, `keys` will
5400 * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
5401 *
5402 * @param {(string|RegExp|Array)} path
5403 * @param {Array=} keys
5404 * @param {Object=} options
5405 * @return {!RegExp}
5406 */
5407 function pathToRegexp (path, keys, options) {
5408 if (path instanceof RegExp) {
5409 return regexpToRegexp(path, keys)
5410 }
5411
5412 if (Array.isArray(path)) {
5413 return arrayToRegexp(/** @type {!Array} */ (path), keys, options)
5414 }
5415
5416 return stringToRegexp(/** @type {string} */ (path), keys, options)
5417 }
5418 pathToRegexp_1.parse = parse_1;
5419 pathToRegexp_1.compile = compile_1;
5420 pathToRegexp_1.tokensToFunction = tokensToFunction_1;
5421 pathToRegexp_1.tokensToRegExp = tokensToRegExp_1;
5422
5423 var History = {
5424 queue: [],
5425 clearQueue: function clearQueue() {
5426 if (History.queue.length === 0) { return; }
5427 var currentQueue = History.queue.shift();
5428 currentQueue();
5429 },
5430 routerQueue: [],
5431 clearRouterQueue: function clearRouterQueue() {
5432 if (History.routerQueue.length === 0) { return; }
5433 var currentQueue = History.routerQueue.pop();
5434 var router = currentQueue.router;
5435 var stateUrl = currentQueue.stateUrl;
5436 var action = currentQueue.action;
5437
5438 var animate = router.params.animate;
5439 if (router.params.pushStateAnimate === false) { animate = false; }
5440
5441 if (action === 'back') {
5442 router.back({ animate: animate, pushState: false });
5443 }
5444 if (action === 'load') {
5445 router.navigate(stateUrl, { animate: animate, pushState: false });
5446 }
5447 },
5448 handle: function handle(e) {
5449 if (History.blockPopstate) { return; }
5450 var app = this;
5451 // const mainView = app.views.main;
5452 var state = e.state;
5453 History.previousState = History.state;
5454 History.state = state;
5455
5456 History.allowChange = true;
5457 History.clearQueue();
5458
5459 state = History.state;
5460 if (!state) { state = {}; }
5461
5462 app.views.forEach(function (view) {
5463 var router = view.router;
5464 var viewState = state[view.id];
5465 if (!viewState && view.params.pushState) {
5466 viewState = {
5467 url: view.router.history[0],
5468 };
5469 }
5470 if (!viewState) { return; }
5471 var stateUrl = viewState.url || undefined;
5472
5473 var animate = router.params.animate;
5474 if (router.params.pushStateAnimate === false) { animate = false; }
5475
5476 if (stateUrl !== router.url) {
5477 if (router.history.indexOf(stateUrl) >= 0) {
5478 // Go Back
5479 if (router.allowPageChange) {
5480 router.back({ animate: animate, pushState: false });
5481 } else {
5482 History.routerQueue.push({
5483 action: 'back',
5484 router: router,
5485 });
5486 }
5487 } else if (router.allowPageChange) {
5488 // Load page
5489 router.navigate(stateUrl, { animate: animate, pushState: false });
5490 } else {
5491 History.routerQueue.unshift({
5492 action: 'load',
5493 stateUrl: stateUrl,
5494 router: router,
5495 });
5496 }
5497 }
5498 });
5499 },
5500 initViewState: function initViewState(viewId, viewState) {
5501 var obj;
5502
5503 var newState = Utils.extend({}, (History.state || {}), ( obj = {}, obj[viewId] = viewState, obj ));
5504 History.state = newState;
5505 win.history.replaceState(newState, '');
5506 },
5507 push: function push(viewId, viewState, url) {
5508 var obj;
5509
5510 if (!History.allowChange) {
5511 History.queue.push(function () {
5512 History.push(viewId, viewState, url);
5513 });
5514 return;
5515 }
5516 History.previousState = History.state;
5517 var newState = Utils.extend({}, (History.previousState || {}), ( obj = {}, obj[viewId] = viewState, obj ));
5518 History.state = newState;
5519 win.history.pushState(newState, '', url);
5520 },
5521 replace: function replace(viewId, viewState, url) {
5522 var obj;
5523
5524 if (!History.allowChange) {
5525 History.queue.push(function () {
5526 History.replace(viewId, viewState, url);
5527 });
5528 return;
5529 }
5530 History.previousState = History.state;
5531 var newState = Utils.extend({}, (History.previousState || {}), ( obj = {}, obj[viewId] = viewState, obj ));
5532 History.state = newState;
5533 win.history.replaceState(newState, '', url);
5534 },
5535 go: function go(index) {
5536 History.allowChange = false;
5537 win.history.go(index);
5538 },
5539 back: function back() {
5540 History.allowChange = false;
5541 win.history.back();
5542 },
5543 allowChange: true,
5544 previousState: {},
5545 state: win.history.state,
5546 blockPopstate: true,
5547 init: function init(app) {
5548 $(win).on('load', function () {
5549 setTimeout(function () {
5550 History.blockPopstate = false;
5551 }, 0);
5552 });
5553
5554 if (doc.readyState && doc.readyState === 'complete') {
5555 History.blockPopstate = false;
5556 }
5557
5558 $(win).on('popstate', History.handle.bind(app));
5559 },
5560 };
5561
5562 function SwipeBack(r) {
5563 var router = r;
5564 var $el = router.$el;
5565 var $navbarEl = router.$navbarEl;
5566 var app = router.app;
5567 var params = router.params;
5568 var isTouched = false;
5569 var isMoved = false;
5570 var touchesStart = {};
5571 var isScrolling;
5572 var currentPage = [];
5573 var previousPage = [];
5574 var viewContainerWidth;
5575 var touchesDiff;
5576 var allowViewTouchMove = true;
5577 var touchStartTime;
5578 var $currentNavbarInner = [];
5579 var $previousNavbarInner = [];
5580 var dynamicNavbar;
5581 var separateNavbar;
5582 var pageShadow;
5583 var pageOpacity;
5584
5585 var animatableNavEls;
5586
5587 var paramsSwipeBackAnimateShadow = params[((app.theme) + "SwipeBackAnimateShadow")];
5588 var paramsSwipeBackAnimateOpacity = params[((app.theme) + "SwipeBackAnimateOpacity")];
5589 var paramsSwipeBackActiveArea = params[((app.theme) + "SwipeBackActiveArea")];
5590 var paramsSwipeBackThreshold = params[((app.theme) + "SwipeBackThreshold")];
5591
5592 var transformOrigin = app.rtl ? 'right center' : 'left center';
5593
5594 function animatableNavElements() {
5595 var els = [];
5596 var inverter = app.rtl ? -1 : 1;
5597 var currentNavIsLarge = $currentNavbarInner.hasClass('navbar-inner-large');
5598 var previousNavIsLarge = $previousNavbarInner.hasClass('navbar-inner-large');
5599 var fromLarge = currentNavIsLarge && !$currentNavbarInner.hasClass('navbar-inner-large-collapsed');
5600 var toLarge = previousNavIsLarge && !$previousNavbarInner.hasClass('navbar-inner-large-collapsed');
5601 var $currentNavElements = $currentNavbarInner.children('.left, .title, .right, .subnavbar, .fading, .title-large');
5602 var $previousNavElements = $previousNavbarInner.children('.left, .title, .right, .subnavbar, .fading, .title-large');
5603 var activeNavBackIconText;
5604 var previousNavBackIconText;
5605
5606 if (params.iosAnimateNavbarBackIcon) {
5607 if ($currentNavbarInner.hasClass('sliding')) {
5608 activeNavBackIconText = $currentNavbarInner.children('.left').find('.back .icon + span').eq(0);
5609 } else {
5610 activeNavBackIconText = $currentNavbarInner.children('.left.sliding').find('.back .icon + span').eq(0);
5611 }
5612 if ($previousNavbarInner.hasClass('sliding')) {
5613 previousNavBackIconText = $previousNavbarInner.children('.left').find('.back .icon + span').eq(0);
5614 } else {
5615 previousNavBackIconText = $previousNavbarInner.children('.left.sliding').find('.back .icon + span').eq(0);
5616 }
5617 if (activeNavBackIconText.length) {
5618 $previousNavElements.each(function (index, el) {
5619 if (!$(el).hasClass('title')) { return; }
5620 el.f7NavbarLeftOffset += activeNavBackIconText.prev('.icon')[0].offsetWidth;
5621 });
5622 }
5623 }
5624 $currentNavElements
5625 .each(function (index, navEl) {
5626 var $navEl = $(navEl);
5627 var isSubnavbar = $navEl.hasClass('subnavbar');
5628 var isLeft = $navEl.hasClass('left');
5629 var isTitle = $navEl.hasClass('title');
5630 if (!fromLarge && $navEl.hasClass('.title-large')) { return; }
5631 var el = {
5632 el: navEl,
5633 };
5634 if (fromLarge) {
5635 if (isTitle) { return; }
5636 if ($navEl.hasClass('title-large')) {
5637 if (!separateNavbar) { return; }
5638 if (toLarge) {
5639 if (els.indexOf(el) < 0) { els.push(el); }
5640 el.overflow = 'visible';
5641 el.transform = 'translateX(100%)';
5642 $navEl.find('.title-large-text, .title-large-inner').each(function (subIndex, subNavEl) {
5643 els.push({
5644 el: subNavEl,
5645 transform: function (progress) { return ("translateX(" + (-100 + progress * 100 * inverter) + "%)"); },
5646 });
5647 });
5648 } else {
5649 if (els.indexOf(el) < 0) { els.push(el); }
5650 el.overflow = 'hidden';
5651 el.transform = function (progress) { return ("translateY(calc(" + (-progress) + " * var(--f7-navbar-large-title-height)))"); };
5652 $navEl.find('.title-large-text, .title-large-inner').each(function (subIndex, subNavEl) {
5653 els.push({
5654 el: subNavEl,
5655 transform: function (progress) { return ("translateX(" + (progress * 100 * inverter) + "%) translateY(calc(" + progress + " * var(--f7-navbar-large-title-height)))"); },
5656 });
5657 });
5658 }
5659 return;
5660 }
5661 }
5662 if (toLarge) {
5663 if (!fromLarge) {
5664 if ($navEl.hasClass('title-large')) {
5665 if (!separateNavbar) { return; }
5666 if (els.indexOf(el) < 0) { els.push(el); }
5667 el.opacity = 0;
5668 }
5669 }
5670 if (isLeft && separateNavbar) {
5671 if (els.indexOf(el) < 0) { els.push(el); }
5672 el.opacity = function (progress) { return (1 - (Math.pow( progress, 0.33 ))); };
5673 $navEl.find('.back span').each(function (subIndex, subNavEl) {
5674 els.push({
5675 el: subNavEl,
5676 'transform-origin': transformOrigin,
5677 transform: function (progress) { return ("translateY(calc(var(--f7-navbar-height) * " + progress + ")) scale(" + (1 + (1 * progress)) + ")"); },
5678 });
5679 });
5680 return;
5681 }
5682 }
5683 if ($navEl.hasClass('title-large')) { return; }
5684 var isSliding = $navEl.hasClass('sliding') || $currentNavbarInner.hasClass('sliding');
5685 if (els.indexOf(el) < 0) { els.push(el); }
5686 if (!isSubnavbar || (isSubnavbar && !isSliding)) {
5687 el.opacity = function (progress) { return (1 - (Math.pow( progress, 0.33 ))); };
5688 }
5689 if (isSliding) {
5690 var transformTarget = el;
5691 if (isLeft && activeNavBackIconText.length && params.iosAnimateNavbarBackIcon) {
5692 var textEl = { el: activeNavBackIconText[0] };
5693 transformTarget = textEl;
5694 els.push(textEl);
5695 }
5696 transformTarget.transform = function (progress) {
5697 var activeNavTranslate = progress * transformTarget.el.f7NavbarRightOffset;
5698 if (Device.pixelRatio === 1) { activeNavTranslate = Math.round(activeNavTranslate); }
5699 if (isSubnavbar && currentNavIsLarge && separateNavbar) {
5700 return ("translate3d(" + activeNavTranslate + "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)");
5701 }
5702 return ("translate3d(" + activeNavTranslate + "px,0,0)");
5703 };
5704 }
5705 });
5706 $previousNavElements
5707 .each(function (index, navEl) {
5708 var $navEl = $(navEl);
5709 var isSubnavbar = $navEl.hasClass('subnavbar');
5710 var isLeft = $navEl.hasClass('left');
5711 var isTitle = $navEl.hasClass('title');
5712 var el = {
5713 el: navEl,
5714 };
5715 if (toLarge) {
5716 if (isTitle) { return; }
5717 if (els.indexOf(el) < 0) { els.push(el); }
5718
5719 if ($navEl.hasClass('title-large')) {
5720 if (!separateNavbar) { return; }
5721 if (fromLarge) {
5722 el.opacity = 1;
5723 el.overflow = 'visible';
5724 el.transform = 'translateY(0)';
5725 $navEl.find('.title-large-text').each(function (subIndex, subNavEl) {
5726 els.push({
5727 el: subNavEl,
5728 'transform-origin': transformOrigin,
5729 opacity: function (progress) { return (Math.pow( progress, 3 )); },
5730 transform: function (progress) { return ("translateY(calc(" + (-1 + progress * 1) + " * var(--f7-navbar-large-title-height))) scale(" + (0.5 + progress * 0.5) + ")"); },
5731 });
5732 });
5733 } else {
5734 el.transform = function (progress) { return ("translateY(calc(" + (progress - 1) + " * var(--f7-navbar-large-title-height)))"); };
5735 el.opacity = 1;
5736 el.overflow = 'hidden';
5737 $navEl.find('.title-large-text').each(function (subIndex, subNavEl) {
5738 els.push({
5739 el: subNavEl,
5740 'transform-origin': transformOrigin,
5741 opacity: function (progress) { return (Math.pow( progress, 3 )); },
5742 transform: function (progress) { return ("scale(" + (0.5 + progress * 0.5) + ")"); },
5743 });
5744 });
5745 }
5746 $navEl.find('.title-large-inner').each(function (subIndex, subNavEl) {
5747 els.push({
5748 el: subNavEl,
5749 'transform-origin': transformOrigin,
5750 opacity: function (progress) { return (Math.pow( progress, 3 )); },
5751 transform: function (progress) { return ("translateX(" + (-100 * (1 - progress) * inverter) + "%)"); },
5752 });
5753 });
5754 return;
5755 }
5756 }
5757 if ($navEl.hasClass('title-large')) { return; }
5758 var isSliding = $navEl.hasClass('sliding') || $previousNavbarInner.hasClass('sliding');
5759 if (els.indexOf(el) < 0) { els.push(el); }
5760 if (!isSubnavbar || (isSubnavbar && !isSliding)) {
5761 el.opacity = function (progress) { return (Math.pow( progress, 3 )); };
5762 }
5763 if (isSliding) {
5764 var transformTarget = el;
5765 if (isLeft && previousNavBackIconText.length && params.iosAnimateNavbarBackIcon) {
5766 var textEl = { el: activeNavBackIconText[0] };
5767 transformTarget = textEl;
5768 els.push(textEl);
5769 }
5770 transformTarget.transform = function (progress) {
5771 var previousNavTranslate = transformTarget.el.f7NavbarLeftOffset * (1 - progress);
5772 if (Device.pixelRatio === 1) { previousNavTranslate = Math.round(previousNavTranslate); }
5773 if (isSubnavbar && previousNavIsLarge && separateNavbar) {
5774 return ("translate3d(" + previousNavTranslate + "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)");
5775 }
5776 return ("translate3d(" + previousNavTranslate + "px,0,0)");
5777 };
5778 }
5779 });
5780 return els;
5781 }
5782
5783 function setAnimatableNavElements(ref) {
5784 if ( ref === void 0 ) ref = {};
5785 var progress = ref.progress;
5786 var reset = ref.reset;
5787 var transition = ref.transition;
5788
5789 var styles = ['overflow', 'transform', 'transform-origin', 'opacity'];
5790 for (var i = 0; i < animatableNavEls.length; i += 1) {
5791 var el = animatableNavEls[i];
5792 if (el && el.el) {
5793 if (transition === true) { el.el.classList.add('navbar-page-transitioning'); }
5794 if (transition === false) { el.el.classList.remove('navbar-page-transitioning'); }
5795 for (var j = 0; j < styles.length; j += 1) {
5796 var styleProp = styles[j];
5797 if (el[styleProp]) {
5798 if (reset) {
5799 el.el.style[styleProp] = '';
5800 } else if (typeof el[styleProp] === 'function') {
5801 el.el.style[styleProp] = el[styleProp](progress);
5802 } else {
5803 el.el.style[styleProp] = el[styleProp];
5804 }
5805 }
5806 }
5807 }
5808 }
5809 }
5810
5811 function handleTouchStart(e) {
5812 var swipeBackEnabled = params[((app.theme) + "SwipeBack")];
5813 if (!allowViewTouchMove || !swipeBackEnabled || isTouched || (app.swipeout && app.swipeout.el) || !router.allowPageChange) { return; }
5814 if ($(e.target).closest('.range-slider, .calendar-months').length > 0) { return; }
5815 if ($(e.target).closest('.page-master, .page-master-detail').length > 0 && params.masterDetailBreakpoint > 0 && app.width >= params.masterDetailBreakpoint) { return; }
5816 isMoved = false;
5817 isTouched = true;
5818 isScrolling = undefined;
5819 touchesStart.x = e.type === 'touchstart' ? e.targetTouches[0].pageX : e.pageX;
5820 touchesStart.y = e.type === 'touchstart' ? e.targetTouches[0].pageY : e.pageY;
5821 touchStartTime = Utils.now();
5822 dynamicNavbar = router.dynamicNavbar;
5823 separateNavbar = router.separateNavbar;
5824 }
5825 function handleTouchMove(e) {
5826 if (!isTouched) { return; }
5827 var pageX = e.type === 'touchmove' ? e.targetTouches[0].pageX : e.pageX;
5828 var pageY = e.type === 'touchmove' ? e.targetTouches[0].pageY : e.pageY;
5829 if (typeof isScrolling === 'undefined') {
5830 isScrolling = !!(isScrolling || Math.abs(pageY - touchesStart.y) > Math.abs(pageX - touchesStart.x)) || (pageX < touchesStart.x && !app.rtl) || (pageX > touchesStart.x && app.rtl);
5831 }
5832 if (isScrolling || e.f7PreventSwipeBack || app.preventSwipeBack) {
5833 isTouched = false;
5834 return;
5835 }
5836 if (!isMoved) {
5837 // Calc values during first move fired
5838 var cancel = false;
5839 var target = $(e.target);
5840
5841 var swipeout = target.closest('.swipeout');
5842 if (swipeout.length > 0) {
5843 if (!app.rtl && swipeout.find('.swipeout-actions-left').length > 0) { cancel = true; }
5844 if (app.rtl && swipeout.find('.swipeout-actions-right').length > 0) { cancel = true; }
5845 }
5846
5847 currentPage = target.closest('.page');
5848 if (currentPage.hasClass('no-swipeback') || target.closest('.no-swipeback, .card-opened').length > 0) { cancel = true; }
5849 previousPage = $el.find('.page-previous:not(.stacked)');
5850
5851 var notFromBorder = touchesStart.x - $el.offset().left > paramsSwipeBackActiveArea;
5852 viewContainerWidth = $el.width();
5853 if (app.rtl) {
5854 notFromBorder = touchesStart.x < ($el.offset().left - $el[0].scrollLeft) + (viewContainerWidth - paramsSwipeBackActiveArea);
5855 } else {
5856 notFromBorder = touchesStart.x - $el.offset().left > paramsSwipeBackActiveArea;
5857 }
5858 if (notFromBorder) { cancel = true; }
5859 if (previousPage.length === 0 || currentPage.length === 0) { cancel = true; }
5860 if (cancel) {
5861 isTouched = false;
5862 return;
5863 }
5864
5865 if (paramsSwipeBackAnimateShadow) {
5866 pageShadow = currentPage.find('.page-shadow-effect');
5867 if (pageShadow.length === 0) {
5868 pageShadow = $('<div class="page-shadow-effect"></div>');
5869 currentPage.append(pageShadow);
5870 }
5871 }
5872 if (paramsSwipeBackAnimateOpacity) {
5873 pageOpacity = previousPage.find('.page-opacity-effect');
5874 if (pageOpacity.length === 0) {
5875 pageOpacity = $('<div class="page-opacity-effect"></div>');
5876 previousPage.append(pageOpacity);
5877 }
5878 }
5879
5880 if (dynamicNavbar) {
5881 if (separateNavbar) {
5882 $currentNavbarInner = $navbarEl.find('.navbar-current:not(.stacked)');
5883 $previousNavbarInner = $navbarEl.find('.navbar-previous:not(.stacked)');
5884 } else {
5885 $currentNavbarInner = currentPage.children('.navbar').children('.navbar-inner');
5886 $previousNavbarInner = previousPage.children('.navbar').children('.navbar-inner');
5887 }
5888
5889 animatableNavEls = animatableNavElements($previousNavbarInner, $currentNavbarInner);
5890 }
5891
5892 // Close/Hide Any Picker
5893 if ($('.sheet.modal-in').length > 0 && app.sheet) {
5894 app.sheet.close($('.sheet.modal-in'));
5895 }
5896 }
5897 e.f7PreventPanelSwipe = true;
5898 isMoved = true;
5899 app.preventSwipePanelBySwipeBack = true;
5900 e.preventDefault();
5901
5902 // RTL inverter
5903 var inverter = app.rtl ? -1 : 1;
5904
5905 // Touches diff
5906 touchesDiff = (pageX - touchesStart.x - paramsSwipeBackThreshold) * inverter;
5907 if (touchesDiff < 0) { touchesDiff = 0; }
5908 var percentage = Math.min(Math.max(touchesDiff / viewContainerWidth, 0), 1);
5909
5910 // Swipe Back Callback
5911 var callbackData = {
5912 percentage: percentage,
5913 progress: percentage,
5914 currentPageEl: currentPage[0],
5915 previousPageEl: previousPage[0],
5916 currentNavbarEl: $currentNavbarInner[0],
5917 previousNavbarEl: $previousNavbarInner[0],
5918 };
5919 $el.trigger('swipeback:move', callbackData);
5920 router.emit('swipebackMove', callbackData);
5921
5922 // Transform pages
5923 var currentPageTranslate = touchesDiff * inverter;
5924 var previousPageTranslate = ((touchesDiff / 5) - (viewContainerWidth / 5)) * inverter;
5925 if (!app.rtl) {
5926 currentPageTranslate = Math.min(currentPageTranslate, viewContainerWidth);
5927 previousPageTranslate = Math.min(previousPageTranslate, 0);
5928 } else {
5929 currentPageTranslate = Math.max(currentPageTranslate, -viewContainerWidth);
5930 previousPageTranslate = Math.max(previousPageTranslate, 0);
5931 }
5932 if (Device.pixelRatio === 1) {
5933 currentPageTranslate = Math.round(currentPageTranslate);
5934 previousPageTranslate = Math.round(previousPageTranslate);
5935 }
5936
5937 router.swipeBackActive = true;
5938 $([currentPage[0], previousPage[0]]).addClass('page-swipeback-active');
5939
5940 currentPage.transform(("translate3d(" + currentPageTranslate + "px,0,0)"));
5941 if (paramsSwipeBackAnimateShadow) { pageShadow[0].style.opacity = 1 - (1 * percentage); }
5942
5943 if (app.theme !== 'md') {
5944 previousPage.transform(("translate3d(" + previousPageTranslate + "px,0,0)"));
5945 }
5946 if (paramsSwipeBackAnimateOpacity) { pageOpacity[0].style.opacity = 1 - (1 * percentage); }
5947
5948 // Dynamic Navbars Animation
5949 if (!dynamicNavbar) { return; }
5950
5951 setAnimatableNavElements({ progress: percentage });
5952 }
5953 function handleTouchEnd() {
5954 app.preventSwipePanelBySwipeBack = false;
5955 if (!isTouched || !isMoved) {
5956 isTouched = false;
5957 isMoved = false;
5958 return;
5959 }
5960 isTouched = false;
5961 isMoved = false;
5962 router.swipeBackActive = false;
5963 $([currentPage[0], previousPage[0]]).removeClass('page-swipeback-active');
5964 if (touchesDiff === 0) {
5965 $([currentPage[0], previousPage[0]]).transform('');
5966 if (pageShadow && pageShadow.length > 0) { pageShadow.remove(); }
5967 if (pageOpacity && pageOpacity.length > 0) { pageOpacity.remove(); }
5968 if (dynamicNavbar) {
5969 setAnimatableNavElements({ reset: true });
5970 }
5971 return;
5972 }
5973 var timeDiff = Utils.now() - touchStartTime;
5974 var pageChanged = false;
5975 // Swipe back to previous page
5976 if (
5977 (timeDiff < 300 && touchesDiff > 10)
5978 || (timeDiff >= 300 && touchesDiff > viewContainerWidth / 2)
5979 ) {
5980 currentPage.removeClass('page-current').addClass(("page-next" + (app.theme === 'md' ? ' page-next-on-right' : '')));
5981 previousPage.removeClass('page-previous').addClass('page-current').removeAttr('aria-hidden');
5982 if (pageShadow) { pageShadow[0].style.opacity = ''; }
5983 if (pageOpacity) { pageOpacity[0].style.opacity = ''; }
5984 if (dynamicNavbar) {
5985 $currentNavbarInner.removeClass('navbar-current').addClass('navbar-next');
5986 $previousNavbarInner.removeClass('navbar-previous').addClass('navbar-current').removeAttr('aria-hidden');
5987 }
5988 pageChanged = true;
5989 }
5990 // Reset custom styles
5991 // Add transitioning class for transition-duration
5992 $([currentPage[0], previousPage[0]]).addClass('page-transitioning page-transitioning-swipeback').transform('');
5993
5994 if (dynamicNavbar) {
5995 setAnimatableNavElements({ progress: pageChanged ? 1 : 0, transition: true });
5996 }
5997 allowViewTouchMove = false;
5998 router.allowPageChange = false;
5999
6000 // Swipe Back Callback
6001 var callbackData = {
6002 currentPageEl: currentPage[0],
6003 previousPageEl: previousPage[0],
6004 currentNavbarEl: $currentNavbarInner[0],
6005 previousNavbarEl: $previousNavbarInner[0],
6006 };
6007
6008 if (pageChanged) {
6009 // Update Route
6010 router.currentRoute = previousPage[0].f7Page.route;
6011 router.currentPage = previousPage[0];
6012
6013 // Page before animation callback
6014 router.pageCallback('beforeOut', currentPage, $currentNavbarInner, 'current', 'next', { route: currentPage[0].f7Page.route, swipeBack: true });
6015 router.pageCallback('beforeIn', previousPage, $previousNavbarInner, 'previous', 'current', { route: previousPage[0].f7Page.route, swipeBack: true });
6016
6017 $el.trigger('swipeback:beforechange', callbackData);
6018 router.emit('swipebackBeforeChange', callbackData);
6019 } else {
6020 $el.trigger('swipeback:beforereset', callbackData);
6021 router.emit('swipebackBeforeReset', callbackData);
6022 }
6023
6024 currentPage.transitionEnd(function () {
6025 $([currentPage[0], previousPage[0]]).removeClass('page-transitioning page-transitioning-swipeback');
6026 if (dynamicNavbar) {
6027 setAnimatableNavElements({ reset: true, transition: false });
6028 }
6029 allowViewTouchMove = true;
6030 router.allowPageChange = true;
6031 if (pageChanged) {
6032 // Update History
6033 if (router.history.length === 1) {
6034 router.history.unshift(router.url);
6035 }
6036 router.history.pop();
6037 router.saveHistory();
6038
6039 // Update push state
6040 if (params.pushState) {
6041 History.back();
6042 }
6043
6044 // Page after animation callback
6045 router.pageCallback('afterOut', currentPage, $currentNavbarInner, 'current', 'next', { route: currentPage[0].f7Page.route, swipeBack: true });
6046 router.pageCallback('afterIn', previousPage, $previousNavbarInner, 'previous', 'current', { route: previousPage[0].f7Page.route, swipeBack: true });
6047
6048 // Remove Old Page
6049 if (params.stackPages && router.initialPages.indexOf(currentPage[0]) >= 0) {
6050 currentPage.addClass('stacked');
6051 if (separateNavbar) {
6052 $currentNavbarInner.addClass('stacked');
6053 }
6054 } else {
6055 router.pageCallback('beforeRemove', currentPage, $currentNavbarInner, 'next', { swipeBack: true });
6056 router.removePage(currentPage);
6057 if (separateNavbar) {
6058 router.removeNavbar($currentNavbarInner);
6059 }
6060 }
6061
6062 $el.trigger('swipeback:afterchange', callbackData);
6063 router.emit('swipebackAfterChange', callbackData);
6064
6065 router.emit('routeChanged', router.currentRoute, router.previousRoute, router);
6066
6067 if (params.preloadPreviousPage) {
6068 router.back(router.history[router.history.length - 2], { preload: true });
6069 }
6070 } else {
6071 $el.trigger('swipeback:afterreset', callbackData);
6072 router.emit('swipebackAfterReset', callbackData);
6073 }
6074 if (pageShadow && pageShadow.length > 0) { pageShadow.remove(); }
6075 if (pageOpacity && pageOpacity.length > 0) { pageOpacity.remove(); }
6076 });
6077 }
6078
6079 function attachEvents() {
6080 var passiveListener = (app.touchEvents.start === 'touchstart' && Support.passiveListener) ? { passive: true, capture: false } : false;
6081 $el.on(app.touchEvents.start, handleTouchStart, passiveListener);
6082 app.on('touchmove:active', handleTouchMove);
6083 app.on('touchend:passive', handleTouchEnd);
6084 }
6085 function detachEvents() {
6086 var passiveListener = (app.touchEvents.start === 'touchstart' && Support.passiveListener) ? { passive: true, capture: false } : false;
6087 $el.off(app.touchEvents.start, handleTouchStart, passiveListener);
6088 app.off('touchmove:active', handleTouchMove);
6089 app.off('touchend:passive', handleTouchEnd);
6090 }
6091
6092 attachEvents();
6093
6094 router.on('routerDestroy', detachEvents);
6095 }
6096
6097 function redirect (direction, route, options) {
6098 var router = this;
6099 var redirect = route.route.redirect;
6100 if (options.initial && router.params.pushState) {
6101 options.replaceState = true; // eslint-disable-line
6102 options.history = true; // eslint-disable-line
6103 }
6104 function redirectResolve(redirectUrl, redirectOptions) {
6105 if ( redirectOptions === void 0 ) redirectOptions = {};
6106
6107 router.allowPageChange = true;
6108 router[direction](redirectUrl, Utils.extend({}, options, redirectOptions));
6109 }
6110 function redirectReject() {
6111 router.allowPageChange = true;
6112 }
6113 if (typeof redirect === 'function') {
6114 router.allowPageChange = false;
6115 var redirectUrl = redirect.call(router, route, redirectResolve, redirectReject);
6116 if (redirectUrl && typeof redirectUrl === 'string') {
6117 router.allowPageChange = true;
6118 return router[direction](redirectUrl, options);
6119 }
6120 return router;
6121 }
6122 return router[direction](redirect, options);
6123 }
6124
6125 function processQueue(router, routerQueue, routeQueue, to, from, resolve, reject) {
6126 var queue = [];
6127
6128 if (Array.isArray(routeQueue)) {
6129 queue.push.apply(queue, routeQueue);
6130 } else if (routeQueue && typeof routeQueue === 'function') {
6131 queue.push(routeQueue);
6132 }
6133 if (routerQueue) {
6134 if (Array.isArray(routerQueue)) {
6135 queue.push.apply(queue, routerQueue);
6136 } else {
6137 queue.push(routerQueue);
6138 }
6139 }
6140
6141 function next() {
6142 if (queue.length === 0) {
6143 resolve();
6144 return;
6145 }
6146 var queueItem = queue.shift();
6147
6148 queueItem.call(
6149 router,
6150 to,
6151 from,
6152 function () {
6153 next();
6154 },
6155 function () {
6156 reject();
6157 }
6158 );
6159 }
6160 next();
6161 }
6162
6163 function processRouteQueue (to, from, resolve, reject) {
6164 var router = this;
6165 function enterNextRoute() {
6166 if (to && to.route && (router.params.routesBeforeEnter || to.route.beforeEnter)) {
6167 router.allowPageChange = false;
6168 processQueue(
6169 router,
6170 router.params.routesBeforeEnter,
6171 to.route.beforeEnter,
6172 to,
6173 from,
6174 function () {
6175 router.allowPageChange = true;
6176 resolve();
6177 },
6178 function () {
6179 reject();
6180 }
6181 );
6182 } else {
6183 resolve();
6184 }
6185 }
6186 function leaveCurrentRoute() {
6187 if (from && from.route && (router.params.routesBeforeLeave || from.route.beforeLeave)) {
6188 router.allowPageChange = false;
6189 processQueue(
6190 router,
6191 router.params.routesBeforeLeave,
6192 from.route.beforeLeave,
6193 to,
6194 from,
6195 function () {
6196 router.allowPageChange = true;
6197 enterNextRoute();
6198 },
6199 function () {
6200 reject();
6201 }
6202 );
6203 } else {
6204 enterNextRoute();
6205 }
6206 }
6207 leaveCurrentRoute();
6208 }
6209
6210 function appRouterCheck (router, method) {
6211 if (!router.view) {
6212 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 + "(...)"));
6213 }
6214 }
6215
6216 function refreshPage() {
6217 var router = this;
6218 appRouterCheck(router, 'refreshPage');
6219 return router.navigate(router.currentRoute.url, {
6220 ignoreCache: true,
6221 reloadCurrent: true,
6222 });
6223 }
6224
6225 function forward(el, forwardOptions) {
6226 if ( forwardOptions === void 0 ) forwardOptions = {};
6227
6228 var router = this;
6229 var $el = $(el);
6230 var app = router.app;
6231 var view = router.view;
6232 var options = Utils.extend(false, {
6233 animate: router.params.animate,
6234 pushState: true,
6235 replaceState: false,
6236 history: true,
6237 reloadCurrent: router.params.reloadPages,
6238 reloadPrevious: false,
6239 reloadAll: false,
6240 clearPreviousHistory: false,
6241 reloadDetail: router.params.reloadDetail,
6242 on: {},
6243 }, forwardOptions);
6244
6245 var masterDetailEnabled = router.params.masterDetailBreakpoint > 0;
6246 var isMaster = masterDetailEnabled && options.route && options.route.route && options.route.route.master === true;
6247 var masterPageEl;
6248 var otherDetailPageEl;
6249
6250 var currentRouteIsModal = router.currentRoute.modal;
6251 var modalType;
6252 if (!currentRouteIsModal) {
6253 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp) {
6254 if (router.currentRoute && router.currentRoute.route && router.currentRoute.route[modalLoadProp]) {
6255 currentRouteIsModal = true;
6256 modalType = modalLoadProp;
6257 }
6258 });
6259 }
6260
6261 if (currentRouteIsModal) {
6262 var modalToClose = router.currentRoute.modal
6263 || router.currentRoute.route.modalInstance
6264 || app[modalType].get();
6265 var previousUrl = router.history[router.history.length - 2];
6266 var previousRoute = router.findMatchingRoute(previousUrl);
6267 if (!previousRoute && previousUrl) {
6268 previousRoute = {
6269 url: previousUrl,
6270 path: previousUrl.split('?')[0],
6271 query: Utils.parseUrlQuery(previousUrl),
6272 route: {
6273 path: previousUrl.split('?')[0],
6274 url: previousUrl,
6275 },
6276 };
6277 }
6278
6279 router.modalRemove(modalToClose);
6280 }
6281
6282 var dynamicNavbar = router.dynamicNavbar;
6283 var separateNavbar = router.separateNavbar;
6284
6285 var $viewEl = router.$el;
6286 var $newPage = $el;
6287 var reload = options.reloadPrevious || options.reloadCurrent || options.reloadAll;
6288 var $oldPage;
6289
6290 var $navbarEl;
6291 var $newNavbarInner;
6292 var $oldNavbarInner;
6293
6294 router.allowPageChange = false;
6295 if ($newPage.length === 0) {
6296 router.allowPageChange = true;
6297 return router;
6298 }
6299
6300 if ($newPage.length) {
6301 // Remove theme elements
6302 router.removeThemeElements($newPage);
6303 }
6304
6305 if (dynamicNavbar) {
6306 $newNavbarInner = $newPage.children('.navbar').children('.navbar-inner');
6307 if (separateNavbar) {
6308 $navbarEl = router.$navbarEl;
6309 if ($newNavbarInner.length > 0) {
6310 $newPage.children('.navbar').remove();
6311 }
6312 if ($newNavbarInner.length === 0 && $newPage[0] && $newPage[0].f7Page) {
6313 // Try from pageData
6314 $newNavbarInner = $newPage[0].f7Page.$navbarEl;
6315 }
6316 }
6317 }
6318
6319 // Save Keep Alive Cache
6320 if (options.route && options.route.route && options.route.route.keepAlive && !options.route.route.keepAliveData) {
6321 options.route.route.keepAliveData = {
6322 pageEl: $el[0],
6323 };
6324 }
6325
6326 // Pages In View
6327 var $pagesInView = $viewEl
6328 .children('.page:not(.stacked)')
6329 .filter(function (index, pageInView) { return pageInView !== $newPage[0]; });
6330
6331 // Navbars In View
6332 var $navbarsInView;
6333 if (separateNavbar) {
6334 $navbarsInView = $navbarEl
6335 .children('.navbar-inner:not(.stacked)')
6336 .filter(function (index, navbarInView) { return navbarInView !== $newNavbarInner[0]; });
6337 }
6338
6339 // Exit when reload previous and only 1 page in view so nothing ro reload
6340 if (options.reloadPrevious && $pagesInView.length < 2) {
6341 router.allowPageChange = true;
6342 return router;
6343 }
6344
6345 // Find Detail' master page
6346 var isDetail;
6347 var reloadDetail;
6348 if (masterDetailEnabled && !options.reloadAll) {
6349 for (var i = 0; i < $pagesInView.length; i += 1) {
6350 if (!masterPageEl
6351 && $pagesInView[i].classList.contains('page-master')
6352 ) {
6353 masterPageEl = $pagesInView[i];
6354 continue; // eslint-disable-line
6355 }
6356 }
6357 isDetail = !isMaster && masterPageEl;
6358
6359 if (isDetail) {
6360 // Find Other Detail
6361 if (masterPageEl) {
6362 for (var i$1 = 0; i$1 < $pagesInView.length; i$1 += 1) {
6363 if ($pagesInView[i$1].classList.contains('page-master-detail')
6364 ) {
6365 otherDetailPageEl = $pagesInView[i$1];
6366 continue; // eslint-disable-line
6367 }
6368 }
6369 }
6370 }
6371 reloadDetail = isDetail && options.reloadDetail && app.width >= router.params.masterDetailBreakpoint && masterPageEl;
6372 }
6373
6374 // New Page
6375 var newPagePosition = 'next';
6376 if (options.reloadCurrent || options.reloadAll || reloadDetail) {
6377 newPagePosition = 'current';
6378 } else if (options.reloadPrevious) {
6379 newPagePosition = 'previous';
6380 }
6381 $newPage
6382 .addClass(("page-" + newPagePosition + (isMaster ? ' page-master' : '') + (isDetail ? ' page-master-detail' : '')))
6383 .removeClass('stacked')
6384 .trigger('page:unstack')
6385 .trigger('page:position', { position: newPagePosition });
6386 if (isMaster || isDetail) {
6387 $newPage.trigger('page:role', { role: isMaster ? 'master' : 'detail' });
6388 }
6389
6390
6391 if (dynamicNavbar && $newNavbarInner.length) {
6392 $newNavbarInner
6393 .addClass(("navbar-" + newPagePosition + (isMaster ? ' navbar-master' : '') + (isDetail ? ' navbar-master-detail' : '')))
6394 .removeClass('stacked');
6395 }
6396
6397 // Find Old Page
6398 if (options.reloadCurrent || reloadDetail) {
6399 $oldPage = $pagesInView.eq($pagesInView.length - 1);
6400 if (separateNavbar) {
6401 // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 1);
6402 $oldNavbarInner = $(app.navbar.getElByPage($oldPage));
6403 }
6404 } else if (options.reloadPrevious) {
6405 $oldPage = $pagesInView.eq($pagesInView.length - 2);
6406 if (separateNavbar) {
6407 // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 2);
6408 $oldNavbarInner = $(app.navbar.getElByPage($oldPage));
6409 }
6410 } else if (options.reloadAll) {
6411 $oldPage = $pagesInView.filter(function (index, pageEl) { return pageEl !== $newPage[0]; });
6412 if (separateNavbar) {
6413 $oldNavbarInner = $navbarsInView.filter(function (index, navbarEl) { return navbarEl !== $newNavbarInner[0]; });
6414 }
6415 } else {
6416 if ($pagesInView.length > 1) {
6417 var i$2 = 0;
6418 for (i$2 = 0; i$2 < $pagesInView.length - 1; i$2 += 1) {
6419 if (masterPageEl
6420 && $pagesInView[i$2] === masterPageEl
6421 ) {
6422 $pagesInView.eq(i$2).addClass('page-master-stacked');
6423 $pagesInView.eq(i$2).trigger('page:masterstack');
6424 if (separateNavbar) {
6425 $(app.navbar.getElByPage(masterPageEl)).addClass('navbar-master-stacked');
6426 }
6427 continue; // eslint-disable-line
6428 }
6429 var oldNavbarInnerEl = app.navbar.getElByPage($pagesInView.eq(i$2));
6430 if (router.params.stackPages) {
6431 $pagesInView.eq(i$2).addClass('stacked');
6432 $pagesInView.eq(i$2).trigger('page:stack');
6433 if (separateNavbar) {
6434 $(oldNavbarInnerEl).addClass('stacked');
6435 }
6436 } else {
6437 // Page remove event
6438 router.pageCallback('beforeRemove', $pagesInView[i$2], $navbarsInView && $navbarsInView[i$2], 'previous', undefined, options);
6439 router.removePage($pagesInView[i$2]);
6440 if (separateNavbar && oldNavbarInnerEl) {
6441 router.removeNavbar(oldNavbarInnerEl);
6442 }
6443 }
6444 }
6445 }
6446 $oldPage = $viewEl
6447 .children('.page:not(.stacked)')
6448 .filter(function (index, page) { return page !== $newPage[0]; });
6449 if (separateNavbar) {
6450 $oldNavbarInner = $navbarEl
6451 .children('.navbar-inner:not(.stacked)')
6452 .filter(function (index, navbarInner) { return navbarInner !== $newNavbarInner[0]; });
6453 }
6454 }
6455
6456 if (dynamicNavbar && !separateNavbar) {
6457 $oldNavbarInner = $oldPage.children('.navbar').children('.navbar-inner');
6458 }
6459 if (isDetail && !options.reloadAll) {
6460 if ($oldPage.length > 1 || reloadDetail) {
6461 $oldPage = $oldPage.filter(function (pageIndex, pageEl) { return !pageEl.classList.contains('page-master'); });
6462 }
6463 if ($oldNavbarInner && ($oldNavbarInner.length > 1 || reloadDetail)) {
6464 $oldNavbarInner = $oldNavbarInner.filter(function (navbarIndex, navbarEl) { return !navbarEl.classList.contains('navbar-master'); });
6465 }
6466 }
6467
6468 // Push State
6469 if (router.params.pushState && (options.pushState || options.replaceState) && !options.reloadPrevious) {
6470 var pushStateRoot = router.params.pushStateRoot || '';
6471 History[options.reloadCurrent || (reloadDetail && otherDetailPageEl) || options.reloadAll || options.replaceState ? 'replace' : 'push'](
6472 view.id,
6473 {
6474 url: options.route.url,
6475 },
6476 pushStateRoot + router.params.pushStateSeparator + options.route.url
6477 );
6478 }
6479
6480 if (!options.reloadPrevious) {
6481 // Current Page & Navbar
6482 router.currentPageEl = $newPage[0];
6483 if (dynamicNavbar && $newNavbarInner.length) {
6484 router.currentNavbarEl = $newNavbarInner[0];
6485 } else {
6486 delete router.currentNavbarEl;
6487 }
6488
6489 // Current Route
6490 router.currentRoute = options.route;
6491 }
6492
6493 // Update router history
6494 var url = options.route.url;
6495
6496 if (options.history) {
6497 if (((options.reloadCurrent || (reloadDetail && otherDetailPageEl)) && router.history.length) > 0 || options.replaceState) {
6498 router.history[router.history.length - (options.reloadPrevious ? 2 : 1)] = url;
6499 } else if (options.reloadPrevious) {
6500 router.history[router.history.length - 2] = url;
6501 } else if (options.reloadAll) {
6502 router.history = [url];
6503 } else {
6504 router.history.push(url);
6505 }
6506 }
6507 router.saveHistory();
6508
6509 // Insert new page and navbar
6510 var newPageInDom = $newPage.parents(doc).length > 0;
6511 var f7Component = $newPage[0].f7Component;
6512 if (options.reloadPrevious) {
6513 if (f7Component && !newPageInDom) {
6514 f7Component.$mount(function (componentEl) {
6515 $(componentEl).insertBefore($oldPage);
6516 });
6517 } else {
6518 $newPage.insertBefore($oldPage);
6519 }
6520 if (separateNavbar && $newNavbarInner.length) {
6521 if ($newNavbarInner.children('.title-large').length) {
6522 $newNavbarInner.addClass('navbar-inner-large');
6523 }
6524 if ($oldNavbarInner.length) {
6525 $newNavbarInner.insertBefore($oldNavbarInner);
6526 } else {
6527 if (!router.$navbarEl.parents(doc).length) {
6528 router.$el.prepend(router.$navbarEl);
6529 }
6530 $navbarEl.append($newNavbarInner);
6531 }
6532 }
6533 } else {
6534 if ($oldPage.next('.page')[0] !== $newPage[0]) {
6535 if (f7Component && !newPageInDom) {
6536 f7Component.$mount(function (componentEl) {
6537 $viewEl.append(componentEl);
6538 });
6539 } else {
6540 $viewEl.append($newPage[0]);
6541 }
6542 }
6543 if (separateNavbar && $newNavbarInner.length) {
6544 if ($newNavbarInner.children('.title-large').length) {
6545 $newNavbarInner.addClass('navbar-inner-large');
6546 }
6547 if (!router.$navbarEl.parents(doc).length) {
6548 router.$el.prepend(router.$navbarEl);
6549 }
6550 $navbarEl.append($newNavbarInner[0]);
6551 }
6552 }
6553 if (!newPageInDom) {
6554 router.pageCallback('mounted', $newPage, $newNavbarInner, newPagePosition, reload ? newPagePosition : 'current', options, $oldPage);
6555 } else if (options.route && options.route.route && options.route.route.keepAlive && !$newPage[0].f7PageMounted) {
6556 $newPage[0].f7PageMounted = true;
6557 router.pageCallback('mounted', $newPage, $newNavbarInner, newPagePosition, reload ? newPagePosition : 'current', options, $oldPage);
6558 }
6559
6560 // Remove old page
6561 if ((options.reloadCurrent || reloadDetail) && $oldPage.length > 0) {
6562 if (router.params.stackPages && router.initialPages.indexOf($oldPage[0]) >= 0) {
6563 $oldPage.addClass('stacked');
6564 $oldPage.trigger('page:stack');
6565 if (separateNavbar) {
6566 $oldNavbarInner.addClass('stacked');
6567 }
6568 } else {
6569 // Page remove event
6570 router.pageCallback('beforeRemove', $oldPage, $oldNavbarInner, 'previous', undefined, options);
6571 router.removePage($oldPage);
6572 if (separateNavbar && $oldNavbarInner && $oldNavbarInner.length) {
6573 router.removeNavbar($oldNavbarInner);
6574 }
6575 }
6576 } else if (options.reloadAll) {
6577 $oldPage.each(function (index, pageEl) {
6578 var $oldPageEl = $(pageEl);
6579 var $oldNavbarInnerEl = $(app.navbar.getElByPage($oldPageEl));
6580 if (router.params.stackPages && router.initialPages.indexOf($oldPageEl[0]) >= 0) {
6581 $oldPageEl.addClass('stacked');
6582 $oldPageEl.trigger('page:stack');
6583 if (separateNavbar) {
6584 $oldNavbarInnerEl.addClass('stacked');
6585 }
6586 } else {
6587 // Page remove event
6588 router.pageCallback('beforeRemove', $oldPageEl, $oldNavbarInner && $oldNavbarInner.eq(index), 'previous', undefined, options);
6589 router.removePage($oldPageEl);
6590 if (separateNavbar && $oldNavbarInnerEl.length) {
6591 router.removeNavbar($oldNavbarInnerEl);
6592 }
6593 }
6594 });
6595 } else if (options.reloadPrevious) {
6596 if (router.params.stackPages && router.initialPages.indexOf($oldPage[0]) >= 0) {
6597 $oldPage.addClass('stacked');
6598 $oldPage.trigger('page:stack');
6599 if (separateNavbar) {
6600 $oldNavbarInner.addClass('stacked');
6601 }
6602 } else {
6603 // Page remove event
6604 router.pageCallback('beforeRemove', $oldPage, $oldNavbarInner, 'previous', undefined, options);
6605 router.removePage($oldPage);
6606 if (separateNavbar && $oldNavbarInner && $oldNavbarInner.length) {
6607 router.removeNavbar($oldNavbarInner);
6608 }
6609 }
6610 }
6611
6612 // Load Tab
6613 if (options.route.route.tab) {
6614 router.tabLoad(options.route.route.tab, Utils.extend({}, options, {
6615 history: false,
6616 pushState: false,
6617 }));
6618 }
6619
6620 // Page init and before init events
6621 router.pageCallback('init', $newPage, $newNavbarInner, newPagePosition, reload ? newPagePosition : 'current', options, $oldPage);
6622
6623 if (options.reloadCurrent || options.reloadAll || reloadDetail) {
6624 router.allowPageChange = true;
6625 router.pageCallback('beforeIn', $newPage, $newNavbarInner, newPagePosition, 'current', options);
6626 router.pageCallback('afterIn', $newPage, $newNavbarInner, newPagePosition, 'current', options);
6627 if (options.reloadCurrent && options.clearPreviousHistory) { router.clearPreviousHistory(); }
6628 if (reloadDetail) {
6629 masterPageEl.classList.add('page-previous');
6630 masterPageEl.classList.remove('page-current');
6631 $(masterPageEl).trigger('page:position', { position: 'previous' });
6632 if (masterPageEl.f7Page && masterPageEl.f7Page.navbarEl) {
6633 masterPageEl.f7Page.navbarEl.classList.add('navbar-previous');
6634 masterPageEl.f7Page.navbarEl.classList.remove('navbar-current');
6635 }
6636 }
6637 return router;
6638 }
6639 if (options.reloadPrevious) {
6640 router.allowPageChange = true;
6641 return router;
6642 }
6643
6644 // Before animation event
6645 router.pageCallback('beforeIn', $newPage, $newNavbarInner, 'next', 'current', options);
6646 router.pageCallback('beforeOut', $oldPage, $oldNavbarInner, 'current', 'previous', options);
6647
6648 // Animation
6649 function afterAnimation() {
6650 var pageClasses = 'page-previous page-current page-next';
6651 var navbarClasses = 'navbar-previous navbar-current navbar-next';
6652 $newPage.removeClass(pageClasses).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position: 'current' });
6653 $oldPage.removeClass(pageClasses).addClass('page-previous').trigger('page:position', { position: 'previous' });
6654 if (!$oldPage.hasClass('page-master')) {
6655 $oldPage.attr('aria-hidden', 'true');
6656 }
6657 if (dynamicNavbar) {
6658 $newNavbarInner.removeClass(navbarClasses).addClass('navbar-current').removeAttr('aria-hidden');
6659 $oldNavbarInner.removeClass(navbarClasses).addClass('navbar-previous');
6660 if (!$oldNavbarInner.hasClass('navbar-master')) {
6661 $oldNavbarInner.attr('aria-hidden', 'true');
6662 }
6663 }
6664 // After animation event
6665 router.allowPageChange = true;
6666 router.pageCallback('afterIn', $newPage, $newNavbarInner, 'next', 'current', options);
6667 router.pageCallback('afterOut', $oldPage, $oldNavbarInner, 'current', 'previous', options);
6668
6669 var keepOldPage = (router.params.preloadPreviousPage || (app.theme === 'ios' ? router.params.iosSwipeBack : router.params.mdSwipeBack)) && !isMaster;
6670 if (!keepOldPage) {
6671 if ($newPage.hasClass('smart-select-page') || $newPage.hasClass('photo-browser-page') || $newPage.hasClass('autocomplete-page')) {
6672 keepOldPage = true;
6673 }
6674 }
6675 if (!keepOldPage) {
6676 if (router.params.stackPages) {
6677 $oldPage.addClass('stacked');
6678 $oldPage.trigger('page:stack');
6679 if (separateNavbar) {
6680 $oldNavbarInner.addClass('stacked');
6681 }
6682 } else if (!($newPage.attr('data-name') && $newPage.attr('data-name') === 'smart-select-page')) {
6683 // Remove event
6684 router.pageCallback('beforeRemove', $oldPage, $oldNavbarInner, 'previous', undefined, options);
6685 router.removePage($oldPage);
6686 if (separateNavbar && $oldNavbarInner.length) {
6687 router.removeNavbar($oldNavbarInner);
6688 }
6689 }
6690 }
6691 if (options.clearPreviousHistory) { router.clearPreviousHistory(); }
6692 router.emit('routeChanged', router.currentRoute, router.previousRoute, router);
6693
6694 if (router.params.pushState) {
6695 History.clearRouterQueue();
6696 }
6697 }
6698 function setPositionClasses() {
6699 var pageClasses = 'page-previous page-current page-next';
6700 var navbarClasses = 'navbar-previous navbar-current navbar-next';
6701 $oldPage.removeClass(pageClasses).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position: 'current' });
6702 $newPage.removeClass(pageClasses).addClass('page-next').removeAttr('aria-hidden').trigger('page:position', { position: 'next' });
6703 if (dynamicNavbar) {
6704 $oldNavbarInner.removeClass(navbarClasses).addClass('navbar-current').removeAttr('aria-hidden');
6705 $newNavbarInner.removeClass(navbarClasses).addClass('navbar-next').removeAttr('aria-hidden');
6706 }
6707 }
6708 if (options.animate && !(isMaster && app.width >= router.params.masterDetailBreakpoint)) {
6709 var delay = router.app.theme === 'md' ? router.params.mdPageLoadDelay : router.params.iosPageLoadDelay;
6710 if (delay) {
6711 setTimeout(function () {
6712 setPositionClasses();
6713 router.animate($oldPage, $newPage, $oldNavbarInner, $newNavbarInner, 'forward', function () {
6714 afterAnimation();
6715 });
6716 }, delay);
6717 } else {
6718 setPositionClasses();
6719 router.animate($oldPage, $newPage, $oldNavbarInner, $newNavbarInner, 'forward', function () {
6720 afterAnimation();
6721 });
6722 }
6723 } else {
6724 afterAnimation();
6725 }
6726 return router;
6727 }
6728 function load(loadParams, loadOptions, ignorePageChange) {
6729 if ( loadParams === void 0 ) loadParams = {};
6730 if ( loadOptions === void 0 ) loadOptions = {};
6731
6732 var router = this;
6733 if (!router.allowPageChange && !ignorePageChange) { return router; }
6734 var params = loadParams;
6735 var options = loadOptions;
6736 var url = params.url;
6737 var content = params.content;
6738 var el = params.el;
6739 var pageName = params.pageName;
6740 var template = params.template;
6741 var templateUrl = params.templateUrl;
6742 var component = params.component;
6743 var componentUrl = params.componentUrl;
6744
6745 if (!options.reloadCurrent
6746 && options.route
6747 && options.route.route
6748 && options.route.route.parentPath
6749 && router.currentRoute.route
6750 && router.currentRoute.route.parentPath === options.route.route.parentPath) {
6751 // Do something nested
6752 if (options.route.url === router.url) {
6753 router.allowPageChange = true;
6754 return false;
6755 }
6756 // Check for same params
6757 var sameParams = Object.keys(options.route.params).length === Object.keys(router.currentRoute.params).length;
6758 if (sameParams) {
6759 // Check for equal params name
6760 Object.keys(options.route.params).forEach(function (paramName) {
6761 if (
6762 !(paramName in router.currentRoute.params)
6763 || (router.currentRoute.params[paramName] !== options.route.params[paramName])
6764 ) {
6765 sameParams = false;
6766 }
6767 });
6768 }
6769 if (sameParams) {
6770 if (options.route.route.tab) {
6771 return router.tabLoad(options.route.route.tab, options);
6772 }
6773 return false;
6774 }
6775 if (!sameParams
6776 && options.route.route.tab
6777 && router.currentRoute.route.tab
6778 && router.currentRoute.parentPath === options.route.parentPath
6779 ) {
6780 return router.tabLoad(options.route.route.tab, options);
6781 }
6782 }
6783
6784 if (
6785 options.route
6786 && options.route.url
6787 && router.url === options.route.url
6788 && !(options.reloadCurrent || options.reloadPrevious)
6789 && !router.params.allowDuplicateUrls
6790 ) {
6791 router.allowPageChange = true;
6792 return false;
6793 }
6794
6795 if (!options.route && url) {
6796 options.route = router.parseRouteUrl(url);
6797 Utils.extend(options.route, { route: { url: url, path: url } });
6798 }
6799
6800 // Component Callbacks
6801 function resolve(pageEl, newOptions) {
6802 return router.forward(pageEl, Utils.extend(options, newOptions));
6803 }
6804 function reject() {
6805 router.allowPageChange = true;
6806 return router;
6807 }
6808
6809 if (url || templateUrl || componentUrl) {
6810 router.allowPageChange = false;
6811 }
6812
6813 // Proceed
6814 if (content) {
6815 router.forward(router.getPageEl(content), options);
6816 } else if (template || templateUrl) {
6817 // Parse template and send page element
6818 try {
6819 router.pageTemplateLoader(template, templateUrl, options, resolve, reject);
6820 } catch (err) {
6821 router.allowPageChange = true;
6822 throw err;
6823 }
6824 } else if (el) {
6825 // Load page from specified HTMLElement or by page name in pages container
6826 router.forward(router.getPageEl(el), options);
6827 } else if (pageName) {
6828 // Load page by page name in pages container
6829 router.forward(router.$el.children((".page[data-name=\"" + pageName + "\"]")).eq(0), options);
6830 } else if (component || componentUrl) {
6831 // Load from component (F7/Vue/React/...)
6832 try {
6833 router.pageComponentLoader(router.el, component, componentUrl, options, resolve, reject);
6834 } catch (err) {
6835 router.allowPageChange = true;
6836 throw err;
6837 }
6838 } else if (url) {
6839 // Load using XHR
6840 if (router.xhr) {
6841 router.xhr.abort();
6842 router.xhr = false;
6843 }
6844 router.xhrRequest(url, options)
6845 .then(function (pageContent) {
6846 router.forward(router.getPageEl(pageContent), options);
6847 })
6848 .catch(function () {
6849 router.allowPageChange = true;
6850 });
6851 }
6852 return router;
6853 }
6854 function navigate(navigateParams, navigateOptions) {
6855 if ( navigateOptions === void 0 ) navigateOptions = {};
6856
6857 var router = this;
6858 if (router.swipeBackActive) { return router; }
6859 var url;
6860 var createRoute;
6861 var name;
6862 var query;
6863 var params;
6864 var route;
6865 if (typeof navigateParams === 'string') {
6866 url = navigateParams;
6867 } else {
6868 url = navigateParams.url;
6869 createRoute = navigateParams.route;
6870 name = navigateParams.name;
6871 query = navigateParams.query;
6872 params = navigateParams.params;
6873 }
6874 if (name) {
6875 // find route by name
6876 route = router.findRouteByKey('name', name);
6877 if (!route) {
6878 throw new Error(("Framework7: route with name \"" + name + "\" not found"));
6879 }
6880 url = router.constructRouteUrl(route, { params: params, query: query });
6881 if (url) {
6882 return router.navigate(url, navigateOptions);
6883 }
6884 throw new Error(("Framework7: can't construct URL for route with name \"" + name + "\""));
6885 }
6886 var app = router.app;
6887 appRouterCheck(router, 'navigate');
6888 if (url === '#' || url === '') {
6889 return router;
6890 }
6891
6892 var navigateUrl = url.replace('./', '');
6893 if (navigateUrl[0] !== '/' && navigateUrl.indexOf('#') !== 0) {
6894 var currentPath = router.currentRoute.parentPath || router.currentRoute.path;
6895 navigateUrl = ((currentPath ? (currentPath + "/") : '/') + navigateUrl)
6896 .replace('///', '/')
6897 .replace('//', '/');
6898 }
6899 if (createRoute) {
6900 route = Utils.extend(router.parseRouteUrl(navigateUrl), {
6901 route: Utils.extend({}, createRoute),
6902 });
6903 } else {
6904 route = router.findMatchingRoute(navigateUrl);
6905 }
6906
6907 if (!route) {
6908 return router;
6909 }
6910
6911 if (route.route.redirect) {
6912 return redirect.call(router, 'navigate', route, navigateOptions);
6913 }
6914
6915
6916 var options = {};
6917 if (route.route.options) {
6918 Utils.extend(options, route.route.options, navigateOptions);
6919 } else {
6920 Utils.extend(options, navigateOptions);
6921 }
6922 options.route = route;
6923
6924 if (options && options.context) {
6925 route.context = options.context;
6926 options.route.context = options.context;
6927 }
6928
6929 function resolve() {
6930 var routerLoaded = false;
6931 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp) {
6932 if (route.route[modalLoadProp] && !routerLoaded) {
6933 routerLoaded = true;
6934 router.modalLoad(modalLoadProp, route, options);
6935 }
6936 });
6937 if (route.route.keepAlive && route.route.keepAliveData) {
6938 router.load({ el: route.route.keepAliveData.pageEl }, options, false);
6939 routerLoaded = true;
6940 }
6941 ('url content component pageName el componentUrl template templateUrl').split(' ').forEach(function (pageLoadProp) {
6942 var obj;
6943
6944 if (route.route[pageLoadProp] && !routerLoaded) {
6945 routerLoaded = true;
6946 router.load(( obj = {}, obj[pageLoadProp] = route.route[pageLoadProp], obj ), options, false);
6947 }
6948 });
6949 if (routerLoaded) { return; }
6950 // Async
6951 function asyncResolve(resolveParams, resolveOptions) {
6952 router.allowPageChange = false;
6953 var resolvedAsModal = false;
6954 if (resolveOptions && resolveOptions.context) {
6955 if (!route.context) { route.context = resolveOptions.context; }
6956 else { route.context = Utils.extend({}, route.context, resolveOptions.context); }
6957 options.route.context = route.context;
6958 }
6959 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp) {
6960 if (resolveParams[modalLoadProp]) {
6961 resolvedAsModal = true;
6962 var modalRoute = Utils.extend({}, route, { route: resolveParams });
6963 router.allowPageChange = true;
6964 router.modalLoad(modalLoadProp, modalRoute, Utils.extend(options, resolveOptions));
6965 }
6966 });
6967 if (resolvedAsModal) { return; }
6968 router.load(resolveParams, Utils.extend(options, resolveOptions), true);
6969 }
6970 function asyncReject() {
6971 router.allowPageChange = true;
6972 }
6973 if (route.route.async) {
6974 router.allowPageChange = false;
6975
6976 route.route.async.call(router, options.route, router.currentRoute, asyncResolve, asyncReject);
6977 }
6978 }
6979 function reject() {
6980 router.allowPageChange = true;
6981 }
6982
6983 if (router.params.masterDetailBreakpoint > 0 && route.route.masterRoute) {
6984 // load detail route
6985 var preloadMaster = true;
6986 if (router.currentRoute && router.currentRoute.route) {
6987 if (router.currentRoute.route.master && (router.currentRoute.route === route.route.masterRoute || router.currentRoute.route.path === route.route.masterRoute.path)) {
6988 preloadMaster = false;
6989 }
6990 if (router.currentRoute.route.masterRoute && ((router.currentRoute.route.masterRoute === route.route.masterRoute) || (router.currentRoute.route.masterRoute.path === route.route.masterRoute.path))) {
6991 preloadMaster = false;
6992 }
6993 }
6994 if (preloadMaster) {
6995 router.navigate(route.route.masterRoute.path, {
6996 animate: false,
6997 reloadAll: navigateOptions.reloadAll,
6998 reloadCurrent: navigateOptions.reloadCurrent,
6999 reloadPrevious: navigateOptions.reloadPrevious,
7000 once: {
7001 pageAfterIn: function pageAfterIn() {
7002 router.navigate(navigateParams, Utils.extend({}, navigateOptions, {
7003 animate: false,
7004 reloadAll: false,
7005 reloadCurrent: false,
7006 reloadPrevious: false,
7007 }));
7008 },
7009 },
7010 });
7011 return router;
7012 }
7013 }
7014
7015 processRouteQueue.call(
7016 router,
7017 route,
7018 router.currentRoute,
7019 function () {
7020 if (route.route.modules) {
7021 app
7022 .loadModules(Array.isArray(route.route.modules) ? route.route.modules : [route.route.modules])
7023 .then(function () {
7024 resolve();
7025 })
7026 .catch(function () {
7027 reject();
7028 });
7029 } else {
7030 resolve();
7031 }
7032 },
7033 function () {
7034 reject();
7035 }
7036 );
7037
7038 // Return Router
7039 return router;
7040 }
7041
7042 function tabLoad(tabRoute, loadOptions) {
7043 if ( loadOptions === void 0 ) loadOptions = {};
7044
7045 var router = this;
7046 var options = Utils.extend({
7047 animate: router.params.animate,
7048 pushState: true,
7049 history: true,
7050 parentPageEl: null,
7051 preload: false,
7052 on: {},
7053 }, loadOptions);
7054
7055 var currentRoute;
7056 var previousRoute;
7057 if (options.route) {
7058 // Set Route
7059 if (!options.preload && options.route !== router.currentRoute) {
7060 previousRoute = router.previousRoute;
7061 router.currentRoute = options.route;
7062 }
7063 if (options.preload) {
7064 currentRoute = options.route;
7065 previousRoute = router.currentRoute;
7066 } else {
7067 currentRoute = router.currentRoute;
7068 if (!previousRoute) { previousRoute = router.previousRoute; }
7069 }
7070
7071 // Update Browser History
7072 if (router.params.pushState && options.pushState && !options.reloadPrevious) {
7073 History.replace(
7074 router.view.id,
7075 {
7076 url: options.route.url,
7077 },
7078 (router.params.pushStateRoot || '') + router.params.pushStateSeparator + options.route.url
7079 );
7080 }
7081
7082 // Update Router History
7083 if (options.history) {
7084 router.history[Math.max(router.history.length - 1, 0)] = options.route.url;
7085 router.saveHistory();
7086 }
7087 }
7088
7089 // Show Tab
7090 var $parentPageEl = $(options.parentPageEl || router.currentPageEl);
7091 var tabEl;
7092 if ($parentPageEl.length && $parentPageEl.find(("#" + (tabRoute.id))).length) {
7093 tabEl = $parentPageEl.find(("#" + (tabRoute.id))).eq(0);
7094 } else if (router.view.selector) {
7095 tabEl = (router.view.selector) + " #" + (tabRoute.id);
7096 } else {
7097 tabEl = "#" + (tabRoute.id);
7098 }
7099 var tabShowResult = router.app.tab.show({
7100 tabEl: tabEl,
7101 animate: options.animate,
7102 tabRoute: options.route,
7103 });
7104
7105 var $newTabEl = tabShowResult.$newTabEl;
7106 var $oldTabEl = tabShowResult.$oldTabEl;
7107 var animated = tabShowResult.animated;
7108 var onTabsChanged = tabShowResult.onTabsChanged;
7109
7110 if ($newTabEl && $newTabEl.parents('.page').length > 0 && options.route) {
7111 var tabParentPageData = $newTabEl.parents('.page')[0].f7Page;
7112 if (tabParentPageData && options.route) {
7113 tabParentPageData.route = options.route;
7114 }
7115 }
7116
7117 // Tab Content Loaded
7118 function onTabLoaded(contentEl) {
7119 // Remove theme elements
7120 router.removeThemeElements($newTabEl);
7121
7122 var tabEventTarget = $newTabEl;
7123 if (typeof contentEl !== 'string') { tabEventTarget = $(contentEl); }
7124
7125 tabEventTarget.trigger('tab:init tab:mounted', tabRoute);
7126 router.emit('tabInit tabMounted', $newTabEl[0], tabRoute);
7127
7128 if ($oldTabEl && $oldTabEl.length) {
7129 if (animated) {
7130 onTabsChanged(function () {
7131 router.emit('routeChanged', router.currentRoute, router.previousRoute, router);
7132 if (router.params.unloadTabContent) {
7133 router.tabRemove($oldTabEl, $newTabEl, tabRoute);
7134 }
7135 });
7136 } else {
7137 router.emit('routeChanged', router.currentRoute, router.previousRoute, router);
7138 if (router.params.unloadTabContent) {
7139 router.tabRemove($oldTabEl, $newTabEl, tabRoute);
7140 }
7141 }
7142 }
7143 }
7144
7145 if ($newTabEl[0].f7RouterTabLoaded) {
7146 if (!$oldTabEl || !$oldTabEl.length) { return router; }
7147 if (animated) {
7148 onTabsChanged(function () {
7149 router.emit('routeChanged', router.currentRoute, router.previousRoute, router);
7150 });
7151 } else {
7152 router.emit('routeChanged', router.currentRoute, router.previousRoute, router);
7153 }
7154 return router;
7155 }
7156
7157 // Load Tab Content
7158 function loadTab(loadTabParams, loadTabOptions) {
7159 // Load Tab Props
7160 var url = loadTabParams.url;
7161 var content = loadTabParams.content;
7162 var el = loadTabParams.el;
7163 var template = loadTabParams.template;
7164 var templateUrl = loadTabParams.templateUrl;
7165 var component = loadTabParams.component;
7166 var componentUrl = loadTabParams.componentUrl;
7167 // Component/Template Callbacks
7168 function resolve(contentEl) {
7169 router.allowPageChange = true;
7170 if (!contentEl) { return; }
7171 if (typeof contentEl === 'string') {
7172 $newTabEl.html(contentEl);
7173 } else {
7174 $newTabEl.html('');
7175 if (contentEl.f7Component) {
7176 contentEl.f7Component.$mount(function (componentEl) {
7177 $newTabEl.append(componentEl);
7178 });
7179 } else {
7180 $newTabEl.append(contentEl);
7181 }
7182 }
7183 $newTabEl[0].f7RouterTabLoaded = true;
7184 onTabLoaded(contentEl);
7185 }
7186 function reject() {
7187 router.allowPageChange = true;
7188 return router;
7189 }
7190
7191 if (content) {
7192 resolve(content);
7193 } else if (template || templateUrl) {
7194 try {
7195 router.tabTemplateLoader(template, templateUrl, loadTabOptions, resolve, reject);
7196 } catch (err) {
7197 router.allowPageChange = true;
7198 throw err;
7199 }
7200 } else if (el) {
7201 resolve(el);
7202 } else if (component || componentUrl) {
7203 // Load from component (F7/Vue/React/...)
7204 try {
7205 router.tabComponentLoader($newTabEl[0], component, componentUrl, loadTabOptions, resolve, reject);
7206 } catch (err) {
7207 router.allowPageChange = true;
7208 throw err;
7209 }
7210 } else if (url) {
7211 // Load using XHR
7212 if (router.xhr) {
7213 router.xhr.abort();
7214 router.xhr = false;
7215 }
7216 router.xhrRequest(url, loadTabOptions)
7217 .then(function (tabContent) {
7218 resolve(tabContent);
7219 })
7220 .catch(function () {
7221 router.allowPageChange = true;
7222 });
7223 }
7224 }
7225
7226 var hasContentLoadProp;
7227 ('url content component el componentUrl template templateUrl').split(' ').forEach(function (tabLoadProp) {
7228 var obj;
7229
7230 if (tabRoute[tabLoadProp]) {
7231 hasContentLoadProp = true;
7232 loadTab(( obj = {}, obj[tabLoadProp] = tabRoute[tabLoadProp], obj ), options);
7233 }
7234 });
7235
7236 // Async
7237 function asyncResolve(resolveParams, resolveOptions) {
7238 loadTab(resolveParams, Utils.extend(options, resolveOptions));
7239 }
7240 function asyncReject() {
7241 router.allowPageChange = true;
7242 }
7243 if (tabRoute.async) {
7244 tabRoute.async.call(router, currentRoute, previousRoute, asyncResolve, asyncReject);
7245 } else if (!hasContentLoadProp) {
7246 router.allowPageChange = true;
7247 }
7248
7249 return router;
7250 }
7251 function tabRemove($oldTabEl, $newTabEl, tabRoute) {
7252 var router = this;
7253
7254 var hasTabComponentChild;
7255 if ($oldTabEl[0]) {
7256 $oldTabEl[0].f7RouterTabLoaded = false;
7257 delete $oldTabEl[0].f7RouterTabLoaded;
7258 }
7259 $oldTabEl.children().each(function (index, tabChild) {
7260 if (tabChild.f7Component) {
7261 hasTabComponentChild = true;
7262 $(tabChild).trigger('tab:beforeremove', tabRoute);
7263 tabChild.f7Component.$destroy();
7264 }
7265 });
7266 if (!hasTabComponentChild) {
7267 $oldTabEl.trigger('tab:beforeremove', tabRoute);
7268 }
7269 router.emit('tabBeforeRemove', $oldTabEl[0], $newTabEl[0], tabRoute);
7270 router.removeTabContent($oldTabEl[0], tabRoute);
7271 }
7272
7273 function modalLoad(modalType, route, loadOptions) {
7274 if ( loadOptions === void 0 ) loadOptions = {};
7275
7276 var router = this;
7277 var app = router.app;
7278 var isPanel = modalType === 'panel';
7279 var modalOrPanel = isPanel ? 'panel' : 'modal';
7280
7281 var options = Utils.extend({
7282 animate: router.params.animate,
7283 pushState: true,
7284 history: true,
7285 on: {},
7286 }, loadOptions);
7287
7288 var modalParams = Utils.extend({}, route.route[modalType]);
7289 var modalRoute = route.route;
7290
7291 function onModalLoaded() {
7292 // Create Modal
7293 var modal = app[modalType].create(modalParams);
7294 modalRoute.modalInstance = modal;
7295
7296 var hasEl = modal.el;
7297
7298 function closeOnSwipeBack() {
7299 modal.close();
7300 }
7301 modal.on((modalOrPanel + "Open"), function () {
7302 if (!hasEl) {
7303 // Remove theme elements
7304 router.removeThemeElements(modal.el);
7305
7306 // Emit events
7307 modal.$el.trigger(((modalType.toLowerCase()) + ":init " + (modalType.toLowerCase()) + ":mounted"), route, modal);
7308 router.emit(((!isPanel ? 'modalInit' : '') + " " + modalType + "Init " + modalType + "Mounted"), modal.el, route, modal);
7309 }
7310 router.once('swipeBackMove', closeOnSwipeBack);
7311 });
7312 modal.on((modalOrPanel + "Close"), function () {
7313 router.off('swipeBackMove', closeOnSwipeBack);
7314 if (!modal.closeByRouter) {
7315 router.back();
7316 }
7317 });
7318
7319 modal.on((modalOrPanel + "Closed"), function () {
7320 modal.$el.trigger(((modalType.toLowerCase()) + ":beforeremove"), route, modal);
7321 modal.emit(("" + (!isPanel ? 'modalBeforeRemove ' : '') + modalType + "BeforeRemove"), modal.el, route, modal);
7322 var modalComponent = modal.el.f7Component;
7323 if (modalComponent) {
7324 modalComponent.$destroy();
7325 }
7326 Utils.nextTick(function () {
7327 if (modalComponent || modalParams.component) {
7328 router.removeModal(modal.el);
7329 }
7330 modal.destroy();
7331 delete modal.route;
7332 delete modalRoute.modalInstance;
7333 });
7334 });
7335
7336 if (options.route) {
7337 // Update Browser History
7338 if (router.params.pushState && options.pushState) {
7339 History.push(
7340 router.view.id,
7341 {
7342 url: options.route.url,
7343 modal: modalType,
7344 },
7345 (router.params.pushStateRoot || '') + router.params.pushStateSeparator + options.route.url
7346 );
7347 }
7348
7349 // Set Route
7350 if (options.route !== router.currentRoute) {
7351 modal.route = Utils.extend(options.route, { modal: modal });
7352 router.currentRoute = modal.route;
7353 }
7354
7355 // Update Router History
7356 if (options.history) {
7357 router.history.push(options.route.url);
7358 router.saveHistory();
7359 }
7360 }
7361
7362 if (hasEl) {
7363 // Remove theme elements
7364 router.removeThemeElements(modal.el);
7365
7366 // Emit events
7367 modal.$el.trigger(((modalType.toLowerCase()) + ":init " + (modalType.toLowerCase()) + ":mounted"), route, modal);
7368 router.emit((modalOrPanel + "Init " + modalType + "Init " + modalType + "Mounted"), modal.el, route, modal);
7369 }
7370
7371 // Open
7372 modal.open();
7373 }
7374
7375 // Load Modal Content
7376 function loadModal(loadModalParams, loadModalOptions) {
7377 // Load Modal Props
7378 var url = loadModalParams.url;
7379 var content = loadModalParams.content;
7380 var template = loadModalParams.template;
7381 var templateUrl = loadModalParams.templateUrl;
7382 var component = loadModalParams.component;
7383 var componentUrl = loadModalParams.componentUrl;
7384
7385 // Component/Template Callbacks
7386 function resolve(contentEl) {
7387 if (contentEl) {
7388 if (typeof contentEl === 'string') {
7389 modalParams.content = contentEl;
7390 } else if (contentEl.f7Component) {
7391 contentEl.f7Component.$mount(function (componentEl) {
7392 modalParams.el = componentEl;
7393 app.root.append(componentEl);
7394 });
7395 } else {
7396 modalParams.el = contentEl;
7397 }
7398 onModalLoaded();
7399 }
7400 }
7401 function reject() {
7402 router.allowPageChange = true;
7403 return router;
7404 }
7405
7406 if (content) {
7407 resolve(content);
7408 } else if (template || templateUrl) {
7409 try {
7410 router.modalTemplateLoader(template, templateUrl, loadModalOptions, resolve, reject);
7411 } catch (err) {
7412 router.allowPageChange = true;
7413 throw err;
7414 }
7415 } else if (component || componentUrl) {
7416 // Load from component (F7/Vue/React/...)
7417 try {
7418 router.modalComponentLoader(app.root[0], component, componentUrl, loadModalOptions, resolve, reject);
7419 } catch (err) {
7420 router.allowPageChange = true;
7421 throw err;
7422 }
7423 } else if (url) {
7424 // Load using XHR
7425 if (router.xhr) {
7426 router.xhr.abort();
7427 router.xhr = false;
7428 }
7429 router.xhrRequest(url, loadModalOptions)
7430 .then(function (modalContent) {
7431 modalParams.content = modalContent;
7432 onModalLoaded();
7433 })
7434 .catch(function () {
7435 router.allowPageChange = true;
7436 });
7437 } else {
7438 onModalLoaded();
7439 }
7440 }
7441
7442 var foundLoadProp;
7443 ('url content component el componentUrl template templateUrl').split(' ').forEach(function (modalLoadProp) {
7444 var obj;
7445
7446 if (modalParams[modalLoadProp] && !foundLoadProp) {
7447 foundLoadProp = true;
7448 loadModal(( obj = {}, obj[modalLoadProp] = modalParams[modalLoadProp], obj ), options);
7449 }
7450 });
7451 if (!foundLoadProp && modalType === 'actions') {
7452 onModalLoaded();
7453 }
7454
7455 // Async
7456 function asyncResolve(resolveParams, resolveOptions) {
7457 loadModal(resolveParams, Utils.extend(options, resolveOptions));
7458 }
7459 function asyncReject() {
7460 router.allowPageChange = true;
7461 }
7462 if (modalParams.async) {
7463 modalParams.async.call(router, options.route, router.currentRoute, asyncResolve, asyncReject);
7464 }
7465 return router;
7466 }
7467 function modalRemove(modal) {
7468 Utils.extend(modal, { closeByRouter: true });
7469 modal.close();
7470 }
7471
7472 function backward(el, backwardOptions) {
7473 var router = this;
7474 var $el = $(el);
7475 var app = router.app;
7476 var view = router.view;
7477
7478 var options = Utils.extend({
7479 animate: router.params.animate,
7480 pushState: true,
7481 }, backwardOptions);
7482
7483 var masterDetailEnabled = router.params.masterDetailBreakpoint > 0;
7484 var isMaster = masterDetailEnabled && options.route && options.route.route && options.route.route.master === true;
7485 var masterPageEl;
7486
7487 var dynamicNavbar = router.dynamicNavbar;
7488 var separateNavbar = router.separateNavbar;
7489
7490 var $newPage = $el;
7491 var $oldPage = router.$el.children('.page-current');
7492 var currentIsMaster = masterDetailEnabled && $oldPage.hasClass('page-master');
7493
7494 if ($newPage.length) {
7495 // Remove theme elements
7496 router.removeThemeElements($newPage);
7497 }
7498
7499 var $navbarEl;
7500 var $newNavbarInner;
7501 var $oldNavbarInner;
7502
7503 if (dynamicNavbar) {
7504 $newNavbarInner = $newPage.children('.navbar').children('.navbar-inner');
7505 if (separateNavbar) {
7506 $navbarEl = router.$navbarEl;
7507 if ($newNavbarInner.length > 0) {
7508 $newPage.children('.navbar').remove();
7509 }
7510 if ($newNavbarInner.length === 0 && $newPage[0] && $newPage[0].f7Page) {
7511 // Try from pageData
7512 $newNavbarInner = $newPage[0].f7Page.$navbarEl;
7513 }
7514 $oldNavbarInner = $navbarEl.find('.navbar-current');
7515 } else {
7516 $oldNavbarInner = $oldPage.children('.navbar').children('.navbar-inner');
7517 }
7518 }
7519
7520 router.allowPageChange = false;
7521 if ($newPage.length === 0 || $oldPage.length === 0) {
7522 router.allowPageChange = true;
7523 return router;
7524 }
7525
7526 // Remove theme elements
7527 router.removeThemeElements($newPage);
7528
7529 // Save Keep Alive Cache
7530 if (options.route && options.route.route && options.route.route.keepAlive && !options.route.route.keepAliveData) {
7531 options.route.route.keepAliveData = {
7532 pageEl: $el[0],
7533 };
7534 }
7535
7536 // Pages In View
7537 var isDetail;
7538 if (masterDetailEnabled) {
7539 var $pagesInView = router.$el
7540 .children('.page:not(.stacked)')
7541 .filter(function (index, pageInView) { return pageInView !== $newPage[0]; });
7542
7543 // Find Detail' master page
7544 for (var i = 0; i < $pagesInView.length; i += 1) {
7545 if (!masterPageEl
7546 && $pagesInView[i].classList.contains('page-master')
7547 ) {
7548 masterPageEl = $pagesInView[i];
7549 continue; // eslint-disable-line
7550 }
7551 }
7552
7553 isDetail = !isMaster
7554 && masterPageEl
7555 && (router.history.indexOf(options.route.url) > router.history.indexOf(masterPageEl.f7Page.route.url));
7556 }
7557
7558
7559 // New Page
7560 $newPage
7561 .addClass(("page-previous" + (isMaster ? ' page-master' : '') + (isDetail ? ' page-master-detail' : '')))
7562 .removeClass('stacked')
7563 .removeAttr('aria-hidden')
7564 .trigger('page:unstack')
7565 .trigger('page:position', { position: 'previous' });
7566 if (isMaster || isDetail) {
7567 $newPage.trigger('page:role', { role: isMaster ? 'master' : 'detail' });
7568 }
7569
7570 if (dynamicNavbar && $newNavbarInner.length > 0) {
7571 $newNavbarInner
7572 .addClass(("navbar-previous" + (isMaster ? ' navbar-master' : '') + (isDetail ? ' navbar-master-detail' : '')))
7573 .removeClass('stacked')
7574 .removeAttr('aria-hidden');
7575 }
7576
7577 // Remove previous page in case of "forced"
7578 var backIndex;
7579 if (options.force) {
7580 if ($oldPage.prev('.page-previous:not(.stacked)').length > 0 || $oldPage.prev('.page-previous').length === 0) {
7581 if (router.history.indexOf(options.route.url) >= 0) {
7582 backIndex = router.history.length - router.history.indexOf(options.route.url) - 1;
7583 router.history = router.history.slice(0, router.history.indexOf(options.route.url) + 2);
7584 view.history = router.history;
7585 } else if (router.history[[router.history.length - 2]]) {
7586 router.history[router.history.length - 2] = options.route.url;
7587 } else {
7588 router.history.unshift(router.url);
7589 }
7590
7591 if (backIndex && router.params.stackPages) {
7592 $oldPage.prevAll('.page-previous').each(function (index, pageToRemove) {
7593 var $pageToRemove = $(pageToRemove);
7594 var $navbarToRemove;
7595 if (separateNavbar) {
7596 // $navbarToRemove = $oldNavbarInner.prevAll('.navbar-previous').eq(index);
7597 $navbarToRemove = $(app.navbar.getElByPage($pageToRemove));
7598 }
7599 if ($pageToRemove[0] !== $newPage[0] && $pageToRemove.index() > $newPage.index()) {
7600 if (router.initialPages.indexOf($pageToRemove[0]) >= 0) {
7601 $pageToRemove.addClass('stacked');
7602 $pageToRemove.trigger('page:stack');
7603 if (separateNavbar) {
7604 $navbarToRemove.addClass('stacked');
7605 }
7606 } else {
7607 router.pageCallback('beforeRemove', $pageToRemove, $navbarToRemove, 'previous', undefined, options);
7608 router.removePage($pageToRemove);
7609 if (separateNavbar && $navbarToRemove.length > 0) {
7610 router.removeNavbar($navbarToRemove);
7611 }
7612 }
7613 }
7614 });
7615 } else {
7616 var $pageToRemove = $oldPage.prev('.page-previous:not(.stacked)');
7617 var $navbarToRemove;
7618 if (separateNavbar) {
7619 // $navbarToRemove = $oldNavbarInner.prev('.navbar-inner:not(.stacked)');
7620 $navbarToRemove = $(app.navbar.getElByPage($pageToRemove));
7621 }
7622 if (router.params.stackPages && router.initialPages.indexOf($pageToRemove[0]) >= 0) {
7623 $pageToRemove.addClass('stacked');
7624 $pageToRemove.trigger('page:stack');
7625 $navbarToRemove.addClass('stacked');
7626 } else if ($pageToRemove.length > 0) {
7627 router.pageCallback('beforeRemove', $pageToRemove, $navbarToRemove, 'previous', undefined, options);
7628 router.removePage($pageToRemove);
7629 if (separateNavbar && $navbarToRemove.length) {
7630 router.removeNavbar($navbarToRemove);
7631 }
7632 }
7633 }
7634 }
7635 }
7636
7637 // Insert new page
7638 var newPageInDom = $newPage.parents(doc).length > 0;
7639 var f7Component = $newPage[0].f7Component;
7640
7641 function insertPage() {
7642 if ($newPage.next($oldPage).length === 0) {
7643 if (!newPageInDom && f7Component) {
7644 f7Component.$mount(function (componentEl) {
7645 $(componentEl).insertBefore($oldPage);
7646 });
7647 } else {
7648 $newPage.insertBefore($oldPage);
7649 }
7650 }
7651 if (separateNavbar && $newNavbarInner.length) {
7652 if ($newNavbarInner.children('.title-large').length) {
7653 $newNavbarInner.addClass('navbar-inner-large');
7654 }
7655 $newNavbarInner.insertBefore($oldNavbarInner);
7656 if ($oldNavbarInner.length > 0) {
7657 $newNavbarInner.insertBefore($oldNavbarInner);
7658 } else {
7659 if (!router.$navbarEl.parents(doc).length) {
7660 router.$el.prepend(router.$navbarEl);
7661 }
7662 $navbarEl.append($newNavbarInner);
7663 }
7664 }
7665 if (!newPageInDom) {
7666 router.pageCallback('mounted', $newPage, $newNavbarInner, 'previous', 'current', options, $oldPage);
7667 } else if (options.route && options.route.route && options.route.route.keepAlive && !$newPage[0].f7PageMounted) {
7668 $newPage[0].f7PageMounted = true;
7669 router.pageCallback('mounted', $newPage, $newNavbarInner, 'previous', 'current', options, $oldPage);
7670 }
7671 }
7672
7673 if (options.preload) {
7674 // Insert Page
7675 insertPage();
7676 // Tab route
7677 if (options.route.route.tab) {
7678 router.tabLoad(options.route.route.tab, Utils.extend({}, options, {
7679 history: false,
7680 pushState: false,
7681 preload: true,
7682 }));
7683 }
7684 if (isMaster) {
7685 $newPage
7686 .removeClass('page-master-stacked')
7687 .trigger('page:masterunstack');
7688 if (separateNavbar) {
7689 $(app.navbar.getElByPage($newPage)).removeClass('navbar-master-stacked');
7690 }
7691 }
7692 // Page init and before init events
7693 router.pageCallback('init', $newPage, $newNavbarInner, 'previous', 'current', options, $oldPage);
7694 var $previousPages = $newPage.prevAll('.page-previous:not(.stacked):not(.page-master)');
7695 if ($previousPages.length > 0) {
7696 $previousPages.each(function (index, pageToRemove) {
7697 var $pageToRemove = $(pageToRemove);
7698 var $navbarToRemove;
7699 if (separateNavbar) {
7700 // $navbarToRemove = $newNavbarInner.prevAll('.navbar-previous:not(.stacked)').eq(index);
7701 $navbarToRemove = $(app.navbar.getElByPage($pageToRemove));
7702 }
7703 if (router.params.stackPages && router.initialPages.indexOf(pageToRemove) >= 0) {
7704 $pageToRemove.addClass('stacked');
7705 $pageToRemove.trigger('page:stack');
7706 if (separateNavbar) {
7707 $navbarToRemove.addClass('stacked');
7708 }
7709 } else {
7710 router.pageCallback('beforeRemove', $pageToRemove, $navbarToRemove, 'previous', undefined);
7711 router.removePage($pageToRemove);
7712 if (separateNavbar && $navbarToRemove.length) {
7713 router.removeNavbar($navbarToRemove);
7714 }
7715 }
7716 });
7717 }
7718 router.allowPageChange = true;
7719 return router;
7720 }
7721
7722 // History State
7723 if (!(Device.ie || Device.edge || (Device.firefox && !Device.ios))) {
7724 if (router.params.pushState && options.pushState) {
7725 if (backIndex) { History.go(-backIndex); }
7726 else { History.back(); }
7727 }
7728 }
7729
7730 // Update History
7731 if (router.history.length === 1) {
7732 router.history.unshift(router.url);
7733 }
7734 router.history.pop();
7735 router.saveHistory();
7736
7737 // Current Page & Navbar
7738 router.currentPageEl = $newPage[0];
7739 if (dynamicNavbar && $newNavbarInner.length) {
7740 router.currentNavbarEl = $newNavbarInner[0];
7741 } else {
7742 delete router.currentNavbarEl;
7743 }
7744
7745 // Current Route
7746 router.currentRoute = options.route;
7747
7748 // History State
7749 if (Device.ie || Device.edge || (Device.firefox && !Device.ios)) {
7750 if (router.params.pushState && options.pushState) {
7751 if (backIndex) { History.go(-backIndex); }
7752 else { History.back(); }
7753 }
7754 }
7755
7756 // Insert Page
7757 insertPage();
7758
7759 // Load Tab
7760 if (options.route.route.tab) {
7761 router.tabLoad(options.route.route.tab, Utils.extend({}, options, {
7762 history: false,
7763 pushState: false,
7764 }));
7765 }
7766
7767 // Page init and before init events
7768 router.pageCallback('init', $newPage, $newNavbarInner, 'previous', 'current', options, $oldPage);
7769
7770 // Before animation callback
7771 router.pageCallback('beforeIn', $newPage, $newNavbarInner, 'previous', 'current', options);
7772 router.pageCallback('beforeOut', $oldPage, $oldNavbarInner, 'current', 'next', options);
7773
7774 // Animation
7775 function afterAnimation() {
7776 // Set classes
7777 var pageClasses = 'page-previous page-current page-next';
7778 var navbarClasses = 'navbar-previous navbar-current navbar-next';
7779 $newPage.removeClass(pageClasses).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position: 'current' });
7780 $oldPage.removeClass(pageClasses).addClass('page-next').attr('aria-hidden', 'true').trigger('page:position', { position: 'next' });
7781 if (dynamicNavbar) {
7782 $newNavbarInner.removeClass(navbarClasses).addClass('navbar-current').removeAttr('aria-hidden');
7783 $oldNavbarInner.removeClass(navbarClasses).addClass('navbar-next').attr('aria-hidden', 'true');
7784 }
7785
7786 // After animation event
7787 router.pageCallback('afterIn', $newPage, $newNavbarInner, 'previous', 'current', options);
7788 router.pageCallback('afterOut', $oldPage, $oldNavbarInner, 'current', 'next', options);
7789
7790 // Remove Old Page
7791 if (router.params.stackPages && router.initialPages.indexOf($oldPage[0]) >= 0) {
7792 $oldPage.addClass('stacked');
7793 $oldPage.trigger('page:stack');
7794 if (separateNavbar) {
7795 $oldNavbarInner.addClass('stacked');
7796 }
7797 } else {
7798 router.pageCallback('beforeRemove', $oldPage, $oldNavbarInner, 'next', undefined, options);
7799 router.removePage($oldPage);
7800 if (separateNavbar && $oldNavbarInner.length) {
7801 router.removeNavbar($oldNavbarInner);
7802 }
7803 }
7804
7805 router.allowPageChange = true;
7806 router.emit('routeChanged', router.currentRoute, router.previousRoute, router);
7807
7808 // Preload previous page
7809 var preloadPreviousPage = router.params.preloadPreviousPage || (app.theme.ios ? router.params.iosSwipeBack : router.params.mdSwipeBack);
7810 if (preloadPreviousPage && router.history[router.history.length - 2] && !isMaster) {
7811 router.back(router.history[router.history.length - 2], { preload: true });
7812 }
7813 if (router.params.pushState) {
7814 History.clearRouterQueue();
7815 }
7816 }
7817
7818 function setPositionClasses() {
7819 var pageClasses = 'page-previous page-current page-next';
7820 var navbarClasses = 'navbar-previous navbar-current navbar-next';
7821 $oldPage.removeClass(pageClasses).addClass('page-current').trigger('page:position', { position: 'current' });
7822 $newPage.removeClass(pageClasses).addClass('page-previous').removeAttr('aria-hidden').trigger('page:position', { position: 'previous' });
7823 if (dynamicNavbar) {
7824 $oldNavbarInner.removeClass(navbarClasses).addClass('navbar-current');
7825 $newNavbarInner.removeClass(navbarClasses).addClass('navbar-previous').removeAttr('aria-hidden');
7826 }
7827 }
7828
7829 if (options.animate && !(currentIsMaster && app.width >= router.params.masterDetailBreakpoint)) {
7830 setPositionClasses();
7831 router.animate($oldPage, $newPage, $oldNavbarInner, $newNavbarInner, 'backward', function () {
7832 afterAnimation();
7833 });
7834 } else {
7835 afterAnimation();
7836 }
7837
7838 return router;
7839 }
7840 function loadBack(backParams, backOptions, ignorePageChange) {
7841 var router = this;
7842
7843 if (!router.allowPageChange && !ignorePageChange) { return router; }
7844 var params = backParams;
7845 var options = backOptions;
7846 var url = params.url;
7847 var content = params.content;
7848 var el = params.el;
7849 var pageName = params.pageName;
7850 var template = params.template;
7851 var templateUrl = params.templateUrl;
7852 var component = params.component;
7853 var componentUrl = params.componentUrl;
7854
7855 if (
7856 options.route.url
7857 && router.url === options.route.url
7858 && !(options.reloadCurrent || options.reloadPrevious)
7859 && !router.params.allowDuplicateUrls
7860 ) {
7861 return false;
7862 }
7863
7864 if (!options.route && url) {
7865 options.route = router.parseRouteUrl(url);
7866 }
7867
7868 // Component Callbacks
7869 function resolve(pageEl, newOptions) {
7870 return router.backward(pageEl, Utils.extend(options, newOptions));
7871 }
7872 function reject() {
7873 router.allowPageChange = true;
7874 return router;
7875 }
7876
7877 if (url || templateUrl || componentUrl) {
7878 router.allowPageChange = false;
7879 }
7880
7881 // Proceed
7882 if (content) {
7883 router.backward(router.getPageEl(content), options);
7884 } else if (template || templateUrl) {
7885 // Parse template and send page element
7886 try {
7887 router.pageTemplateLoader(template, templateUrl, options, resolve, reject);
7888 } catch (err) {
7889 router.allowPageChange = true;
7890 throw err;
7891 }
7892 } else if (el) {
7893 // Load page from specified HTMLElement or by page name in pages container
7894 router.backward(router.getPageEl(el), options);
7895 } else if (pageName) {
7896 // Load page by page name in pages container
7897 router.backward(router.$el.children((".page[data-name=\"" + pageName + "\"]")).eq(0), options);
7898 } else if (component || componentUrl) {
7899 // Load from component (F7/Vue/React/...)
7900 try {
7901 router.pageComponentLoader(router.el, component, componentUrl, options, resolve, reject);
7902 } catch (err) {
7903 router.allowPageChange = true;
7904 throw err;
7905 }
7906 } else if (url) {
7907 // Load using XHR
7908 if (router.xhr) {
7909 router.xhr.abort();
7910 router.xhr = false;
7911 }
7912 router.xhrRequest(url, options)
7913 .then(function (pageContent) {
7914 router.backward(router.getPageEl(pageContent), options);
7915 })
7916 .catch(function () {
7917 router.allowPageChange = true;
7918 });
7919 }
7920 return router;
7921 }
7922 function back() {
7923 var args = [], len = arguments.length;
7924 while ( len-- ) args[ len ] = arguments[ len ];
7925
7926 var router = this;
7927 if (router.swipeBackActive) { return router; }
7928 var navigateUrl;
7929 var navigateOptions;
7930 var route;
7931 if (typeof args[0] === 'object') {
7932 navigateOptions = args[0] || {};
7933 } else {
7934 navigateUrl = args[0];
7935 navigateOptions = args[1] || {};
7936 }
7937
7938 var name = navigateOptions.name;
7939 var params = navigateOptions.params;
7940 var query = navigateOptions.query;
7941 if (name) {
7942 // find route by name
7943 route = router.findRouteByKey('name', name);
7944 if (!route) {
7945 throw new Error(("Framework7: route with name \"" + name + "\" not found"));
7946 }
7947 navigateUrl = router.constructRouteUrl(route, { params: params, query: query });
7948 if (navigateUrl) {
7949 return router.back(navigateUrl, Utils.extend({}, navigateOptions, {
7950 name: null,
7951 params: null,
7952 query: null,
7953 }));
7954 }
7955 throw new Error(("Framework7: can't construct URL for route with name \"" + name + "\""));
7956 }
7957
7958 var app = router.app;
7959 appRouterCheck(router, 'back');
7960
7961 var currentRouteIsModal = router.currentRoute.modal;
7962 var modalType;
7963 if (!currentRouteIsModal) {
7964 ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach(function (modalLoadProp) {
7965 if (router.currentRoute.route[modalLoadProp]) {
7966 currentRouteIsModal = true;
7967 modalType = modalLoadProp;
7968 }
7969 });
7970 }
7971 if (currentRouteIsModal) {
7972 var modalToClose = router.currentRoute.modal
7973 || router.currentRoute.route.modalInstance
7974 || app[modalType].get();
7975 var previousUrl = router.history[router.history.length - 2];
7976 var previousRoute;
7977 // check if previous route is modal too
7978 if (modalToClose && modalToClose.$el) {
7979 var prevOpenedModals = modalToClose.$el.prevAll('.modal-in');
7980 if (prevOpenedModals.length && prevOpenedModals[0].f7Modal) {
7981 previousRoute = prevOpenedModals[0].f7Modal.route;
7982 }
7983 }
7984 if (!previousRoute) {
7985 previousRoute = router.findMatchingRoute(previousUrl);
7986 }
7987
7988 if (!previousRoute && previousUrl) {
7989 previousRoute = {
7990 url: previousUrl,
7991 path: previousUrl.split('?')[0],
7992 query: Utils.parseUrlQuery(previousUrl),
7993 route: {
7994 path: previousUrl.split('?')[0],
7995 url: previousUrl,
7996 },
7997 };
7998 }
7999 if (!navigateUrl || navigateUrl.replace(/[# ]/g, '').trim().length === 0) {
8000 if (!previousRoute || !modalToClose) {
8001 return router;
8002 }
8003 }
8004 var forceOtherUrl = navigateOptions.force && previousRoute && navigateUrl;
8005 if (previousRoute && modalToClose) {
8006 if (router.params.pushState && navigateOptions.pushState !== false) {
8007 History.back();
8008 }
8009 router.currentRoute = previousRoute;
8010 router.history.pop();
8011 router.saveHistory();
8012 router.modalRemove(modalToClose);
8013 if (forceOtherUrl) {
8014 router.navigate(navigateUrl, { reloadCurrent: true });
8015 }
8016 } else if (modalToClose) {
8017 router.modalRemove(modalToClose);
8018 if (navigateUrl) {
8019 router.navigate(navigateUrl, { reloadCurrent: true });
8020 }
8021 }
8022 return router;
8023 }
8024 var $previousPage = router.$el.children('.page-current').prevAll('.page-previous:not(.page-master)').eq(0);
8025
8026 var skipMaster;
8027 if (router.params.masterDetailBreakpoint > 0) {
8028 var $previousMaster = router.$el.children('.page-current').prevAll('.page-master').eq(0);
8029 if ($previousMaster.length) {
8030 var expectedPreviousPageUrl = router.history[router.history.length - 2];
8031 var expectedPreviousPageRoute = router.findMatchingRoute(expectedPreviousPageUrl);
8032 if (expectedPreviousPageRoute && expectedPreviousPageRoute.route === $previousMaster[0].f7Page.route.route) {
8033 $previousPage = $previousMaster;
8034 if (!navigateOptions.preload) {
8035 skipMaster = app.width >= router.params.masterDetailBreakpoint;
8036 }
8037 }
8038 }
8039 }
8040 if (!navigateOptions.force && $previousPage.length && !skipMaster) {
8041 if (router.params.pushState
8042 && $previousPage[0].f7Page
8043 && router.history[router.history.length - 2] !== $previousPage[0].f7Page.route.url
8044 ) {
8045 router.back(
8046 router.history[router.history.length - 2],
8047 Utils.extend(navigateOptions, { force: true })
8048 );
8049 return router;
8050 }
8051 var previousPageRoute = $previousPage[0].f7Page.route;
8052
8053 processRouteQueue.call(
8054 router,
8055 previousPageRoute,
8056 router.currentRoute,
8057 function () {
8058 router.loadBack({ el: $previousPage }, Utils.extend(navigateOptions, {
8059 route: previousPageRoute,
8060 }));
8061 },
8062 function () {}
8063 );
8064
8065 return router;
8066 }
8067
8068 // Navigate URL
8069 if (navigateUrl === '#') {
8070 navigateUrl = undefined;
8071 }
8072 if (navigateUrl && navigateUrl[0] !== '/' && navigateUrl.indexOf('#') !== 0) {
8073 navigateUrl = ((router.path || '/') + navigateUrl).replace('//', '/');
8074 }
8075 if (!navigateUrl && router.history.length > 1) {
8076 navigateUrl = router.history[router.history.length - 2];
8077 }
8078 if (skipMaster && !navigateOptions.force && router.history[router.history.length - 3]) {
8079 return router.back(router.history[router.history.length - 3], Utils.extend({}, navigateOptions || {}, {
8080 force: true,
8081 animate: false,
8082 }));
8083 }
8084 if (skipMaster && !navigateOptions.force) {
8085 return router;
8086 }
8087
8088 // Find route to load
8089 route = router.findMatchingRoute(navigateUrl);
8090 if (!route) {
8091 if (navigateUrl) {
8092 route = {
8093 url: navigateUrl,
8094 path: navigateUrl.split('?')[0],
8095 query: Utils.parseUrlQuery(navigateUrl),
8096 route: {
8097 path: navigateUrl.split('?')[0],
8098 url: navigateUrl,
8099 },
8100 };
8101 }
8102 }
8103 if (!route) {
8104 return router;
8105 }
8106
8107 if (route.route.redirect) {
8108 return redirect.call(router, 'back', route, navigateOptions);
8109 }
8110
8111 var options = {};
8112 if (route.route.options) {
8113 Utils.extend(options, route.route.options, navigateOptions);
8114 } else {
8115 Utils.extend(options, navigateOptions);
8116 }
8117 options.route = route;
8118
8119 if (options && options.context) {
8120 route.context = options.context;
8121 options.route.context = options.context;
8122 }
8123
8124 var backForceLoaded;
8125 if (options.force && router.params.stackPages) {
8126 router.$el.children('.page-previous.stacked').each(function (index, pageEl) {
8127 if (pageEl.f7Page && pageEl.f7Page.route && pageEl.f7Page.route.url === route.url) {
8128 backForceLoaded = true;
8129 router.loadBack({ el: pageEl }, options);
8130 }
8131 });
8132 if (backForceLoaded) {
8133 return router;
8134 }
8135 }
8136 function resolve() {
8137 var routerLoaded = false;
8138 if (route.route.keepAlive && route.route.keepAliveData) {
8139 router.loadBack({ el: route.route.keepAliveData.pageEl }, options);
8140 routerLoaded = true;
8141 }
8142 ('url content component pageName el componentUrl template templateUrl').split(' ').forEach(function (pageLoadProp) {
8143 var obj;
8144
8145 if (route.route[pageLoadProp] && !routerLoaded) {
8146 routerLoaded = true;
8147 router.loadBack(( obj = {}, obj[pageLoadProp] = route.route[pageLoadProp], obj ), options);
8148 }
8149 });
8150 if (routerLoaded) { return; }
8151 // Async
8152 function asyncResolve(resolveParams, resolveOptions) {
8153 router.allowPageChange = false;
8154 if (resolveOptions && resolveOptions.context) {
8155 if (!route.context) { route.context = resolveOptions.context; }
8156 else { route.context = Utils.extend({}, route.context, resolveOptions.context); }
8157 options.route.context = route.context;
8158 }
8159 router.loadBack(resolveParams, Utils.extend(options, resolveOptions), true);
8160 }
8161 function asyncReject() {
8162 router.allowPageChange = true;
8163 }
8164 if (route.route.async) {
8165 router.allowPageChange = false;
8166
8167 route.route.async.call(router, route, router.currentRoute, asyncResolve, asyncReject);
8168 }
8169 }
8170 function reject() {
8171 router.allowPageChange = true;
8172 }
8173
8174 if (options.preload) {
8175 resolve();
8176 } else {
8177 processRouteQueue.call(
8178 router,
8179 route,
8180 router.currentRoute,
8181 function () {
8182 if (route.route.modules) {
8183 app
8184 .loadModules(Array.isArray(route.route.modules) ? route.route.modules : [route.route.modules])
8185 .then(function () {
8186 resolve();
8187 })
8188 .catch(function () {
8189 reject();
8190 });
8191 } else {
8192 resolve();
8193 }
8194 },
8195 function () {
8196 reject();
8197 }
8198 );
8199 }
8200
8201 // Return Router
8202 return router;
8203 }
8204
8205 function clearPreviousPages() {
8206 var router = this;
8207 appRouterCheck(router, 'clearPreviousPages');
8208 var app = router.app;
8209 var separateNavbar = router.separateNavbar;
8210
8211 var $pagesToRemove = router.$el
8212 .children('.page')
8213 .filter(function (index, pageInView) {
8214 if (router.currentRoute && (router.currentRoute.modal || router.currentRoute.panel)) { return true; }
8215 return pageInView !== router.currentPageEl;
8216 });
8217
8218 $pagesToRemove.each(function (index, pageEl) {
8219 var $oldPageEl = $(pageEl);
8220 var $oldNavbarInnerEl = $(app.navbar.getElByPage($oldPageEl));
8221 if (router.params.stackPages && router.initialPages.indexOf($oldPageEl[0]) >= 0) {
8222 $oldPageEl.addClass('stacked');
8223 if (separateNavbar) {
8224 $oldNavbarInnerEl.addClass('stacked');
8225 }
8226 } else {
8227 // Page remove event
8228 router.pageCallback('beforeRemove', $oldPageEl, $oldNavbarInnerEl, 'previous', undefined, {});
8229 router.removePage($oldPageEl);
8230 if (separateNavbar && $oldNavbarInnerEl.length) {
8231 router.removeNavbar($oldNavbarInnerEl);
8232 }
8233 }
8234 });
8235 }
8236
8237 function clearPreviousHistory() {
8238 var router = this;
8239 appRouterCheck(router, 'clearPreviousHistory');
8240 var url = router.history[router.history.length - 1];
8241
8242 router.clearPreviousPages();
8243
8244 router.history = [url];
8245 router.view.history = [url];
8246 router.saveHistory();
8247 }
8248
8249 var Router = /*@__PURE__*/(function (Framework7Class$$1) {
8250 function Router(app, view) {
8251 Framework7Class$$1.call(this, {}, [typeof view === 'undefined' ? app : view]);
8252 var router = this;
8253
8254 // Is App Router
8255 router.isAppRouter = typeof view === 'undefined';
8256
8257 if (router.isAppRouter) {
8258 // App Router
8259 Utils.extend(false, router, {
8260 app: app,
8261 params: app.params.view,
8262 routes: app.routes || [],
8263 cache: app.cache,
8264 });
8265 } else {
8266 // View Router
8267 Utils.extend(false, router, {
8268 app: app,
8269 view: view,
8270 viewId: view.id,
8271 params: view.params,
8272 routes: view.routes,
8273 $el: view.$el,
8274 el: view.el,
8275 $navbarEl: view.$navbarEl,
8276 navbarEl: view.navbarEl,
8277 history: view.history,
8278 scrollHistory: view.scrollHistory,
8279 cache: app.cache,
8280 dynamicNavbar: app.theme === 'ios' && view.params.iosDynamicNavbar,
8281 separateNavbar: app.theme === 'ios' && view.params.iosDynamicNavbar && view.params.iosSeparateDynamicNavbar,
8282 initialPages: [],
8283 initialNavbars: [],
8284 });
8285 }
8286
8287 // Install Modules
8288 router.useModules();
8289
8290 // Temporary Dom
8291 router.tempDom = doc.createElement('div');
8292
8293 // AllowPageChage
8294 router.allowPageChange = true;
8295
8296 // Current Route
8297 var currentRoute = {};
8298 var previousRoute = {};
8299 Object.defineProperty(router, 'currentRoute', {
8300 enumerable: true,
8301 configurable: true,
8302 set: function set(newRoute) {
8303 if ( newRoute === void 0 ) newRoute = {};
8304
8305 previousRoute = Utils.extend({}, currentRoute);
8306 currentRoute = newRoute;
8307 if (!currentRoute) { return; }
8308 router.url = currentRoute.url;
8309 router.emit('routeChange', newRoute, previousRoute, router);
8310 },
8311 get: function get() {
8312 return currentRoute;
8313 },
8314 });
8315 Object.defineProperty(router, 'previousRoute', {
8316 enumerable: true,
8317 configurable: true,
8318 get: function get() {
8319 return previousRoute;
8320 },
8321 set: function set(newRoute) {
8322 previousRoute = newRoute;
8323 },
8324 });
8325
8326 return router;
8327 }
8328
8329 if ( Framework7Class$$1 ) Router.__proto__ = Framework7Class$$1;
8330 Router.prototype = Object.create( Framework7Class$$1 && Framework7Class$$1.prototype );
8331 Router.prototype.constructor = Router;
8332
8333 Router.prototype.animatableNavElements = function animatableNavElements (newNavbarInner, oldNavbarInner, toLarge, fromLarge, direction) {
8334 var router = this;
8335 var dynamicNavbar = router.dynamicNavbar;
8336 var separateNavbar = router.separateNavbar;
8337 var animateIcon = router.params.iosAnimateNavbarBackIcon;
8338
8339 var newNavEls;
8340 var oldNavEls;
8341 function animatableNavEl($el, navbarInner) {
8342 var isSliding = $el.hasClass('sliding') || navbarInner.hasClass('sliding');
8343 var isSubnavbar = $el.hasClass('subnavbar');
8344 var needsOpacityTransition = isSliding ? !isSubnavbar : true;
8345 var $iconEl = $el.find('.back .icon');
8346 var isIconLabel;
8347 if (isSliding && animateIcon && $el.hasClass('left') && $iconEl.length > 0 && $iconEl.next('span').length) {
8348 $el = $iconEl.next('span'); // eslint-disable-line
8349 isIconLabel = true;
8350 }
8351 return {
8352 $el: $el,
8353 isIconLabel: isIconLabel,
8354 leftOffset: $el[0].f7NavbarLeftOffset,
8355 rightOffset: $el[0].f7NavbarRightOffset,
8356 isSliding: isSliding,
8357 isSubnavbar: isSubnavbar,
8358 needsOpacityTransition: needsOpacityTransition,
8359 };
8360 }
8361 if (dynamicNavbar) {
8362 newNavEls = [];
8363 oldNavEls = [];
8364 newNavbarInner.children('.left, .right, .title, .subnavbar').each(function (index, navEl) {
8365 var $navEl = $(navEl);
8366 if ($navEl.hasClass('left') && fromLarge && direction === 'forward' && separateNavbar) { return; }
8367 if ($navEl.hasClass('title') && toLarge) { return; }
8368 newNavEls.push(animatableNavEl($navEl, newNavbarInner));
8369 });
8370 if (!(oldNavbarInner.hasClass('navbar-master') && router.params.masterDetailBreakpoint > 0 && router.app.width >= router.params.masterDetailBreakpoint)) {
8371 oldNavbarInner.children('.left, .right, .title, .subnavbar').each(function (index, navEl) {
8372 var $navEl = $(navEl);
8373 if ($navEl.hasClass('left') && toLarge && !fromLarge && direction === 'forward' && separateNavbar) { return; }
8374 if ($navEl.hasClass('left') && toLarge && direction === 'backward' && separateNavbar) { return; }
8375 if ($navEl.hasClass('title') && fromLarge) {
8376 return;
8377 }
8378 oldNavEls.push(animatableNavEl($navEl, oldNavbarInner));
8379 });
8380 }
8381 [oldNavEls, newNavEls].forEach(function (navEls) {
8382 navEls.forEach(function (navEl) {
8383 var n = navEl;
8384 var isSliding = navEl.isSliding;
8385 var $el = navEl.$el;
8386 var otherEls = navEls === oldNavEls ? newNavEls : oldNavEls;
8387 if (!(isSliding && $el.hasClass('title') && otherEls)) { return; }
8388 otherEls.forEach(function (otherNavEl) {
8389 if (otherNavEl.isIconLabel) {
8390 var iconTextEl = otherNavEl.$el[0];
8391 n.leftOffset += iconTextEl ? (iconTextEl.offsetLeft || 0) : 0;
8392 }
8393 });
8394 });
8395 });
8396 }
8397
8398 return { newNavEls: newNavEls, oldNavEls: oldNavEls };
8399 };
8400
8401 Router.prototype.animate = function animate (oldPage, newPage, oldNavbarInner, newNavbarInner, direction, callback) {
8402 var router = this;
8403 if (router.params.animateCustom) {
8404 router.params.animateCustom.apply(router, [oldPage, newPage, oldNavbarInner, newNavbarInner, direction, callback]);
8405 return;
8406 }
8407 var dynamicNavbar = router.dynamicNavbar;
8408 var ios = router.app.theme === 'ios';
8409 // Router Animation class
8410 var routerTransitionClass = "router-transition-" + direction + " router-transition";
8411
8412 var newNavEls;
8413 var oldNavEls;
8414
8415 var fromLarge;
8416 var toLarge;
8417
8418 var oldIsLarge;
8419 var newIsLarge;
8420
8421 if (ios && dynamicNavbar) {
8422 oldIsLarge = oldNavbarInner && oldNavbarInner.hasClass('navbar-inner-large');
8423 newIsLarge = newNavbarInner && newNavbarInner.hasClass('navbar-inner-large');
8424 fromLarge = oldIsLarge && !oldNavbarInner.hasClass('navbar-inner-large-collapsed');
8425 toLarge = newIsLarge && !newNavbarInner.hasClass('navbar-inner-large-collapsed');
8426 var navEls = router.animatableNavElements(newNavbarInner, oldNavbarInner, toLarge, fromLarge, direction);
8427 newNavEls = navEls.newNavEls;
8428 oldNavEls = navEls.oldNavEls;
8429 }
8430
8431 function animateNavbars(progress) {
8432 if (!(ios && dynamicNavbar)) { return; }
8433 if (progress === 1) {
8434 if (toLarge) {
8435 newNavbarInner.addClass('router-navbar-transition-to-large');
8436 oldNavbarInner.addClass('router-navbar-transition-to-large');
8437 }
8438 if (fromLarge) {
8439 newNavbarInner.addClass('router-navbar-transition-from-large');
8440 oldNavbarInner.addClass('router-navbar-transition-from-large');
8441 }
8442 }
8443 newNavEls.forEach(function (navEl) {
8444 var $el = navEl.$el;
8445 var offset = direction === 'forward' ? navEl.rightOffset : navEl.leftOffset;
8446 if (navEl.isSliding) {
8447 if (navEl.isSubnavbar && newIsLarge) {
8448 $el[0].style.setProperty('transform', ("translate3d(" + (offset * (1 - progress)) + "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)"), 'important');
8449 } else {
8450 $el.transform(("translate3d(" + (offset * (1 - progress)) + "px,0,0)"));
8451 }
8452 }
8453 });
8454 oldNavEls.forEach(function (navEl) {
8455 var $el = navEl.$el;
8456 var offset = direction === 'forward' ? navEl.leftOffset : navEl.rightOffset;
8457 if (navEl.isSliding) {
8458 if (navEl.isSubnavbar && oldIsLarge) {
8459 $el.transform(("translate3d(" + (offset * (progress)) + "px, calc(-1 * var(--f7-navbar-large-collapse-progress) * var(--f7-navbar-large-title-height)), 0)"));
8460 } else {
8461 $el.transform(("translate3d(" + (offset * (progress)) + "px,0,0)"));
8462 }
8463 }
8464 });
8465 }
8466
8467 // AnimationEnd Callback
8468 function onDone() {
8469 if (router.dynamicNavbar) {
8470 if (newNavbarInner) {
8471 newNavbarInner.removeClass('router-navbar-transition-to-large router-navbar-transition-from-large');
8472 newNavbarInner.addClass('navbar-no-title-large-transition');
8473 Utils.nextFrame(function () {
8474 newNavbarInner.removeClass('navbar-no-title-large-transition');
8475 });
8476 }
8477 if (oldNavbarInner) {
8478 oldNavbarInner.removeClass('router-navbar-transition-to-large router-navbar-transition-from-large');
8479 }
8480 if (newNavbarInner.hasClass('sliding')) {
8481 newNavbarInner.find('.title, .left, .right, .left .icon, .subnavbar').transform('');
8482 } else {
8483 newNavbarInner.find('.sliding').transform('');
8484 }
8485 if (oldNavbarInner.hasClass('sliding')) {
8486 oldNavbarInner.find('.title, .left, .right, .left .icon, .subnavbar').transform('');
8487 } else {
8488 oldNavbarInner.find('.sliding').transform('');
8489 }
8490 }
8491 router.$el.removeClass(routerTransitionClass);
8492 if (callback) { callback(); }
8493 }
8494
8495 (direction === 'forward' ? newPage : oldPage).animationEnd(function () {
8496 onDone();
8497 });
8498
8499 // Animate
8500 if (dynamicNavbar) {
8501 // Prepare Navbars
8502 animateNavbars(0);
8503 Utils.nextFrame(function () {
8504 // Add class, start animation
8505 animateNavbars(1);
8506 router.$el.addClass(routerTransitionClass);
8507 });
8508 } else {
8509 // Add class, start animation
8510 router.$el.addClass(routerTransitionClass);
8511 }
8512 };
8513
8514 Router.prototype.removeModal = function removeModal (modalEl) {
8515 var router = this;
8516 router.removeEl(modalEl);
8517 };
8518 // eslint-disable-next-line
8519 Router.prototype.removeTabContent = function removeTabContent (tabEl) {
8520 var $tabEl = $(tabEl);
8521 $tabEl.html('');
8522 };
8523
8524 Router.prototype.removeNavbar = function removeNavbar (el) {
8525 var router = this;
8526 router.removeEl(el);
8527 };
8528
8529 Router.prototype.removePage = function removePage (el) {
8530 var $el = $(el);
8531 var f7Page = $el && $el[0] && $el[0].f7Page;
8532 var router = this;
8533 if (f7Page && f7Page.route && f7Page.route.route && f7Page.route.route.keepAlive) {
8534 $el.remove();
8535 return;
8536 }
8537 router.removeEl(el);
8538 };
8539
8540 Router.prototype.removeEl = function removeEl (el) {
8541 if (!el) { return; }
8542 var router = this;
8543 var $el = $(el);
8544 if ($el.length === 0) { return; }
8545 $el.find('.tab').each(function (tabIndex, tabEl) {
8546 $(tabEl).children().each(function (index, tabChild) {
8547 if (tabChild.f7Component) {
8548 $(tabChild).trigger('tab:beforeremove');
8549 tabChild.f7Component.$destroy();
8550 }
8551 });
8552 });
8553 if ($el[0].f7Component && $el[0].f7Component.$destroy) {
8554 $el[0].f7Component.$destroy();
8555 }
8556 if (!router.params.removeElements) {
8557 return;
8558 }
8559 if (router.params.removeElementsWithTimeout) {
8560 setTimeout(function () {
8561 $el.remove();
8562 }, router.params.removeElementsTimeout);
8563 } else {
8564 $el.remove();
8565 }
8566 };
8567
8568 Router.prototype.getPageEl = function getPageEl (content) {
8569 var router = this;
8570 if (typeof content === 'string') {
8571 router.tempDom.innerHTML = content;
8572 } else {
8573 if ($(content).hasClass('page')) {
8574 return content;
8575 }
8576 router.tempDom.innerHTML = '';
8577 $(router.tempDom).append(content);
8578 }
8579
8580 return router.findElement('.page', router.tempDom);
8581 };
8582
8583 Router.prototype.findElement = function findElement (stringSelector, container, notStacked) {
8584 var router = this;
8585 var view = router.view;
8586 var app = router.app;
8587
8588 // Modals Selector
8589 var modalsSelector = '.popup, .dialog, .popover, .actions-modal, .sheet-modal, .login-screen, .page';
8590
8591 var $container = $(container);
8592 var selector = stringSelector;
8593 if (notStacked) { selector += ':not(.stacked)'; }
8594
8595 var found = $container
8596 .find(selector)
8597 .filter(function (index, el) { return $(el).parents(modalsSelector).length === 0; });
8598
8599 if (found.length > 1) {
8600 if (typeof view.selector === 'string') {
8601 // Search in related view
8602 found = $container.find(((view.selector) + " " + selector));
8603 }
8604 if (found.length > 1) {
8605 // Search in main view
8606 found = $container.find(("." + (app.params.viewMainClass) + " " + selector));
8607 }
8608 }
8609 if (found.length === 1) { return found; }
8610
8611 // Try to find not stacked
8612 if (!notStacked) { found = router.findElement(selector, $container, true); }
8613 if (found && found.length === 1) { return found; }
8614 if (found && found.length > 1) { return $(found[0]); }
8615 return undefined;
8616 };
8617
8618 Router.prototype.flattenRoutes = function flattenRoutes (routes) {
8619 if ( routes === void 0 ) routes = this.routes;
8620
8621 var router = this;
8622 var flattenedRoutes = [];
8623 routes.forEach(function (route) {
8624 var hasTabRoutes = false;
8625 if ('tabs' in route && route.tabs) {
8626 var mergedPathsRoutes = route.tabs.map(function (tabRoute) {
8627 var tRoute = Utils.extend({}, route, {
8628 path: (((route.path) + "/" + (tabRoute.path))).replace('///', '/').replace('//', '/'),
8629 parentPath: route.path,
8630 tab: tabRoute,
8631 });
8632 delete tRoute.tabs;
8633 delete tRoute.routes;
8634 return tRoute;
8635 });
8636 hasTabRoutes = true;
8637 flattenedRoutes = flattenedRoutes.concat(router.flattenRoutes(mergedPathsRoutes));
8638 }
8639 if ('detailRoutes' in route) {
8640 var mergedPathsRoutes$1 = route.detailRoutes.map(function (detailRoute) {
8641 var dRoute = Utils.extend({}, detailRoute);
8642 dRoute.masterRoute = route;
8643 dRoute.masterRoutePath = route.path;
8644 return dRoute;
8645 });
8646 flattenedRoutes = flattenedRoutes.concat(route, router.flattenRoutes(mergedPathsRoutes$1));
8647 }
8648 if ('routes' in route) {
8649 var mergedPathsRoutes$2 = route.routes.map(function (childRoute) {
8650 var cRoute = Utils.extend({}, childRoute);
8651 cRoute.path = (((route.path) + "/" + (cRoute.path))).replace('///', '/').replace('//', '/');
8652 return cRoute;
8653 });
8654 if (hasTabRoutes) {
8655 flattenedRoutes = flattenedRoutes.concat(router.flattenRoutes(mergedPathsRoutes$2));
8656 } else {
8657 flattenedRoutes = flattenedRoutes.concat(route, router.flattenRoutes(mergedPathsRoutes$2));
8658 }
8659 }
8660 if (!('routes' in route) && !('tabs' in route && route.tabs) && !('detailRoutes' in route)) {
8661 flattenedRoutes.push(route);
8662 }
8663 });
8664 return flattenedRoutes;
8665 };
8666
8667 // eslint-disable-next-line
8668 Router.prototype.parseRouteUrl = function parseRouteUrl (url) {
8669 if (!url) { return {}; }
8670 var query = Utils.parseUrlQuery(url);
8671 var hash = url.split('#')[1];
8672 var params = {};
8673 var path = url.split('#')[0].split('?')[0];
8674 return {
8675 query: query,
8676 hash: hash,
8677 params: params,
8678 url: url,
8679 path: path,
8680 };
8681 };
8682
8683 // eslint-disable-next-line
8684 Router.prototype.constructRouteUrl = function constructRouteUrl (route, ref) {
8685 if ( ref === void 0 ) ref = {};
8686 var params = ref.params;
8687 var query = ref.query;
8688
8689 var path = route.path;
8690 var toUrl = pathToRegexp_1.compile(path);
8691 var url;
8692 try {
8693 url = toUrl(params || {});
8694 } catch (error) {
8695 throw new Error(("Framework7: error constructing route URL from passed params:\nRoute: " + path + "\n" + (error.toString())));
8696 }
8697
8698 if (query) {
8699 if (typeof query === 'string') { url += "?" + query; }
8700 else { url += "?" + (Utils.serializeObject(query)); }
8701 }
8702
8703 return url;
8704 };
8705
8706 Router.prototype.findTabRoute = function findTabRoute (tabEl) {
8707 var router = this;
8708 var $tabEl = $(tabEl);
8709 var parentPath = router.currentRoute.route.parentPath;
8710 var tabId = $tabEl.attr('id');
8711 var flattenedRoutes = router.flattenRoutes(router.routes);
8712 var foundTabRoute;
8713 flattenedRoutes.forEach(function (route) {
8714 if (
8715 route.parentPath === parentPath
8716 && route.tab
8717 && route.tab.id === tabId
8718 ) {
8719 foundTabRoute = route;
8720 }
8721 });
8722 return foundTabRoute;
8723 };
8724
8725 Router.prototype.findRouteByKey = function findRouteByKey (key, value) {
8726 var router = this;
8727 var routes = router.routes;
8728 var flattenedRoutes = router.flattenRoutes(routes);
8729 var matchingRoute;
8730
8731 flattenedRoutes.forEach(function (route) {
8732 if (matchingRoute) { return; }
8733 if (route[key] === value) {
8734 matchingRoute = route;
8735 }
8736 });
8737 return matchingRoute;
8738 };
8739
8740 Router.prototype.findMatchingRoute = function findMatchingRoute (url) {
8741 if (!url) { return undefined; }
8742 var router = this;
8743 var routes = router.routes;
8744 var flattenedRoutes = router.flattenRoutes(routes);
8745 var ref = router.parseRouteUrl(url);
8746 var path = ref.path;
8747 var query = ref.query;
8748 var hash = ref.hash;
8749 var params = ref.params;
8750 var matchingRoute;
8751 flattenedRoutes.forEach(function (route) {
8752 if (matchingRoute) { return; }
8753 var keys = [];
8754
8755 var pathsToMatch = [route.path];
8756 if (route.alias) {
8757 if (typeof route.alias === 'string') { pathsToMatch.push(route.alias); }
8758 else if (Array.isArray(route.alias)) {
8759 route.alias.forEach(function (aliasPath) {
8760 pathsToMatch.push(aliasPath);
8761 });
8762 }
8763 }
8764
8765 var matched;
8766 pathsToMatch.forEach(function (pathToMatch) {
8767 if (matched) { return; }
8768 matched = pathToRegexp_1(pathToMatch, keys).exec(path);
8769 });
8770
8771 if (matched) {
8772 keys.forEach(function (keyObj, index) {
8773 if (typeof keyObj.name === 'number') { return; }
8774 var paramValue = matched[index + 1];
8775 params[keyObj.name] = paramValue;
8776 });
8777
8778 var parentPath;
8779 if (route.parentPath) {
8780 parentPath = path.split('/').slice(0, route.parentPath.split('/').length - 1).join('/');
8781 }
8782
8783 matchingRoute = {
8784 query: query,
8785 hash: hash,
8786 params: params,
8787 url: url,
8788 path: path,
8789 parentPath: parentPath,
8790 route: route,
8791 name: route.name,
8792 };
8793 }
8794 });
8795 return matchingRoute;
8796 };
8797
8798 // eslint-disable-next-line
8799 Router.prototype.replaceRequestUrlParams = function replaceRequestUrlParams (url, options) {
8800 if ( url === void 0 ) url = '';
8801 if ( options === void 0 ) options = {};
8802
8803 var compiledUrl = url;
8804 if (typeof compiledUrl === 'string'
8805 && compiledUrl.indexOf('{{') >= 0
8806 && options
8807 && options.route
8808 && options.route.params
8809 && Object.keys(options.route.params).length
8810 ) {
8811 Object.keys(options.route.params).forEach(function (paramName) {
8812 var regExp = new RegExp(("{{" + paramName + "}}"), 'g');
8813 compiledUrl = compiledUrl.replace(regExp, options.route.params[paramName] || '');
8814 });
8815 }
8816 return compiledUrl;
8817 };
8818
8819 Router.prototype.removeFromXhrCache = function removeFromXhrCache (url) {
8820 var router = this;
8821 var xhrCache = router.cache.xhr;
8822 var index = false;
8823 for (var i = 0; i < xhrCache.length; i += 1) {
8824 if (xhrCache[i].url === url) { index = i; }
8825 }
8826 if (index !== false) { xhrCache.splice(index, 1); }
8827 };
8828
8829 Router.prototype.xhrRequest = function xhrRequest (requestUrl, options) {
8830 var router = this;
8831 var params = router.params;
8832 var ignoreCache = options.ignoreCache;
8833 var url = requestUrl;
8834
8835 var hasQuery = url.indexOf('?') >= 0;
8836 if (params.passRouteQueryToRequest
8837 && options
8838 && options.route
8839 && options.route.query
8840 && Object.keys(options.route.query).length
8841 ) {
8842 url += "" + (hasQuery ? '&' : '?') + (Utils.serializeObject(options.route.query));
8843 hasQuery = true;
8844 }
8845
8846 if (params.passRouteParamsToRequest
8847 && options
8848 && options.route
8849 && options.route.params
8850 && Object.keys(options.route.params).length
8851 ) {
8852 url += "" + (hasQuery ? '&' : '?') + (Utils.serializeObject(options.route.params));
8853 hasQuery = true;
8854 }
8855
8856 if (url.indexOf('{{') >= 0) {
8857 url = router.replaceRequestUrlParams(url, options);
8858 }
8859 // should we ignore get params or not
8860 if (params.xhrCacheIgnoreGetParameters && url.indexOf('?') >= 0) {
8861 url = url.split('?')[0];
8862 }
8863 return new Promise(function (resolve, reject) {
8864 if (params.xhrCache && !ignoreCache && url.indexOf('nocache') < 0 && params.xhrCacheIgnore.indexOf(url) < 0) {
8865 for (var i = 0; i < router.cache.xhr.length; i += 1) {
8866 var cachedUrl = router.cache.xhr[i];
8867 if (cachedUrl.url === url) {
8868 // Check expiration
8869 if (Utils.now() - cachedUrl.time < params.xhrCacheDuration) {
8870 // Load from cache
8871 resolve(cachedUrl.content);
8872 return;
8873 }
8874 }
8875 }
8876 }
8877 router.xhr = router.app.request({
8878 url: url,
8879 method: 'GET',
8880 beforeSend: function beforeSend(xhr) {
8881 router.emit('routerAjaxStart', xhr, options);
8882 },
8883 complete: function complete(xhr, status) {
8884 router.emit('routerAjaxComplete', xhr);
8885 if ((status !== 'error' && status !== 'timeout' && (xhr.status >= 200 && xhr.status < 300)) || xhr.status === 0) {
8886 if (params.xhrCache && xhr.responseText !== '') {
8887 router.removeFromXhrCache(url);
8888 router.cache.xhr.push({
8889 url: url,
8890 time: Utils.now(),
8891 content: xhr.responseText,
8892 });
8893 }
8894 router.emit('routerAjaxSuccess', xhr, options);
8895 resolve(xhr.responseText);
8896 } else {
8897 router.emit('routerAjaxError', xhr, options);
8898 reject(xhr);
8899 }
8900 },
8901 error: function error(xhr) {
8902 router.emit('routerAjaxError', xhr, options);
8903 reject(xhr);
8904 },
8905 });
8906 });
8907 };
8908
8909 // Remove theme elements
8910 Router.prototype.removeThemeElements = function removeThemeElements (el) {
8911 var router = this;
8912 var theme = router.app.theme;
8913 $(el).find(("." + (theme === 'md' ? 'ios' : 'md') + "-only, .if-" + (theme === 'md' ? 'ios' : 'md'))).remove();
8914 };
8915
8916 Router.prototype.getPageData = function getPageData (pageEl, navbarEl, from, to, route, pageFromEl) {
8917 if ( route === void 0 ) route = {};
8918
8919 var router = this;
8920 var $pageEl = $(pageEl).eq(0);
8921 var $navbarEl = $(navbarEl).eq(0);
8922 var currentPage = $pageEl[0].f7Page || {};
8923 var direction;
8924 var pageFrom;
8925 if ((from === 'next' && to === 'current') || (from === 'current' && to === 'previous')) { direction = 'forward'; }
8926 if ((from === 'current' && to === 'next') || (from === 'previous' && to === 'current')) { direction = 'backward'; }
8927 if (currentPage && !currentPage.fromPage) {
8928 var $pageFromEl = $(pageFromEl);
8929 if ($pageFromEl.length) {
8930 pageFrom = $pageFromEl[0].f7Page;
8931 }
8932 }
8933 pageFrom = currentPage.pageFrom || pageFrom;
8934 if (pageFrom && pageFrom.pageFrom) {
8935 pageFrom.pageFrom = null;
8936 }
8937 var page = {
8938 app: router.app,
8939 view: router.view,
8940 router: router,
8941 $el: $pageEl,
8942 el: $pageEl[0],
8943 $pageEl: $pageEl,
8944 pageEl: $pageEl[0],
8945 $navbarEl: $navbarEl,
8946 navbarEl: $navbarEl[0],
8947 name: $pageEl.attr('data-name'),
8948 position: from,
8949 from: from,
8950 to: to,
8951 direction: direction,
8952 route: currentPage.route ? currentPage.route : route,
8953 pageFrom: pageFrom,
8954 };
8955
8956 $pageEl[0].f7Page = page;
8957 return page;
8958 };
8959
8960 // Callbacks
8961 Router.prototype.pageCallback = function pageCallback (callback, pageEl, navbarEl, from, to, options, pageFromEl) {
8962 if ( options === void 0 ) options = {};
8963
8964 if (!pageEl) { return; }
8965 var router = this;
8966 var $pageEl = $(pageEl);
8967 if (!$pageEl.length) { return; }
8968 var $navbarEl = $(navbarEl);
8969 var route = options.route;
8970 var restoreScrollTopOnBack = router.params.restoreScrollTopOnBack
8971 && !(
8972 router.params.masterDetailBreakpoint > 0
8973 && $pageEl.hasClass('page-master')
8974 && router.app.width >= router.params.masterDetailBreakpoint
8975 );
8976 var keepAlive = $pageEl[0].f7Page && $pageEl[0].f7Page.route && $pageEl[0].f7Page.route.route && $pageEl[0].f7Page.route.route.keepAlive;
8977
8978 if (callback === 'beforeRemove' && keepAlive) {
8979 callback = 'beforeUnmount'; // eslint-disable-line
8980 }
8981
8982 var camelName = "page" + (callback[0].toUpperCase() + callback.slice(1, callback.length));
8983 var colonName = "page:" + (callback.toLowerCase());
8984
8985 var page = {};
8986 if (callback === 'beforeRemove' && $pageEl[0].f7Page) {
8987 page = Utils.extend($pageEl[0].f7Page, { from: from, to: to, position: from });
8988 } else {
8989 page = router.getPageData($pageEl[0], $navbarEl[0], from, to, route, pageFromEl);
8990 }
8991 page.swipeBack = !!options.swipeBack;
8992
8993 var ref = options.route ? options.route.route : {};
8994 var on = ref.on; if ( on === void 0 ) on = {};
8995 var once = ref.once; if ( once === void 0 ) once = {};
8996 if (options.on) {
8997 Utils.extend(on, options.on);
8998 }
8999 if (options.once) {
9000 Utils.extend(once, options.once);
9001 }
9002
9003 function attachEvents() {
9004 if ($pageEl[0].f7RouteEventsAttached) { return; }
9005 $pageEl[0].f7RouteEventsAttached = true;
9006 if (on && Object.keys(on).length > 0) {
9007 $pageEl[0].f7RouteEventsOn = on;
9008 Object.keys(on).forEach(function (eventName) {
9009 on[eventName] = on[eventName].bind(router);
9010 $pageEl.on(Utils.eventNameToColonCase(eventName), on[eventName]);
9011 });
9012 }
9013 if (once && Object.keys(once).length > 0) {
9014 $pageEl[0].f7RouteEventsOnce = once;
9015 Object.keys(once).forEach(function (eventName) {
9016 once[eventName] = once[eventName].bind(router);
9017 $pageEl.once(Utils.eventNameToColonCase(eventName), once[eventName]);
9018 });
9019 }
9020 }
9021
9022 function detachEvents() {
9023 if (!$pageEl[0].f7RouteEventsAttached) { return; }
9024 if ($pageEl[0].f7RouteEventsOn) {
9025 Object.keys($pageEl[0].f7RouteEventsOn).forEach(function (eventName) {
9026 $pageEl.off(Utils.eventNameToColonCase(eventName), $pageEl[0].f7RouteEventsOn[eventName]);
9027 });
9028 }
9029 if ($pageEl[0].f7RouteEventsOnce) {
9030 Object.keys($pageEl[0].f7RouteEventsOnce).forEach(function (eventName) {
9031 $pageEl.off(Utils.eventNameToColonCase(eventName), $pageEl[0].f7RouteEventsOnce[eventName]);
9032 });
9033 }
9034 $pageEl[0].f7RouteEventsAttached = null;
9035 $pageEl[0].f7RouteEventsOn = null;
9036 $pageEl[0].f7RouteEventsOnce = null;
9037 delete $pageEl[0].f7RouteEventsAttached;
9038 delete $pageEl[0].f7RouteEventsOn;
9039 delete $pageEl[0].f7RouteEventsOnce;
9040 }
9041
9042 if (callback === 'mounted') {
9043 attachEvents();
9044 }
9045 if (callback === 'init') {
9046 if (restoreScrollTopOnBack && (from === 'previous' || !from) && to === 'current' && router.scrollHistory[page.route.url] && !$pageEl.hasClass('no-restore-scroll')) {
9047 var $pageContent = $pageEl.find('.page-content');
9048 if ($pageContent.length > 0) {
9049 // eslint-disable-next-line
9050 $pageContent = $pageContent.filter(function (pageContentIndex, pageContentEl) {
9051 return (
9052 $(pageContentEl).parents('.tab:not(.tab-active)').length === 0
9053 && !$(pageContentEl).is('.tab:not(.tab-active)')
9054 );
9055 });
9056 }
9057 $pageContent.scrollTop(router.scrollHistory[page.route.url]);
9058 }
9059 attachEvents();
9060 if ($pageEl[0].f7PageInitialized) {
9061 $pageEl.trigger('page:reinit', page);
9062 router.emit('pageReinit', page);
9063 return;
9064 }
9065 $pageEl[0].f7PageInitialized = true;
9066 }
9067 if (restoreScrollTopOnBack && callback === 'beforeOut' && from === 'current' && to === 'previous') {
9068 // Save scroll position
9069 var $pageContent$1 = $pageEl.find('.page-content');
9070 if ($pageContent$1.length > 0) {
9071 // eslint-disable-next-line
9072 $pageContent$1 = $pageContent$1.filter(function (pageContentIndex, pageContentEl) {
9073 return (
9074 $(pageContentEl).parents('.tab:not(.tab-active)').length === 0
9075 && !$(pageContentEl).is('.tab:not(.tab-active)')
9076 );
9077 });
9078 }
9079 router.scrollHistory[page.route.url] = $pageContent$1.scrollTop();
9080 }
9081 if (restoreScrollTopOnBack && callback === 'beforeOut' && from === 'current' && to === 'next') {
9082 // Delete scroll position
9083 delete router.scrollHistory[page.route.url];
9084 }
9085
9086 $pageEl.trigger(colonName, page);
9087 router.emit(camelName, page);
9088
9089 if (callback === 'beforeRemove' || callback === 'beforeUnmount') {
9090 detachEvents();
9091 if (!keepAlive) {
9092 if ($pageEl[0].f7Page && $pageEl[0].f7Page.navbarEl) {
9093 delete $pageEl[0].f7Page.navbarEl.f7Page;
9094 }
9095 $pageEl[0].f7Page = null;
9096 }
9097 }
9098 };
9099
9100 Router.prototype.saveHistory = function saveHistory () {
9101 var router = this;
9102 router.view.history = router.history;
9103 if (router.params.pushState) {
9104 win.localStorage[("f7router-" + (router.view.id) + "-history")] = JSON.stringify(router.history);
9105 }
9106 };
9107
9108 Router.prototype.restoreHistory = function restoreHistory () {
9109 var router = this;
9110 if (router.params.pushState && win.localStorage[("f7router-" + (router.view.id) + "-history")]) {
9111 router.history = JSON.parse(win.localStorage[("f7router-" + (router.view.id) + "-history")]);
9112 router.view.history = router.history;
9113 }
9114 };
9115
9116 Router.prototype.clearHistory = function clearHistory () {
9117 var router = this;
9118 router.history = [];
9119 if (router.view) { router.view.history = []; }
9120 router.saveHistory();
9121 };
9122
9123 Router.prototype.updateCurrentUrl = function updateCurrentUrl (newUrl) {
9124 var router = this;
9125 appRouterCheck(router, 'updateCurrentUrl');
9126 // Update history
9127 if (router.history.length) {
9128 router.history[router.history.length - 1] = newUrl;
9129 } else {
9130 router.history.push(newUrl);
9131 }
9132
9133 // Update current route params
9134 var ref = router.parseRouteUrl(newUrl);
9135 var query = ref.query;
9136 var hash = ref.hash;
9137 var params = ref.params;
9138 var url = ref.url;
9139 var path = ref.path;
9140 if (router.currentRoute) {
9141 Utils.extend(router.currentRoute, {
9142 query: query,
9143 hash: hash,
9144 params: params,
9145 url: url,
9146 path: path,
9147 });
9148 }
9149
9150 if (router.params.pushState) {
9151 var pushStateRoot = router.params.pushStateRoot || '';
9152 History.replace(
9153 router.view.id,
9154 {
9155 url: newUrl,
9156 },
9157 pushStateRoot + router.params.pushStateSeparator + newUrl
9158 );
9159 }
9160
9161 // Save History
9162 router.saveHistory();
9163
9164 router.emit('routeUrlUpdate', router.currentRoute, router);
9165 };
9166
9167 Router.prototype.init = function init () {
9168 var router = this;
9169 var app = router.app;
9170 var view = router.view;
9171
9172 // Init Swipeback
9173 {
9174 if (
9175 (view && router.params.iosSwipeBack && app.theme === 'ios')
9176 || (view && router.params.mdSwipeBack && app.theme === 'md')
9177 ) {
9178 SwipeBack(router);
9179 }
9180 }
9181
9182 // Dynamic not separated navbbar
9183 if (router.dynamicNavbar && !router.separateNavbar) {
9184 router.$el.addClass('router-dynamic-navbar-inside');
9185 }
9186
9187 var initUrl = router.params.url;
9188 var documentUrl = doc.location.href.split(doc.location.origin)[1];
9189 var historyRestored;
9190 var ref = router.params;
9191 var pushState = ref.pushState;
9192 var pushStateOnLoad = ref.pushStateOnLoad;
9193 var pushStateSeparator = ref.pushStateSeparator;
9194 var pushStateAnimateOnLoad = ref.pushStateAnimateOnLoad;
9195 var ref$1 = router.params;
9196 var pushStateRoot = ref$1.pushStateRoot;
9197 if (win.cordova && pushState && !pushStateSeparator && !pushStateRoot && doc.location.pathname.indexOf('index.html')) {
9198 // eslint-disable-next-line
9199 console.warn('Framework7: wrong or not complete pushState configuration, trying to guess pushStateRoot');
9200 pushStateRoot = doc.location.pathname.split('index.html')[0];
9201 }
9202
9203 if (!pushState || !pushStateOnLoad) {
9204 if (!initUrl) {
9205 initUrl = documentUrl;
9206 }
9207 if (doc.location.search && initUrl.indexOf('?') < 0) {
9208 initUrl += doc.location.search;
9209 }
9210 if (doc.location.hash && initUrl.indexOf('#') < 0) {
9211 initUrl += doc.location.hash;
9212 }
9213 } else {
9214 if (pushStateRoot && documentUrl.indexOf(pushStateRoot) >= 0) {
9215 documentUrl = documentUrl.split(pushStateRoot)[1];
9216 if (documentUrl === '') { documentUrl = '/'; }
9217 }
9218 if (pushStateSeparator.length > 0 && documentUrl.indexOf(pushStateSeparator) >= 0) {
9219 initUrl = documentUrl.split(pushStateSeparator)[1];
9220 } else {
9221 initUrl = documentUrl;
9222 }
9223 router.restoreHistory();
9224 if (router.history.indexOf(initUrl) >= 0) {
9225 router.history = router.history.slice(0, router.history.indexOf(initUrl) + 1);
9226 } else if (router.params.url === initUrl) {
9227 router.history = [initUrl];
9228 } else if (History.state && History.state[view.id] && History.state[view.id].url === router.history[router.history.length - 1]) {
9229 initUrl = router.history[router.history.length - 1];
9230 } else {
9231 router.history = [documentUrl.split(pushStateSeparator)[0] || '/', initUrl];
9232 }
9233 if (router.history.length > 1) {
9234 historyRestored = true;
9235 } else {
9236 router.history = [];
9237 }
9238 router.saveHistory();
9239 }
9240 var currentRoute;
9241 if (router.history.length > 1) {
9242 // Will load page
9243 currentRoute = router.findMatchingRoute(router.history[0]);
9244 if (!currentRoute) {
9245 currentRoute = Utils.extend(router.parseRouteUrl(router.history[0]), {
9246 route: {
9247 url: router.history[0],
9248 path: router.history[0].split('?')[0],
9249 },
9250 });
9251 }
9252 } else {
9253 // Don't load page
9254 currentRoute = router.findMatchingRoute(initUrl);
9255 if (!currentRoute) {
9256 currentRoute = Utils.extend(router.parseRouteUrl(initUrl), {
9257 route: {
9258 url: initUrl,
9259 path: initUrl.split('?')[0],
9260 },
9261 });
9262 }
9263 }
9264
9265 if (router.params.stackPages) {
9266 router.$el.children('.page').each(function (index, pageEl) {
9267 var $pageEl = $(pageEl);
9268 router.initialPages.push($pageEl[0]);
9269 if (router.separateNavbar && $pageEl.children('.navbar').length > 0) {
9270 router.initialNavbars.push($pageEl.children('.navbar').find('.navbar-inner')[0]);
9271 }
9272 });
9273 }
9274
9275 if (router.$el.children('.page:not(.stacked)').length === 0 && initUrl) {
9276 // No pages presented in DOM, reload new page
9277 router.navigate(initUrl, {
9278 initial: true,
9279 reloadCurrent: true,
9280 pushState: false,
9281 });
9282 } else {
9283 // Init current DOM page
9284 var hasTabRoute;
9285 router.currentRoute = currentRoute;
9286 router.$el.children('.page:not(.stacked)').each(function (index, pageEl) {
9287 var $pageEl = $(pageEl);
9288 var $navbarInnerEl;
9289 $pageEl.addClass('page-current');
9290 if (router.separateNavbar) {
9291 $navbarInnerEl = $pageEl.children('.navbar').children('.navbar-inner');
9292 if ($navbarInnerEl.length > 0) {
9293 if (!router.$navbarEl.parents(doc).length) {
9294 router.$el.prepend(router.$navbarEl);
9295 }
9296 $navbarInnerEl.addClass('navbar-current');
9297 router.$navbarEl.append($navbarInnerEl);
9298 if ($navbarInnerEl.children('.title-large').length) {
9299 $navbarInnerEl.addClass('navbar-inner-large');
9300 }
9301 $pageEl.children('.navbar').remove();
9302 } else {
9303 router.$navbarEl.addClass('navbar-hidden');
9304 if ($navbarInnerEl.children('.title-large').length) {
9305 router.$navbarEl.addClass('navbar-hidden navbar-large-hidden');
9306 }
9307 }
9308 }
9309 if (router.currentRoute && router.currentRoute.route && router.currentRoute.route.master && router.params.masterDetailBreakpoint > 0) {
9310 $pageEl.addClass('page-master');
9311 $pageEl.trigger('page:role', { role: 'master' });
9312 if ($navbarInnerEl && $navbarInnerEl.length) {
9313 $navbarInnerEl.addClass('navbar-master');
9314 }
9315 }
9316 var initOptions = {
9317 route: router.currentRoute,
9318 };
9319 if (router.currentRoute && router.currentRoute.route && router.currentRoute.route.options) {
9320 Utils.extend(initOptions, router.currentRoute.route.options);
9321 }
9322 router.currentPageEl = $pageEl[0];
9323 if (router.separateNavbar && $navbarInnerEl.length) {
9324 router.currentNavbarEl = $navbarInnerEl[0];
9325 }
9326 router.removeThemeElements($pageEl);
9327 if (router.separateNavbar && $navbarInnerEl.length) {
9328 router.removeThemeElements($navbarInnerEl);
9329 }
9330 if (initOptions.route.route.tab) {
9331 hasTabRoute = true;
9332 router.tabLoad(initOptions.route.route.tab, Utils.extend({}, initOptions));
9333 }
9334 router.pageCallback('init', $pageEl, $navbarInnerEl, 'current', undefined, initOptions);
9335 });
9336 if (historyRestored) {
9337 router.navigate(initUrl, {
9338 initial: true,
9339 pushState: false,
9340 history: false,
9341 animate: pushStateAnimateOnLoad,
9342 once: {
9343 pageAfterIn: function pageAfterIn() {
9344 if (router.history.length > 2) {
9345 router.back({ preload: true });
9346 }
9347 },
9348 },
9349 });
9350 }
9351 if (!historyRestored && !hasTabRoute) {
9352 router.history.push(initUrl);
9353 router.saveHistory();
9354 }
9355 }
9356 if (initUrl && pushState && pushStateOnLoad && (!History.state || !History.state[view.id])) {
9357 History.initViewState(view.id, {
9358 url: initUrl,
9359 });
9360 }
9361 router.emit('local::init routerInit', router);
9362 };
9363
9364 Router.prototype.destroy = function destroy () {
9365 var router = this;
9366
9367 router.emit('local::destroy routerDestroy', router);
9368
9369 // Delete props & methods
9370 Object.keys(router).forEach(function (routerProp) {
9371 router[routerProp] = null;
9372 delete router[routerProp];
9373 });
9374
9375 router = null;
9376 };
9377
9378 return Router;
9379 }(Framework7Class));
9380
9381 // Load
9382 Router.prototype.forward = forward;
9383 Router.prototype.load = load;
9384 Router.prototype.navigate = navigate;
9385 Router.prototype.refreshPage = refreshPage;
9386 // Tab
9387 Router.prototype.tabLoad = tabLoad;
9388 Router.prototype.tabRemove = tabRemove;
9389 // Modal
9390 Router.prototype.modalLoad = modalLoad;
9391 Router.prototype.modalRemove = modalRemove;
9392 // Back
9393 Router.prototype.backward = backward;
9394 Router.prototype.loadBack = loadBack;
9395 Router.prototype.back = back;
9396 // Clear previoius pages from the DOM
9397 Router.prototype.clearPreviousPages = clearPreviousPages;
9398 // Clear history
9399 Router.prototype.clearPreviousHistory = clearPreviousHistory;
9400
9401 var Router$1 = {
9402 name: 'router',
9403 static: {
9404 Router: Router,
9405 },
9406 instance: {
9407 cache: {
9408 xhr: [],
9409 templates: [],
9410 components: [],
9411 },
9412 },
9413 create: function create() {
9414 var instance = this;
9415 if (instance.app) {
9416 // View Router
9417 if (instance.params.router) {
9418 instance.router = new Router(instance.app, instance);
9419 }
9420 } else {
9421 // App Router
9422 instance.router = new Router(instance);
9423 }
9424 },
9425 };
9426
9427 var View = /*@__PURE__*/(function (Framework7Class$$1) {
9428 function View(appInstance, el, viewParams) {
9429 if ( viewParams === void 0 ) viewParams = {};
9430
9431 Framework7Class$$1.call(this, viewParams, [appInstance]);
9432
9433 var app = appInstance;
9434 var $el = $(el);
9435 var view = this;
9436
9437 var defaults = {
9438 routes: [],
9439 routesAdd: [],
9440 };
9441
9442 // Default View params
9443 view.params = Utils.extend(defaults, app.params.view, viewParams);
9444
9445 // Routes
9446 if (view.params.routes.length > 0) {
9447 view.routes = view.params.routes;
9448 } else {
9449 view.routes = [].concat(app.routes, view.params.routesAdd);
9450 }
9451
9452 // Selector
9453 var selector;
9454 if (typeof el === 'string') { selector = el; }
9455 else {
9456 // Supposed to be HTMLElement or Dom7
9457 selector = ($el.attr('id') ? ("#" + ($el.attr('id'))) : '') + ($el.attr('class') ? ("." + ($el.attr('class').replace(/ /g, '.').replace('.active', ''))) : '');
9458 }
9459
9460 // DynamicNavbar
9461 var $navbarEl;
9462 if (app.theme === 'ios' && view.params.iosDynamicNavbar && view.params.iosSeparateDynamicNavbar) {
9463 $navbarEl = $el.children('.navbar').eq(0);
9464 if ($navbarEl.length === 0) {
9465 $navbarEl = $('<div class="navbar"></div>');
9466 }
9467 }
9468
9469 // View Props
9470 Utils.extend(false, view, {
9471 app: app,
9472 $el: $el,
9473 el: $el[0],
9474 name: view.params.name,
9475 main: view.params.main || $el.hasClass('view-main'),
9476 $navbarEl: $navbarEl,
9477 navbarEl: $navbarEl ? $navbarEl[0] : undefined,
9478 selector: selector,
9479 history: [],
9480 scrollHistory: {},
9481 });
9482
9483 // Save in DOM
9484 $el[0].f7View = view;
9485
9486 // Install Modules
9487 view.useModules();
9488
9489 // Add to app
9490 app.views.push(view);
9491 if (view.main) {
9492 app.views.main = view;
9493 }
9494 if (view.name) {
9495 app.views[view.name] = view;
9496 }
9497
9498 // Index
9499 view.index = app.views.indexOf(view);
9500
9501 // View ID
9502 var viewId;
9503 if (view.name) {
9504 viewId = "view_" + (view.name);
9505 } else if (view.main) {
9506 viewId = 'view_main';
9507 } else {
9508 viewId = "view_" + (view.index);
9509 }
9510 view.id = viewId;
9511
9512 // Init View
9513 if (app.initialized) {
9514 view.init();
9515 } else {
9516 app.on('init', function () {
9517 view.init();
9518 });
9519 }
9520
9521 return view;
9522 }
9523
9524 if ( Framework7Class$$1 ) View.__proto__ = Framework7Class$$1;
9525 View.prototype = Object.create( Framework7Class$$1 && Framework7Class$$1.prototype );
9526 View.prototype.constructor = View;
9527
9528 View.prototype.destroy = function destroy () {
9529 var view = this;
9530 var app = view.app;
9531
9532 view.$el.trigger('view:beforedestroy', view);
9533 view.emit('local::beforeDestroy viewBeforeDestroy', view);
9534
9535 app.off('resize', view.checkmasterDetailBreakpoint);
9536
9537 if (view.main) {
9538 app.views.main = null;
9539 delete app.views.main;
9540 } else if (view.name) {
9541 app.views[view.name] = null;
9542 delete app.views[view.name];
9543 }
9544 view.$el[0].f7View = null;
9545 delete view.$el[0].f7View;
9546
9547 app.views.splice(app.views.indexOf(view), 1);
9548
9549 // Destroy Router
9550 if (view.params.router && view.router) {
9551 view.router.destroy();
9552 }
9553
9554 view.emit('local::destroy viewDestroy', view);
9555
9556 // Delete props & methods
9557 Object.keys(view).forEach(function (viewProp) {
9558 view[viewProp] = null;
9559 delete view[viewProp];
9560 });
9561
9562 view = null;
9563 };
9564
9565 View.prototype.checkmasterDetailBreakpoint = function checkmasterDetailBreakpoint () {
9566 var view = this;
9567 var app = view.app;
9568 var wasMasterDetail = view.$el.hasClass('view-master-detail');
9569 if (app.width >= view.params.masterDetailBreakpoint) {
9570 view.$el.addClass('view-master-detail');
9571 if (!wasMasterDetail) {
9572 view.emit('local::masterDetailBreakpoint viewMasterDetailBreakpoint');
9573 view.$el.trigger('view:masterDetailBreakpoint', view);
9574 }
9575 } else {
9576 view.$el.removeClass('view-master-detail');
9577 if (wasMasterDetail) {
9578 view.emit('local::masterDetailBreakpoint viewMasterDetailBreakpoint');
9579 view.$el.trigger('view:masterDetailBreakpoint', view);
9580 }
9581 }
9582 };
9583
9584 View.prototype.initMasterDetail = function initMasterDetail () {
9585 var view = this;
9586 var app = view.app;
9587 view.checkmasterDetailBreakpoint = view.checkmasterDetailBreakpoint.bind(view);
9588 view.checkmasterDetailBreakpoint();
9589 app.on('resize', view.checkmasterDetailBreakpoint);
9590 };
9591
9592 View.prototype.init = function init () {
9593 var view = this;
9594 if (view.params.router) {
9595 if (view.params.masterDetailBreakpoint > 0) {
9596 view.initMasterDetail();
9597 }
9598 view.router.init();
9599 view.$el.trigger('view:init', view);
9600 view.emit('local::init viewInit', view);
9601 }
9602 };
9603
9604 return View;
9605 }(Framework7Class));
9606
9607 // Use Router
9608 View.use(Router$1);
9609
9610 function initClicks(app) {
9611 function handleClicks(e) {
9612 var $clickedEl = $(e.target);
9613 var $clickedLinkEl = $clickedEl.closest('a');
9614 var isLink = $clickedLinkEl.length > 0;
9615 var url = isLink && $clickedLinkEl.attr('href');
9616 var isTabLink = isLink && $clickedLinkEl.hasClass('tab-link') && ($clickedLinkEl.attr('data-tab') || (url && url.indexOf('#') === 0));
9617
9618 // Check if link is external
9619 if (isLink) {
9620 // eslint-disable-next-line
9621 if ($clickedLinkEl.is(app.params.clicks.externalLinks) || (url && url.indexOf('javascript:') >= 0)) {
9622 var target = $clickedLinkEl.attr('target');
9623 if (
9624 url
9625 && win.cordova
9626 && win.cordova.InAppBrowser
9627 && (target === '_system' || target === '_blank')
9628 ) {
9629 e.preventDefault();
9630 win.cordova.InAppBrowser.open(url, target);
9631 }
9632 return;
9633 }
9634 }
9635
9636 // Modules Clicks
9637 Object.keys(app.modules).forEach(function (moduleName) {
9638 var moduleClicks = app.modules[moduleName].clicks;
9639 if (!moduleClicks) { return; }
9640 Object.keys(moduleClicks).forEach(function (clickSelector) {
9641 var matchingClickedElement = $clickedEl.closest(clickSelector).eq(0);
9642 if (matchingClickedElement.length > 0) {
9643 moduleClicks[clickSelector].call(app, matchingClickedElement, matchingClickedElement.dataset(), e);
9644 }
9645 });
9646 });
9647
9648
9649 // Load Page
9650 var clickedLinkData = {};
9651 if (isLink) {
9652 e.preventDefault();
9653 clickedLinkData = $clickedLinkEl.dataset();
9654 }
9655
9656 // Prevent Router
9657 if ($clickedLinkEl.hasClass('prevent-router') || $clickedLinkEl.hasClass('router-prevent')) { return; }
9658
9659 var validUrl = url && url.length > 0 && url !== '#' && !isTabLink;
9660 if (validUrl || $clickedLinkEl.hasClass('back')) {
9661 var view;
9662 if (clickedLinkData.view) {
9663 view = $(clickedLinkData.view)[0].f7View;
9664 } else {
9665 view = $clickedEl.parents('.view')[0] && $clickedEl.parents('.view')[0].f7View;
9666 if (!$clickedLinkEl.hasClass('back') && view && view.params.linksView) {
9667 if (typeof view.params.linksView === 'string') { view = $(view.params.linksView)[0].f7View; }
9668 else if (view.params.linksView instanceof View) { view = view.params.linksView; }
9669 }
9670 }
9671 if (!view) {
9672 if (app.views.main) { view = app.views.main; }
9673 }
9674 if (!view || !view.router) { return; }
9675 if (clickedLinkData.context && typeof clickedLinkData.context === 'string') {
9676 try {
9677 clickedLinkData.context = JSON.parse(clickedLinkData.context);
9678 } catch (err) {
9679 // something wrong there
9680 }
9681 }
9682 if ($clickedLinkEl[0].f7RouteProps) {
9683 clickedLinkData.props = $clickedLinkEl[0].f7RouteProps;
9684 }
9685 if ($clickedLinkEl.hasClass('back')) { view.router.back(url, clickedLinkData); }
9686 else { view.router.navigate(url, clickedLinkData); }
9687 }
9688 }
9689
9690 app.on('click', handleClicks);
9691
9692 // TODO: check if need this in iOS
9693 // Prevent scrolling on overlays
9694 // function preventScrolling(e) {
9695 // e.preventDefault();
9696 // }
9697 // if (Support.touch && !Device.android) {
9698 // const activeListener = Support.passiveListener ? { passive: false, capture: false } : false;
9699 // $(document).on((app.params.touch.fastClicks ? 'touchstart' : 'touchmove'), '.panel-backdrop, .dialog-backdrop, .preloader-backdrop, .popup-backdrop, .searchbar-backdrop', preventScrolling, activeListener);
9700 // }
9701 }
9702 var ClicksModule = {
9703 name: 'clicks',
9704 params: {
9705 clicks: {
9706 // External Links
9707 externalLinks: '.external',
9708 },
9709 },
9710 on: {
9711 init: function init() {
9712 var app = this;
9713 initClicks(app);
9714 },
9715 },
9716 };
9717
9718 var RouterTemplateLoaderModule = {
9719 name: 'routerTemplateLoader',
9720 proto: {
9721 templateLoader: function templateLoader(template, templateUrl, options, resolve, reject) {
9722 var router = this;
9723 function compile(t) {
9724 var compiledHtml;
9725 var context;
9726 try {
9727 context = options.context || {};
9728 if (typeof context === 'function') { context = context.call(router); }
9729 else if (typeof context === 'string') {
9730 try {
9731 context = JSON.parse(context);
9732 } catch (err) {
9733 reject();
9734 throw (err);
9735 }
9736 }
9737 if (typeof t === 'function') {
9738 compiledHtml = t(context);
9739 } else {
9740 compiledHtml = Template7.compile(t)(Utils.extend({}, context || {}, {
9741 $app: router.app,
9742 $root: Utils.extend({}, router.app.data, router.app.methods),
9743 $route: options.route,
9744 $f7route: options.route,
9745 $router: router,
9746 $f7router: router,
9747 $theme: {
9748 ios: router.app.theme === 'ios',
9749 md: router.app.theme === 'md',
9750 },
9751 }));
9752 }
9753 } catch (err) {
9754 reject();
9755 throw (err);
9756 }
9757 resolve(compiledHtml, { context: context });
9758 }
9759 if (templateUrl) {
9760 // Load via XHR
9761 if (router.xhr) {
9762 router.xhr.abort();
9763 router.xhr = false;
9764 }
9765 router
9766 .xhrRequest(templateUrl, options)
9767 .then(function (templateContent) {
9768 compile(templateContent);
9769 })
9770 .catch(function () {
9771 reject();
9772 });
9773 } else {
9774 compile(template);
9775 }
9776 },
9777
9778 modalTemplateLoader: function modalTemplateLoader(template, templateUrl, options, resolve, reject) {
9779 var router = this;
9780 return router.templateLoader(template, templateUrl, options, function (html) {
9781 resolve(html);
9782 }, reject);
9783 },
9784
9785 tabTemplateLoader: function tabTemplateLoader(template, templateUrl, options, resolve, reject) {
9786 var router = this;
9787 return router.templateLoader(template, templateUrl, options, function (html) {
9788 resolve(html);
9789 }, reject);
9790 },
9791
9792 pageTemplateLoader: function pageTemplateLoader(template, templateUrl, options, resolve, reject) {
9793 var router = this;
9794 return router.templateLoader(template, templateUrl, options, function (html, newOptions) {
9795 if ( newOptions === void 0 ) newOptions = {};
9796
9797 resolve(router.getPageEl(html), newOptions);
9798 }, reject);
9799 },
9800 },
9801 };
9802
9803 var RouterComponentLoaderModule = {
9804 name: 'routerComponentLoader',
9805 proto: {
9806 componentLoader: function componentLoader(component, componentUrl, options, resolve, reject) {
9807 if ( options === void 0 ) options = {};
9808
9809 var router = this;
9810 var app = router.app;
9811 var url = typeof component === 'string' ? component : componentUrl;
9812 var compiledUrl = router.replaceRequestUrlParams(url, options);
9813 function compile(componentOptions) {
9814 var context = options.context || {};
9815 if (typeof context === 'function') { context = context.call(router); }
9816 else if (typeof context === 'string') {
9817 try {
9818 context = JSON.parse(context);
9819 } catch (err) {
9820 reject();
9821 throw (err);
9822 }
9823 }
9824 var extendContext = Utils.merge(
9825 {},
9826 context,
9827 {
9828 $route: options.route,
9829 $f7route: options.route,
9830 $router: router,
9831 $f7router: router,
9832 $theme: {
9833 ios: app.theme === 'ios',
9834 md: app.theme === 'md',
9835 },
9836 }
9837 );
9838 var createdComponent = app.component.create(componentOptions, extendContext);
9839 resolve(createdComponent.el);
9840 }
9841 var cachedComponent;
9842 if (compiledUrl) {
9843 router.cache.components.forEach(function (cached) {
9844 if (cached.url === compiledUrl) { cachedComponent = cached.component; }
9845 });
9846 }
9847 if (compiledUrl && cachedComponent) {
9848 compile(cachedComponent);
9849 } else if (compiledUrl && !cachedComponent) {
9850 // Load via XHR
9851 if (router.xhr) {
9852 router.xhr.abort();
9853 router.xhr = false;
9854 }
9855 router
9856 .xhrRequest(url, options)
9857 .then(function (loadedComponent) {
9858 var parsedComponent = app.component.parse(loadedComponent);
9859 router.cache.components.push({
9860 url: compiledUrl,
9861 component: parsedComponent,
9862 });
9863 compile(parsedComponent);
9864 })
9865 .catch(function (err) {
9866 reject();
9867 throw (err);
9868 });
9869 } else {
9870 compile(component);
9871 }
9872 },
9873
9874 modalComponentLoader: function modalComponentLoader(rootEl, component, componentUrl, options, resolve, reject) {
9875 var router = this;
9876 router.componentLoader(component, componentUrl, options, function (el) {
9877 resolve(el);
9878 }, reject);
9879 },
9880
9881 tabComponentLoader: function tabComponentLoader(tabEl, component, componentUrl, options, resolve, reject) {
9882 var router = this;
9883 router.componentLoader(component, componentUrl, options, function (el) {
9884 resolve(el);
9885 }, reject);
9886 },
9887
9888 pageComponentLoader: function pageComponentLoader(routerEl, component, componentUrl, options, resolve, reject) {
9889 var router = this;
9890 router.componentLoader(component, componentUrl, options, function (el, newOptions) {
9891 if ( newOptions === void 0 ) newOptions = {};
9892
9893 resolve(el, newOptions);
9894 }, reject);
9895 },
9896 },
9897 };
9898
9899 var HistoryModule = {
9900 name: 'history',
9901 static: {
9902 history: History,
9903 },
9904 on: {
9905 init: function init() {
9906 History.init(this);
9907 },
9908 },
9909 };
9910
9911 var keyPrefix = 'f7storage-';
9912 var Storage = {
9913 get: function get(key) {
9914 return new Promise(function (resolve, reject) {
9915 try {
9916 var value = JSON.parse(win.localStorage.getItem(("" + keyPrefix + key)));
9917 resolve(value);
9918 } catch (e) {
9919 reject(e);
9920 }
9921 });
9922 },
9923 set: function set(key, value) {
9924 return new Promise(function (resolve, reject) {
9925 try {
9926 win.localStorage.setItem(("" + keyPrefix + key), JSON.stringify(value));
9927 resolve();
9928 } catch (e) {
9929 reject(e);
9930 }
9931 });
9932 },
9933 remove: function remove(key) {
9934 return new Promise(function (resolve, reject) {
9935 try {
9936 win.localStorage.removeItem(("" + keyPrefix + key));
9937 resolve();
9938 } catch (e) {
9939 reject(e);
9940 }
9941 });
9942 },
9943 clear: function clear() {
9944
9945 },
9946 length: function length() {
9947
9948 },
9949 keys: function keys() {
9950 return new Promise(function (resolve, reject) {
9951 try {
9952 var keys = Object.keys(win.localStorage)
9953 .filter(function (keyName) { return keyName.indexOf(keyPrefix) === 0; })
9954 .map(function (keyName) { return keyName.replace(keyPrefix, ''); });
9955 resolve(keys);
9956 } catch (e) {
9957 reject(e);
9958 }
9959 });
9960 },
9961 forEach: function forEach(callback) {
9962 return new Promise(function (resolve, reject) {
9963 try {
9964 Object.keys(win.localStorage)
9965 .filter(function (keyName) { return keyName.indexOf(keyPrefix) === 0; })
9966 .forEach(function (keyName, index) {
9967 var key = keyName.replace(keyPrefix, '');
9968 Storage.get(key).then(function (value) {
9969 callback(key, value, index);
9970 });
9971 });
9972 resolve();
9973 } catch (e) {
9974 reject(e);
9975 }
9976 });
9977 },
9978 };
9979
9980 var StorageModule = {
9981 name: 'storage',
9982 static: {
9983 Storage: Storage,
9984 storage: Storage,
9985 },
9986 };
9987
9988 function vnode(sel, data, children, text, elm) {
9989 var key = data === undefined ? undefined : data.key;
9990 return { sel: sel, data: data, children: children,
9991 text: text, elm: elm, key: key };
9992 }
9993
9994 var array = Array.isArray;
9995 function primitive(s) {
9996 return typeof s === 'string' || typeof s === 'number';
9997 }
9998
9999 function addNS(data, children, sel) {
10000 data.ns = 'http://www.w3.org/2000/svg';
10001 if (sel !== 'foreignObject' && children !== undefined) {
10002 for (var i = 0; i < children.length; ++i) {
10003 var childData = children[i].data;
10004 if (childData !== undefined) {
10005 addNS(childData, children[i].children, children[i].sel);
10006 }
10007 }
10008 }
10009 }
10010 function h(sel, b, c) {
10011 var data = {}, children, text, i;
10012 if (c !== undefined) {
10013 data = b;
10014 if (array(c)) {
10015 children = c;
10016 }
10017 else if (primitive(c)) {
10018 text = c;
10019 }
10020 else if (c && c.sel) {
10021 children = [c];
10022 }
10023 }
10024 else if (b !== undefined) {
10025 if (array(b)) {
10026 children = b;
10027 }
10028 else if (primitive(b)) {
10029 text = b;
10030 }
10031 else if (b && b.sel) {
10032 children = [b];
10033 }
10034 else {
10035 data = b;
10036 }
10037 }
10038 if (array(children)) {
10039 for (i = 0; i < children.length; ++i) {
10040 if (primitive(children[i]))
10041 { children[i] = vnode(undefined, undefined, undefined, children[i], undefined); }
10042 }
10043 }
10044 if (sel[0] === 's' && sel[1] === 'v' && sel[2] === 'g' &&
10045 (sel.length === 3 || sel[3] === '.' || sel[3] === '#')) {
10046 addNS(data, children, sel);
10047 }
10048 return vnode(sel, data, children, text, undefined);
10049 }
10050
10051 /* eslint no-use-before-define: "off" */
10052
10053 var selfClosing = 'area base br col command embed hr img input keygen link menuitem meta param source track wbr'.split(' ');
10054 var propsAttrs = 'hidden checked disabled readonly selected autocomplete autofocus autoplay required multiple value'.split(' ');
10055 var booleanProps = 'hidden checked disabled readonly selected autocomplete autofocus autoplay required multiple readOnly'.split(' ');
10056 var tempDom = doc.createElement('div');
10057
10058 function getHooks(data, app, initial, isRoot) {
10059 var hooks = {};
10060 if (!data || !data.attrs || !data.attrs.class) { return hooks; }
10061 var classNames = data.attrs.class;
10062 var insert = [];
10063 var destroy = [];
10064 var update = [];
10065 var postpatch = [];
10066 classNames.split(' ').forEach(function (className) {
10067 if (!initial) {
10068 insert.push.apply(insert, app.getVnodeHooks('insert', className));
10069 }
10070 destroy.push.apply(destroy, app.getVnodeHooks('destroy', className));
10071 update.push.apply(update, app.getVnodeHooks('update', className));
10072 postpatch.push.apply(postpatch, app.getVnodeHooks('postpatch', className));
10073 });
10074
10075 if (isRoot && !initial) {
10076 postpatch.push(function (oldVnode, vnode) {
10077 var vn = vnode || oldVnode;
10078 if (!vn) { return; }
10079 if (vn.data && vn.data.context && vn.data.context.$options.updated) {
10080 vn.data.context.$options.updated();
10081 }
10082 });
10083 }
10084 if (insert.length === 0 && destroy.length === 0 && update.length === 0 && postpatch.length === 0) {
10085 return hooks;
10086 }
10087 if (insert.length) {
10088 hooks.insert = function (vnode) {
10089 insert.forEach(function (f) { return f(vnode); });
10090 };
10091 }
10092 if (destroy.length) {
10093 hooks.destroy = function (vnode) {
10094 destroy.forEach(function (f) { return f(vnode); });
10095 };
10096 }
10097 if (update.length) {
10098 hooks.update = function (oldVnode, vnode) {
10099 update.forEach(function (f) { return f(oldVnode, vnode); });
10100 };
10101 }
10102 if (postpatch.length) {
10103 hooks.postpatch = function (oldVnode, vnode) {
10104 postpatch.forEach(function (f) { return f(oldVnode, vnode); });
10105 };
10106 }
10107
10108 return hooks;
10109 }
10110 function getEventHandler(handlerString, context, ref) {
10111 if ( ref === void 0 ) ref = {};
10112 var stop = ref.stop;
10113 var prevent = ref.prevent;
10114 var once = ref.once;
10115
10116 var fired = false;
10117
10118 var methodName;
10119 var method;
10120 var customArgs = [];
10121 var needMethodBind = true;
10122
10123 if (handlerString.indexOf('(') < 0) {
10124 methodName = handlerString;
10125 } else {
10126 methodName = handlerString.split('(')[0];
10127 }
10128 if (methodName.indexOf('.') >= 0) {
10129 methodName.split('.').forEach(function (path, pathIndex) {
10130 if (pathIndex === 0 && path === 'this') { return; }
10131 if (pathIndex === 0 && path === 'window') {
10132 // eslint-disable-next-line
10133 method = win;
10134 needMethodBind = false;
10135 return;
10136 }
10137 if (!method) { method = context; }
10138 if (method[path]) { method = method[path]; }
10139 else {
10140 throw new Error(("Framework7: Component doesn't have method \"" + (methodName.split('.').slice(0, pathIndex + 1).join('.')) + "\""));
10141 }
10142 });
10143 } else {
10144 if (!context[methodName]) {
10145 throw new Error(("Framework7: Component doesn't have method \"" + methodName + "\""));
10146 }
10147 method = context[methodName];
10148 }
10149 if (needMethodBind) {
10150 method = method.bind(context);
10151 }
10152
10153 function handler() {
10154 var args = [], len = arguments.length;
10155 while ( len-- ) args[ len ] = arguments[ len ];
10156
10157 var e = args[0];
10158 if (once && fired) { return; }
10159 if (stop) { e.stopPropagation(); }
10160 if (prevent) { e.preventDefault(); }
10161 fired = true;
10162
10163 if (handlerString.indexOf('(') < 0) {
10164 customArgs = args;
10165 } else {
10166 handlerString.split('(')[1].split(')')[0].split(',').forEach(function (argument) {
10167 var arg = argument.trim();
10168 // eslint-disable-next-line
10169 if (!isNaN(arg)) { arg = parseFloat(arg); }
10170 else if (arg === 'true') { arg = true; }
10171 else if (arg === 'false') { arg = false; }
10172 else if (arg === 'null') { arg = null; }
10173 else if (arg === 'undefined') { arg = undefined; }
10174 else if (arg[0] === '"') { arg = arg.replace(/"/g, ''); }
10175 else if (arg[0] === '\'') { arg = arg.replace(/'/g, ''); }
10176 else if (arg.indexOf('.') > 0) {
10177 var deepArg;
10178 arg.split('.').forEach(function (path) {
10179 if (!deepArg) { deepArg = context; }
10180 deepArg = deepArg[path];
10181 });
10182 arg = deepArg;
10183 } else {
10184 arg = context[arg];
10185 }
10186 customArgs.push(arg);
10187 });
10188 }
10189
10190 method.apply(void 0, customArgs);
10191 }
10192
10193 return handler;
10194 }
10195
10196 function getData(el, context, app, initial, isRoot) {
10197 var data = {
10198 context: context,
10199 };
10200 var attributes = el.attributes;
10201 Array.prototype.forEach.call(attributes, function (attr) {
10202 var attrName = attr.name;
10203 var attrValue = attr.value;
10204 if (propsAttrs.indexOf(attrName) >= 0) {
10205 // Props
10206 if (!data.props) { data.props = {}; }
10207 if (attrName === 'readonly') {
10208 attrName = 'readOnly';
10209 }
10210 if (booleanProps.indexOf(attrName) >= 0) {
10211 // eslint-disable-next-line
10212 data.props[attrName] = attrValue === false ? false : true;
10213 } else {
10214 data.props[attrName] = attrValue;
10215 }
10216 } else if (attrName === 'key') {
10217 // Key
10218 data.key = attrValue;
10219 } else if (attrName.indexOf('@') === 0) {
10220 // Events
10221 if (!data.on) { data.on = {}; }
10222 var eventName = attrName.substr(1);
10223 var stop = false;
10224 var prevent = false;
10225 var once = false;
10226 if (eventName.indexOf('.') >= 0) {
10227 eventName.split('.').forEach(function (eventNamePart, eventNameIndex) {
10228 if (eventNameIndex === 0) { eventName = eventNamePart; }
10229 else {
10230 if (eventNamePart === 'stop') { stop = true; }
10231 if (eventNamePart === 'prevent') { prevent = true; }
10232 if (eventNamePart === 'once') { once = true; }
10233 }
10234 });
10235 }
10236 data.on[eventName] = getEventHandler(attrValue, context, { stop: stop, prevent: prevent, once: once });
10237 } else if (attrName === 'style') {
10238 // Style
10239 if (attrValue.indexOf('{') >= 0 && attrValue.indexOf('}') >= 0) {
10240 try {
10241 data.style = JSON.parse(attrValue);
10242 } catch (e) {
10243 if (!data.attrs) { data.attrs = {}; }
10244 data.attrs.style = attrValue;
10245 }
10246 } else {
10247 if (!data.attrs) { data.attrs = {}; }
10248 data.attrs.style = attrValue;
10249 }
10250 } else {
10251 // Rest of attribures
10252 if (!data.attrs) { data.attrs = {}; }
10253 data.attrs[attrName] = attrValue;
10254
10255 // ID -> Key
10256 if (attrName === 'id' && !data.key && !isRoot) {
10257 data.key = attrValue;
10258 }
10259 }
10260 });
10261 var hooks = getHooks(data, app, initial, isRoot);
10262 hooks.prepatch = function (oldVnode, vnode) {
10263 if (!oldVnode || !vnode) { return; }
10264 if (oldVnode && oldVnode.data && oldVnode.data.props) {
10265 Object.keys(oldVnode.data.props).forEach(function (key) {
10266 if (booleanProps.indexOf(key) < 0) { return; }
10267 if (!vnode.data) { vnode.data = {}; }
10268 if (!vnode.data.props) { vnode.data.props = {}; }
10269 if (oldVnode.data.props[key] === true && !(key in vnode.data.props)) {
10270 vnode.data.props[key] = false;
10271 }
10272 });
10273 }
10274 };
10275 if (hooks) {
10276 data.hook = hooks;
10277 }
10278 return data;
10279 }
10280
10281 function getChildren(el, context, app, initial) {
10282 var children = [];
10283 var nodes = el.childNodes;
10284 for (var i = 0; i < nodes.length; i += 1) {
10285 var childNode = nodes[i];
10286 var child = elementToVNode(childNode, context, app, initial);
10287 if (child) {
10288 children.push(child);
10289 }
10290 }
10291 return children;
10292 }
10293
10294 function elementToVNode(el, context, app, initial, isRoot) {
10295 if (el.nodeType === 1) {
10296 // element
10297 var tagName = el.nodeName.toLowerCase();
10298 return h(
10299 tagName,
10300 getData(el, context, app, initial, isRoot),
10301 selfClosing.indexOf(tagName) >= 0 ? [] : getChildren(el, context, app, initial)
10302 );
10303 }
10304 if (el.nodeType === 3) {
10305 // text
10306 return el.textContent;
10307 }
10308 return null;
10309 }
10310
10311 function vdom (html, context, app, initial) {
10312 if ( html === void 0 ) html = '';
10313
10314 // Save to temp dom
10315 tempDom.innerHTML = html.trim();
10316
10317 // Parse DOM
10318 var rootEl;
10319 for (var i = 0; i < tempDom.childNodes.length; i += 1) {
10320 if (!rootEl && tempDom.childNodes[i].nodeType === 1) {
10321 rootEl = tempDom.childNodes[i];
10322 }
10323 }
10324 var result = elementToVNode(rootEl, context, app, initial, true);
10325
10326 // Clean
10327 tempDom.innerHTML = '';
10328
10329 return result;
10330 }
10331
10332 function createElement(tagName) {
10333 return document.createElement(tagName);
10334 }
10335 function createElementNS(namespaceURI, qualifiedName) {
10336 return document.createElementNS(namespaceURI, qualifiedName);
10337 }
10338 function createTextNode(text) {
10339 return document.createTextNode(text);
10340 }
10341 function createComment(text) {
10342 return document.createComment(text);
10343 }
10344 function insertBefore$1(parentNode, newNode, referenceNode) {
10345 parentNode.insertBefore(newNode, referenceNode);
10346 }
10347 function removeChild(node, child) {
10348 if (!node) { return; }
10349 node.removeChild(child);
10350 }
10351 function appendChild(node, child) {
10352 node.appendChild(child);
10353 }
10354 function parentNode(node) {
10355 return node.parentNode;
10356 }
10357 function nextSibling(node) {
10358 return node.nextSibling;
10359 }
10360 function tagName(elm) {
10361 return elm.tagName;
10362 }
10363 function setTextContent(node, text) {
10364 node.textContent = text;
10365 }
10366 function getTextContent(node) {
10367 return node.textContent;
10368 }
10369 function isElement(node) {
10370 return node.nodeType === 1;
10371 }
10372 function isText(node) {
10373 return node.nodeType === 3;
10374 }
10375 function isComment(node) {
10376 return node.nodeType === 8;
10377 }
10378 var htmlDomApi = {
10379 createElement: createElement,
10380 createElementNS: createElementNS,
10381 createTextNode: createTextNode,
10382 createComment: createComment,
10383 insertBefore: insertBefore$1,
10384 removeChild: removeChild,
10385 appendChild: appendChild,
10386 parentNode: parentNode,
10387 nextSibling: nextSibling,
10388 tagName: tagName,
10389 setTextContent: setTextContent,
10390 getTextContent: getTextContent,
10391 isElement: isElement,
10392 isText: isText,
10393 isComment: isComment,
10394 };
10395
10396 function isUndef(s) { return s === undefined; }
10397 function isDef(s) { return s !== undefined; }
10398 var emptyNode = vnode('', {}, [], undefined, undefined);
10399 function sameVnode(vnode1, vnode2) {
10400 return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;
10401 }
10402 function isVnode(vnode$$1) {
10403 return vnode$$1.sel !== undefined;
10404 }
10405 function createKeyToOldIdx(children, beginIdx, endIdx) {
10406 var i, map = {}, key, ch;
10407 for (i = beginIdx; i <= endIdx; ++i) {
10408 ch = children[i];
10409 if (ch != null) {
10410 key = ch.key;
10411 if (key !== undefined)
10412 { map[key] = i; }
10413 }
10414 }
10415 return map;
10416 }
10417 var hooks = ['create', 'update', 'remove', 'destroy', 'pre', 'post'];
10418 function init$1(modules, domApi) {
10419 var i, j, cbs = {};
10420 var api = domApi !== undefined ? domApi : htmlDomApi;
10421 for (i = 0; i < hooks.length; ++i) {
10422 cbs[hooks[i]] = [];
10423 for (j = 0; j < modules.length; ++j) {
10424 var hook = modules[j][hooks[i]];
10425 if (hook !== undefined) {
10426 cbs[hooks[i]].push(hook);
10427 }
10428 }
10429 }
10430 function emptyNodeAt(elm) {
10431 var id = elm.id ? '#' + elm.id : '';
10432 var c = elm.className ? '.' + elm.className.split(' ').join('.') : '';
10433 return vnode(api.tagName(elm).toLowerCase() + id + c, {}, [], undefined, elm);
10434 }
10435 function createRmCb(childElm, listeners) {
10436 return function rmCb() {
10437 if (--listeners === 0) {
10438 var parent_1 = api.parentNode(childElm);
10439 api.removeChild(parent_1, childElm);
10440 }
10441 };
10442 }
10443 function createElm(vnode$$1, insertedVnodeQueue) {
10444 var i, data = vnode$$1.data;
10445 if (data !== undefined) {
10446 if (isDef(i = data.hook) && isDef(i = i.init)) {
10447 i(vnode$$1);
10448 data = vnode$$1.data;
10449 }
10450 }
10451 var children = vnode$$1.children, sel = vnode$$1.sel;
10452 if (sel === '!') {
10453 if (isUndef(vnode$$1.text)) {
10454 vnode$$1.text = '';
10455 }
10456 vnode$$1.elm = api.createComment(vnode$$1.text);
10457 }
10458 else if (sel !== undefined) {
10459 // Parse selector
10460 var hashIdx = sel.indexOf('#');
10461 var dotIdx = sel.indexOf('.', hashIdx);
10462 var hash = hashIdx > 0 ? hashIdx : sel.length;
10463 var dot = dotIdx > 0 ? dotIdx : sel.length;
10464 var tag = hashIdx !== -1 || dotIdx !== -1 ? sel.slice(0, Math.min(hash, dot)) : sel;
10465 var elm = vnode$$1.elm = isDef(data) && isDef(i = data.ns) ? api.createElementNS(i, tag)
10466 : api.createElement(tag);
10467 if (hash < dot)
10468 { elm.setAttribute('id', sel.slice(hash + 1, dot)); }
10469 if (dotIdx > 0)
10470 { elm.setAttribute('class', sel.slice(dot + 1).replace(/\./g, ' ')); }
10471 for (i = 0; i < cbs.create.length; ++i)
10472 { cbs.create[i](emptyNode, vnode$$1); }
10473 if (array(children)) {
10474 for (i = 0; i < children.length; ++i) {
10475 var ch = children[i];
10476 if (ch != null) {
10477 api.appendChild(elm, createElm(ch, insertedVnodeQueue));
10478 }
10479 }
10480 }
10481 else if (primitive(vnode$$1.text)) {
10482 api.appendChild(elm, api.createTextNode(vnode$$1.text));
10483 }
10484 i = vnode$$1.data.hook; // Reuse variable
10485 if (isDef(i)) {
10486 if (i.create)
10487 { i.create(emptyNode, vnode$$1); }
10488 if (i.insert)
10489 { insertedVnodeQueue.push(vnode$$1); }
10490 }
10491 }
10492 else {
10493 vnode$$1.elm = api.createTextNode(vnode$$1.text);
10494 }
10495 return vnode$$1.elm;
10496 }
10497 function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
10498 for (; startIdx <= endIdx; ++startIdx) {
10499 var ch = vnodes[startIdx];
10500 if (ch != null) {
10501 api.insertBefore(parentElm, createElm(ch, insertedVnodeQueue), before);
10502 }
10503 }
10504 }
10505 function invokeDestroyHook(vnode$$1) {
10506 var i, j, data = vnode$$1.data;
10507 if (data !== undefined) {
10508 if (isDef(i = data.hook) && isDef(i = i.destroy))
10509 { i(vnode$$1); }
10510 for (i = 0; i < cbs.destroy.length; ++i)
10511 { cbs.destroy[i](vnode$$1); }
10512 if (vnode$$1.children !== undefined) {
10513 for (j = 0; j < vnode$$1.children.length; ++j) {
10514 i = vnode$$1.children[j];
10515 if (i != null && typeof i !== "string") {
10516 invokeDestroyHook(i);
10517 }
10518 }
10519 }
10520 }
10521 }
10522 function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
10523 for (; startIdx <= endIdx; ++startIdx) {
10524 var i_1 = void 0, listeners = void 0, rm = void 0, ch = vnodes[startIdx];
10525 if (ch != null) {
10526 if (isDef(ch.sel)) {
10527 invokeDestroyHook(ch);
10528 listeners = cbs.remove.length + 1;
10529 rm = createRmCb(ch.elm, listeners);
10530 for (i_1 = 0; i_1 < cbs.remove.length; ++i_1)
10531 { cbs.remove[i_1](ch, rm); }
10532 if (isDef(i_1 = ch.data) && isDef(i_1 = i_1.hook) && isDef(i_1 = i_1.remove)) {
10533 i_1(ch, rm);
10534 }
10535 else {
10536 rm();
10537 }
10538 }
10539 else {
10540 api.removeChild(parentElm, ch.elm);
10541 }
10542 }
10543 }
10544 }
10545 function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {
10546 var oldStartIdx = 0, newStartIdx = 0;
10547 var oldEndIdx = oldCh.length - 1;
10548 var oldStartVnode = oldCh[0];
10549 var oldEndVnode = oldCh[oldEndIdx];
10550 var newEndIdx = newCh.length - 1;
10551 var newStartVnode = newCh[0];
10552 var newEndVnode = newCh[newEndIdx];
10553 var oldKeyToIdx;
10554 var idxInOld;
10555 var elmToMove;
10556 var before;
10557 while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
10558 if (oldStartVnode == null) {
10559 oldStartVnode = oldCh[++oldStartIdx]; // Vnode might have been moved left
10560 }
10561 else if (oldEndVnode == null) {
10562 oldEndVnode = oldCh[--oldEndIdx];
10563 }
10564 else if (newStartVnode == null) {
10565 newStartVnode = newCh[++newStartIdx];
10566 }
10567 else if (newEndVnode == null) {
10568 newEndVnode = newCh[--newEndIdx];
10569 }
10570 else if (sameVnode(oldStartVnode, newStartVnode)) {
10571 patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);
10572 oldStartVnode = oldCh[++oldStartIdx];
10573 newStartVnode = newCh[++newStartIdx];
10574 }
10575 else if (sameVnode(oldEndVnode, newEndVnode)) {
10576 patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);
10577 oldEndVnode = oldCh[--oldEndIdx];
10578 newEndVnode = newCh[--newEndIdx];
10579 }
10580 else if (sameVnode(oldStartVnode, newEndVnode)) {
10581 patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);
10582 api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));
10583 oldStartVnode = oldCh[++oldStartIdx];
10584 newEndVnode = newCh[--newEndIdx];
10585 }
10586 else if (sameVnode(oldEndVnode, newStartVnode)) {
10587 patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);
10588 api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
10589 oldEndVnode = oldCh[--oldEndIdx];
10590 newStartVnode = newCh[++newStartIdx];
10591 }
10592 else {
10593 if (oldKeyToIdx === undefined) {
10594 oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
10595 }
10596 idxInOld = oldKeyToIdx[newStartVnode.key];
10597 if (isUndef(idxInOld)) {
10598 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
10599 newStartVnode = newCh[++newStartIdx];
10600 }
10601 else {
10602 elmToMove = oldCh[idxInOld];
10603 if (elmToMove.sel !== newStartVnode.sel) {
10604 api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
10605 }
10606 else {
10607 patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
10608 oldCh[idxInOld] = undefined;
10609 api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
10610 }
10611 newStartVnode = newCh[++newStartIdx];
10612 }
10613 }
10614 }
10615 if (oldStartIdx <= oldEndIdx || newStartIdx <= newEndIdx) {
10616 if (oldStartIdx > oldEndIdx) {
10617 before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;
10618 addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
10619 }
10620 else {
10621 removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
10622 }
10623 }
10624 }
10625 function patchVnode(oldVnode, vnode$$1, insertedVnodeQueue) {
10626 var i, hook;
10627 if (isDef(i = vnode$$1.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {
10628 i(oldVnode, vnode$$1);
10629 }
10630 var elm = vnode$$1.elm = oldVnode.elm;
10631 var oldCh = oldVnode.children;
10632 var ch = vnode$$1.children;
10633 if (oldVnode === vnode$$1)
10634 { return; }
10635 if (vnode$$1.data !== undefined) {
10636 for (i = 0; i < cbs.update.length; ++i)
10637 { cbs.update[i](oldVnode, vnode$$1); }
10638 i = vnode$$1.data.hook;
10639 if (isDef(i) && isDef(i = i.update))
10640 { i(oldVnode, vnode$$1); }
10641 }
10642 if (isUndef(vnode$$1.text)) {
10643 if (isDef(oldCh) && isDef(ch)) {
10644 if (oldCh !== ch)
10645 { updateChildren(elm, oldCh, ch, insertedVnodeQueue); }
10646 }
10647 else if (isDef(ch)) {
10648 if (isDef(oldVnode.text))
10649 { api.setTextContent(elm, ''); }
10650 addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
10651 }
10652 else if (isDef(oldCh)) {
10653 removeVnodes(elm, oldCh, 0, oldCh.length - 1);
10654 }
10655 else if (isDef(oldVnode.text)) {
10656 api.setTextContent(elm, '');
10657 }
10658 }
10659 else if (oldVnode.text !== vnode$$1.text) {
10660 api.setTextContent(elm, vnode$$1.text);
10661 }
10662 if (isDef(hook) && isDef(i = hook.postpatch)) {
10663 i(oldVnode, vnode$$1);
10664 }
10665 }
10666 return function patch(oldVnode, vnode$$1) {
10667 var i, elm, parent;
10668 var insertedVnodeQueue = [];
10669 for (i = 0; i < cbs.pre.length; ++i)
10670 { cbs.pre[i](); }
10671 if (!isVnode(oldVnode)) {
10672 oldVnode = emptyNodeAt(oldVnode);
10673 }
10674 if (sameVnode(oldVnode, vnode$$1)) {
10675 patchVnode(oldVnode, vnode$$1, insertedVnodeQueue);
10676 }
10677 else {
10678 elm = oldVnode.elm;
10679 parent = api.parentNode(elm);
10680 createElm(vnode$$1, insertedVnodeQueue);
10681 if (parent !== null) {
10682 api.insertBefore(parent, vnode$$1.elm, api.nextSibling(elm));
10683 removeVnodes(parent, [oldVnode], 0, 0);
10684 }
10685 }
10686 for (i = 0; i < insertedVnodeQueue.length; ++i) {
10687 insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]);
10688 }
10689 for (i = 0; i < cbs.post.length; ++i)
10690 { cbs.post[i](); }
10691 return vnode$$1;
10692 };
10693 }
10694
10695 var xlinkNS = 'http://www.w3.org/1999/xlink';
10696 var xmlNS = 'http://www.w3.org/XML/1998/namespace';
10697 var colonChar = 58;
10698 var xChar = 120;
10699 function updateAttrs(oldVnode, vnode) {
10700 var key, elm = vnode.elm, oldAttrs = oldVnode.data.attrs, attrs = vnode.data.attrs;
10701 if (!oldAttrs && !attrs)
10702 { return; }
10703 if (oldAttrs === attrs)
10704 { return; }
10705 oldAttrs = oldAttrs || {};
10706 attrs = attrs || {};
10707 // update modified attributes, add new attributes
10708 for (key in attrs) {
10709 var cur = attrs[key];
10710 var old = oldAttrs[key];
10711 if (old !== cur) {
10712 if (cur === true) {
10713 elm.setAttribute(key, "");
10714 }
10715 else if (cur === false) {
10716 elm.removeAttribute(key);
10717 }
10718 else {
10719 if (key.charCodeAt(0) !== xChar) {
10720 elm.setAttribute(key, cur);
10721 }
10722 else if (key.charCodeAt(3) === colonChar) {
10723 // Assume xml namespace
10724 elm.setAttributeNS(xmlNS, key, cur);
10725 }
10726 else if (key.charCodeAt(5) === colonChar) {
10727 // Assume xlink namespace
10728 elm.setAttributeNS(xlinkNS, key, cur);
10729 }
10730 else {
10731 elm.setAttribute(key, cur);
10732 }
10733 }
10734 }
10735 }
10736 // remove removed attributes
10737 // use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value)
10738 // the other option is to remove all attributes with value == undefined
10739 for (key in oldAttrs) {
10740 if (!(key in attrs)) {
10741 elm.removeAttribute(key);
10742 }
10743 }
10744 }
10745 var attributesModule = { create: updateAttrs, update: updateAttrs };
10746
10747 function updateProps(oldVnode, vnode) {
10748 var key, cur, old, elm = vnode.elm, oldProps = oldVnode.data.props, props = vnode.data.props;
10749 if (!oldProps && !props)
10750 { return; }
10751 if (oldProps === props)
10752 { return; }
10753 oldProps = oldProps || {};
10754 props = props || {};
10755 for (key in oldProps) {
10756 if (!props[key]) {
10757 delete elm[key];
10758 }
10759 }
10760 for (key in props) {
10761 cur = props[key];
10762 old = oldProps[key];
10763 if (old !== cur && (key !== 'value' || elm[key] !== cur)) {
10764 elm[key] = cur;
10765 }
10766 }
10767 }
10768 var propsModule = { create: updateProps, update: updateProps };
10769
10770 var raf = (typeof window !== 'undefined' && window.requestAnimationFrame) || setTimeout;
10771 var nextFrame = function (fn) { raf(function () { raf(fn); }); };
10772 function setNextFrame(obj, prop, val) {
10773 nextFrame(function () { obj[prop] = val; });
10774 }
10775 function updateStyle(oldVnode, vnode) {
10776 var cur, name, elm = vnode.elm, oldStyle = oldVnode.data.style, style = vnode.data.style;
10777 if (!oldStyle && !style)
10778 { return; }
10779 if (oldStyle === style)
10780 { return; }
10781 oldStyle = oldStyle || {};
10782 style = style || {};
10783 var oldHasDel = 'delayed' in oldStyle;
10784 for (name in oldStyle) {
10785 if (!style[name]) {
10786 if (name[0] === '-' && name[1] === '-') {
10787 elm.style.removeProperty(name);
10788 }
10789 else {
10790 elm.style[name] = '';
10791 }
10792 }
10793 }
10794 for (name in style) {
10795 cur = style[name];
10796 if (name === 'delayed' && style.delayed) {
10797 for (var name2 in style.delayed) {
10798 cur = style.delayed[name2];
10799 if (!oldHasDel || cur !== oldStyle.delayed[name2]) {
10800 setNextFrame(elm.style, name2, cur);
10801 }
10802 }
10803 }
10804 else if (name !== 'remove' && cur !== oldStyle[name]) {
10805 if (name[0] === '-' && name[1] === '-') {
10806 elm.style.setProperty(name, cur);
10807 }
10808 else {
10809 elm.style[name] = cur;
10810 }
10811 }
10812 }
10813 }
10814 function applyDestroyStyle(vnode) {
10815 var style, name, elm = vnode.elm, s = vnode.data.style;
10816 if (!s || !(style = s.destroy))
10817 { return; }
10818 for (name in style) {
10819 elm.style[name] = style[name];
10820 }
10821 }
10822 function applyRemoveStyle(vnode, rm) {
10823 var s = vnode.data.style;
10824 if (!s || !s.remove) {
10825 rm();
10826 return;
10827 }
10828 var name, elm = vnode.elm, i = 0, compStyle, style = s.remove, amount = 0, applied = [];
10829 for (name in style) {
10830 applied.push(name);
10831 elm.style[name] = style[name];
10832 }
10833 compStyle = getComputedStyle(elm);
10834 var props = compStyle['transition-property'].split(', ');
10835 for (; i < props.length; ++i) {
10836 if (applied.indexOf(props[i]) !== -1)
10837 { amount++; }
10838 }
10839 elm.addEventListener('transitionend', function (ev) {
10840 if (ev.target === elm)
10841 { --amount; }
10842 if (amount === 0)
10843 { rm(); }
10844 });
10845 }
10846 var styleModule = {
10847 create: updateStyle,
10848 update: updateStyle,
10849 destroy: applyDestroyStyle,
10850 remove: applyRemoveStyle
10851 };
10852
10853 function invokeHandler(handler, event, args) {
10854 if (typeof handler === 'function') {
10855 // call function handler
10856 handler.apply(void 0, [ event ].concat( args ));
10857 }
10858 }
10859 function handleEvent(event, args, vnode) {
10860 var name = event.type;
10861 var on = vnode.data.on;
10862 // call event handler(s) if exists
10863 if (on && on[name]) {
10864 invokeHandler(on[name], event, args, vnode);
10865 }
10866 }
10867 function createListener() {
10868 return function handler(event) {
10869 var args = [], len = arguments.length - 1;
10870 while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
10871
10872 handleEvent(event, args, handler.vnode);
10873 };
10874 }
10875 function updateEvents(oldVnode, vnode) {
10876 var oldOn = oldVnode.data.on;
10877 var oldListener = oldVnode.listener;
10878 var oldElm = oldVnode.elm;
10879 var on = vnode && vnode.data.on;
10880 var elm = (vnode && vnode.elm);
10881 // optimization for reused immutable handlers
10882 if (oldOn === on) {
10883 return;
10884 }
10885 // remove existing listeners which no longer used
10886 if (oldOn && oldListener) {
10887 // if element changed or deleted we remove all existing listeners unconditionally
10888 if (!on) {
10889 Object.keys(oldOn).forEach(function (name) {
10890 $(oldElm).off(name, oldListener);
10891 });
10892 } else {
10893 Object.keys(oldOn).forEach(function (name) {
10894 if (!on[name]) {
10895 $(oldElm).off(name, oldListener);
10896 }
10897 });
10898 }
10899 }
10900 // add new listeners which has not already attached
10901 if (on) {
10902 // reuse existing listener or create new
10903 var listener = oldVnode.listener || createListener();
10904 vnode.listener = listener;
10905 // update vnode for listener
10906 listener.vnode = vnode;
10907 // if element changed or added we add all needed listeners unconditionally
10908 if (!oldOn) {
10909 Object.keys(on).forEach(function (name) {
10910 $(elm).on(name, listener);
10911 });
10912 } else {
10913 Object.keys(on).forEach(function (name) {
10914 if (!oldOn[name]) {
10915 $(elm).on(name, listener);
10916 }
10917 });
10918 }
10919 }
10920 }
10921
10922 var eventListenersModule = {
10923 create: updateEvents,
10924 update: updateEvents,
10925 destroy: updateEvents,
10926 };
10927
10928 /* eslint import/no-named-as-default: off */
10929
10930 var patch = init$1([
10931 attributesModule,
10932 propsModule,
10933 styleModule,
10934 eventListenersModule ]);
10935
10936 var Framework7Component = function Framework7Component(app, options, extendContext) {
10937 if ( extendContext === void 0 ) extendContext = {};
10938
10939 var id = Utils.id();
10940 var self = Utils.merge(
10941 this,
10942 extendContext,
10943 {
10944 $: $,
10945 $$: $,
10946 $dom7: $,
10947 $app: app,
10948 $f7: app,
10949 $options: Utils.extend({ id: id }, options),
10950 }
10951 );
10952 var $options = self.$options;
10953
10954 // Root data and methods
10955 Object.defineProperty(self, '$root', {
10956 enumerable: true,
10957 configurable: true,
10958 get: function get() {
10959 var root = Utils.merge({}, app.data, app.methods);
10960 if (win && win.Proxy) {
10961 root = new win.Proxy(root, {
10962 set: function set(target, name, val) {
10963 app.data[name] = val;
10964 },
10965 deleteProperty: function deleteProperty(target, name) {
10966 delete app.data[name];
10967 delete app.methods[name];
10968 },
10969 has: function has(target, name) {
10970 return (name in app.data || name in app.methods);
10971 },
10972 });
10973 }
10974 return root;
10975 },
10976 set: function set() {},
10977 });
10978
10979 // Apply context
10980 ('beforeCreate created beforeMount mounted beforeDestroy destroyed updated').split(' ').forEach(function (cycleKey) {
10981 if ($options[cycleKey]) { $options[cycleKey] = $options[cycleKey].bind(self); }
10982 });
10983
10984 if ($options.data) {
10985 $options.data = $options.data.bind(self);
10986 // Data
10987 Utils.extend(self, $options.data());
10988 }
10989 if ($options.render) { $options.render = $options.render.bind(self); }
10990 if ($options.methods) {
10991 Object.keys($options.methods).forEach(function (methodName) {
10992 self[methodName] = $options.methods[methodName].bind(self);
10993 });
10994 }
10995
10996 // Bind Events
10997 if ($options.on) {
10998 Object.keys($options.on).forEach(function (eventName) {
10999 $options.on[eventName] = $options.on[eventName].bind(self);
11000 });
11001 }
11002 if ($options.once) {
11003 Object.keys($options.once).forEach(function (eventName) {
11004 $options.once[eventName] = $options.once[eventName].bind(self);
11005 });
11006 }
11007
11008 // Before create hook
11009 if ($options.beforeCreate) { $options.beforeCreate(); }
11010
11011 // Render
11012 var html = self.$render();
11013
11014 // Make Dom
11015 if (html && typeof html === 'string') {
11016 html = html.trim();
11017 self.$vnode = vdom(html, self, app, true);
11018 self.el = doc.createElement('div');
11019 patch(self.el, self.$vnode);
11020 } else if (html) {
11021 self.el = html;
11022 }
11023 self.$el = $(self.el);
11024
11025 // Set styles scope ID
11026 if ($options.style) {
11027 self.$styleEl = doc.createElement('style');
11028 self.$styleEl.innerHTML = $options.style;
11029 if ($options.styleScoped) {
11030 self.el.setAttribute(("data-f7-" + ($options.id)), '');
11031 }
11032 }
11033
11034 self.$attachEvents();
11035
11036 // Created callback
11037 if ($options.created) { $options.created(); }
11038
11039 // Store component instance
11040 self.el.f7Component = self;
11041
11042 return self;
11043 };
11044
11045 Framework7Component.prototype.$attachEvents = function $attachEvents () {
11046 var self = this;
11047 var $options = self.$options;
11048 var $el = self.$el;
11049 if ($options.on) {
11050 Object.keys($options.on).forEach(function (eventName) {
11051 $el.on(Utils.eventNameToColonCase(eventName), $options.on[eventName]);
11052 });
11053 }
11054 if ($options.once) {
11055 Object.keys($options.once).forEach(function (eventName) {
11056 $el.once(Utils.eventNameToColonCase(eventName), $options.once[eventName]);
11057 });
11058 }
11059 };
11060
11061 Framework7Component.prototype.$detachEvents = function $detachEvents () {
11062 var self = this;
11063 var $options = self.$options;
11064 var $el = self.$el;
11065 if ($options.on) {
11066 Object.keys($options.on).forEach(function (eventName) {
11067 $el.off(Utils.eventNameToColonCase(eventName), $options.on[eventName]);
11068 });
11069 }
11070 if ($options.once) {
11071 Object.keys($options.once).forEach(function (eventName) {
11072 $el.off(Utils.eventNameToColonCase(eventName), $options.once[eventName]);
11073 });
11074 }
11075 };
11076
11077 Framework7Component.prototype.$render = function $render () {
11078 var self = this;
11079 var $options = self.$options;
11080 var html = '';
11081 if ($options.render) {
11082 html = $options.render();
11083 } else if ($options.template) {
11084 if (typeof $options.template === 'string') {
11085 try {
11086 html = Template7.compile($options.template)(self);
11087 } catch (err) {
11088 throw err;
11089 }
11090 } else {
11091 // Supposed to be function
11092 html = $options.template(self);
11093 }
11094 }
11095 return html;
11096 };
11097
11098 Framework7Component.prototype.$forceUpdate = function $forceUpdate () {
11099 var self = this;
11100 var html = self.$render();
11101
11102 // Make Dom
11103 if (html && typeof html === 'string') {
11104 html = html.trim();
11105 var newVNode = vdom(html, self, self.$app);
11106 self.$vnode = patch(self.$vnode, newVNode);
11107 }
11108 };
11109
11110 Framework7Component.prototype.$setState = function $setState (mergeState) {
11111 var self = this;
11112 Utils.merge(self, mergeState);
11113 self.$forceUpdate();
11114 };
11115
11116 Framework7Component.prototype.$mount = function $mount (mountMethod) {
11117 var self = this;
11118 if (self.$options.beforeMount) { self.$options.beforeMount(); }
11119 if (self.$styleEl) { $('head').append(self.$styleEl); }
11120 if (mountMethod) { mountMethod(self.el); }
11121 if (self.$options.mounted) { self.$options.mounted(); }
11122 };
11123
11124 Framework7Component.prototype.$destroy = function $destroy () {
11125 var self = this;
11126 if (self.$options.beforeDestroy) { self.$options.beforeDestroy(); }
11127 if (self.$styleEl) { $(self.$styleEl).remove(); }
11128 self.$detachEvents();
11129 if (self.$options.destroyed) { self.$options.destroyed(); }
11130 // Delete component instance
11131 if (self.el && self.el.f7Component) {
11132 self.el.f7Component = null;
11133 delete self.el.f7Component;
11134 }
11135 // Patch with empty node
11136 if (self.$vnode) {
11137 self.$vnode = patch(self.$vnode, { sel: self.$vnode.sel, data: {} });
11138 }
11139 Utils.deleteProps(self);
11140 };
11141
11142 function parseComponent(componentString) {
11143 var id = Utils.id();
11144 var callbackCreateName = "f7_component_create_callback_" + id;
11145 var callbackRenderName = "f7_component_render_callback_" + id;
11146
11147 // Template
11148 var template;
11149 var hasTemplate = componentString.match(/<template([ ]?)([a-z0-9-]*)>/);
11150 var templateType = hasTemplate[2] || 't7';
11151 if (hasTemplate) {
11152 template = componentString
11153 .split(/<template[ ]?[a-z0-9-]*>/)
11154 .filter(function (item, index) { return index > 0; })
11155 .join('<template>')
11156 .split('</template>')
11157 .filter(function (item, index, arr) { return index < arr.length - 1; })
11158 .join('</template>')
11159 .replace(/{{#raw}}([ \n]*)<template/g, '{{#raw}}<template')
11160 .replace(/\/template>([ \n]*){{\/raw}}/g, '/template>{{/raw}}')
11161 .replace(/([ \n])<template/g, '$1{{#raw}}<template')
11162 .replace(/\/template>([ \n])/g, '/template>{{/raw}}$1');
11163 }
11164
11165 // Parse Styles
11166 var style = null;
11167 var styleScoped = false;
11168
11169 if (componentString.indexOf('<style>') >= 0) {
11170 style = componentString.split('<style>')[1].split('</style>')[0];
11171 } else if (componentString.indexOf('<style scoped>') >= 0) {
11172 styleScoped = true;
11173 style = componentString.split('<style scoped>')[1].split('</style>')[0];
11174 style = style.split('\n').map(function (line) {
11175 var trimmedLine = line.trim();
11176 if (trimmedLine.indexOf('@') === 0) { return line; }
11177 if (line.indexOf('{') >= 0) {
11178 if (line.indexOf('{{this}}') >= 0) {
11179 return line.replace('{{this}}', ("[data-f7-" + id + "]"));
11180 }
11181 return ("[data-f7-" + id + "] " + (line.trim()));
11182 }
11183 return line;
11184 }).join('\n');
11185 }
11186
11187 // Parse Script
11188 var scriptContent;
11189 var scriptEl;
11190 if (componentString.indexOf('<script>') >= 0) {
11191 var scripts = componentString.split('<script>');
11192 scriptContent = scripts[scripts.length - 1].split('</script>')[0].trim();
11193 } else {
11194 scriptContent = 'return {}';
11195 }
11196 if (!scriptContent || !scriptContent.trim()) { scriptContent = 'return {}'; }
11197
11198 scriptContent = "window." + callbackCreateName + " = function () {" + scriptContent + "}";
11199
11200 // Insert Script El
11201 scriptEl = doc.createElement('script');
11202 scriptEl.innerHTML = scriptContent;
11203 $('head').append(scriptEl);
11204
11205 var component = win[callbackCreateName]();
11206
11207 // Remove Script El
11208 $(scriptEl).remove();
11209 win[callbackCreateName] = null;
11210 delete win[callbackCreateName];
11211
11212 // Assign Template
11213 if (!component.template && !component.render) {
11214 component.template = template;
11215 component.templateType = templateType;
11216 }
11217 if (component.template) {
11218 if (component.templateType === 't7') {
11219 component.template = Template7.compile(component.template);
11220 }
11221 if (component.templateType === 'es') {
11222 var renderContent = "window." + callbackRenderName + " = function () {\n return function render() {\n return `" + (component.template) + "`;\n }\n }";
11223 scriptEl = doc.createElement('script');
11224 scriptEl.innerHTML = renderContent;
11225 $('head').append(scriptEl);
11226
11227 component.render = win[callbackRenderName]();
11228
11229 // Remove Script El
11230 $(scriptEl).remove();
11231 win[callbackRenderName] = null;
11232 delete win[callbackRenderName];
11233 }
11234 }
11235
11236 // Assign Style
11237 if (style) {
11238 component.style = style;
11239 component.styleScoped = styleScoped;
11240 }
11241
11242 // Component ID
11243 component.id = id;
11244 return component;
11245 }
11246
11247 var ComponentModule = {
11248 name: 'component',
11249 create: function create() {
11250 var app = this;
11251 app.component = {
11252 parse: function parse(componentString) {
11253 return parseComponent(componentString);
11254 },
11255 create: function create(options, extendContext) {
11256 return new Framework7Component(app, options, extendContext);
11257 },
11258 };
11259 },
11260 };
11261
11262 var SW = {
11263 registrations: [],
11264 register: function register(path, scope) {
11265 var app = this;
11266 if (!('serviceWorker' in window.navigator) || !app.serviceWorker.container) {
11267 return new Promise(function (resolve, reject) {
11268 reject(new Error('Service worker is not supported'));
11269 });
11270 }
11271 return new Promise(function (resolve, reject) {
11272 app.serviceWorker.container.register(path, (scope ? { scope: scope } : {}))
11273 .then(function (reg) {
11274 SW.registrations.push(reg);
11275 app.emit('serviceWorkerRegisterSuccess', reg);
11276 resolve(reg);
11277 }).catch(function (error) {
11278 app.emit('serviceWorkerRegisterError', error);
11279 reject(error);
11280 });
11281 });
11282 },
11283 unregister: function unregister(registration) {
11284 var app = this;
11285 if (!('serviceWorker' in window.navigator) || !app.serviceWorker.container) {
11286 return new Promise(function (resolve, reject) {
11287 reject(new Error('Service worker is not supported'));
11288 });
11289 }
11290 var registrations;
11291 if (!registration) { registrations = SW.registrations; }
11292 else if (Array.isArray(registration)) { registrations = registration; }
11293 else { registrations = [registration]; }
11294 return Promise.all(registrations.map(function (reg) { return new Promise(function (resolve, reject) {
11295 reg.unregister()
11296 .then(function () {
11297 if (SW.registrations.indexOf(reg) >= 0) {
11298 SW.registrations.splice(SW.registrations.indexOf(reg), 1);
11299 }
11300 app.emit('serviceWorkerUnregisterSuccess', reg);
11301 resolve();
11302 })
11303 .catch(function (error) {
11304 app.emit('serviceWorkerUnregisterError', reg, error);
11305 reject(error);
11306 });
11307 }); }));
11308 },
11309 };
11310
11311 var ServiceWorkerModule = {
11312 name: 'sw',
11313 params: {
11314 serviceWorker: {
11315 path: undefined,
11316 scope: undefined,
11317 },
11318 },
11319 create: function create() {
11320 var app = this;
11321 Utils.extend(app, {
11322 serviceWorker: {
11323 container: ('serviceWorker' in window.navigator) ? window.navigator.serviceWorker : undefined,
11324 registrations: SW.registrations,
11325 register: SW.register.bind(app),
11326 unregister: SW.unregister.bind(app),
11327 },
11328 });
11329 },
11330 on: {
11331 init: function init() {
11332 if (!('serviceWorker' in window.navigator)) { return; }
11333 var app = this;
11334 if (!app.serviceWorker.container) { return; }
11335 var paths = app.params.serviceWorker.path;
11336 var scope = app.params.serviceWorker.scope;
11337 if (!paths || (Array.isArray(paths) && !paths.length)) { return; }
11338 var toRegister = Array.isArray(paths) ? paths : [paths];
11339 toRegister.forEach(function (path) {
11340 app.serviceWorker.register(path, scope);
11341 });
11342 },
11343 },
11344 };
11345
11346 var Statusbar = {
11347 hide: function hide() {
11348 $('html').removeClass('with-statusbar');
11349 if (Device.cordova && win.StatusBar) {
11350 win.StatusBar.hide();
11351 }
11352 },
11353 show: function show() {
11354 if (Device.cordova && win.StatusBar) {
11355 win.StatusBar.show();
11356 Utils.nextTick(function () {
11357 if (Device.needsStatusbarOverlay()) {
11358 $('html').addClass('with-statusbar');
11359 }
11360 });
11361 return;
11362 }
11363 $('html').addClass('with-statusbar');
11364 },
11365 onClick: function onClick() {
11366 var app = this;
11367 var pageContent;
11368 if ($('.popup.modal-in').length > 0) {
11369 // Check for opened popup
11370 pageContent = $('.popup.modal-in').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11371 } else if ($('.panel.panel-active').length > 0) {
11372 // Check for opened panel
11373 pageContent = $('.panel.panel-active').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11374 } else if ($('.views > .view.tab-active').length > 0) {
11375 // View in tab bar app layout
11376 pageContent = $('.views > .view.tab-active').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11377 } else if ($('.views').length > 0) {
11378 pageContent = $('.views').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11379 } else {
11380 pageContent = app.root.children('.view').find('.page:not(.page-previous):not(.page-next):not(.cached)').find('.page-content');
11381 }
11382
11383 if (pageContent && pageContent.length > 0) {
11384 // Check for tab
11385 if (pageContent.hasClass('tab')) {
11386 pageContent = pageContent.parent('.tabs').children('.page-content.tab-active');
11387 }
11388 if (pageContent.length > 0) { pageContent.scrollTop(0, 300); }
11389 }
11390 },
11391 setTextColor: function setTextColor(color) {
11392 if (Device.cordova && win.StatusBar) {
11393 if (color === 'white') {
11394 win.StatusBar.styleLightContent();
11395 } else {
11396 win.StatusBar.styleDefault();
11397 }
11398 }
11399 },
11400 setIosTextColor: function setIosTextColor(color) {
11401 if (!Device.ios) { return; }
11402 Statusbar.setTextColor(color);
11403 },
11404 setBackgroundColor: function setBackgroundColor(color) {
11405 $('.statusbar').css('background-color', color);
11406 if (Device.cordova && win.StatusBar) {
11407 win.StatusBar.backgroundColorByHexString(color);
11408 }
11409 },
11410 isVisible: function isVisible() {
11411 if (Device.cordova && win.StatusBar) {
11412 return win.StatusBar.isVisible;
11413 }
11414 return false;
11415 },
11416 overlaysWebView: function overlaysWebView(overlays) {
11417 if ( overlays === void 0 ) overlays = true;
11418
11419 if (Device.cordova && win.StatusBar) {
11420 win.StatusBar.overlaysWebView(overlays);
11421 if (overlays) {
11422 $('html').addClass('with-statusbar');
11423 } else {
11424 $('html').removeClass('with-statusbar');
11425 }
11426 }
11427 },
11428 checkOverlay: function checkOverlay() {
11429 if (Device.needsStatusbarOverlay()) {
11430 $('html').addClass('with-statusbar');
11431 } else {
11432 $('html').removeClass('with-statusbar');
11433 }
11434 },
11435 init: function init() {
11436 var app = this;
11437 var params = app.params.statusbar;
11438 if (!params.enabled) { return; }
11439
11440 if (params.overlay === 'auto') {
11441 if (Device.needsStatusbarOverlay()) {
11442 $('html').addClass('with-statusbar');
11443 } else {
11444 $('html').removeClass('with-statusbar');
11445 }
11446
11447 if (Device.ios && (Device.cordova || Device.webView)) {
11448 if (win.orientation === 0) {
11449 app.once('resize', function () {
11450 Statusbar.checkOverlay();
11451 });
11452 }
11453
11454 $(doc).on('resume', function () {
11455 Statusbar.checkOverlay();
11456 }, false);
11457
11458 app.on(Device.ios ? 'orientationchange' : 'orientationchange resize', function () {
11459 Statusbar.checkOverlay();
11460 });
11461 }
11462 } else if (params.overlay === true) {
11463 $('html').addClass('with-statusbar');
11464 } else if (params.overlay === false) {
11465 $('html').removeClass('with-statusbar');
11466 }
11467
11468 if (Device.cordova && win.StatusBar) {
11469 if (params.scrollTopOnClick) {
11470 $(win).on('statusTap', Statusbar.onClick.bind(app));
11471 }
11472 if (Device.ios) {
11473 if (params.iosOverlaysWebView) {
11474 win.StatusBar.overlaysWebView(true);
11475 } else {
11476 win.StatusBar.overlaysWebView(false);
11477 }
11478 if (params.iosTextColor === 'white') {
11479 win.StatusBar.styleLightContent();
11480 } else {
11481 win.StatusBar.styleDefault();
11482 }
11483 }
11484 if (Device.android) {
11485 if (params.androidOverlaysWebView) {
11486 win.StatusBar.overlaysWebView(true);
11487 } else {
11488 win.StatusBar.overlaysWebView(false);
11489 }
11490 if (params.androidTextColor === 'white') {
11491 win.StatusBar.styleLightContent();
11492 } else {
11493 win.StatusBar.styleDefault();
11494 }
11495 }
11496 }
11497 if (params.iosBackgroundColor && Device.ios) {
11498 Statusbar.setBackgroundColor(params.iosBackgroundColor);
11499 }
11500 if ((params.materialBackgroundColor || params.androidBackgroundColor) && Device.android) {
11501 Statusbar.setBackgroundColor(params.materialBackgroundColor || params.androidBackgroundColor);
11502 }
11503 },
11504 };
11505
11506 var Statusbar$1 = {
11507 name: 'statusbar',
11508 params: {
11509 statusbar: {
11510 enabled: true,
11511 overlay: 'auto',
11512 scrollTopOnClick: true,
11513
11514 iosOverlaysWebView: true,
11515 iosTextColor: 'black',
11516 iosBackgroundColor: null,
11517
11518 androidOverlaysWebView: false,
11519 androidTextColor: 'black',
11520 androidBackgroundColor: null,
11521 },
11522 },
11523 create: function create() {
11524 var app = this;
11525 Utils.extend(app, {
11526 statusbar: {
11527 checkOverlay: Statusbar.checkOverlay,
11528 hide: Statusbar.hide,
11529 show: Statusbar.show,
11530 overlaysWebView: Statusbar.overlaysWebView,
11531 setTextColor: Statusbar.setTextColor,
11532 setBackgroundColor: Statusbar.setBackgroundColor,
11533 isVisible: Statusbar.isVisible,
11534 init: Statusbar.init.bind(app),
11535 },
11536 });
11537 },
11538 on: {
11539 init: function init() {
11540 var app = this;
11541 Statusbar.init.call(app);
11542 },
11543 },
11544 clicks: {
11545 '.statusbar': function onStatusbarClick() {
11546 var app = this;
11547 if (!app.params.statusbar.enabled) { return; }
11548 if (!app.params.statusbar.scrollTopOnClick) { return; }
11549 Statusbar.onClick.call(app);
11550 },
11551 },
11552 };
11553
11554 function getCurrentView(app) {
11555 var popoverView = $('.popover.modal-in .view');
11556 var popupView = $('.popup.modal-in .view');
11557 var panelView = $('.panel.panel-active .view');
11558 var appViews = $('.views');
11559 if (appViews.length === 0) { appViews = app.root; }
11560 // Find active view as tab
11561 var appView = appViews.children('.view');
11562 // Propably in tabs or split view
11563 if (appView.length > 1) {
11564 if (appView.hasClass('tab')) {
11565 // Tabs
11566 appView = appViews.children('.view.tab-active');
11567 }
11568 }
11569 if (popoverView.length > 0 && popoverView[0].f7View) { return popoverView[0].f7View; }
11570 if (popupView.length > 0 && popupView[0].f7View) { return popupView[0].f7View; }
11571 if (panelView.length > 0 && panelView[0].f7View) { return panelView[0].f7View; }
11572 if (appView.length > 0) {
11573 if (appView.length === 1 && appView[0].f7View) { return appView[0].f7View; }
11574 if (appView.length > 1) {
11575 return app.views.main;
11576 }
11577 }
11578 return undefined;
11579 }
11580
11581 var View$1 = {
11582 name: 'view',
11583 params: {
11584 view: {
11585 name: undefined,
11586 main: false,
11587 router: true,
11588 linksView: null,
11589 stackPages: false,
11590 xhrCache: true,
11591 xhrCacheIgnore: [],
11592 xhrCacheIgnoreGetParameters: false,
11593 xhrCacheDuration: 1000 * 60 * 10, // Ten minutes
11594 preloadPreviousPage: true,
11595 allowDuplicateUrls: false,
11596 reloadPages: false,
11597 reloadDetail: false,
11598 masterDetailBreakpoint: 0,
11599 removeElements: true,
11600 removeElementsWithTimeout: false,
11601 removeElementsTimeout: 0,
11602 restoreScrollTopOnBack: true,
11603 unloadTabContent: true,
11604 passRouteQueryToRequest: true,
11605 passRouteParamsToRequest: false,
11606 // Swipe Back
11607 iosSwipeBack: true,
11608 iosSwipeBackAnimateShadow: true,
11609 iosSwipeBackAnimateOpacity: true,
11610 iosSwipeBackActiveArea: 30,
11611 iosSwipeBackThreshold: 0,
11612 mdSwipeBack: false,
11613 mdSwipeBackAnimateShadow: true,
11614 mdSwipeBackAnimateOpacity: false,
11615 mdSwipeBackActiveArea: 30,
11616 mdSwipeBackThreshold: 0,
11617 // Push State
11618 pushState: false,
11619 pushStateRoot: undefined,
11620 pushStateAnimate: true,
11621 pushStateAnimateOnLoad: false,
11622 pushStateSeparator: '#!',
11623 pushStateOnLoad: true,
11624 // Animate Pages
11625 animate: true,
11626 // iOS Dynamic Navbar
11627 iosDynamicNavbar: true,
11628 iosSeparateDynamicNavbar: true,
11629 // Animate iOS Navbar Back Icon
11630 iosAnimateNavbarBackIcon: true,
11631 // Delays
11632 iosPageLoadDelay: 0,
11633 mdPageLoadDelay: 0,
11634 // Routes hooks
11635 routesBeforeEnter: null,
11636 routesBeforeLeave: null,
11637 },
11638 },
11639 static: {
11640 View: View,
11641 },
11642 create: function create() {
11643 var app = this;
11644 Utils.extend(app, {
11645 views: Utils.extend([], {
11646 create: function create(el, params) {
11647 return new View(app, el, params);
11648 },
11649 get: function get(viewEl) {
11650 var $viewEl = $(viewEl);
11651 if ($viewEl.length && $viewEl[0].f7View) { return $viewEl[0].f7View; }
11652 return undefined;
11653 },
11654 }),
11655 });
11656 Object.defineProperty(app.views, 'current', {
11657 enumerable: true,
11658 configurable: true,
11659 get: function get() {
11660 return getCurrentView(app);
11661 },
11662 });
11663 // Alias
11664 app.view = app.views;
11665 },
11666 on: {
11667 init: function init() {
11668 var app = this;
11669 $('.view-init').each(function (index, viewEl) {
11670 if (viewEl.f7View) { return; }
11671 var viewParams = $(viewEl).dataset();
11672 app.views.create(viewEl, viewParams);
11673 });
11674 },
11675 modalOpen: function modalOpen(modal) {
11676 var app = this;
11677 modal.$el.find('.view-init').each(function (index, viewEl) {
11678 if (viewEl.f7View) { return; }
11679 var viewParams = $(viewEl).dataset();
11680 app.views.create(viewEl, viewParams);
11681 });
11682 },
11683 modalBeforeDestroy: function modalBeforeDestroy(modal) {
11684 if (!modal || !modal.$el) { return; }
11685 modal.$el.find('.view-init').each(function (index, viewEl) {
11686 var view = viewEl.f7View;
11687 if (!view) { return; }
11688 view.destroy();
11689 });
11690 },
11691 },
11692 };
11693
11694 var Navbar = {
11695 size: function size(el) {
11696 var app = this;
11697 if (app.theme === 'md' && !app.params.navbar.mdCenterTitle) { return; }
11698 var $el = $(el);
11699 if ($el.hasClass('navbar')) {
11700 $el = $el.children('.navbar-inner').each(function (index, navbarEl) {
11701 app.navbar.size(navbarEl);
11702 });
11703 return;
11704 }
11705
11706 if (
11707 $el.hasClass('stacked')
11708 || $el.parents('.stacked').length > 0
11709 || $el.parents('.tab:not(.tab-active)').length > 0
11710 || $el.parents('.popup:not(.modal-in)').length > 0
11711 ) {
11712 return;
11713 }
11714
11715 if (app.theme === 'md' && app.params.navbar.mdCenterTitle) {
11716 $el.addClass('navbar-inner-centered-title');
11717 }
11718 if (app.theme === 'ios' && !app.params.navbar.iosCenterTitle) {
11719 $el.addClass('navbar-inner-left-title');
11720 }
11721
11722 var $viewEl = $el.parents('.view').eq(0);
11723 var left = app.rtl ? $el.children('.right') : $el.children('.left');
11724 var right = app.rtl ? $el.children('.left') : $el.children('.right');
11725 var title = $el.children('.title');
11726 var subnavbar = $el.children('.subnavbar');
11727 var noLeft = left.length === 0;
11728 var noRight = right.length === 0;
11729 var leftWidth = noLeft ? 0 : left.outerWidth(true);
11730 var rightWidth = noRight ? 0 : right.outerWidth(true);
11731 var titleWidth = title.outerWidth(true);
11732 var navbarStyles = $el.styles();
11733 var navbarWidth = $el[0].offsetWidth;
11734 var navbarInnerWidth = navbarWidth - parseInt(navbarStyles.paddingLeft, 10) - parseInt(navbarStyles.paddingRight, 10);
11735 var isPrevious = $el.hasClass('navbar-previous');
11736 var sliding = $el.hasClass('sliding');
11737
11738 var router;
11739 var dynamicNavbar;
11740 var separateNavbar;
11741 var separateNavbarRightOffset = 0;
11742 var separateNavbarLeftOffset = 0;
11743
11744 if ($viewEl.length > 0 && $viewEl[0].f7View) {
11745 router = $viewEl[0].f7View.router;
11746 dynamicNavbar = router && router.dynamicNavbar;
11747 separateNavbar = router && router.separateNavbar;
11748 if (!separateNavbar) {
11749 separateNavbarRightOffset = navbarWidth;
11750 separateNavbarLeftOffset = navbarWidth / 5;
11751 }
11752 }
11753
11754 var currLeft;
11755 var diff;
11756 if (noRight) {
11757 currLeft = navbarInnerWidth - titleWidth;
11758 }
11759 if (noLeft) {
11760 currLeft = 0;
11761 }
11762 if (!noLeft && !noRight) {
11763 currLeft = ((navbarInnerWidth - rightWidth - titleWidth) + leftWidth) / 2;
11764 }
11765 var requiredLeft = (navbarInnerWidth - titleWidth) / 2;
11766 if (navbarInnerWidth - leftWidth - rightWidth > titleWidth) {
11767 if (requiredLeft < leftWidth) {
11768 requiredLeft = leftWidth;
11769 }
11770 if (requiredLeft + titleWidth > navbarInnerWidth - rightWidth) {
11771 requiredLeft = navbarInnerWidth - rightWidth - titleWidth;
11772 }
11773 diff = requiredLeft - currLeft;
11774 } else {
11775 diff = 0;
11776 }
11777
11778 // RTL inverter
11779 var inverter = app.rtl ? -1 : 1;
11780
11781 if (dynamicNavbar && app.theme === 'ios') {
11782 if (title.hasClass('sliding') || (title.length > 0 && sliding)) {
11783 var titleLeftOffset = (-(currLeft + diff) * inverter) + separateNavbarLeftOffset;
11784 var titleRightOffset = ((navbarInnerWidth - currLeft - diff - titleWidth) * inverter) - separateNavbarRightOffset;
11785
11786 if (isPrevious) {
11787 if (router && router.params.iosAnimateNavbarBackIcon) {
11788 var activeNavbarBackLink = $el.parent().find('.navbar-current').children('.left.sliding').find('.back .icon ~ span');
11789 if (activeNavbarBackLink.length > 0) {
11790 titleLeftOffset += activeNavbarBackLink[0].offsetLeft;
11791 }
11792 }
11793 }
11794 title[0].f7NavbarLeftOffset = titleLeftOffset;
11795 title[0].f7NavbarRightOffset = titleRightOffset;
11796 }
11797 if (!noLeft && (left.hasClass('sliding') || sliding)) {
11798 if (app.rtl) {
11799 left[0].f7NavbarLeftOffset = (-(navbarInnerWidth - left[0].offsetWidth) / 2) * inverter;
11800 left[0].f7NavbarRightOffset = leftWidth * inverter;
11801 } else {
11802 left[0].f7NavbarLeftOffset = -leftWidth + separateNavbarLeftOffset;
11803 left[0].f7NavbarRightOffset = ((navbarInnerWidth - left[0].offsetWidth) / 2) - separateNavbarRightOffset;
11804 if (router && router.params.iosAnimateNavbarBackIcon && left.find('.back .icon').length > 0) {
11805 if (left.find('.back .icon ~ span').length) {
11806 var leftOffset = left[0].f7NavbarLeftOffset;
11807 var rightOffset = left[0].f7NavbarRightOffset;
11808 left[0].f7NavbarLeftOffset = 0;
11809 left[0].f7NavbarRightOffset = 0;
11810 left.find('.back .icon ~ span')[0].f7NavbarLeftOffset = leftOffset;
11811 left.find('.back .icon ~ span')[0].f7NavbarRightOffset = rightOffset - left.find('.back .icon')[0].offsetWidth;
11812 }
11813 }
11814 }
11815 }
11816 if (!noRight && (right.hasClass('sliding') || sliding)) {
11817 if (app.rtl) {
11818 right[0].f7NavbarLeftOffset = -rightWidth * inverter;
11819 right[0].f7NavbarRightOffset = ((navbarInnerWidth - right[0].offsetWidth) / 2) * inverter;
11820 } else {
11821 right[0].f7NavbarLeftOffset = (-(navbarInnerWidth - right[0].offsetWidth) / 2) + separateNavbarLeftOffset;
11822 right[0].f7NavbarRightOffset = rightWidth - separateNavbarRightOffset;
11823 }
11824 }
11825 if (subnavbar.length && (subnavbar.hasClass('sliding') || sliding)) {
11826 subnavbar[0].f7NavbarLeftOffset = app.rtl ? subnavbar[0].offsetWidth : (-subnavbar[0].offsetWidth + separateNavbarLeftOffset);
11827 subnavbar[0].f7NavbarRightOffset = (-subnavbar[0].f7NavbarLeftOffset - separateNavbarRightOffset) + separateNavbarLeftOffset;
11828 }
11829 }
11830
11831 // Center title
11832 if (
11833 (app.theme === 'ios' && app.params.navbar.iosCenterTitle)
11834 || (app.theme === 'md' && app.params.navbar.mdCenterTitle)
11835 ) {
11836 var titleLeft = diff;
11837 if (app.rtl && noLeft && noRight && title.length > 0) { titleLeft = -titleLeft; }
11838 title.css({ left: (titleLeft + "px") });
11839 }
11840 },
11841 hide: function hide(el, animate) {
11842 if ( animate === void 0 ) animate = true;
11843
11844 var app = this;
11845 var $el = $(el);
11846 if ($el.hasClass('navbar-inner')) { $el = $el.parents('.navbar'); }
11847 if (!$el.length) { return; }
11848 if ($el.hasClass('navbar-hidden')) { return; }
11849 var className = "navbar-hidden" + (animate ? ' navbar-transitioning' : '');
11850 var currentIsLarge = app.theme === 'ios' ? $el.find('.navbar-current .title-large').length : $el.find('.title-large').length;
11851 if (currentIsLarge) {
11852 className += ' navbar-large-hidden';
11853 }
11854 $el.transitionEnd(function () {
11855 $el.removeClass('navbar-transitioning');
11856 });
11857 $el.addClass(className);
11858 },
11859 show: function show(el, animate) {
11860 if ( el === void 0 ) el = '.navbar-hidden';
11861 if ( animate === void 0 ) animate = true;
11862
11863 var $el = $(el);
11864 if ($el.hasClass('navbar-inner')) { $el = $el.parents('.navbar'); }
11865 if (!$el.length) { return; }
11866 if (!$el.hasClass('navbar-hidden')) { return; }
11867 if (animate) {
11868 $el.addClass('navbar-transitioning');
11869 $el.transitionEnd(function () {
11870 $el.removeClass('navbar-transitioning');
11871 });
11872 }
11873 $el.removeClass('navbar-hidden navbar-large-hidden');
11874 },
11875 getElByPage: function getElByPage(page) {
11876 var $pageEl;
11877 var $navbarInnerEl;
11878 var pageData;
11879 if (page.$navbarEl || page.$el) {
11880 pageData = page;
11881 $pageEl = page.$el;
11882 } else {
11883 $pageEl = $(page);
11884 if ($pageEl.length > 0) { pageData = $pageEl[0].f7Page; }
11885 }
11886 if (pageData && pageData.$navbarEl && pageData.$navbarEl.length > 0) {
11887 $navbarInnerEl = pageData.$navbarEl;
11888 } else if ($pageEl) {
11889 $navbarInnerEl = $pageEl.children('.navbar').children('.navbar-inner');
11890 }
11891 if (!$navbarInnerEl || ($navbarInnerEl && $navbarInnerEl.length === 0)) { return undefined; }
11892 return $navbarInnerEl[0];
11893 },
11894 getPageByEl: function getPageByEl(navbarInnerEl) {
11895 var $navbarInnerEl = $(navbarInnerEl);
11896 if ($navbarInnerEl.hasClass('navbar')) {
11897 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner');
11898 if ($navbarInnerEl.length > 1) { return undefined; }
11899 }
11900 if ($navbarInnerEl.parents('.page').length) {
11901 return $navbarInnerEl.parents('.page')[0];
11902 }
11903 var pageEl;
11904 $navbarInnerEl.parents('.view').find('.page').each(function (index, el) {
11905 if (el && el.f7Page && el.f7Page.navbarEl && $navbarInnerEl[0] === el.f7Page.navbarEl) {
11906 pageEl = el;
11907 }
11908 });
11909 return pageEl;
11910 },
11911
11912 collapseLargeTitle: function collapseLargeTitle(navbarInnerEl) {
11913 var app = this;
11914 var $navbarInnerEl = $(navbarInnerEl);
11915 if ($navbarInnerEl.hasClass('navbar')) {
11916 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner-large');
11917 if ($navbarInnerEl.length > 1) {
11918 $navbarInnerEl = $(navbarInnerEl).find('.navbar-inner-large.navbar-current');
11919 }
11920 if ($navbarInnerEl.length > 1 || !$navbarInnerEl.length) {
11921 return;
11922 }
11923 }
11924 var $pageEl = $(app.navbar.getPageByEl($navbarInnerEl));
11925 $navbarInnerEl.addClass('navbar-inner-large-collapsed');
11926 $pageEl.eq(0).addClass('page-with-navbar-large-collapsed').trigger('page:navbarlargecollapsed');
11927 if (app.theme === 'md') {
11928 $navbarInnerEl.parents('.navbar').addClass('navbar-large-collapsed');
11929 }
11930 },
11931 expandLargeTitle: function expandLargeTitle(navbarInnerEl) {
11932 var app = this;
11933 var $navbarInnerEl = $(navbarInnerEl);
11934 if ($navbarInnerEl.hasClass('navbar')) {
11935 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner-large');
11936 if ($navbarInnerEl.length > 1) {
11937 $navbarInnerEl = $(navbarInnerEl).find('.navbar-inner-large.navbar-current');
11938 }
11939 if ($navbarInnerEl.length > 1 || !$navbarInnerEl.length) {
11940 return;
11941 }
11942 }
11943 var $pageEl = $(app.navbar.getPageByEl($navbarInnerEl));
11944 $navbarInnerEl.removeClass('navbar-inner-large-collapsed');
11945 $pageEl.eq(0).removeClass('page-with-navbar-large-collapsed').trigger('page:navbarlargeexpanded');
11946 if (app.theme === 'md') {
11947 $navbarInnerEl.parents('.navbar').removeClass('navbar-large-collapsed');
11948 }
11949 },
11950 toggleLargeTitle: function toggleLargeTitle(navbarInnerEl) {
11951 var app = this;
11952 var $navbarInnerEl = $(navbarInnerEl);
11953 if ($navbarInnerEl.hasClass('navbar')) {
11954 $navbarInnerEl = $navbarInnerEl.find('.navbar-inner-large');
11955 if ($navbarInnerEl.length > 1) {
11956 $navbarInnerEl = $(navbarInnerEl).find('.navbar-inner-large.navbar-current');
11957 }
11958 if ($navbarInnerEl.length > 1 || !$navbarInnerEl.length) {
11959 return;
11960 }
11961 }
11962 if ($navbarInnerEl.hasClass('navbar-inner-large-collapsed')) {
11963 app.navbar.expandLargeTitle($navbarInnerEl);
11964 } else {
11965 app.navbar.collapseLargeTitle($navbarInnerEl);
11966 }
11967 },
11968 initNavbarOnScroll: function initNavbarOnScroll(pageEl, navbarInnerEl, needHide, needCollapse) {
11969 var app = this;
11970 var $pageEl = $(pageEl);
11971 var $navbarInnerEl = $(navbarInnerEl);
11972 var $navbarEl = app.theme === 'md'
11973 ? $navbarInnerEl.parents('.navbar')
11974 : $(navbarInnerEl || app.navbar.getElByPage(pageEl)).closest('.navbar');
11975 var isLarge = $navbarInnerEl.find('.title-large').length || $navbarInnerEl.hasClass('.navbar-inner-large');
11976 var navbarHideHeight = 44;
11977 var snapPageScrollToLargeTitle = app.params.navbar.snapPageScrollToLargeTitle;
11978
11979 var previousScrollTop;
11980 var currentScrollTop;
11981
11982 var scrollHeight;
11983 var offsetHeight;
11984 var reachEnd;
11985 var action;
11986 var navbarHidden;
11987
11988 var navbarCollapsed;
11989 var navbarTitleLargeHeight;
11990 if (needCollapse || (needHide && isLarge)) {
11991 navbarTitleLargeHeight = $navbarInnerEl.css('--f7-navbar-large-title-height');
11992 if (navbarTitleLargeHeight && navbarTitleLargeHeight.indexOf('px') >= 0) {
11993 navbarTitleLargeHeight = parseInt(navbarTitleLargeHeight, 10);
11994 if (Number.isNaN(navbarTitleLargeHeight)) {
11995 navbarTitleLargeHeight = app.theme === 'ios' ? 52 : 48;
11996 }
11997 } else {
11998 navbarTitleLargeHeight = app.theme === 'ios' ? 52 : 48;
11999 }
12000 }
12001 if (needHide && isLarge) {
12002 navbarHideHeight += navbarTitleLargeHeight;
12003 }
12004
12005 var scrollChanged;
12006 var scrollContent;
12007 var scrollTimeoutId;
12008 var touchEndTimeoutId;
12009 var touchSnapTimeout = 70;
12010 var desktopSnapTimeout = 300;
12011
12012 function snapLargeNavbar() {
12013 var inSearchbarExpanded = $navbarInnerEl.hasClass('with-searchbar-expandable-enabled');
12014 if (inSearchbarExpanded) { return; }
12015 if (!scrollContent || currentScrollTop < 0) { return; }
12016 if (currentScrollTop >= navbarTitleLargeHeight / 2 && currentScrollTop < navbarTitleLargeHeight) {
12017 $(scrollContent).scrollTop(navbarTitleLargeHeight, 100);
12018 } else if (currentScrollTop < navbarTitleLargeHeight) {
12019 $(scrollContent).scrollTop(0, 200);
12020 }
12021 }
12022
12023 function handleLargeNavbarCollapse() {
12024 var collapseProgress = Math.min(Math.max((currentScrollTop / navbarTitleLargeHeight), 0), 1);
12025 var inSearchbarExpanded = $navbarInnerEl.hasClass('with-searchbar-expandable-enabled');
12026 if (inSearchbarExpanded) { return; }
12027 navbarCollapsed = $navbarInnerEl.hasClass('navbar-inner-large-collapsed');
12028 if (collapseProgress === 0 && navbarCollapsed) {
12029 app.navbar.expandLargeTitle($navbarInnerEl[0]);
12030 $navbarInnerEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12031 $pageEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12032 $navbarInnerEl[0].style.overflow = '';
12033 if (app.theme === 'md') {
12034 $navbarEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12035 }
12036 } else if (collapseProgress === 1 && !navbarCollapsed) {
12037 app.navbar.collapseLargeTitle($navbarInnerEl[0]);
12038 $navbarInnerEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12039 $navbarInnerEl[0].style.overflow = '';
12040 $pageEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12041 if (app.theme === 'md') {
12042 $navbarEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12043 }
12044 } else if ((collapseProgress === 1 && navbarCollapsed) || (collapseProgress === 0 && !navbarCollapsed)) {
12045 $navbarInnerEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12046 $navbarInnerEl[0].style.overflow = '';
12047 $pageEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12048 if (app.theme === 'md') {
12049 $navbarEl[0].style.removeProperty('--f7-navbar-large-collapse-progress');
12050 }
12051 } else {
12052 $navbarInnerEl[0].style.setProperty('--f7-navbar-large-collapse-progress', collapseProgress);
12053 $navbarInnerEl[0].style.overflow = 'visible';
12054 $pageEl[0].style.setProperty('--f7-navbar-large-collapse-progress', collapseProgress);
12055 if (app.theme === 'md') {
12056 $navbarEl[0].style.setProperty('--f7-navbar-large-collapse-progress', collapseProgress);
12057 }
12058 }
12059
12060 if (snapPageScrollToLargeTitle) {
12061 if (!Support.touch) {
12062 clearTimeout(scrollTimeoutId);
12063 scrollTimeoutId = setTimeout(function () {
12064 snapLargeNavbar();
12065 }, desktopSnapTimeout);
12066 } else if (touchEndTimeoutId) {
12067 clearTimeout(touchEndTimeoutId);
12068 touchEndTimeoutId = null;
12069 touchEndTimeoutId = setTimeout(function () {
12070 snapLargeNavbar();
12071 clearTimeout(touchEndTimeoutId);
12072 touchEndTimeoutId = null;
12073 }, touchSnapTimeout);
12074 }
12075 }
12076 }
12077
12078 function handleTitleHideShow() {
12079 scrollHeight = scrollContent.scrollHeight;
12080 offsetHeight = scrollContent.offsetHeight;
12081 reachEnd = currentScrollTop + offsetHeight >= scrollHeight;
12082 navbarHidden = $navbarEl.hasClass('navbar-hidden');
12083
12084 if (reachEnd) {
12085 if (app.params.navbar.showOnPageScrollEnd) {
12086 action = 'show';
12087 }
12088 } else if (previousScrollTop > currentScrollTop) {
12089 if (app.params.navbar.showOnPageScrollTop || currentScrollTop <= navbarHideHeight) {
12090 action = 'show';
12091 } else {
12092 action = 'hide';
12093 }
12094 } else if (currentScrollTop > navbarHideHeight) {
12095 action = 'hide';
12096 } else {
12097 action = 'show';
12098 }
12099
12100 if (action === 'show' && navbarHidden) {
12101 app.navbar.show($navbarEl);
12102 navbarHidden = false;
12103 } else if (action === 'hide' && !navbarHidden) {
12104 app.navbar.hide($navbarEl);
12105 navbarHidden = true;
12106 }
12107 previousScrollTop = currentScrollTop;
12108 }
12109
12110 function handleScroll() {
12111 scrollContent = this;
12112 currentScrollTop = scrollContent.scrollTop;
12113 scrollChanged = currentScrollTop;
12114
12115 if (needCollapse) {
12116 handleLargeNavbarCollapse();
12117 }
12118 if ($pageEl.hasClass('page-previous')) { return; }
12119 if (needHide) {
12120 handleTitleHideShow();
12121 }
12122 }
12123 function handeTouchStart() {
12124 scrollChanged = false;
12125 }
12126 function handleTouchEnd() {
12127 clearTimeout(touchEndTimeoutId);
12128 touchEndTimeoutId = null;
12129 touchEndTimeoutId = setTimeout(function () {
12130 if (scrollChanged !== false) {
12131 snapLargeNavbar();
12132 clearTimeout(touchEndTimeoutId);
12133 touchEndTimeoutId = null;
12134 }
12135 }, touchSnapTimeout);
12136 }
12137 $pageEl.on('scroll', '.page-content', handleScroll, true);
12138 if (Support.touch && needCollapse && snapPageScrollToLargeTitle) {
12139 app.on('touchstart:passive', handeTouchStart);
12140 app.on('touchend:passive', handleTouchEnd);
12141 }
12142 if (needCollapse) {
12143 $pageEl.find('.page-content').each(function (pageContentIndex, pageContentEl) {
12144 if (pageContentEl.scrollTop > 0) { handleScroll.call(pageContentEl); }
12145 });
12146 }
12147 $pageEl[0].f7DetachNavbarScrollHandlers = function f7DetachNavbarScrollHandlers() {
12148 delete $pageEl[0].f7DetachNavbarScrollHandlers;
12149 $pageEl.off('scroll', '.page-content', handleScroll, true);
12150 if (Support.touch && needCollapse && snapPageScrollToLargeTitle) {
12151 app.off('touchstart:passive', handeTouchStart);
12152 app.off('touchend:passive', handleTouchEnd);
12153 }
12154 };
12155 },
12156 };
12157 var Navbar$1 = {
12158 name: 'navbar',
12159 create: function create() {
12160 var app = this;
12161 Utils.extend(app, {
12162 navbar: {
12163 size: Navbar.size.bind(app),
12164 hide: Navbar.hide.bind(app),
12165 show: Navbar.show.bind(app),
12166 getElByPage: Navbar.getElByPage.bind(app),
12167 getPageByEl: Navbar.getPageByEl.bind(app),
12168 collapseLargeTitle: Navbar.collapseLargeTitle.bind(app),
12169 expandLargeTitle: Navbar.expandLargeTitle.bind(app),
12170 toggleLargeTitle: Navbar.toggleLargeTitle.bind(app),
12171 initNavbarOnScroll: Navbar.initNavbarOnScroll.bind(app),
12172 },
12173 });
12174 },
12175 params: {
12176 navbar: {
12177 scrollTopOnTitleClick: true,
12178 iosCenterTitle: true,
12179 mdCenterTitle: false,
12180 hideOnPageScroll: false,
12181 showOnPageScrollEnd: true,
12182 showOnPageScrollTop: true,
12183 collapseLargeTitleOnScroll: true,
12184 snapPageScrollToLargeTitle: true,
12185 },
12186 },
12187 on: {
12188 'panelBreakpoint resize viewMasterDetailBreakpoint': function onResize() {
12189 var app = this;
12190 $('.navbar').each(function (index, navbarEl) {
12191 app.navbar.size(navbarEl);
12192 });
12193 },
12194 pageBeforeRemove: function pageBeforeRemove(page) {
12195 if (page.$el[0].f7DetachNavbarScrollHandlers) {
12196 page.$el[0].f7DetachNavbarScrollHandlers();
12197 }
12198 },
12199 pageBeforeIn: function pageBeforeIn(page) {
12200 var app = this;
12201 if (app.theme !== 'ios') { return; }
12202 var $navbarEl;
12203 var view = page.$el.parents('.view')[0].f7View;
12204 var navbarInnerEl = app.navbar.getElByPage(page);
12205 if (!navbarInnerEl) {
12206 $navbarEl = page.$el.parents('.view').children('.navbar');
12207 } else {
12208 $navbarEl = $(navbarInnerEl).parents('.navbar');
12209 }
12210 if (page.$el.hasClass('no-navbar') || (view.router.dynamicNavbar && !navbarInnerEl)) {
12211 var animate = !!(page.pageFrom && page.router.history.length > 0);
12212 app.navbar.hide($navbarEl, animate);
12213 } else {
12214 app.navbar.show($navbarEl);
12215 }
12216 },
12217 pageReinit: function pageReinit(page) {
12218 var app = this;
12219 var $navbarInnerEl = $(app.navbar.getElByPage(page));
12220 if (!$navbarInnerEl || $navbarInnerEl.length === 0) { return; }
12221 app.navbar.size($navbarInnerEl);
12222 },
12223 pageInit: function pageInit(page) {
12224 var app = this;
12225 var $navbarInnerEl = $(app.navbar.getElByPage(page));
12226 if (!$navbarInnerEl || $navbarInnerEl.length === 0) { return; }
12227
12228 // Size
12229 app.navbar.size($navbarInnerEl);
12230
12231 // Need Collapse On Scroll
12232 var needCollapseOnScrollHandler;
12233 if ($navbarInnerEl.children('.title-large').length > 0) {
12234 $navbarInnerEl.addClass('navbar-inner-large');
12235 }
12236 if ($navbarInnerEl.hasClass('navbar-inner-large')) {
12237 if (app.params.navbar.collapseLargeTitleOnScroll) { needCollapseOnScrollHandler = true; }
12238 if (app.theme === 'md') {
12239 $navbarInnerEl.parents('.navbar').addClass('navbar-large');
12240 }
12241 page.$el.addClass('page-with-navbar-large');
12242 }
12243
12244 // Need Hide On Scroll
12245 var needHideOnScrollHandler;
12246 if (
12247 app.params.navbar.hideOnPageScroll
12248 || page.$el.find('.hide-navbar-on-scroll').length
12249 || page.$el.hasClass('hide-navbar-on-scroll')
12250 || page.$el.find('.hide-bars-on-scroll').length
12251 || page.$el.hasClass('hide-bars-on-scroll')
12252 ) {
12253 if (
12254 page.$el.find('.keep-navbar-on-scroll').length
12255 || page.$el.hasClass('keep-navbar-on-scroll')
12256 || page.$el.find('.keep-bars-on-scroll').length
12257 || page.$el.hasClass('keep-bars-on-scroll')
12258 ) {
12259 needHideOnScrollHandler = false;
12260 } else {
12261 needHideOnScrollHandler = true;
12262 }
12263 }
12264
12265 if (needCollapseOnScrollHandler || needHideOnScrollHandler) {
12266 app.navbar.initNavbarOnScroll(page.el, $navbarInnerEl[0], needHideOnScrollHandler, needCollapseOnScrollHandler);
12267 }
12268 },
12269 modalOpen: function modalOpen(modal) {
12270 var app = this;
12271 if (
12272 (app.theme === 'ios' && !app.params.navbar.iosCenterTitle)
12273 || (app.theme === 'md' && !app.params.navbar.mdCenterTitle)
12274 ) {
12275 return;
12276 }
12277 modal.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12278 app.navbar.size(navbarEl);
12279 });
12280 },
12281 panelOpen: function panelOpen(panel) {
12282 var app = this;
12283 if (
12284 (app.theme === 'ios' && !app.params.navbar.iosCenterTitle)
12285 || (app.theme === 'md' && !app.params.navbar.mdCenterTitle)
12286 ) {
12287 return;
12288 }
12289 panel.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12290 app.navbar.size(navbarEl);
12291 });
12292 },
12293 panelSwipeOpen: function panelSwipeOpen(panel) {
12294 var app = this;
12295 if (
12296 (app.theme === 'ios' && !app.params.navbar.iosCenterTitle)
12297 || (app.theme === 'md' && !app.params.navbar.mdCenterTitle)
12298 ) {
12299 return;
12300 }
12301 panel.$el.find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12302 app.navbar.size(navbarEl);
12303 });
12304 },
12305 tabShow: function tabShow(tabEl) {
12306 var app = this;
12307 if (
12308 (app.theme === 'ios' && !app.params.navbar.iosCenterTitle)
12309 || (app.theme === 'md' && !app.params.navbar.mdCenterTitle)
12310 ) {
12311 return;
12312 }
12313 $(tabEl).find('.navbar:not(.navbar-previous):not(.stacked)').each(function (index, navbarEl) {
12314 app.navbar.size(navbarEl);
12315 });
12316 },
12317 },
12318 clicks: {
12319 '.navbar .title': function onTitleClick($clickedEl) {
12320 var app = this;
12321 if (!app.params.navbar.scrollTopOnTitleClick) { return; }
12322 if ($clickedEl.closest('a').length > 0) {
12323 return;
12324 }
12325 var pageContent;
12326 // Find active page
12327 var navbar = $clickedEl.parents('.navbar');
12328
12329 // Static Layout
12330 pageContent = navbar.parents('.page-content');
12331
12332 if (pageContent.length === 0) {
12333 // Fixed Layout
12334 if (navbar.parents('.page').length > 0) {
12335 pageContent = navbar.parents('.page').find('.page-content');
12336 }
12337 // Through Layout
12338 if (pageContent.length === 0) {
12339 if (navbar.nextAll('.page-current:not(.stacked)').length > 0) {
12340 pageContent = navbar.nextAll('.page-current:not(.stacked)').find('.page-content');
12341 }
12342 }
12343 }
12344 if (pageContent && pageContent.length > 0) {
12345 // Check for tab
12346 if (pageContent.hasClass('tab')) {
12347 pageContent = pageContent.parent('.tabs').children('.page-content.tab-active');
12348 }
12349 if (pageContent.length > 0) { pageContent.scrollTop(0, 300); }
12350 }
12351 },
12352 },
12353 vnode: {
12354 'navbar-inner': {
12355 postpatch: function postpatch(vnode) {
12356 var app = this;
12357 if (
12358 (app.theme === 'ios' && !app.params.navbar.iosCenterTitle)
12359 || (app.theme === 'md' && !app.params.navbar.mdCenterTitle)
12360 ) {
12361 return;
12362 }
12363 app.navbar.size(vnode.elm);
12364 },
12365 },
12366 },
12367 };
12368
12369 var Toolbar = {
12370 setHighlight: function setHighlight(tabbarEl) {
12371 var app = this;
12372 if (app.theme !== 'md') { return; }
12373
12374 var $tabbarEl = $(tabbarEl);
12375
12376 if ($tabbarEl.length === 0 || !($tabbarEl.hasClass('tabbar') || $tabbarEl.hasClass('tabbar-labels'))) { return; }
12377
12378 var $highlightEl = $tabbarEl.find('.tab-link-highlight');
12379 var tabLinksCount = $tabbarEl.find('.tab-link').length;
12380 if (tabLinksCount === 0) {
12381 $highlightEl.remove();
12382 return;
12383 }
12384
12385 if ($highlightEl.length === 0) {
12386 $tabbarEl.children('.toolbar-inner').append('<span class="tab-link-highlight"></span>');
12387 $highlightEl = $tabbarEl.find('.tab-link-highlight');
12388 } else if ($highlightEl.next().length) {
12389 $tabbarEl.children('.toolbar-inner').append($highlightEl);
12390 }
12391
12392 var $activeLink = $tabbarEl.find('.tab-link-active');
12393 var highlightWidth;
12394 var highlightTranslate;
12395
12396 if ($tabbarEl.hasClass('tabbar-scrollable') && $activeLink && $activeLink[0]) {
12397 highlightWidth = ($activeLink[0].offsetWidth) + "px";
12398 highlightTranslate = ($activeLink[0].offsetLeft) + "px";
12399 } else {
12400 var activeIndex = $activeLink.index();
12401 highlightWidth = (100 / tabLinksCount) + "%";
12402 highlightTranslate = ((app.rtl ? -activeIndex : activeIndex) * 100) + "%";
12403 }
12404
12405 Utils.nextFrame(function () {
12406 $highlightEl
12407 .css('width', highlightWidth)
12408 .transform(("translate3d(" + highlightTranslate + ",0,0)"));
12409 });
12410 },
12411 init: function init(tabbarEl) {
12412 var app = this;
12413 app.toolbar.setHighlight(tabbarEl);
12414 },
12415 hide: function hide(el, animate) {
12416 if ( animate === void 0 ) animate = true;
12417
12418 var $el = $(el);
12419 if ($el.hasClass('toolbar-hidden')) { return; }
12420 var className = "toolbar-hidden" + (animate ? ' toolbar-transitioning' : '');
12421 $el.transitionEnd(function () {
12422 $el.removeClass('toolbar-transitioning');
12423 });
12424 $el.addClass(className);
12425 },
12426 show: function show(el, animate) {
12427 if ( animate === void 0 ) animate = true;
12428
12429 var $el = $(el);
12430 if (!$el.hasClass('toolbar-hidden')) { return; }
12431 if (animate) {
12432 $el.addClass('toolbar-transitioning');
12433 $el.transitionEnd(function () {
12434 $el.removeClass('toolbar-transitioning');
12435 });
12436 }
12437 $el.removeClass('toolbar-hidden');
12438 },
12439 initHideToolbarOnScroll: function initHideToolbarOnScroll(pageEl) {
12440 var app = this;
12441 var $pageEl = $(pageEl);
12442 var $toolbarEl = $pageEl.parents('.view').children('.toolbar');
12443 if ($toolbarEl.length === 0) {
12444 $toolbarEl = $pageEl.find('.toolbar');
12445 }
12446 if ($toolbarEl.length === 0) {
12447 $toolbarEl = $pageEl.parents('.views').children('.tabbar, .tabbar-labels');
12448 }
12449 if ($toolbarEl.length === 0) {
12450 return;
12451 }
12452
12453 var previousScrollTop;
12454 var currentScrollTop;
12455
12456 var scrollHeight;
12457 var offsetHeight;
12458 var reachEnd;
12459 var action;
12460 var toolbarHidden;
12461 function handleScroll() {
12462 var scrollContent = this;
12463 if ($pageEl.hasClass('page-previous')) { return; }
12464 currentScrollTop = scrollContent.scrollTop;
12465 scrollHeight = scrollContent.scrollHeight;
12466 offsetHeight = scrollContent.offsetHeight;
12467 reachEnd = currentScrollTop + offsetHeight >= scrollHeight;
12468 toolbarHidden = $toolbarEl.hasClass('toolbar-hidden');
12469
12470 if (reachEnd) {
12471 if (app.params.toolbar.showOnPageScrollEnd) {
12472 action = 'show';
12473 }
12474 } else if (previousScrollTop > currentScrollTop) {
12475 if (app.params.toolbar.showOnPageScrollTop || currentScrollTop <= 44) {
12476 action = 'show';
12477 } else {
12478 action = 'hide';
12479 }
12480 } else if (currentScrollTop > 44) {
12481 action = 'hide';
12482 } else {
12483 action = 'show';
12484 }
12485
12486 if (action === 'show' && toolbarHidden) {
12487 app.toolbar.show($toolbarEl);
12488 toolbarHidden = false;
12489 } else if (action === 'hide' && !toolbarHidden) {
12490 app.toolbar.hide($toolbarEl);
12491 toolbarHidden = true;
12492 }
12493
12494 previousScrollTop = currentScrollTop;
12495 }
12496 $pageEl.on('scroll', '.page-content', handleScroll, true);
12497 $pageEl[0].f7ScrollToolbarHandler = handleScroll;
12498 },
12499 };
12500 var Toolbar$1 = {
12501 name: 'toolbar',
12502 create: function create() {
12503 var app = this;
12504 Utils.extend(app, {
12505 toolbar: {
12506 hide: Toolbar.hide.bind(app),
12507 show: Toolbar.show.bind(app),
12508 setHighlight: Toolbar.setHighlight.bind(app),
12509 initHideToolbarOnScroll: Toolbar.initHideToolbarOnScroll.bind(app),
12510 init: Toolbar.init.bind(app),
12511 },
12512 });
12513 },
12514 params: {
12515 toolbar: {
12516 hideOnPageScroll: false,
12517 showOnPageScrollEnd: true,
12518 showOnPageScrollTop: true,
12519 },
12520 },
12521 on: {
12522 pageBeforeRemove: function pageBeforeRemove(page) {
12523 if (page.$el[0].f7ScrollToolbarHandler) {
12524 page.$el.off('scroll', '.page-content', page.$el[0].f7ScrollToolbarHandler, true);
12525 }
12526 },
12527 pageBeforeIn: function pageBeforeIn(page) {
12528 var app = this;
12529 var $toolbarEl = page.$el.parents('.view').children('.toolbar');
12530 if ($toolbarEl.length === 0) {
12531 $toolbarEl = page.$el.parents('.views').children('.tabbar, .tabbar-labels');
12532 }
12533 if ($toolbarEl.length === 0) {
12534 $toolbarEl = page.$el.find('.toolbar');
12535 }
12536 if ($toolbarEl.length === 0) {
12537 return;
12538 }
12539 if (page.$el.hasClass('no-toolbar')) {
12540 app.toolbar.hide($toolbarEl);
12541 } else {
12542 app.toolbar.show($toolbarEl);
12543 }
12544 },
12545 pageInit: function pageInit(page) {
12546 var app = this;
12547 page.$el.find('.tabbar, .tabbar-labels').each(function (index, tabbarEl) {
12548 app.toolbar.init(tabbarEl);
12549 });
12550 if (
12551 app.params.toolbar.hideOnPageScroll
12552 || page.$el.find('.hide-toolbar-on-scroll').length
12553 || page.$el.hasClass('hide-toolbar-on-scroll')
12554 || page.$el.find('.hide-bars-on-scroll').length
12555 || page.$el.hasClass('hide-bars-on-scroll')
12556 ) {
12557 if (
12558 page.$el.find('.keep-toolbar-on-scroll').length
12559 || page.$el.hasClass('keep-toolbar-on-scroll')
12560 || page.$el.find('.keep-bars-on-scroll').length
12561 || page.$el.hasClass('keep-bars-on-scroll')
12562 ) {
12563 return;
12564 }
12565 app.toolbar.initHideToolbarOnScroll(page.el);
12566 }
12567 },
12568 init: function init() {
12569 var app = this;
12570 app.root.find('.tabbar, .tabbar-labels').each(function (index, tabbarEl) {
12571 app.toolbar.init(tabbarEl);
12572 });
12573 },
12574 },
12575 };
12576
12577 var Subnavbar = {
12578 name: 'subnavbar',
12579 on: {
12580 pageInit: function pageInit(page) {
12581 if (page.$navbarEl && page.$navbarEl.length && page.$navbarEl.find('.subnavbar').length) {
12582 page.$el.addClass('page-with-subnavbar');
12583 }
12584 if (page.$el.find('.subnavbar').length) {
12585 page.$el.addClass('page-with-subnavbar');
12586 }
12587 },
12588 },
12589 };
12590
12591 var TouchRipple = function TouchRipple($el, x, y) {
12592 var ripple = this;
12593 if (!$el) { return undefined; }
12594 var box = $el[0].getBoundingClientRect();
12595 var center = {
12596 x: x - box.left,
12597 y: y - box.top,
12598 };
12599 var width = box.width;
12600 var height = box.height;
12601 var diameter = Math.max((Math.pow( ((Math.pow( height, 2 )) + (Math.pow( width, 2 ))), 0.5 )), 48);
12602
12603 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>"));
12604
12605 $el.prepend(ripple.$rippleWaveEl);
12606
12607 /* eslint no-underscore-dangle: ["error", { "allow": ["_clientLeft"] }] */
12608 // ripple._clientLeft = ripple.$rippleWaveEl[0].clientLeft;
12609 ripple.rippleTransform = "translate3d(" + (-center.x + (width / 2)) + "px, " + (-center.y + (height / 2)) + "px, 0) scale(1)";
12610
12611 Utils.nextFrame(function () {
12612 if (!ripple || !ripple.$rippleWaveEl) { return; }
12613 ripple.$rippleWaveEl.transform(ripple.rippleTransform);
12614 });
12615
12616 return ripple;
12617 };
12618
12619 TouchRipple.prototype.onRemove = function onRemove () {
12620 var ripple = this;
12621 if (ripple.$rippleWaveEl) {
12622 ripple.$rippleWaveEl.remove();
12623 }
12624 Object.keys(ripple).forEach(function (key) {
12625 ripple[key] = null;
12626 delete ripple[key];
12627 });
12628 ripple = null;
12629 };
12630
12631 TouchRipple.prototype.remove = function remove () {
12632 var ripple = this;
12633 if (ripple.removing) { return; }
12634 var $rippleWaveEl = this.$rippleWaveEl;
12635 var rippleTransform = this.rippleTransform;
12636 var removeTimeout = Utils.nextTick(function () {
12637 ripple.onRemove();
12638 }, 400);
12639 ripple.removing = true;
12640 $rippleWaveEl
12641 .addClass('ripple-wave-fill')
12642 .transform(rippleTransform.replace('scale(1)', 'scale(1.01)'))
12643 .transitionEnd(function () {
12644 clearTimeout(removeTimeout);
12645 Utils.nextFrame(function () {
12646 $rippleWaveEl
12647 .addClass('ripple-wave-out')
12648 .transform(rippleTransform.replace('scale(1)', 'scale(1.01)'));
12649
12650 removeTimeout = Utils.nextTick(function () {
12651 ripple.onRemove();
12652 }, 700);
12653
12654 $rippleWaveEl.transitionEnd(function () {
12655 clearTimeout(removeTimeout);
12656 ripple.onRemove();
12657 });
12658 });
12659 });
12660 };
12661
12662 var TouchRipple$1 = {
12663 name: 'touch-ripple',
12664 static: {
12665 TouchRipple: TouchRipple,
12666 },
12667 create: function create() {
12668 var app = this;
12669 app.touchRipple = {
12670 create: function create() {
12671 var args = [], len = arguments.length;
12672 while ( len-- ) args[ len ] = arguments[ len ];
12673
12674 return new (Function.prototype.bind.apply( TouchRipple, [ null ].concat( args) ));
12675 },
12676 };
12677 },
12678 };
12679
12680 var openedModals = [];
12681 var dialogsQueue = [];
12682 function clearDialogsQueue() {
12683 if (dialogsQueue.length === 0) { return; }
12684 var dialog = dialogsQueue.shift();
12685 dialog.open();
12686 }
12687 var Modal = /*@__PURE__*/(function (Framework7Class$$1) {
12688 function Modal(app, params) {
12689 Framework7Class$$1.call(this, params, [app]);
12690
12691 var modal = this;
12692
12693 var defaults = {};
12694
12695 // Extend defaults with modules params
12696 modal.useModulesParams(defaults);
12697
12698 modal.params = Utils.extend(defaults, params);
12699 modal.opened = false;
12700
12701 // Install Modules
12702 modal.useModules();
12703
12704 return this;
12705 }
12706
12707 if ( Framework7Class$$1 ) Modal.__proto__ = Framework7Class$$1;
12708 Modal.prototype = Object.create( Framework7Class$$1 && Framework7Class$$1.prototype );
12709 Modal.prototype.constructor = Modal;
12710
12711 Modal.prototype.onOpen = function onOpen () {
12712 var modal = this;
12713 modal.opened = true;
12714 openedModals.push(modal);
12715 $('html').addClass(("with-modal-" + (modal.type.toLowerCase())));
12716 modal.$el.trigger(("modal:open " + (modal.type.toLowerCase()) + ":open"), modal);
12717 modal.emit(("local::open modalOpen " + (modal.type) + "Open"), modal);
12718 };
12719
12720 Modal.prototype.onOpened = function onOpened () {
12721 var modal = this;
12722 modal.$el.trigger(("modal:opened " + (modal.type.toLowerCase()) + ":opened"), modal);
12723 modal.emit(("local::opened modalOpened " + (modal.type) + "Opened"), modal);
12724 };
12725
12726 Modal.prototype.onClose = function onClose () {
12727 var modal = this;
12728 modal.opened = false;
12729 if (!modal.type || !modal.$el) { return; }
12730 openedModals.splice(openedModals.indexOf(modal), 1);
12731 $('html').removeClass(("with-modal-" + (modal.type.toLowerCase())));
12732 modal.$el.trigger(("modal:close " + (modal.type.toLowerCase()) + ":close"), modal);
12733 modal.emit(("local::close modalClose " + (modal.type) + "Close"), modal);
12734 };
12735
12736 Modal.prototype.onClosed = function onClosed () {
12737 var modal = this;
12738 if (!modal.type || !modal.$el) { return; }
12739 modal.$el.removeClass('modal-out');
12740 modal.$el.hide();
12741 modal.$el.trigger(("modal:closed " + (modal.type.toLowerCase()) + ":closed"), modal);
12742 modal.emit(("local::closed modalClosed " + (modal.type) + "Closed"), modal);
12743 };
12744
12745 Modal.prototype.open = function open (animateModal) {
12746 var modal = this;
12747 var app = modal.app;
12748 var $el = modal.$el;
12749 var $backdropEl = modal.$backdropEl;
12750 var type = modal.type;
12751 var animate = true;
12752 if (typeof animateModal !== 'undefined') { animate = animateModal; }
12753 else if (typeof modal.params.animate !== 'undefined') {
12754 animate = modal.params.animate;
12755 }
12756
12757 if (!$el || $el.hasClass('modal-in')) {
12758 return modal;
12759 }
12760
12761 if (type === 'dialog' && app.params.modal.queueDialogs) {
12762 var pushToQueue;
12763 if ($('.dialog.modal-in').length > 0) {
12764 pushToQueue = true;
12765 } else if (openedModals.length > 0) {
12766 openedModals.forEach(function (openedModal) {
12767 if (openedModal.type === 'dialog') { pushToQueue = true; }
12768 });
12769 }
12770 if (pushToQueue) {
12771 dialogsQueue.push(modal);
12772 return modal;
12773 }
12774 }
12775
12776 var $modalParentEl = $el.parent();
12777 var wasInDom = $el.parents(doc).length > 0;
12778 if (app.params.modal.moveToRoot && !$modalParentEl.is(app.root)) {
12779 app.root.append($el);
12780 modal.once((type + "Closed"), function () {
12781 if (wasInDom) {
12782 $modalParentEl.append($el);
12783 } else {
12784 $el.remove();
12785 }
12786 });
12787 }
12788 // Show Modal
12789 $el.show();
12790
12791 /* eslint no-underscore-dangle: ["error", { "allow": ["_clientLeft"] }] */
12792 modal._clientLeft = $el[0].clientLeft;
12793
12794 // Modal
12795 function transitionEnd() {
12796 if ($el.hasClass('modal-out')) {
12797 modal.onClosed();
12798 } else if ($el.hasClass('modal-in')) {
12799 modal.onOpened();
12800 }
12801 }
12802 if (animate) {
12803 if ($backdropEl) {
12804 $backdropEl.removeClass('not-animated');
12805 $backdropEl.addClass('backdrop-in');
12806 }
12807 $el
12808 .animationEnd(function () {
12809 transitionEnd();
12810 });
12811 $el
12812 .transitionEnd(function () {
12813 transitionEnd();
12814 });
12815 $el
12816 .removeClass('modal-out not-animated')
12817 .addClass('modal-in');
12818 modal.onOpen();
12819 } else {
12820 if ($backdropEl) {
12821 $backdropEl.addClass('backdrop-in not-animated');
12822 }
12823 $el.removeClass('modal-out').addClass('modal-in not-animated');
12824 modal.onOpen();
12825 modal.onOpened();
12826 }
12827
12828 return modal;
12829 };
12830
12831 Modal.prototype.close = function close (animateModal) {
12832 var modal = this;
12833 var $el = modal.$el;
12834 var $backdropEl = modal.$backdropEl;
12835
12836 var animate = true;
12837 if (typeof animateModal !== 'undefined') { animate = animateModal; }
12838 else if (typeof modal.params.animate !== 'undefined') {
12839 animate = modal.params.animate;
12840 }
12841
12842 if (!$el || !$el.hasClass('modal-in')) {
12843 return modal;
12844 }
12845
12846 // backdrop
12847 if ($backdropEl) {
12848 var needToHideBackdrop = true;
12849 if (modal.type === 'popup') {
12850 modal.$el.prevAll('.popup.modal-in').each(function (index, popupEl) {
12851 var popupInstance = popupEl.f7Modal;
12852 if (!popupInstance) { return; }
12853 if (
12854 popupInstance.params.closeByBackdropClick
12855 && popupInstance.params.backdrop
12856 && popupInstance.backdropEl === modal.backdropEl
12857 ) {
12858 needToHideBackdrop = false;
12859 }
12860 });
12861 }
12862 if (needToHideBackdrop) {
12863 $backdropEl[animate ? 'removeClass' : 'addClass']('not-animated');
12864 $backdropEl.removeClass('backdrop-in');
12865 }
12866 }
12867
12868 // Modal
12869 $el[animate ? 'removeClass' : 'addClass']('not-animated');
12870 function transitionEnd() {
12871 if ($el.hasClass('modal-out')) {
12872 modal.onClosed();
12873 } else if ($el.hasClass('modal-in')) {
12874 modal.onOpened();
12875 }
12876 }
12877 if (animate) {
12878 $el
12879 .animationEnd(function () {
12880 transitionEnd();
12881 });
12882 $el
12883 .transitionEnd(function () {
12884 transitionEnd();
12885 });
12886 $el
12887 .removeClass('modal-in')
12888 .addClass('modal-out');
12889 // Emit close
12890 modal.onClose();
12891 } else {
12892 $el
12893 .addClass('not-animated')
12894 .removeClass('modal-in')
12895 .addClass('modal-out');
12896 // Emit close
12897 modal.onClose();
12898 modal.onClosed();
12899 }
12900
12901 if (modal.type === 'dialog') {
12902 clearDialogsQueue();
12903 }
12904
12905 return modal;
12906 };
12907
12908 Modal.prototype.destroy = function destroy () {
12909 var modal = this;
12910 if (modal.destroyed) { return; }
12911 modal.emit(("local::beforeDestroy modalBeforeDestroy " + (modal.type) + "BeforeDestroy"), modal);
12912 if (modal.$el) {
12913 modal.$el.trigger(("modal:beforedestroy " + (modal.type.toLowerCase()) + ":beforedestroy"), modal);
12914 if (modal.$el.length && modal.$el[0].f7Modal) {
12915 delete modal.$el[0].f7Modal;
12916 }
12917 }
12918 Utils.deleteProps(modal);
12919 modal.destroyed = true;
12920 };
12921
12922 return Modal;
12923 }(Framework7Class));
12924
12925 var CustomModal = /*@__PURE__*/(function (Modal$$1) {
12926 function CustomModal(app, params) {
12927 var extendedParams = Utils.extend({
12928 backdrop: true,
12929 closeByBackdropClick: true,
12930 on: {},
12931 }, params);
12932
12933 // Extends with open/close Modal methods;
12934 Modal$$1.call(this, app, extendedParams);
12935
12936 var customModal = this;
12937
12938 customModal.params = extendedParams;
12939
12940 // Find Element
12941 var $el;
12942 if (!customModal.params.el) {
12943 $el = $(customModal.params.content);
12944 } else {
12945 $el = $(customModal.params.el);
12946 }
12947
12948 if ($el && $el.length > 0 && $el[0].f7Modal) {
12949 return $el[0].f7Modal;
12950 }
12951
12952 if ($el.length === 0) {
12953 return customModal.destroy();
12954 }
12955 var $backdropEl;
12956 if (customModal.params.backdrop) {
12957 $backdropEl = app.root.children('.custom-modal-backdrop');
12958 if ($backdropEl.length === 0) {
12959 $backdropEl = $('<div class="custom-modal-backdrop"></div>');
12960 app.root.append($backdropEl);
12961 }
12962 }
12963
12964 function handleClick(e) {
12965 if (!customModal || customModal.destroyed) { return; }
12966 if ($backdropEl && e.target === $backdropEl[0]) {
12967 customModal.close();
12968 }
12969 }
12970
12971 customModal.on('customModalOpened', function () {
12972 if (customModal.params.closeByBackdropClick && customModal.params.backdrop) {
12973 app.on('click', handleClick);
12974 }
12975 });
12976 customModal.on('customModalClose', function () {
12977 if (customModal.params.closeByBackdropClick && customModal.params.backdrop) {
12978 app.off('click', handleClick);
12979 }
12980 });
12981
12982 Utils.extend(customModal, {
12983 app: app,
12984 $el: $el,
12985 el: $el[0],
12986 $backdropEl: $backdropEl,
12987 backdropEl: $backdropEl && $backdropEl[0],
12988 type: 'customModal',
12989 });
12990
12991 $el[0].f7Modal = customModal;
12992
12993 return customModal;
12994 }
12995
12996 if ( Modal$$1 ) CustomModal.__proto__ = Modal$$1;
12997 CustomModal.prototype = Object.create( Modal$$1 && Modal$$1.prototype );
12998 CustomModal.prototype.constructor = CustomModal;
12999
13000 return CustomModal;
13001 }(Modal));
13002
13003 var Modal$1 = {
13004 name: 'modal',
13005 static: {
13006 Modal: Modal,
13007 CustomModal: CustomModal,
13008 },
13009 create: function create() {
13010 var app = this;
13011 app.customModal = {
13012 create: function create(params) {
13013 return new CustomModal(app, params);
13014 },
13015 };
13016 },
13017 params: {
13018 modal: {
13019 moveToRoot: true,
13020 queueDialogs: true,
13021 },
13022 },
13023 };
13024
13025 {
13026 if (typeof window !== 'undefined') {
13027 // Template7
13028 if (!window.Template7) { window.Template7 = Template7; }
13029
13030 // Dom7
13031 if (!window.Dom7) { window.Dom7 = $; }
13032 }
13033 }
13034
13035 // Install Core Modules & Components
13036 Router.use([
13037 RouterTemplateLoaderModule,
13038 RouterComponentLoaderModule ]);
13039
13040 Framework7.use([
13041 DeviceModule,
13042 SupportModule,
13043 UtilsModule,
13044 ResizeModule,
13045 RequestModule,
13046 TouchModule,
13047 ClicksModule,
13048 Router$1,
13049 HistoryModule,
13050 StorageModule,
13051 ComponentModule,
13052 ServiceWorkerModule,
13053 Statusbar$1,
13054 View$1,
13055 Navbar$1,
13056 Toolbar$1,
13057 Subnavbar,
13058 TouchRipple$1,
13059 Modal$1 ]);
13060
13061 return Framework7;
13062
13063 }));