1 |
|
2 | (function (global, factory) {
|
3 | typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
4 | typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
5 | (factory((global.riot = {})));
|
6 | }(this, (function (exports) { 'use strict';
|
7 |
|
8 | |
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | function $(selector, ctx) {
|
15 | return (ctx || document).querySelector(selector)
|
16 | }
|
17 |
|
18 | var
|
19 |
|
20 |
|
21 |
|
22 | __TAGS_CACHE = [],
|
23 |
|
24 | __TAG_IMPL = {},
|
25 | YIELD_TAG = 'yield',
|
26 |
|
27 | |
28 |
|
29 |
|
30 | GLOBAL_MIXIN = '__global_mixin',
|
31 |
|
32 |
|
33 | ATTRS_PREFIX = 'riot-',
|
34 |
|
35 |
|
36 | REF_DIRECTIVES = ['ref', 'data-ref'],
|
37 | IS_DIRECTIVE = 'data-is',
|
38 | CONDITIONAL_DIRECTIVE = 'if',
|
39 | LOOP_DIRECTIVE = 'each',
|
40 | LOOP_NO_REORDER_DIRECTIVE = 'no-reorder',
|
41 | SHOW_DIRECTIVE = 'show',
|
42 | HIDE_DIRECTIVE = 'hide',
|
43 | KEY_DIRECTIVE = 'key',
|
44 | RIOT_EVENTS_KEY = '__riot-events__',
|
45 |
|
46 |
|
47 | T_STRING = 'string',
|
48 | T_OBJECT = 'object',
|
49 | T_UNDEF = 'undefined',
|
50 | T_FUNCTION = 'function',
|
51 |
|
52 | XLINK_NS = 'http://www.w3.org/1999/xlink',
|
53 | SVG_NS = 'http://www.w3.org/2000/svg',
|
54 | XLINK_REGEX = /^xlink:(\w+)/,
|
55 |
|
56 | WIN = typeof window === T_UNDEF ? undefined : window,
|
57 |
|
58 |
|
59 | RE_SPECIAL_TAGS = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?|opt(?:ion|group))$/,
|
60 | RE_SPECIAL_TAGS_NO_OPTION = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/,
|
61 | RE_EVENTS_PREFIX = /^on/,
|
62 | RE_HTML_ATTRS = /([-\w]+) ?= ?(?:"([^"]*)|'([^']*)|({[^}]*}))/g,
|
63 |
|
64 | CASE_SENSITIVE_ATTRIBUTES = {
|
65 | 'viewbox': 'viewBox',
|
66 | 'preserveaspectratio': 'preserveAspectRatio'
|
67 | },
|
68 | |
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | RE_BOOL_ATTRS = /^(?:disabled|checked|readonly|required|allowfullscreen|auto(?:focus|play)|compact|controls|default|formnovalidate|hidden|ismap|itemscope|loop|multiple|muted|no(?:resize|shade|validate|wrap)?|open|reversed|seamless|selected|sortable|truespeed|typemustmatch)$/,
|
75 |
|
76 | IE_VERSION = (WIN && WIN.document || {}).documentMode | 0;
|
77 |
|
78 | |
79 |
|
80 |
|
81 |
|
82 |
|
83 | function makeElement(name) {
|
84 | return name === 'svg' ? document.createElementNS(SVG_NS, name) : document.createElement(name)
|
85 | }
|
86 |
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | function setAttribute(dom, name, val) {
|
94 | var xlink = XLINK_REGEX.exec(name);
|
95 | if (xlink && xlink[1])
|
96 | { dom.setAttributeNS(XLINK_NS, xlink[1], val); }
|
97 | else
|
98 | { dom.setAttribute(name, val); }
|
99 | }
|
100 |
|
101 | var styleNode;
|
102 |
|
103 | var cssTextProp;
|
104 | var byName = {};
|
105 | var needsInject = false;
|
106 |
|
107 |
|
108 | if (WIN) {
|
109 | styleNode = ((function () {
|
110 |
|
111 | var newNode = makeElement('style');
|
112 |
|
113 | var userNode = $('style[type=riot]');
|
114 |
|
115 | setAttribute(newNode, 'type', 'text/css');
|
116 |
|
117 | if (userNode) {
|
118 | if (userNode.id) { newNode.id = userNode.id; }
|
119 | userNode.parentNode.replaceChild(newNode, userNode);
|
120 | } else { document.head.appendChild(newNode); }
|
121 |
|
122 | return newNode
|
123 | }))();
|
124 | cssTextProp = styleNode.styleSheet;
|
125 | }
|
126 |
|
127 | |
128 |
|
129 |
|
130 | var styleManager = {
|
131 | styleNode: styleNode,
|
132 | |
133 |
|
134 |
|
135 |
|
136 |
|
137 | add: function add(css, name) {
|
138 | byName[name] = css;
|
139 | needsInject = true;
|
140 | },
|
141 | |
142 |
|
143 |
|
144 |
|
145 | inject: function inject() {
|
146 | if (!WIN || !needsInject) { return }
|
147 | needsInject = false;
|
148 | var style = Object.keys(byName)
|
149 | .map(function (k) { return byName[k]; })
|
150 | .join('\n');
|
151 |
|
152 | if (cssTextProp) { cssTextProp.cssText = style; }
|
153 | else { styleNode.innerHTML = style; }
|
154 | },
|
155 |
|
156 | |
157 |
|
158 |
|
159 |
|
160 | remove: function remove(name) {
|
161 | delete byName[name];
|
162 | needsInject = true;
|
163 | }
|
164 | };
|
165 |
|
166 | |
167 |
|
168 |
|
169 |
|
170 |
|
171 |
|
172 | var skipRegex = (function () {
|
173 |
|
174 | var beforeReChars = '[{(,;:?=|&!^~>%*/';
|
175 |
|
176 | var beforeReWords = [
|
177 | 'case',
|
178 | 'default',
|
179 | 'do',
|
180 | 'else',
|
181 | 'in',
|
182 | 'instanceof',
|
183 | 'prefix',
|
184 | 'return',
|
185 | 'typeof',
|
186 | 'void',
|
187 | 'yield'
|
188 | ];
|
189 |
|
190 | var wordsLastChar = beforeReWords.reduce(function (s, w) {
|
191 | return s + w.slice(-1)
|
192 | }, '');
|
193 |
|
194 | var RE_REGEX = /^\/(?=[^*>/])[^[/\\]*(?:(?:\\.|\[(?:\\.|[^\]\\]*)*\])[^[\\/]*)*?\/[gimuy]*/;
|
195 | var RE_VN_CHAR = /[$\w]/;
|
196 |
|
197 | function prev (code, pos) {
|
198 | while (--pos >= 0 && /\s/.test(code[pos])){ }
|
199 | return pos
|
200 | }
|
201 |
|
202 | function _skipRegex (code, start) {
|
203 |
|
204 | var re = /.*/g;
|
205 | var pos = re.lastIndex = start++;
|
206 | var match = re.exec(code)[0].match(RE_REGEX);
|
207 |
|
208 | if (match) {
|
209 | var next = pos + match[0].length;
|
210 |
|
211 | pos = prev(code, pos);
|
212 | var c = code[pos];
|
213 |
|
214 | if (pos < 0 || ~beforeReChars.indexOf(c)) {
|
215 | return next
|
216 | }
|
217 |
|
218 | if (c === '.') {
|
219 |
|
220 | if (code[pos - 1] === '.') {
|
221 | start = next;
|
222 | }
|
223 |
|
224 | } else if (c === '+' || c === '-') {
|
225 |
|
226 | if (code[--pos] !== c ||
|
227 | (pos = prev(code, pos)) < 0 ||
|
228 | !RE_VN_CHAR.test(code[pos])) {
|
229 | start = next;
|
230 | }
|
231 |
|
232 | } else if (~wordsLastChar.indexOf(c)) {
|
233 |
|
234 | var end = pos + 1;
|
235 |
|
236 | while (--pos >= 0 && RE_VN_CHAR.test(code[pos])){ }
|
237 | if (~beforeReWords.indexOf(code.slice(pos + 1, end))) {
|
238 | start = next;
|
239 | }
|
240 | }
|
241 | }
|
242 |
|
243 | return start
|
244 | }
|
245 |
|
246 | return _skipRegex
|
247 |
|
248 | })();
|
249 |
|
250 | |
251 |
|
252 |
|
253 |
|
254 |
|
255 |
|
256 |
|
257 |
|
258 |
|
259 |
|
260 |
|
261 |
|
262 | var brackets = (function (UNDEF) {
|
263 |
|
264 | var
|
265 | REGLOB = 'g',
|
266 |
|
267 | R_MLCOMMS = /\/\*[^*]*\*+(?:[^*\/][^*]*\*+)*\//g,
|
268 |
|
269 | R_STRINGS = /"[^"\\]*(?:\\[\S\s][^"\\]*)*"|'[^'\\]*(?:\\[\S\s][^'\\]*)*'|`[^`\\]*(?:\\[\S\s][^`\\]*)*`/g,
|
270 |
|
271 | S_QBLOCKS = R_STRINGS.source + '|' +
|
272 | /(?:\breturn\s+|(?:[$\w\)\]]|\+\+|--)\s*(\/)(?![*\/]))/.source + '|' +
|
273 | /\/(?=[^*\/])[^[\/\\]*(?:(?:\[(?:\\.|[^\]\\]*)*\]|\\.)[^[\/\\]*)*?([^<]\/)[gim]*/.source,
|
274 |
|
275 | UNSUPPORTED = RegExp('[\\' + 'x00-\\x1F<>a-zA-Z0-9\'",;\\\\]'),
|
276 |
|
277 | NEED_ESCAPE = /(?=[[\]()*+?.^$|])/g,
|
278 |
|
279 | S_QBLOCK2 = R_STRINGS.source + '|' + /(\/)(?![*\/])/.source,
|
280 |
|
281 | FINDBRACES = {
|
282 | '(': RegExp('([()])|' + S_QBLOCK2, REGLOB),
|
283 | '[': RegExp('([[\\]])|' + S_QBLOCK2, REGLOB),
|
284 | '{': RegExp('([{}])|' + S_QBLOCK2, REGLOB)
|
285 | },
|
286 |
|
287 | DEFAULT = '{ }';
|
288 |
|
289 | var _pairs = [
|
290 | '{', '}',
|
291 | '{', '}',
|
292 | /{[^}]*}/,
|
293 | /\\([{}])/g,
|
294 | /\\({)|{/g,
|
295 | RegExp('\\\\(})|([[({])|(})|' + S_QBLOCK2, REGLOB),
|
296 | DEFAULT,
|
297 | /^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/,
|
298 | /(^|[^\\]){=[\S\s]*?}/
|
299 | ];
|
300 |
|
301 | var
|
302 | cachedBrackets = UNDEF,
|
303 | _regex,
|
304 | _cache = [],
|
305 | _settings;
|
306 |
|
307 | function _loopback (re) { return re }
|
308 |
|
309 | function _rewrite (re, bp) {
|
310 | if (!bp) { bp = _cache; }
|
311 | return new RegExp(
|
312 | re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : ''
|
313 | )
|
314 | }
|
315 |
|
316 | function _create (pair) {
|
317 | if (pair === DEFAULT) { return _pairs }
|
318 |
|
319 | var arr = pair.split(' ');
|
320 |
|
321 | if (arr.length !== 2 || UNSUPPORTED.test(pair)) {
|
322 | throw new Error('Unsupported brackets "' + pair + '"')
|
323 | }
|
324 | arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' '));
|
325 |
|
326 | arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr);
|
327 | arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr);
|
328 | arr[6] = _rewrite(_pairs[6], arr);
|
329 | arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCK2, REGLOB);
|
330 | arr[8] = pair;
|
331 | return arr
|
332 | }
|
333 |
|
334 | function _brackets (reOrIdx) {
|
335 | return reOrIdx instanceof RegExp ? _regex(reOrIdx) : _cache[reOrIdx]
|
336 | }
|
337 |
|
338 | _brackets.split = function split (str, tmpl, _bp) {
|
339 | // istanbul ignore next: _bp is for the compiler
|
340 | if (!_bp) { _bp = _cache; }
|
341 |
|
342 | var
|
343 | parts = [],
|
344 | match,
|
345 | isexpr,
|
346 | start,
|
347 | pos,
|
348 | re = _bp[6];
|
349 |
|
350 | var qblocks = [];
|
351 | var prevStr = '';
|
352 | var mark, lastIndex;
|
353 |
|
354 | isexpr = start = re.lastIndex = 0;
|
355 |
|
356 | while ((match = re.exec(str))) {
|
357 |
|
358 | lastIndex = re.lastIndex;
|
359 | pos = match.index;
|
360 |
|
361 | if (isexpr) {
|
362 |
|
363 | if (match[2]) {
|
364 |
|
365 | var ch = match[2];
|
366 | var rech = FINDBRACES[ch];
|
367 | var ix = 1;
|
368 |
|
369 | rech.lastIndex = lastIndex;
|
370 | while ((match = rech.exec(str))) {
|
371 | if (match[1]) {
|
372 | if (match[1] === ch) { ++ix; }
|
373 | else if (!--ix) { break }
|
374 | } else {
|
375 | rech.lastIndex = pushQBlock(match.index, rech.lastIndex, match[2]);
|
376 | }
|
377 | }
|
378 | re.lastIndex = ix ? str.length : rech.lastIndex;
|
379 | continue
|
380 | }
|
381 |
|
382 | if (!match[3]) {
|
383 | re.lastIndex = pushQBlock(pos, lastIndex, match[4]);
|
384 | continue
|
385 | }
|
386 | }
|
387 |
|
388 | if (!match[1]) {
|
389 | unescapeStr(str.slice(start, pos));
|
390 | start = re.lastIndex;
|
391 | re = _bp[6 + (isexpr ^= 1)];
|
392 | re.lastIndex = start;
|
393 | }
|
394 | }
|
395 |
|
396 | if (str && start < str.length) {
|
397 | unescapeStr(str.slice(start));
|
398 | }
|
399 |
|
400 | parts.qblocks = qblocks;
|
401 |
|
402 | return parts
|
403 |
|
404 | function unescapeStr (s) {
|
405 | if (prevStr) {
|
406 | s = prevStr + s;
|
407 | prevStr = '';
|
408 | }
|
409 | if (tmpl || isexpr) {
|
410 | parts.push(s && s.replace(_bp[5], '$1'));
|
411 | } else {
|
412 | parts.push(s);
|
413 | }
|
414 | }
|
415 |
|
416 | function pushQBlock(_pos, _lastIndex, slash) { //eslint-disable-line
|
417 | if (slash) {
|
418 | _lastIndex = skipRegex(str, _pos);
|
419 | }
|
420 |
|
421 | if (tmpl && _lastIndex > _pos + 2) {
|
422 | mark = '\u2057' + qblocks.length + '~';
|
423 | qblocks.push(str.slice(_pos, _lastIndex));
|
424 | prevStr += str.slice(start, _pos) + mark;
|
425 | start = _lastIndex;
|
426 | }
|
427 | return _lastIndex
|
428 | }
|
429 | };
|
430 |
|
431 | _brackets.hasExpr = function hasExpr (str) {
|
432 | return _cache[4].test(str)
|
433 | };
|
434 |
|
435 | _brackets.loopKeys = function loopKeys (expr) {
|
436 | var m = expr.match(_cache[9]);
|
437 |
|
438 | return m
|
439 | ? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] }
|
440 | : { val: expr.trim() }
|
441 | };
|
442 |
|
443 | _brackets.array = function array (pair) {
|
444 | return pair ? _create(pair) : _cache
|
445 | };
|
446 |
|
447 | function _reset (pair) {
|
448 | if ((pair || (pair = DEFAULT)) !== _cache[8]) {
|
449 | _cache = _create(pair);
|
450 | _regex = pair === DEFAULT ? _loopback : _rewrite;
|
451 | _cache[9] = _regex(_pairs[9]);
|
452 | }
|
453 | cachedBrackets = pair;
|
454 | }
|
455 |
|
456 | function _setSettings (o) {
|
457 | var b;
|
458 |
|
459 | o = o || {};
|
460 | b = o.brackets;
|
461 | Object.defineProperty(o, 'brackets', {
|
462 | set: _reset,
|
463 | get: function () { return cachedBrackets },
|
464 | enumerable: true
|
465 | });
|
466 | _settings = o;
|
467 | _reset(b);
|
468 | }
|
469 |
|
470 | Object.defineProperty(_brackets, 'settings', {
|
471 | set: _setSettings,
|
472 | get: function () { return _settings }
|
473 | });
|
474 |
|
475 | /* istanbul ignore next: in the browser riot is always in the scope */
|
476 | _brackets.settings = typeof riot !== 'undefined' && riot.settings || {};
|
477 | _brackets.set = _reset;
|
478 | _brackets.skipRegex = skipRegex;
|
479 |
|
480 | _brackets.R_STRINGS = R_STRINGS;
|
481 | _brackets.R_MLCOMMS = R_MLCOMMS;
|
482 | _brackets.S_QBLOCKS = S_QBLOCKS;
|
483 | _brackets.S_QBLOCK2 = S_QBLOCK2;
|
484 |
|
485 | return _brackets
|
486 |
|
487 | })();
|
488 |
|
489 | /**
|
490 | * @module tmpl
|
491 | *
|
492 | * tmpl - Root function, returns the template value, render with data
|
493 | * tmpl.hasExpr - Test the existence of a expression inside a string
|
494 | * tmpl.loopKeys - Get the keys for an 'each' loop (used by `_each`)
|
495 | */
|
496 |
|
497 | /* istanbul ignore next */
|
498 | var tmpl = (function () {
|
499 |
|
500 | var _cache = {};
|
501 |
|
502 | function _tmpl (str, data) {
|
503 | if (!str) { return str }
|
504 |
|
505 | return (_cache[str] || (_cache[str] = _create(str))).call(
|
506 | data, _logErr.bind({
|
507 | data: data,
|
508 | tmpl: str
|
509 | })
|
510 | )
|
511 | }
|
512 |
|
513 | _tmpl.hasExpr = brackets.hasExpr;
|
514 |
|
515 | _tmpl.loopKeys = brackets.loopKeys;
|
516 |
|
517 | // istanbul ignore next
|
518 | _tmpl.clearCache = function () { _cache = {}; };
|
519 |
|
520 | _tmpl.errorHandler = null;
|
521 |
|
522 | function _logErr (err, ctx) {
|
523 |
|
524 | err.riotData = {
|
525 | tagName: ctx && ctx.__ && ctx.__.tagName,
|
526 | _riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase
|
527 | };
|
528 |
|
529 | if (_tmpl.errorHandler) { _tmpl.errorHandler(err); }
|
530 | else if (
|
531 | typeof console !== 'undefined' &&
|
532 | typeof console.error === 'function'
|
533 | ) {
|
534 | console.error(err.message);
|
535 | console.log('<%s> %s', err.riotData.tagName || 'Unknown tag', this.tmpl); // eslint-disable-line
|
536 | console.log(this.data); // eslint-disable-line
|
537 | }
|
538 | }
|
539 |
|
540 | function _create (str) {
|
541 | var expr = _getTmpl(str);
|
542 |
|
543 | if (expr.slice(0, 11) !== 'try{return ') { expr = 'return ' + expr; }
|
544 |
|
545 | return new Function('E', expr + ';') // eslint-disable-line no-new-func
|
546 | }
|
547 |
|
548 | var RE_DQUOTE = /\u2057/g;
|
549 | var RE_QBMARK = /\u2057(\d+)~/g;
|
550 |
|
551 | function _getTmpl (str) {
|
552 | var parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1);
|
553 | var qstr = parts.qblocks;
|
554 | var expr;
|
555 |
|
556 | if (parts.length > 2 || parts[0]) {
|
557 | var i, j, list = [];
|
558 |
|
559 | for (i = j = 0; i < parts.length; ++i) {
|
560 |
|
561 | expr = parts[i];
|
562 |
|
563 | if (expr && (expr = i & 1
|
564 |
|
565 | ? _parseExpr(expr, 1, qstr)
|
566 |
|
567 | : '"' + expr
|
568 | .replace(/\\/g, '\\\\')
|
569 | .replace(/\r\n?|\n/g, '\\n')
|
570 | .replace(/"/g, '\\"') +
|
571 | '"'
|
572 |
|
573 | )) { list[j++] = expr; }
|
574 |
|
575 | }
|
576 |
|
577 | expr = j < 2 ? list[0]
|
578 | : '[' + list.join(',') + '].join("")';
|
579 |
|
580 | } else {
|
581 |
|
582 | expr = _parseExpr(parts[1], 0, qstr);
|
583 | }
|
584 |
|
585 | if (qstr.length) {
|
586 | expr = expr.replace(RE_QBMARK, function (_, pos) {
|
587 | return qstr[pos]
|
588 | .replace(/\r/g, '\\r')
|
589 | .replace(/\n/g, '\\n')
|
590 | });
|
591 | }
|
592 | return expr
|
593 | }
|
594 |
|
595 | var RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/;
|
596 | var
|
597 | RE_BREND = {
|
598 | '(': /[()]/g,
|
599 | '[': /[[\]]/g,
|
600 | '{': /[{}]/g
|
601 | };
|
602 |
|
603 | function _parseExpr (expr, asText, qstr) {
|
604 |
|
605 | expr = expr
|
606 | .replace(/\s+/g, ' ').trim()
|
607 | .replace(/\ ?([[\({},?\.:])\ ?/g, '$1');
|
608 |
|
609 | if (expr) {
|
610 | var
|
611 | list = [],
|
612 | cnt = 0,
|
613 | match;
|
614 |
|
615 | while (expr &&
|
616 | (match = expr.match(RE_CSNAME)) &&
|
617 | !match.index
|
618 | ) {
|
619 | var
|
620 | key,
|
621 | jsb,
|
622 | re = /,|([[{(])|$/g;
|
623 |
|
624 | expr = RegExp.rightContext;
|
625 | key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1];
|
626 |
|
627 | while (jsb = (match = re.exec(expr))[1]) { skipBraces(jsb, re); }
|
628 |
|
629 | jsb = expr.slice(0, match.index);
|
630 | expr = RegExp.rightContext;
|
631 |
|
632 | list[cnt++] = _wrapExpr(jsb, 1, key);
|
633 | }
|
634 |
|
635 | expr = !cnt ? _wrapExpr(expr, asText)
|
636 | : cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0];
|
637 | }
|
638 | return expr
|
639 |
|
640 | function skipBraces (ch, re) {
|
641 | var
|
642 | mm,
|
643 | lv = 1,
|
644 | ir = RE_BREND[ch];
|
645 |
|
646 | ir.lastIndex = re.lastIndex;
|
647 | while (mm = ir.exec(expr)) {
|
648 | if (mm[0] === ch) { ++lv; }
|
649 | else if (!--lv) { break }
|
650 | }
|
651 | re.lastIndex = lv ? expr.length : ir.lastIndex;
|
652 | }
|
653 | }
|
654 |
|
655 | // istanbul ignore next: not both
|
656 | var // eslint-disable-next-line max-len
|
657 | JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').',
|
658 | JS_VARNAME = /[,{][\$\w]+(?=:)|(^ *|[^$\w\.{])(?!(?:typeof|true|false|null|undefined|in|instanceof|is(?:Finite|NaN)|void|NaN|new|Date|RegExp|Math)(?![$\w]))([$_A-Za-z][$\w]*)/g,
|
659 | JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/;
|
660 |
|
661 | function _wrapExpr (expr, asText, key) {
|
662 | var tb;
|
663 |
|
664 | expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) {
|
665 | if (mvar) {
|
666 | pos = tb ? 0 : pos + match.length;
|
667 |
|
668 | if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') {
|
669 | match = p + '("' + mvar + JS_CONTEXT + mvar;
|
670 | if (pos) { tb = (s = s[pos]) === '.' || s === '(' || s === '['; }
|
671 | } else if (pos) {
|
672 | tb = !JS_NOPROPS.test(s.slice(pos));
|
673 | }
|
674 | }
|
675 | return match
|
676 | });
|
677 |
|
678 | if (tb) {
|
679 | expr = 'try{return ' + expr + '}catch(e){E(e,this)}';
|
680 | }
|
681 |
|
682 | if (key) {
|
683 |
|
684 | expr = (tb
|
685 | ? 'function(){' + expr + '}.call(this)' : '(' + expr + ')'
|
686 | ) + '?"' + key + '":""';
|
687 |
|
688 | } else if (asText) {
|
689 |
|
690 | expr = 'function(v){' + (tb
|
691 | ? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
|
692 | ) + ';return v||v===0?v:""}.call(this)';
|
693 | }
|
694 |
|
695 | return expr
|
696 | }
|
697 |
|
698 | _tmpl.version = brackets.version = 'v3.0.8';
|
699 |
|
700 | return _tmpl
|
701 |
|
702 | })();
|
703 |
|
704 | /* istanbul ignore next */
|
705 | var observable = function(el) {
|
706 |
|
707 | /**
|
708 | * Extend the original object or create a new empty one
|
709 | * @type { Object }
|
710 | */
|
711 |
|
712 | el = el || {};
|
713 |
|
714 | /**
|
715 | * Private variables
|
716 | */
|
717 | var callbacks = {},
|
718 | slice = Array.prototype.slice;
|
719 |
|
720 | /**
|
721 | * Public Api
|
722 | */
|
723 |
|
724 | // extend the el object adding the observable methods
|
725 | Object.defineProperties(el, {
|
726 | /**
|
727 | * Listen to the given `event` ands
|
728 | * execute the `callback` each time an event is triggered.
|
729 | * @param { String } event - event id
|
730 | * @param { Function } fn - callback function
|
731 | * @returns { Object } el
|
732 | */
|
733 | on: {
|
734 | value: function(event, fn) {
|
735 | if (typeof fn == 'function')
|
736 | { (callbacks[event] = callbacks[event] || []).push(fn); }
|
737 | return el
|
738 | },
|
739 | enumerable: false,
|
740 | writable: false,
|
741 | configurable: false
|
742 | },
|
743 |
|
744 | /**
|
745 | * Removes the given `event` listeners
|
746 | * @param { String } event - event id
|
747 | * @param { Function } fn - callback function
|
748 | * @returns { Object } el
|
749 | */
|
750 | off: {
|
751 | value: function(event, fn) {
|
752 | if (event == '*' && !fn) { callbacks = {}; }
|
753 | else {
|
754 | if (fn) {
|
755 | var arr = callbacks[event];
|
756 | for (var i = 0, cb; cb = arr && arr[i]; ++i) {
|
757 | if (cb == fn) { arr.splice(i--, 1); }
|
758 | }
|
759 | } else { delete callbacks[event]; }
|
760 | }
|
761 | return el
|
762 | },
|
763 | enumerable: false,
|
764 | writable: false,
|
765 | configurable: false
|
766 | },
|
767 |
|
768 | /**
|
769 | * Listen to the given `event` and
|
770 | * execute the `callback` at most once
|
771 | * @param { String } event - event id
|
772 | * @param { Function } fn - callback function
|
773 | * @returns { Object } el
|
774 | */
|
775 | one: {
|
776 | value: function(event, fn) {
|
777 | function on() {
|
778 | el.off(event, on);
|
779 | fn.apply(el, arguments);
|
780 | }
|
781 | return el.on(event, on)
|
782 | },
|
783 | enumerable: false,
|
784 | writable: false,
|
785 | configurable: false
|
786 | },
|
787 |
|
788 | /**
|
789 | * Execute all callback functions that listen to
|
790 | * the given `event`
|
791 | * @param { String } event - event id
|
792 | * @returns { Object } el
|
793 | */
|
794 | trigger: {
|
795 | value: function(event) {
|
796 | var arguments$1 = arguments;
|
797 |
|
798 |
|
799 | // getting the arguments
|
800 | var arglen = arguments.length - 1,
|
801 | args = new Array(arglen),
|
802 | fns,
|
803 | fn,
|
804 | i;
|
805 |
|
806 | for (i = 0; i < arglen; i++) {
|
807 | args[i] = arguments$1[i + 1]; // skip first argument
|
808 | }
|
809 |
|
810 | fns = slice.call(callbacks[event] || [], 0);
|
811 |
|
812 | for (i = 0; fn = fns[i]; ++i) {
|
813 | fn.apply(el, args);
|
814 | }
|
815 |
|
816 | if (callbacks['*'] && event != '*')
|
817 | { el.trigger.apply(el, ['*', event].concat(args)); }
|
818 |
|
819 | return el
|
820 | },
|
821 | enumerable: false,
|
822 | writable: false,
|
823 | configurable: false
|
824 | }
|
825 | });
|
826 |
|
827 | return el
|
828 |
|
829 | };
|
830 |
|
831 | /**
|
832 | * Short alias for Object.getOwnPropertyDescriptor
|
833 | */
|
834 | function getPropDescriptor (o, k) {
|
835 | return Object.getOwnPropertyDescriptor(o, k)
|
836 | }
|
837 |
|
838 | /**
|
839 | * Check if passed argument is undefined
|
840 | * @param { * } value -
|
841 | * @returns { Boolean } -
|
842 | */
|
843 | function isUndefined(value) {
|
844 | return typeof value === T_UNDEF
|
845 | }
|
846 |
|
847 | /**
|
848 | * Check whether object's property could be overridden
|
849 | * @param { Object } obj - source object
|
850 | * @param { String } key - object property
|
851 | * @returns { Boolean } true if writable
|
852 | */
|
853 | function isWritable(obj, key) {
|
854 | var descriptor = getPropDescriptor(obj, key);
|
855 | return isUndefined(obj[key]) || descriptor && descriptor.writable
|
856 | }
|
857 |
|
858 | /**
|
859 | * Extend any object with other properties
|
860 | * @param { Object } src - source object
|
861 | * @returns { Object } the resulting extended object
|
862 | *
|
863 | * var obj = { foo: 'baz' }
|
864 | * extend(obj, {bar: 'bar', foo: 'bar'})
|
865 | * console.log(obj) => {bar: 'bar', foo: 'bar'}
|
866 | *
|
867 | */
|
868 | function extend(src) {
|
869 | var obj;
|
870 | var i = 1;
|
871 | var args = arguments;
|
872 | var l = args.length;
|
873 |
|
874 | for (; i < l; i++) {
|
875 | if (obj = args[i]) {
|
876 | for (var key in obj) {
|
877 | // check if this property of the source object could be overridden
|
878 | if (isWritable(src, key))
|
879 | { src[key] = obj[key]; }
|
880 | }
|
881 | }
|
882 | }
|
883 | return src
|
884 | }
|
885 |
|
886 | /**
|
887 | * Alias for Object.create
|
888 | */
|
889 | function create(src) {
|
890 | return Object.create(src)
|
891 | }
|
892 |
|
893 | var settings = extend(create(brackets.settings), {
|
894 | skipAnonymousTags: true,
|
895 | // the "value" attributes will be preserved
|
896 | keepValueAttributes: false,
|
897 | // handle the auto updates on any DOM event
|
898 | autoUpdate: true
|
899 | });
|
900 |
|
901 | /**
|
902 | * Shorter and fast way to select multiple nodes in the DOM
|
903 | * @param { String } selector - DOM selector
|
904 | * @param { Object } ctx - DOM node where the targets of our search will is located
|
905 | * @returns { Object } dom nodes found
|
906 | */
|
907 | function $$(selector, ctx) {
|
908 | return [].slice.call((ctx || document).querySelectorAll(selector))
|
909 | }
|
910 |
|
911 | /**
|
912 | * Create a document text node
|
913 | * @returns { Object } create a text node to use as placeholder
|
914 | */
|
915 | function createDOMPlaceholder() {
|
916 | return document.createTextNode('')
|
917 | }
|
918 |
|
919 | /**
|
920 | * Toggle the visibility of any DOM node
|
921 | * @param { Object } dom - DOM node we want to hide
|
922 | * @param { Boolean } show - do we want to show it?
|
923 | */
|
924 |
|
925 | function toggleVisibility(dom, show) {
|
926 | dom.style.display = show ? '' : 'none';
|
927 | dom.hidden = show ? false : true;
|
928 | }
|
929 |
|
930 | /**
|
931 | * Get the value of any DOM attribute on a node
|
932 | * @param { Object } dom - DOM node we want to parse
|
933 | * @param { String } name - name of the attribute we want to get
|
934 | * @returns { String | undefined } name of the node attribute whether it exists
|
935 | */
|
936 | function getAttribute(dom, name) {
|
937 | return dom.getAttribute(name)
|
938 | }
|
939 |
|
940 | /**
|
941 | * Remove any DOM attribute from a node
|
942 | * @param { Object } dom - DOM node we want to update
|
943 | * @param { String } name - name of the property we want to remove
|
944 | */
|
945 | function removeAttribute(dom, name) {
|
946 | dom.removeAttribute(name);
|
947 | }
|
948 |
|
949 | /**
|
950 | * Set the inner html of any DOM node SVGs included
|
951 | * @param { Object } container - DOM node where we'll inject new html
|
952 | * @param { String } html - html to inject
|
953 | * @param { Boolean } isSvg - svg tags should be treated a bit differently
|
954 | */
|
955 | /* istanbul ignore next */
|
956 | function setInnerHTML(container, html, isSvg) {
|
957 | // innerHTML is not supported on svg tags so we neet to treat them differently
|
958 | if (isSvg) {
|
959 | var node = container.ownerDocument.importNode(
|
960 | new DOMParser()
|
961 | .parseFromString(("<svg xmlns=\"" + SVG_NS + "\">" + html + "</svg>"), 'application/xml')
|
962 | .documentElement,
|
963 | true
|
964 | );
|
965 |
|
966 | container.appendChild(node);
|
967 | } else {
|
968 | container.innerHTML = html;
|
969 | }
|
970 | }
|
971 |
|
972 | /**
|
973 | * Minimize risk: only zero or one _space_ between attr & value
|
974 | * @param { String } html - html string we want to parse
|
975 | * @param { Function } fn - callback function to apply on any attribute found
|
976 | */
|
977 | function walkAttributes(html, fn) {
|
978 | if (!html) { return }
|
979 | var m;
|
980 | while (m = RE_HTML_ATTRS.exec(html))
|
981 | { fn(m[1].toLowerCase(), m[2] || m[3] || m[4]); }
|
982 | }
|
983 |
|
984 | /**
|
985 | * Create a document fragment
|
986 | * @returns { Object } document fragment
|
987 | */
|
988 | function createFragment() {
|
989 | return document.createDocumentFragment()
|
990 | }
|
991 |
|
992 | /**
|
993 | * Insert safely a tag to fix #1962 #1649
|
994 | * @param { HTMLElement } root - children container
|
995 | * @param { HTMLElement } curr - node to insert
|
996 | * @param { HTMLElement } next - node that should preceed the current node inserted
|
997 | */
|
998 | function safeInsert(root, curr, next) {
|
999 | root.insertBefore(curr, next.parentNode && next);
|
1000 | }
|
1001 |
|
1002 | /**
|
1003 | * Convert a style object to a string
|
1004 | * @param { Object } style - style object we need to parse
|
1005 | * @returns { String } resulting css string
|
1006 | * @example
|
1007 | * styleObjectToString({ color: 'red', height: '10px'}) // => 'color: red; height: 10px'
|
1008 | */
|
1009 | function styleObjectToString(style) {
|
1010 | return Object.keys(style).reduce(function (acc, prop) {
|
1011 | return (acc + " " + prop + ": " + (style[prop]) + ";")
|
1012 | }, '')
|
1013 | }
|
1014 |
|
1015 | /**
|
1016 | * Walk down recursively all the children tags starting dom node
|
1017 | * @param { Object } dom - starting node where we will start the recursion
|
1018 | * @param { Function } fn - callback to transform the child node just found
|
1019 | * @param { Object } context - fn can optionally return an object, which is passed to children
|
1020 | */
|
1021 | function walkNodes(dom, fn, context) {
|
1022 | if (dom) {
|
1023 | var res = fn(dom, context);
|
1024 | var next;
|
1025 | // stop the recursion
|
1026 | if (res === false) { return }
|
1027 |
|
1028 | dom = dom.firstChild;
|
1029 |
|
1030 | while (dom) {
|
1031 | next = dom.nextSibling;
|
1032 | walkNodes(dom, fn, res);
|
1033 | dom = next;
|
1034 | }
|
1035 | }
|
1036 | }
|
1037 |
|
1038 |
|
1039 |
|
1040 | var dom = /*#__PURE__*/Object.freeze({
|
1041 | $$: $$,
|
1042 | $: $,
|
1043 | createDOMPlaceholder: createDOMPlaceholder,
|
1044 | mkEl: makeElement,
|
1045 | setAttr: setAttribute,
|
1046 | toggleVisibility: toggleVisibility,
|
1047 | getAttr: getAttribute,
|
1048 | remAttr: removeAttribute,
|
1049 | setInnerHTML: setInnerHTML,
|
1050 | walkAttrs: walkAttributes,
|
1051 | createFrag: createFragment,
|
1052 | safeInsert: safeInsert,
|
1053 | styleObjectToString: styleObjectToString,
|
1054 | walkNodes: walkNodes
|
1055 | });
|
1056 |
|
1057 | /**
|
1058 | * Check against the null and undefined values
|
1059 | * @param { * } value -
|
1060 | * @returns {Boolean} -
|
1061 | */
|
1062 | function isNil(value) {
|
1063 | return isUndefined(value) || value === null
|
1064 | }
|
1065 |
|
1066 | /**
|
1067 | * Check if passed argument is empty. Different from falsy, because we dont consider 0 or false to be blank
|
1068 | * @param { * } value -
|
1069 | * @returns { Boolean } -
|
1070 | */
|
1071 | function isBlank(value) {
|
1072 | return isNil(value) || value === ''
|
1073 | }
|
1074 |
|
1075 | /**
|
1076 | * Check if passed argument is a function
|
1077 | * @param { * } value -
|
1078 | * @returns { Boolean } -
|
1079 | */
|
1080 | function isFunction(value) {
|
1081 | return typeof value === T_FUNCTION
|
1082 | }
|
1083 |
|
1084 | /**
|
1085 | * Check if passed argument is an object, exclude null
|
1086 | * NOTE: use isObject(x) && !isArray(x) to excludes arrays.
|
1087 | * @param { * } value -
|
1088 | * @returns { Boolean } -
|
1089 | */
|
1090 | function isObject(value) {
|
1091 | return value && typeof value === T_OBJECT // typeof null is 'object'
|
1092 | }
|
1093 |
|
1094 | /**
|
1095 | * Check if a DOM node is an svg tag or part of an svg
|
1096 | * @param { HTMLElement } el - node we want to test
|
1097 | * @returns {Boolean} true if it's an svg node
|
1098 | */
|
1099 | function isSvg(el) {
|
1100 | var owner = el.ownerSVGElement;
|
1101 | return !!owner || owner === null
|
1102 | }
|
1103 |
|
1104 | /**
|
1105 | * Check if passed argument is a kind of array
|
1106 | * @param { * } value -
|
1107 | * @returns { Boolean } -
|
1108 | */
|
1109 | function isArray(value) {
|
1110 | return Array.isArray(value) || value instanceof Array
|
1111 | }
|
1112 |
|
1113 | /**
|
1114 | * Check if the passed argument is a boolean attribute
|
1115 | * @param { String } value -
|
1116 | * @returns { Boolean } -
|
1117 | */
|
1118 | function isBoolAttr(value) {
|
1119 | return RE_BOOL_ATTRS.test(value)
|
1120 | }
|
1121 |
|
1122 | /**
|
1123 | * Check if passed argument is a string
|
1124 | * @param { * } value -
|
1125 | * @returns { Boolean } -
|
1126 | */
|
1127 | function isString(value) {
|
1128 | return typeof value === T_STRING
|
1129 | }
|
1130 |
|
1131 |
|
1132 |
|
1133 | var check = /*#__PURE__*/Object.freeze({
|
1134 | isBlank: isBlank,
|
1135 | isFunction: isFunction,
|
1136 | isObject: isObject,
|
1137 | isSvg: isSvg,
|
1138 | isWritable: isWritable,
|
1139 | isArray: isArray,
|
1140 | isBoolAttr: isBoolAttr,
|
1141 | isNil: isNil,
|
1142 | isString: isString,
|
1143 | isUndefined: isUndefined
|
1144 | });
|
1145 |
|
1146 | /**
|
1147 | * Check whether an array contains an item
|
1148 | * @param { Array } array - target array
|
1149 | * @param { * } item - item to test
|
1150 | * @returns { Boolean } -
|
1151 | */
|
1152 | function contains(array, item) {
|
1153 | return array.indexOf(item) !== -1
|
1154 | }
|
1155 |
|
1156 | /**
|
1157 | * Specialized function for looping an array-like collection with `each={}`
|
1158 | * @param { Array } list - collection of items
|
1159 | * @param {Function} fn - callback function
|
1160 | * @returns { Array } the array looped
|
1161 | */
|
1162 | function each(list, fn) {
|
1163 | var len = list ? list.length : 0;
|
1164 | var i = 0;
|
1165 | for (; i < len; i++) { fn(list[i], i); }
|
1166 | return list
|
1167 | }
|
1168 |
|
1169 | /**
|
1170 | * Faster String startsWith alternative
|
1171 | * @param { String } str - source string
|
1172 | * @param { String } value - test string
|
1173 | * @returns { Boolean } -
|
1174 | */
|
1175 | function startsWith(str, value) {
|
1176 | return str.slice(0, value.length) === value
|
1177 | }
|
1178 |
|
1179 | /**
|
1180 | * Function returning always a unique identifier
|
1181 | * @returns { Number } - number from 0...n
|
1182 | */
|
1183 | var uid = (function uid() {
|
1184 | var i = -1;
|
1185 | return function () { return ++i; }
|
1186 | })();
|
1187 |
|
1188 | /**
|
1189 | * Helper function to set an immutable property
|
1190 | * @param { Object } el - object where the new property will be set
|
1191 | * @param { String } key - object key where the new property will be stored
|
1192 | * @param { * } value - value of the new property
|
1193 | * @param { Object } options - set the propery overriding the default options
|
1194 | * @returns { Object } - the initial object
|
1195 | */
|
1196 | function define(el, key, value, options) {
|
1197 | Object.defineProperty(el, key, extend({
|
1198 | value: value,
|
1199 | enumerable: false,
|
1200 | writable: false,
|
1201 | configurable: true
|
1202 | }, options));
|
1203 | return el
|
1204 | }
|
1205 |
|
1206 | /**
|
1207 | * Convert a string containing dashes to camel case
|
1208 | * @param { String } str - input string
|
1209 | * @returns { String } my-string -> myString
|
1210 | */
|
1211 | function toCamel(str) {
|
1212 | return str.replace(/-(\w)/g, function (_, c) { return c.toUpperCase(); })
|
1213 | }
|
1214 |
|
1215 | /**
|
1216 | * Warn a message via console
|
1217 | * @param {String} message - warning message
|
1218 | */
|
1219 | function warn(message) {
|
1220 | if (console && console.warn) { console.warn(message); }
|
1221 | }
|
1222 |
|
1223 |
|
1224 |
|
1225 | var misc = /*#__PURE__*/Object.freeze({
|
1226 | contains: contains,
|
1227 | each: each,
|
1228 | getPropDescriptor: getPropDescriptor,
|
1229 | startsWith: startsWith,
|
1230 | uid: uid,
|
1231 | defineProperty: define,
|
1232 | objectCreate: create,
|
1233 | extend: extend,
|
1234 | toCamel: toCamel,
|
1235 | warn: warn
|
1236 | });
|
1237 |
|
1238 | /**
|
1239 | * Set the property of an object for a given key. If something already
|
1240 | * exists there, then it becomes an array containing both the old and new value.
|
1241 | * @param { Object } obj - object on which to set the property
|
1242 | * @param { String } key - property name
|
1243 | * @param { Object } value - the value of the property to be set
|
1244 | * @param { Boolean } ensureArray - ensure that the property remains an array
|
1245 | * @param { Number } index - add the new item in a certain array position
|
1246 | */
|
1247 | function arrayishAdd(obj, key, value, ensureArray, index) {
|
1248 | var dest = obj[key];
|
1249 | var isArr = isArray(dest);
|
1250 | var hasIndex = !isUndefined(index);
|
1251 |
|
1252 | if (dest && dest === value) { return }
|
1253 |
|
1254 | // if the key was never set, set it once
|
1255 | if (!dest && ensureArray) { obj[key] = [value]; }
|
1256 | else if (!dest) { obj[key] = value; }
|
1257 | // if it was an array and not yet set
|
1258 | else {
|
1259 | if (isArr) {
|
1260 | var oldIndex = dest.indexOf(value);
|
1261 | // this item never changed its position
|
1262 | if (oldIndex === index) { return }
|
1263 | // remove the item from its old position
|
1264 | if (oldIndex !== -1) { dest.splice(oldIndex, 1); }
|
1265 | // move or add the item
|
1266 | if (hasIndex) {
|
1267 | dest.splice(index, 0, value);
|
1268 | } else {
|
1269 | dest.push(value);
|
1270 | }
|
1271 | } else { obj[key] = [dest, value]; }
|
1272 | }
|
1273 | }
|
1274 |
|
1275 | /**
|
1276 | * Detect the tag implementation by a DOM node
|
1277 | * @param { Object } dom - DOM node we need to parse to get its tag implementation
|
1278 | * @returns { Object } it returns an object containing the implementation of a custom tag (template and boot function)
|
1279 | */
|
1280 | function get(dom) {
|
1281 | return dom.tagName && __TAG_IMPL[getAttribute(dom, IS_DIRECTIVE) ||
|
1282 | getAttribute(dom, IS_DIRECTIVE) || dom.tagName.toLowerCase()]
|
1283 | }
|
1284 |
|
1285 | /**
|
1286 | * Get the tag name of any DOM node
|
1287 | * @param { Object } dom - DOM node we want to parse
|
1288 | * @param { Boolean } skipDataIs - hack to ignore the data-is attribute when attaching to parent
|
1289 | * @returns { String } name to identify this dom node in riot
|
1290 | */
|
1291 | function getName(dom, skipDataIs) {
|
1292 | var child = get(dom);
|
1293 | var namedTag = !skipDataIs && getAttribute(dom, IS_DIRECTIVE);
|
1294 | return namedTag && !tmpl.hasExpr(namedTag) ?
|
1295 | namedTag : child ? child.name : dom.tagName.toLowerCase()
|
1296 | }
|
1297 |
|
1298 | /**
|
1299 | * Return a temporary context containing also the parent properties
|
1300 | * @this Tag
|
1301 | * @param { Tag } - temporary tag context containing all the parent properties
|
1302 | */
|
1303 | function inheritParentProps() {
|
1304 | if (this.parent) { return extend(create(this), this.parent) }
|
1305 | return this
|
1306 | }
|
1307 |
|
1308 | /*
|
1309 | Includes hacks needed for the Internet Explorer version 9 and below
|
1310 | See: http://kangax.github.io/compat-table/es5/#ie8
|
1311 | http://codeplanet.io/dropping-ie8/
|
1312 | */
|
1313 |
|
1314 | var
|
1315 | reHasYield = /<yield\b/i,
|
1316 | reYieldAll = /<yield\s*(?:\/>|>([\S\s]*?)<\/yield\s*>|>)/ig,
|
1317 | reYieldSrc = /<yield\s+to=['"]([^'">]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig,
|
1318 | reYieldDest = /<yield\s+from=['"]?([-\w]+)['"]?\s*(?:\/>|>([\S\s]*?)<\/yield\s*>)/ig,
|
1319 | rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' },
|
1320 | tblTags = IE_VERSION && IE_VERSION < 10 ? RE_SPECIAL_TAGS : RE_SPECIAL_TAGS_NO_OPTION,
|
1321 | GENERIC = 'div',
|
1322 | SVG = 'svg';
|
1323 |
|
1324 |
|
1325 | /*
|
1326 | Creates the root element for table or select child elements:
|
1327 | tr/th/td/thead/tfoot/tbody/caption/col/colgroup/option/optgroup
|
1328 | */
|
1329 | function specialTags(el, tmpl, tagName) {
|
1330 |
|
1331 | var
|
1332 | select = tagName[0] === 'o',
|
1333 | parent = select ? 'select>' : 'table>';
|
1334 |
|
1335 | // trim() is important here, this ensures we don't have artifacts,
|
1336 | // so we can check if we have only one element inside the parent
|
1337 | el.innerHTML = '<' + parent + tmpl.trim() + '</' + parent;
|
1338 | parent = el.firstChild;
|
1339 |
|
1340 | // returns the immediate parent if tr/th/td/col is the only element, if not
|
1341 | // returns the whole tree, as this can include additional elements
|
1342 | /* istanbul ignore next */
|
1343 | if (select) {
|
1344 | parent.selectedIndex = -1; // for IE9, compatible w/current riot behavior
|
1345 | } else {
|
1346 | // avoids insertion of cointainer inside container (ex: tbody inside tbody)
|
1347 | var tname = rootEls[tagName];
|
1348 | if (tname && parent.childElementCount === 1) { parent = $(tname, parent); }
|
1349 | }
|
1350 | return parent
|
1351 | }
|
1352 |
|
1353 | /*
|
1354 | Replace the yield tag from any tag template with the innerHTML of the
|
1355 | original tag in the page
|
1356 | */
|
1357 | function replaceYield(tmpl, html) {
|
1358 | // do nothing if no yield
|
1359 | if (!reHasYield.test(tmpl)) { return tmpl }
|
1360 |
|
1361 | // be careful with #1343 - string on the source having `$1`
|
1362 | var src = {};
|
1363 |
|
1364 | html = html && html.replace(reYieldSrc, function (_, ref, text) {
|
1365 | src[ref] = src[ref] || text; // preserve first definition
|
1366 | return ''
|
1367 | }).trim();
|
1368 |
|
1369 | return tmpl
|
1370 | .replace(reYieldDest, function (_, ref, def) { // yield with from - to attrs
|
1371 | return src[ref] || def || ''
|
1372 | })
|
1373 | .replace(reYieldAll, function (_, def) { // yield without any "from"
|
1374 | return html || def || ''
|
1375 | })
|
1376 | }
|
1377 |
|
1378 | /**
|
1379 | * Creates a DOM element to wrap the given content. Normally an `DIV`, but can be
|
1380 | * also a `TABLE`, `SELECT`, `TBODY`, `TR`, or `COLGROUP` element.
|
1381 | *
|
1382 | * @param { String } tmpl - The template coming from the custom tag definition
|
1383 | * @param { String } html - HTML content that comes from the DOM element where you
|
1384 | * will mount the tag, mostly the original tag in the page
|
1385 | * @param { Boolean } isSvg - true if the root node is an svg
|
1386 | * @returns { HTMLElement } DOM element with _tmpl_ merged through `YIELD` with the _html_.
|
1387 | */
|
1388 | function mkdom(tmpl, html, isSvg) {
|
1389 | var match = tmpl && tmpl.match(/^\s*<([-\w]+)/);
|
1390 | var tagName = match && match[1].toLowerCase();
|
1391 | var el = makeElement(isSvg ? SVG : GENERIC);
|
1392 |
|
1393 | // replace all the yield tags with the tag inner html
|
1394 | tmpl = replaceYield(tmpl, html);
|
1395 |
|
1396 | /* istanbul ignore next */
|
1397 | if (tblTags.test(tagName))
|
1398 | { el = specialTags(el, tmpl, tagName); }
|
1399 | else
|
1400 | { setInnerHTML(el, tmpl, isSvg); }
|
1401 |
|
1402 | return el
|
1403 | }
|
1404 |
|
1405 | var EVENT_ATTR_RE = /^on/;
|
1406 |
|
1407 | /**
|
1408 | * True if the event attribute starts with 'on'
|
1409 | * @param { String } attribute - event attribute
|
1410 | * @returns { Boolean }
|
1411 | */
|
1412 | function isEventAttribute(attribute) {
|
1413 | return EVENT_ATTR_RE.test(attribute)
|
1414 | }
|
1415 |
|
1416 | /**
|
1417 | * Loop backward all the parents tree to detect the first custom parent tag
|
1418 | * @param { Object } tag - a Tag instance
|
1419 | * @returns { Object } the instance of the first custom parent tag found
|
1420 | */
|
1421 | function getImmediateCustomParent(tag) {
|
1422 | var ptag = tag;
|
1423 | while (ptag.__.isAnonymous) {
|
1424 | if (!ptag.parent) { break }
|
1425 | ptag = ptag.parent;
|
1426 | }
|
1427 | return ptag
|
1428 | }
|
1429 |
|
1430 | /**
|
1431 | * Trigger DOM events
|
1432 | * @param { HTMLElement } dom - dom element target of the event
|
1433 | * @param { Function } handler - user function
|
1434 | * @param { Object } e - event object
|
1435 | */
|
1436 | function handleEvent(dom, handler, e) {
|
1437 | var ptag = this.__.parent;
|
1438 | var item = this.__.item;
|
1439 |
|
1440 | if (!item)
|
1441 | { while (ptag && !item) {
|
1442 | item = ptag.__.item;
|
1443 | ptag = ptag.__.parent;
|
1444 | } }
|
1445 |
|
1446 | // override the event properties
|
1447 | /* istanbul ignore next */
|
1448 | if (isWritable(e, 'currentTarget')) { e.currentTarget = dom; }
|
1449 | /* istanbul ignore next */
|
1450 | if (isWritable(e, 'target')) { e.target = e.srcElement; }
|
1451 | /* istanbul ignore next */
|
1452 | if (isWritable(e, 'which')) { e.which = e.charCode || e.keyCode; }
|
1453 |
|
1454 | e.item = item;
|
1455 |
|
1456 | handler.call(this, e);
|
1457 |
|
1458 | // avoid auto updates
|
1459 | if (!settings.autoUpdate) { return }
|
1460 |
|
1461 | if (!e.preventUpdate) {
|
1462 | var p = getImmediateCustomParent(this);
|
1463 | // fixes #2083
|
1464 | if (p.isMounted) { p.update(); }
|
1465 | }
|
1466 | }
|
1467 |
|
1468 | /**
|
1469 | * Attach an event to a DOM node
|
1470 | * @param { String } name - event name
|
1471 | * @param { Function } handler - event callback
|
1472 | * @param { Object } dom - dom node
|
1473 | * @param { Tag } tag - tag instance
|
1474 | */
|
1475 | function setEventHandler(name, handler, dom, tag) {
|
1476 | var eventName;
|
1477 | var cb = handleEvent.bind(tag, dom, handler);
|
1478 |
|
1479 | // avoid to bind twice the same event
|
1480 | // possible fix for #2332
|
1481 | dom[name] = null;
|
1482 |
|
1483 | // normalize event name
|
1484 | eventName = name.replace(RE_EVENTS_PREFIX, '');
|
1485 |
|
1486 | // cache the listener into the listeners array
|
1487 | if (!contains(tag.__.listeners, dom)) { tag.__.listeners.push(dom); }
|
1488 | if (!dom[RIOT_EVENTS_KEY]) { dom[RIOT_EVENTS_KEY] = {}; }
|
1489 | if (dom[RIOT_EVENTS_KEY][name]) { dom.removeEventListener(eventName, dom[RIOT_EVENTS_KEY][name]); }
|
1490 |
|
1491 | dom[RIOT_EVENTS_KEY][name] = cb;
|
1492 | dom.addEventListener(eventName, cb, false);
|
1493 | }
|
1494 |
|
1495 | /**
|
1496 | * Create a new child tag including it correctly into its parent
|
1497 | * @param { Object } child - child tag implementation
|
1498 | * @param { Object } opts - tag options containing the DOM node where the tag will be mounted
|
1499 | * @param { String } innerHTML - inner html of the child node
|
1500 | * @param { Object } parent - instance of the parent tag including the child custom tag
|
1501 | * @returns { Object } instance of the new child tag just created
|
1502 | */
|
1503 | function initChild(child, opts, innerHTML, parent) {
|
1504 | var tag = createTag(child, opts, innerHTML);
|
1505 | var tagName = opts.tagName || getName(opts.root, true);
|
1506 | var ptag = getImmediateCustomParent(parent);
|
1507 | // fix for the parent attribute in the looped elements
|
1508 | define(tag, 'parent', ptag);
|
1509 | // store the real parent tag
|
1510 | // in some cases this could be different from the custom parent tag
|
1511 | // for example in nested loops
|
1512 | tag.__.parent = parent;
|
1513 |
|
1514 | // add this tag to the custom parent tag
|
1515 | arrayishAdd(ptag.tags, tagName, tag);
|
1516 |
|
1517 | // and also to the real parent tag
|
1518 | if (ptag !== parent)
|
1519 | { arrayishAdd(parent.tags, tagName, tag); }
|
1520 |
|
1521 | return tag
|
1522 | }
|
1523 |
|
1524 | /**
|
1525 | * Removes an item from an object at a given key. If the key points to an array,
|
1526 | * then the item is just removed from the array.
|
1527 | * @param { Object } obj - object on which to remove the property
|
1528 | * @param { String } key - property name
|
1529 | * @param { Object } value - the value of the property to be removed
|
1530 | * @param { Boolean } ensureArray - ensure that the property remains an array
|
1531 | */
|
1532 | function arrayishRemove(obj, key, value, ensureArray) {
|
1533 | if (isArray(obj[key])) {
|
1534 | var index = obj[key].indexOf(value);
|
1535 | if (index !== -1) { obj[key].splice(index, 1); }
|
1536 | if (!obj[key].length) { delete obj[key]; }
|
1537 | else if (obj[key].length === 1 && !ensureArray) { obj[key] = obj[key][0]; }
|
1538 | } else if (obj[key] === value)
|
1539 | { delete obj[key]; } // otherwise just delete the key
|
1540 | }
|
1541 |
|
1542 | /**
|
1543 | * Adds the elements for a virtual tag
|
1544 | * @this Tag
|
1545 | * @param { Node } src - the node that will do the inserting or appending
|
1546 | * @param { Tag } target - only if inserting, insert before this tag's first child
|
1547 | */
|
1548 | function makeVirtual(src, target) {
|
1549 | var this$1 = this;
|
1550 |
|
1551 | var head = createDOMPlaceholder();
|
1552 | var tail = createDOMPlaceholder();
|
1553 | var frag = createFragment();
|
1554 | var sib;
|
1555 | var el;
|
1556 |
|
1557 | this.root.insertBefore(head, this.root.firstChild);
|
1558 | this.root.appendChild(tail);
|
1559 |
|
1560 | this.__.head = el = head;
|
1561 | this.__.tail = tail;
|
1562 |
|
1563 | while (el) {
|
1564 | sib = el.nextSibling;
|
1565 | frag.appendChild(el);
|
1566 | this$1.__.virts.push(el); // hold for unmounting
|
1567 | el = sib;
|
1568 | }
|
1569 |
|
1570 | if (target)
|
1571 | { src.insertBefore(frag, target.__.head); }
|
1572 | else
|
1573 | { src.appendChild(frag); }
|
1574 | }
|
1575 |
|
1576 | /**
|
1577 | * makes a tag virtual and replaces a reference in the dom
|
1578 | * @this Tag
|
1579 | * @param { tag } the tag to make virtual
|
1580 | * @param { ref } the dom reference location
|
1581 | */
|
1582 | function makeReplaceVirtual(tag, ref) {
|
1583 | if (!ref.parentNode) { return }
|
1584 | var frag = createFragment();
|
1585 | makeVirtual.call(tag, frag);
|
1586 | ref.parentNode.replaceChild(frag, ref);
|
1587 | }
|
1588 |
|
1589 | /**
|
1590 | * Update dynamically created data-is tags with changing expressions
|
1591 | * @param { Object } expr - expression tag and expression info
|
1592 | * @param { Tag } parent - parent for tag creation
|
1593 | * @param { String } tagName - tag implementation we want to use
|
1594 | */
|
1595 | function updateDataIs(expr, parent, tagName) {
|
1596 | var tag = expr.tag || expr.dom._tag;
|
1597 | var ref;
|
1598 |
|
1599 | var ref$1 = tag ? tag.__ : {};
|
1600 | var head = ref$1.head;
|
1601 | var isVirtual = expr.dom.tagName === 'VIRTUAL';
|
1602 |
|
1603 | if (tag && expr.tagName === tagName) {
|
1604 | tag.update();
|
1605 | return
|
1606 | }
|
1607 |
|
1608 | // sync _parent to accommodate changing tagnames
|
1609 | if (tag) {
|
1610 | // need placeholder before unmount
|
1611 | if(isVirtual) {
|
1612 | ref = createDOMPlaceholder();
|
1613 | head.parentNode.insertBefore(ref, head);
|
1614 | }
|
1615 |
|
1616 | tag.unmount(true);
|
1617 | }
|
1618 |
|
1619 | // unable to get the tag name
|
1620 | if (!isString(tagName)) { return }
|
1621 |
|
1622 | expr.impl = __TAG_IMPL[tagName];
|
1623 |
|
1624 | // unknown implementation
|
1625 | if (!expr.impl) { return }
|
1626 |
|
1627 | expr.tag = tag = initChild(
|
1628 | expr.impl, {
|
1629 | root: expr.dom,
|
1630 | parent: parent,
|
1631 | tagName: tagName
|
1632 | },
|
1633 | expr.dom.innerHTML,
|
1634 | parent
|
1635 | );
|
1636 |
|
1637 | each(expr.attrs, function (a) { return setAttribute(tag.root, a.name, a.value); });
|
1638 | expr.tagName = tagName;
|
1639 | tag.mount();
|
1640 |
|
1641 | // root exist first time, after use placeholder
|
1642 | if (isVirtual) { makeReplaceVirtual(tag, ref || tag.root); }
|
1643 |
|
1644 | // parent is the placeholder tag, not the dynamic tag so clean up
|
1645 | parent.__.onUnmount = function () {
|
1646 | var delName = tag.opts.dataIs;
|
1647 | arrayishRemove(tag.parent.tags, delName, tag);
|
1648 | arrayishRemove(tag.__.parent.tags, delName, tag);
|
1649 | tag.unmount();
|
1650 | };
|
1651 | }
|
1652 |
|
1653 | /**
|
1654 | * Nomalize any attribute removing the "riot-" prefix
|
1655 | * @param { String } attrName - original attribute name
|
1656 | * @returns { String } valid html attribute name
|
1657 | */
|
1658 | function normalizeAttrName(attrName) {
|
1659 | if (!attrName) { return null }
|
1660 | attrName = attrName.replace(ATTRS_PREFIX, '');
|
1661 | if (CASE_SENSITIVE_ATTRIBUTES[attrName]) { attrName = CASE_SENSITIVE_ATTRIBUTES[attrName]; }
|
1662 | return attrName
|
1663 | }
|
1664 |
|
1665 | /**
|
1666 | * Update on single tag expression
|
1667 | * @this Tag
|
1668 | * @param { Object } expr - expression logic
|
1669 | * @returns { undefined }
|
1670 | */
|
1671 | function updateExpression(expr) {
|
1672 | if (this.root && getAttribute(this.root,'virtualized')) { return }
|
1673 |
|
1674 | var dom = expr.dom;
|
1675 | // remove the riot- prefix
|
1676 | var attrName = normalizeAttrName(expr.attr);
|
1677 | var isToggle = contains([SHOW_DIRECTIVE, HIDE_DIRECTIVE], attrName);
|
1678 | var isVirtual = expr.root && expr.root.tagName === 'VIRTUAL';
|
1679 | var ref = this.__;
|
1680 | var isAnonymous = ref.isAnonymous;
|
1681 | var parent = dom && (expr.parent || dom.parentNode);
|
1682 | var keepValueAttributes = settings.keepValueAttributes;
|
1683 | // detect the style attributes
|
1684 | var isStyleAttr = attrName === 'style';
|
1685 | var isClassAttr = attrName === 'class';
|
1686 | var isValueAttr = attrName === 'value';
|
1687 |
|
1688 | var value;
|
1689 |
|
1690 | // if it's a tag we could totally skip the rest
|
1691 | if (expr._riot_id) {
|
1692 | if (expr.__.wasCreated) {
|
1693 | expr.update();
|
1694 | // if it hasn't been mounted yet, do that now.
|
1695 | } else {
|
1696 | expr.mount();
|
1697 | if (isVirtual) {
|
1698 | makeReplaceVirtual(expr, expr.root);
|
1699 | }
|
1700 | }
|
1701 | return
|
1702 | }
|
1703 |
|
1704 | // if this expression has the update method it means it can handle the DOM changes by itself
|
1705 | if (expr.update) { return expr.update() }
|
1706 |
|
1707 | var context = isToggle && !isAnonymous ? inheritParentProps.call(this) : this;
|
1708 |
|
1709 | // ...it seems to be a simple expression so we try to calculate its value
|
1710 | value = tmpl(expr.expr, context);
|
1711 |
|
1712 | var hasValue = !isBlank(value);
|
1713 | var isObj = isObject(value);
|
1714 |
|
1715 | // convert the style/class objects to strings
|
1716 | if (isObj) {
|
1717 | if (isClassAttr) {
|
1718 | value = tmpl(JSON.stringify(value), this);
|
1719 | } else if (isStyleAttr) {
|
1720 | value = styleObjectToString(value);
|
1721 | }
|
1722 | }
|
1723 |
|
1724 | // remove original attribute
|
1725 | if (expr.attr &&
|
1726 | (
|
1727 | // the original attribute can be removed only if we are parsing the original expression
|
1728 | !expr.wasParsedOnce ||
|
1729 | // or its value is false
|
1730 | value === false ||
|
1731 | // or if its value is currently falsy...
|
1732 | // We will keep the "value" attributes if the "keepValueAttributes"
|
1733 | // is enabled though
|
1734 | (!hasValue && (!isValueAttr || isValueAttr && !keepValueAttributes))
|
1735 | )
|
1736 | ) {
|
1737 | // remove either riot-* attributes or just the attribute name
|
1738 | removeAttribute(dom, getAttribute(dom, expr.attr) ? expr.attr : attrName);
|
1739 | }
|
1740 |
|
1741 | // for the boolean attributes we don't need the value
|
1742 | // we can convert it to checked=true to checked=checked
|
1743 | if (expr.bool) { value = value ? attrName : false; }
|
1744 | if (expr.isRtag) { return updateDataIs(expr, this, value) }
|
1745 | if (expr.wasParsedOnce && expr.value === value) { return }
|
1746 |
|
1747 | // update the expression value
|
1748 | expr.value = value;
|
1749 | expr.wasParsedOnce = true;
|
1750 |
|
1751 | // if the value is an object (and it's not a style or class attribute) we can not do much more with it
|
1752 | if (isObj && !isClassAttr && !isStyleAttr && !isToggle) { return }
|
1753 | // avoid to render undefined/null values
|
1754 | if (!hasValue) { value = ''; }
|
1755 |
|
1756 | // textarea and text nodes have no attribute name
|
1757 | if (!attrName) {
|
1758 | // about #815 w/o replace: the browser converts the value to a string,
|
1759 | // the comparison by "==" does too, but not in the server
|
1760 | value += '';
|
1761 | // test for parent avoids error with invalid assignment to nodeValue
|
1762 | if (parent) {
|
1763 | // cache the parent node because somehow it will become null on IE
|
1764 | // on the next iteration
|
1765 | expr.parent = parent;
|
1766 | if (parent.tagName === 'TEXTAREA') {
|
1767 | parent.value = value; // #1113
|
1768 | if (!IE_VERSION) { dom.nodeValue = value; } // #1625 IE throws here, nodeValue
|
1769 | } // will be available on 'updated'
|
1770 | else { dom.nodeValue = value; }
|
1771 | }
|
1772 | return
|
1773 | }
|
1774 |
|
1775 | switch (true) {
|
1776 | // handle events binding
|
1777 | case isFunction(value):
|
1778 | if (isEventAttribute(attrName)) {
|
1779 | setEventHandler(attrName, value, dom, this);
|
1780 | }
|
1781 | break
|
1782 | // show / hide
|
1783 | case isToggle:
|
1784 | toggleVisibility(dom, attrName === HIDE_DIRECTIVE ? !value : value);
|
1785 | break
|
1786 | // handle attributes
|
1787 | default:
|
1788 | if (expr.bool) {
|
1789 | dom[attrName] = value;
|
1790 | }
|
1791 |
|
1792 | if (isValueAttr && dom.value !== value) {
|
1793 | dom.value = value;
|
1794 | } else if (hasValue && value !== false) {
|
1795 | setAttribute(dom, attrName, value);
|
1796 | }
|
1797 |
|
1798 | // make sure that in case of style changes
|
1799 | // the element stays hidden
|
1800 | if (isStyleAttr && dom.hidden) { toggleVisibility(dom, false); }
|
1801 | }
|
1802 | }
|
1803 |
|
1804 | /**
|
1805 | * Update all the expressions in a Tag instance
|
1806 | * @this Tag
|
1807 | * @param { Array } expressions - expression that must be re evaluated
|
1808 | */
|
1809 | function update(expressions) {
|
1810 | each(expressions, updateExpression.bind(this));
|
1811 | }
|
1812 |
|
1813 | /**
|
1814 | * We need to update opts for this tag. That requires updating the expressions
|
1815 | * in any attributes on the tag, and then copying the result onto opts.
|
1816 | * @this Tag
|
1817 | * @param {Boolean} isLoop - is it a loop tag?
|
1818 | * @param { Tag } parent - parent tag node
|
1819 | * @param { Boolean } isAnonymous - is it a tag without any impl? (a tag not registered)
|
1820 | * @param { Object } opts - tag options
|
1821 | * @param { Array } instAttrs - tag attributes array
|
1822 | */
|
1823 | function updateOpts(isLoop, parent, isAnonymous, opts, instAttrs) {
|
1824 | // isAnonymous `each` tags treat `dom` and `root` differently. In this case
|
1825 | // (and only this case) we don't need to do updateOpts, because the regular parse
|
1826 | // will update those attrs. Plus, isAnonymous tags don't need opts anyway
|
1827 | if (isLoop && isAnonymous) { return }
|
1828 | var ctx = isLoop ? inheritParentProps.call(this) : parent || this;
|
1829 |
|
1830 | each(instAttrs, function (attr) {
|
1831 | if (attr.expr) { updateExpression.call(ctx, attr.expr); }
|
1832 | // normalize the attribute names
|
1833 | opts[toCamel(attr.name).replace(ATTRS_PREFIX, '')] = attr.expr ? attr.expr.value : attr.value;
|
1834 | });
|
1835 | }
|
1836 |
|
1837 | /**
|
1838 | * Update the tag expressions and options
|
1839 | * @param { Tag } tag - tag object
|
1840 | * @param { * } data - data we want to use to extend the tag properties
|
1841 | * @param { Array } expressions - component expressions array
|
1842 | * @returns { Tag } the current tag instance
|
1843 | */
|
1844 | function componentUpdate(tag, data, expressions) {
|
1845 | var __ = tag.__;
|
1846 | var nextOpts = {};
|
1847 | var canTrigger = tag.isMounted && !__.skipAnonymous;
|
1848 |
|
1849 | // inherit properties from the parent tag
|
1850 | if (__.isAnonymous && __.parent) { extend(tag, __.parent); }
|
1851 | extend(tag, data);
|
1852 |
|
1853 | updateOpts.apply(tag, [__.isLoop, __.parent, __.isAnonymous, nextOpts, __.instAttrs]);
|
1854 |
|
1855 | if (
|
1856 | canTrigger &&
|
1857 | tag.isMounted &&
|
1858 | isFunction(tag.shouldUpdate) && !tag.shouldUpdate(data, nextOpts)
|
1859 | ) {
|
1860 | return tag
|
1861 | }
|
1862 |
|
1863 | extend(tag.opts, nextOpts);
|
1864 |
|
1865 | if (canTrigger) { tag.trigger('update', data); }
|
1866 | update.call(tag, expressions);
|
1867 | if (canTrigger) { tag.trigger('updated'); }
|
1868 |
|
1869 | return tag
|
1870 | }
|
1871 |
|
1872 | /**
|
1873 | * Get selectors for tags
|
1874 | * @param { Array } tags - tag names to select
|
1875 | * @returns { String } selector
|
1876 | */
|
1877 | function query(tags) {
|
1878 | // select all tags
|
1879 | if (!tags) {
|
1880 | var keys = Object.keys(__TAG_IMPL);
|
1881 | return keys + query(keys)
|
1882 | }
|
1883 |
|
1884 | return tags
|
1885 | .filter(function (t) { return !/[^-\w]/.test(t); })
|
1886 | .reduce(function (list, t) {
|
1887 | var name = t.trim().toLowerCase();
|
1888 | return list + ",[" + IS_DIRECTIVE + "=\"" + name + "\"]"
|
1889 | }, '')
|
1890 | }
|
1891 |
|
1892 | /**
|
1893 | * Another way to create a riot tag a bit more es6 friendly
|
1894 | * @param { HTMLElement } el - tag DOM selector or DOM node/s
|
1895 | * @param { Object } opts - tag logic
|
1896 | * @returns { Tag } new riot tag instance
|
1897 | */
|
1898 | function Tag(el, opts) {
|
1899 | // get the tag properties from the class constructor
|
1900 | var ref = this;
|
1901 | var name = ref.name;
|
1902 | var tmpl = ref.tmpl;
|
1903 | var css = ref.css;
|
1904 | var attrs = ref.attrs;
|
1905 | var onCreate = ref.onCreate;
|
1906 | // register a new tag and cache the class prototype
|
1907 | if (!__TAG_IMPL[name]) {
|
1908 | tag(name, tmpl, css, attrs, onCreate);
|
1909 | // cache the class constructor
|
1910 | __TAG_IMPL[name].class = this.constructor;
|
1911 | }
|
1912 |
|
1913 | // mount the tag using the class instance
|
1914 | mount$1(el, name, opts, this);
|
1915 | // inject the component css
|
1916 | if (css) { styleManager.inject(); }
|
1917 |
|
1918 | return this
|
1919 | }
|
1920 |
|
1921 | /**
|
1922 | * Create a new riot tag implementation
|
1923 | * @param { String } name - name/id of the new riot tag
|
1924 | * @param { String } tmpl - tag template
|
1925 | * @param { String } css - custom tag css
|
1926 | * @param { String } attrs - root tag attributes
|
1927 | * @param { Function } fn - user function
|
1928 | * @returns { String } name/id of the tag just created
|
1929 | */
|
1930 | function tag(name, tmpl, css, attrs, fn) {
|
1931 | if (isFunction(attrs)) {
|
1932 | fn = attrs;
|
1933 |
|
1934 | if (/^[\w-]+\s?=/.test(css)) {
|
1935 | attrs = css;
|
1936 | css = '';
|
1937 | } else
|
1938 | { attrs = ''; }
|
1939 | }
|
1940 |
|
1941 | if (css) {
|
1942 | if (isFunction(css))
|
1943 | { fn = css; }
|
1944 | else
|
1945 | { styleManager.add(css, name); }
|
1946 | }
|
1947 |
|
1948 | name = name.toLowerCase();
|
1949 | __TAG_IMPL[name] = { name: name, tmpl: tmpl, attrs: attrs, fn: fn };
|
1950 |
|
1951 | return name
|
1952 | }
|
1953 |
|
1954 | /**
|
1955 | * Create a new riot tag implementation (for use by the compiler)
|
1956 | * @param { String } name - name/id of the new riot tag
|
1957 | * @param { String } tmpl - tag template
|
1958 | * @param { String } css - custom tag css
|
1959 | * @param { String } attrs - root tag attributes
|
1960 | * @param { Function } fn - user function
|
1961 | * @returns { String } name/id of the tag just created
|
1962 | */
|
1963 | function tag2(name, tmpl, css, attrs, fn) {
|
1964 | if (css) { styleManager.add(css, name); }
|
1965 |
|
1966 | __TAG_IMPL[name] = { name: name, tmpl: tmpl, attrs: attrs, fn: fn };
|
1967 |
|
1968 | return name
|
1969 | }
|
1970 |
|
1971 | /**
|
1972 | * Mount a tag using a specific tag implementation
|
1973 | * @param { * } selector - tag DOM selector or DOM node/s
|
1974 | * @param { String } tagName - tag implementation name
|
1975 | * @param { Object } opts - tag logic
|
1976 | * @returns { Array } new tags instances
|
1977 | */
|
1978 | function mount(selector, tagName, opts) {
|
1979 | var tags = [];
|
1980 | var elem, allTags;
|
1981 |
|
1982 | function pushTagsTo(root) {
|
1983 | if (root.tagName) {
|
1984 | var riotTag = getAttribute(root, IS_DIRECTIVE), tag;
|
1985 |
|
1986 | // have tagName? force riot-tag to be the same
|
1987 | if (tagName && riotTag !== tagName) {
|
1988 | riotTag = tagName;
|
1989 | setAttribute(root, IS_DIRECTIVE, tagName);
|
1990 | }
|
1991 |
|
1992 | tag = mount$1(
|
1993 | root,
|
1994 | riotTag || root.tagName.toLowerCase(),
|
1995 | isFunction(opts) ? opts() : opts
|
1996 | );
|
1997 |
|
1998 | if (tag)
|
1999 | { tags.push(tag); }
|
2000 | } else if (root.length)
|
2001 | { each(root, pushTagsTo); } // assume nodeList
|
2002 | }
|
2003 |
|
2004 | // inject styles into DOM
|
2005 | styleManager.inject();
|
2006 |
|
2007 | if (isObject(tagName) || isFunction(tagName)) {
|
2008 | opts = tagName;
|
2009 | tagName = 0;
|
2010 | }
|
2011 |
|
2012 | // crawl the DOM to find the tag
|
2013 | if (isString(selector)) {
|
2014 | selector = selector === '*' ?
|
2015 | // select all registered tags
|
2016 | // & tags found with the riot-tag attribute set
|
2017 | allTags = query() :
|
2018 | // or just the ones named like the selector
|
2019 | selector + query(selector.split(/, */));
|
2020 |
|
2021 | // make sure to pass always a selector
|
2022 | // to the querySelectorAll function
|
2023 | elem = selector ? $$(selector) : [];
|
2024 | }
|
2025 | else
|
2026 | // probably you have passed already a tag or a NodeList
|
2027 | { elem = selector; }
|
2028 |
|
2029 | // select all the registered and mount them inside their root elements
|
2030 | if (tagName === '*') {
|
2031 | // get all custom tags
|
2032 | tagName = allTags || query();
|
2033 | // if the root els it's just a single tag
|
2034 | if (elem.tagName)
|
2035 | { elem = $$(tagName, elem); }
|
2036 | else {
|
2037 | // select all the children for all the different root elements
|
2038 | var nodeList = [];
|
2039 |
|
2040 | each(elem, function (_el) { return nodeList.push($$(tagName, _el)); });
|
2041 |
|
2042 | elem = nodeList;
|
2043 | }
|
2044 | // get rid of the tagName
|
2045 | tagName = 0;
|
2046 | }
|
2047 |
|
2048 | pushTagsTo(elem);
|
2049 |
|
2050 | return tags
|
2051 | }
|
2052 |
|
2053 | // Create a mixin that could be globally shared across all the tags
|
2054 | var mixins = {};
|
2055 | var globals = mixins[GLOBAL_MIXIN] = {};
|
2056 | var mixins_id = 0;
|
2057 |
|
2058 | /**
|
2059 | * Create/Return a mixin by its name
|
2060 | * @param { String } name - mixin name (global mixin if object)
|
2061 | * @param { Object } mix - mixin logic
|
2062 | * @param { Boolean } g - is global?
|
2063 | * @returns { Object } the mixin logic
|
2064 | */
|
2065 | function mixin(name, mix, g) {
|
2066 | // Unnamed global
|
2067 | if (isObject(name)) {
|
2068 | mixin(("__" + (mixins_id++) + "__"), name, true);
|
2069 | return
|
2070 | }
|
2071 |
|
2072 | var store = g ? globals : mixins;
|
2073 |
|
2074 | // Getter
|
2075 | if (!mix) {
|
2076 | if (isUndefined(store[name]))
|
2077 | { throw new Error(("Unregistered mixin: " + name)) }
|
2078 |
|
2079 | return store[name]
|
2080 | }
|
2081 |
|
2082 | // Setter
|
2083 | store[name] = isFunction(mix) ?
|
2084 | extend(mix.prototype, store[name] || {}) && mix :
|
2085 | extend(store[name] || {}, mix);
|
2086 | }
|
2087 |
|
2088 | /**
|
2089 | * Update all the tags instances created
|
2090 | * @returns { Array } all the tags instances
|
2091 | */
|
2092 | function update$1() {
|
2093 | return each(__TAGS_CACHE, function (tag) { return tag.update(); })
|
2094 | }
|
2095 |
|
2096 | function unregister(name) {
|
2097 | styleManager.remove(name);
|
2098 | return delete __TAG_IMPL[name]
|
2099 | }
|
2100 |
|
2101 | var version = 'v3.13.2';
|
2102 |
|
2103 | var core = /*#__PURE__*/Object.freeze({
|
2104 | Tag: Tag,
|
2105 | tag: tag,
|
2106 | tag2: tag2,
|
2107 | mount: mount,
|
2108 | mixin: mixin,
|
2109 | update: update$1,
|
2110 | unregister: unregister,
|
2111 | version: version
|
2112 | });
|
2113 |
|
2114 | /**
|
2115 | * Add a mixin to this tag
|
2116 | * @returns { Tag } the current tag instance
|
2117 | */
|
2118 | function componentMixin(tag$$1) {
|
2119 | var mixins = [], len = arguments.length - 1;
|
2120 | while ( len-- > 0 ) mixins[ len ] = arguments[ len + 1 ];
|
2121 |
|
2122 | each(mixins, function (mix) {
|
2123 | var instance;
|
2124 | var obj;
|
2125 | var props = [];
|
2126 |
|
2127 | // properties blacklisted and will not be bound to the tag instance
|
2128 | var propsBlacklist = ['init', '__proto__'];
|
2129 |
|
2130 | mix = isString(mix) ? mixin(mix) : mix;
|
2131 |
|
2132 | // check if the mixin is a function
|
2133 | if (isFunction(mix)) {
|
2134 | // create the new mixin instance
|
2135 | instance = new mix();
|
2136 | } else { instance = mix; }
|
2137 |
|
2138 | var proto = Object.getPrototypeOf(instance);
|
2139 |
|
2140 | // build multilevel prototype inheritance chain property list
|
2141 | do { props = props.concat(Object.getOwnPropertyNames(obj || instance)); }
|
2142 | while (obj = Object.getPrototypeOf(obj || instance))
|
2143 |
|
2144 | // loop the keys in the function prototype or the all object keys
|
2145 | each(props, function (key) {
|
2146 | // bind methods to tag
|
2147 | // allow mixins to override other properties/parent mixins
|
2148 | if (!contains(propsBlacklist, key)) {
|
2149 | // check for getters/setters
|
2150 | var descriptor = getPropDescriptor(instance, key) || getPropDescriptor(proto, key);
|
2151 | var hasGetterSetter = descriptor && (descriptor.get || descriptor.set);
|
2152 |
|
2153 | // apply method only if it does not already exist on the instance
|
2154 | if (!tag$$1.hasOwnProperty(key) && hasGetterSetter) {
|
2155 | Object.defineProperty(tag$$1, key, descriptor);
|
2156 | } else {
|
2157 | tag$$1[key] = isFunction(instance[key]) ?
|
2158 | instance[key].bind(tag$$1) :
|
2159 | instance[key];
|
2160 | }
|
2161 | }
|
2162 | });
|
2163 |
|
2164 | // init method will be called automatically
|
2165 | if (instance.init)
|
2166 | { instance.init.bind(tag$$1)(tag$$1.opts); }
|
2167 | });
|
2168 |
|
2169 | return tag$$1
|
2170 | }
|
2171 |
|
2172 | /**
|
2173 | * Move the position of a custom tag in its parent tag
|
2174 | * @this Tag
|
2175 | * @param { String } tagName - key where the tag was stored
|
2176 | * @param { Number } newPos - index where the new tag will be stored
|
2177 | */
|
2178 | function moveChild(tagName, newPos) {
|
2179 | var parent = this.parent;
|
2180 | var tags;
|
2181 | // no parent no move
|
2182 | if (!parent) { return }
|
2183 |
|
2184 | tags = parent.tags[tagName];
|
2185 |
|
2186 | if (isArray(tags))
|
2187 | { tags.splice(newPos, 0, tags.splice(tags.indexOf(this), 1)[0]); }
|
2188 | else { arrayishAdd(parent.tags, tagName, this); }
|
2189 | }
|
2190 |
|
2191 | /**
|
2192 | * Move virtual tag and all child nodes
|
2193 | * @this Tag
|
2194 | * @param { Node } src - the node that will do the inserting
|
2195 | * @param { Tag } target - insert before this tag's first child
|
2196 | */
|
2197 | function moveVirtual(src, target) {
|
2198 | var this$1 = this;
|
2199 |
|
2200 | var el = this.__.head;
|
2201 | var sib;
|
2202 | var frag = createFragment();
|
2203 |
|
2204 | while (el) {
|
2205 | sib = el.nextSibling;
|
2206 | frag.appendChild(el);
|
2207 | el = sib;
|
2208 | if (el === this$1.__.tail) {
|
2209 | frag.appendChild(el);
|
2210 | src.insertBefore(frag, target.__.head);
|
2211 | break
|
2212 | }
|
2213 | }
|
2214 | }
|
2215 |
|
2216 | /**
|
2217 | * Convert the item looped into an object used to extend the child tag properties
|
2218 | * @param { Object } expr - object containing the keys used to extend the children tags
|
2219 | * @param { * } key - value to assign to the new object returned
|
2220 | * @param { * } val - value containing the position of the item in the array
|
2221 | * @returns { Object } - new object containing the values of the original item
|
2222 | *
|
2223 | * The variables 'key' and 'val' are arbitrary.
|
2224 | * They depend on the collection type looped (Array, Object)
|
2225 | * and on the expression used on the each tag
|
2226 | *
|
2227 | */
|
2228 | function mkitem(expr, key, val) {
|
2229 | var item = {};
|
2230 | item[expr.key] = key;
|
2231 | if (expr.pos) { item[expr.pos] = val; }
|
2232 | return item
|
2233 | }
|
2234 |
|
2235 | /**
|
2236 | * Unmount the redundant tags
|
2237 | * @param { Array } items - array containing the current items to loop
|
2238 | * @param { Array } tags - array containing all the children tags
|
2239 | */
|
2240 | function unmountRedundant(items, tags, filteredItemsCount) {
|
2241 | var i = tags.length;
|
2242 | var j = items.length - filteredItemsCount;
|
2243 |
|
2244 | while (i > j) {
|
2245 | i--;
|
2246 | remove.apply(tags[i], [tags, i]);
|
2247 | }
|
2248 | }
|
2249 |
|
2250 |
|
2251 | /**
|
2252 | * Remove a child tag
|
2253 | * @this Tag
|
2254 | * @param { Array } tags - tags collection
|
2255 | * @param { Number } i - index of the tag to remove
|
2256 | */
|
2257 | function remove(tags, i) {
|
2258 | tags.splice(i, 1);
|
2259 | this.unmount();
|
2260 | arrayishRemove(this.parent, this, this.__.tagName, true);
|
2261 | }
|
2262 |
|
2263 | /**
|
2264 | * Move the nested custom tags in non custom loop tags
|
2265 | * @this Tag
|
2266 | * @param { Number } i - current position of the loop tag
|
2267 | */
|
2268 | function moveNestedTags(i) {
|
2269 | var this$1 = this;
|
2270 |
|
2271 | each(Object.keys(this.tags), function (tagName) {
|
2272 | moveChild.apply(this$1.tags[tagName], [tagName, i]);
|
2273 | });
|
2274 | }
|
2275 |
|
2276 | /**
|
2277 | * Move a child tag
|
2278 | * @this Tag
|
2279 | * @param { HTMLElement } root - dom node containing all the loop children
|
2280 | * @param { Tag } nextTag - instance of the next tag preceding the one we want to move
|
2281 | * @param { Boolean } isVirtual - is it a virtual tag?
|
2282 | */
|
2283 | function move(root, nextTag, isVirtual) {
|
2284 | if (isVirtual)
|
2285 | { moveVirtual.apply(this, [root, nextTag]); }
|
2286 | else
|
2287 | { safeInsert(root, this.root, nextTag.root); }
|
2288 | }
|
2289 |
|
2290 | /**
|
2291 | * Insert and mount a child tag
|
2292 | * @this Tag
|
2293 | * @param { HTMLElement } root - dom node containing all the loop children
|
2294 | * @param { Tag } nextTag - instance of the next tag preceding the one we want to insert
|
2295 | * @param { Boolean } isVirtual - is it a virtual tag?
|
2296 | */
|
2297 | function insert(root, nextTag, isVirtual) {
|
2298 | if (isVirtual)
|
2299 | { makeVirtual.apply(this, [root, nextTag]); }
|
2300 | else
|
2301 | { safeInsert(root, this.root, nextTag.root); }
|
2302 | }
|
2303 |
|
2304 | /**
|
2305 | * Append a new tag into the DOM
|
2306 | * @this Tag
|
2307 | * @param { HTMLElement } root - dom node containing all the loop children
|
2308 | * @param { Boolean } isVirtual - is it a virtual tag?
|
2309 | */
|
2310 | function append(root, isVirtual) {
|
2311 | if (isVirtual)
|
2312 | { makeVirtual.call(this, root); }
|
2313 | else
|
2314 | { root.appendChild(this.root); }
|
2315 | }
|
2316 |
|
2317 | /**
|
2318 | * Return the value we want to use to lookup the postion of our items in the collection
|
2319 | * @param { String } keyAttr - lookup string or expression
|
2320 | * @param { * } originalItem - original item from the collection
|
2321 | * @param { Object } keyedItem - object created by riot via { item, i in collection }
|
2322 | * @param { Boolean } hasKeyAttrExpr - flag to check whether the key is an expression
|
2323 | * @returns { * } value that we will use to figure out the item position via collection.indexOf
|
2324 | */
|
2325 | function getItemId(keyAttr, originalItem, keyedItem, hasKeyAttrExpr) {
|
2326 | if (keyAttr) {
|
2327 | return hasKeyAttrExpr ? tmpl(keyAttr, keyedItem) : originalItem[keyAttr]
|
2328 | }
|
2329 |
|
2330 | return originalItem
|
2331 | }
|
2332 |
|
2333 | /**
|
2334 | * Manage tags having the 'each'
|
2335 | * @param { HTMLElement } dom - DOM node we need to loop
|
2336 | * @param { Tag } parent - parent tag instance where the dom node is contained
|
2337 | * @param { String } expr - string contained in the 'each' attribute
|
2338 | * @returns { Object } expression object for this each loop
|
2339 | */
|
2340 | function _each(dom, parent, expr) {
|
2341 | var mustReorder = typeof getAttribute(dom, LOOP_NO_REORDER_DIRECTIVE) !== T_STRING || removeAttribute(dom, LOOP_NO_REORDER_DIRECTIVE);
|
2342 | var keyAttr = getAttribute(dom, KEY_DIRECTIVE);
|
2343 | var hasKeyAttrExpr = keyAttr ? tmpl.hasExpr(keyAttr) : false;
|
2344 | var tagName = getName(dom);
|
2345 | var impl = __TAG_IMPL[tagName];
|
2346 | var parentNode = dom.parentNode;
|
2347 | var placeholder = createDOMPlaceholder();
|
2348 | var child = get(dom);
|
2349 | var ifExpr = getAttribute(dom, CONDITIONAL_DIRECTIVE);
|
2350 | var tags = [];
|
2351 | var isLoop = true;
|
2352 | var innerHTML = dom.innerHTML;
|
2353 | var isAnonymous = !__TAG_IMPL[tagName];
|
2354 | var isVirtual = dom.tagName === 'VIRTUAL';
|
2355 | var oldItems = [];
|
2356 |
|
2357 | // remove the each property from the original tag
|
2358 | removeAttribute(dom, LOOP_DIRECTIVE);
|
2359 | removeAttribute(dom, KEY_DIRECTIVE);
|
2360 |
|
2361 | // parse the each expression
|
2362 | expr = tmpl.loopKeys(expr);
|
2363 | expr.isLoop = true;
|
2364 |
|
2365 | if (ifExpr) { removeAttribute(dom, CONDITIONAL_DIRECTIVE); }
|
2366 |
|
2367 | // insert a marked where the loop tags will be injected
|
2368 | parentNode.insertBefore(placeholder, dom);
|
2369 | parentNode.removeChild(dom);
|
2370 |
|
2371 | expr.update = function updateEach() {
|
2372 | // get the new items collection
|
2373 | expr.value = tmpl(expr.val, parent);
|
2374 |
|
2375 | var items = expr.value;
|
2376 | var frag = createFragment();
|
2377 | var isObject = !isArray(items) && !isString(items);
|
2378 | var root = placeholder.parentNode;
|
2379 | var tmpItems = [];
|
2380 | var hasKeys = isObject && !!items;
|
2381 |
|
2382 | // if this DOM was removed the update here is useless
|
2383 | // this condition fixes also a weird async issue on IE in our unit test
|
2384 | if (!root) { return }
|
2385 |
|
2386 | // object loop. any changes cause full redraw
|
2387 | if (isObject) {
|
2388 | items = items ? Object.keys(items).map(function (key) { return mkitem(expr, items[key], key); }) : [];
|
2389 | }
|
2390 |
|
2391 | // store the amount of filtered items
|
2392 | var filteredItemsCount = 0;
|
2393 |
|
2394 | // loop all the new items
|
2395 | each(items, function (_item, index) {
|
2396 | var i = index - filteredItemsCount;
|
2397 | var item = !hasKeys && expr.key ? mkitem(expr, _item, index) : _item;
|
2398 |
|
2399 | // skip this item because it must be filtered
|
2400 | if (ifExpr && !tmpl(ifExpr, extend(create(parent), item))) {
|
2401 | filteredItemsCount ++;
|
2402 | return
|
2403 | }
|
2404 |
|
2405 | var itemId = getItemId(keyAttr, _item, item, hasKeyAttrExpr);
|
2406 | // reorder only if the items are not objects
|
2407 | // or a key attribute has been provided
|
2408 | var doReorder = !isObject && mustReorder && typeof _item === T_OBJECT || keyAttr;
|
2409 | var oldPos = oldItems.indexOf(itemId);
|
2410 | var isNew = oldPos === -1;
|
2411 | var pos = !isNew && doReorder ? oldPos : i;
|
2412 | // does a tag exist in this position?
|
2413 | var tag = tags[pos];
|
2414 | var mustAppend = i >= oldItems.length;
|
2415 | var mustCreate = doReorder && isNew || !doReorder && !tag || !tags[i];
|
2416 |
|
2417 | // new tag
|
2418 | if (mustCreate) {
|
2419 | tag = createTag(impl, {
|
2420 | parent: parent,
|
2421 | isLoop: isLoop,
|
2422 | isAnonymous: isAnonymous,
|
2423 | tagName: tagName,
|
2424 | root: dom.cloneNode(isAnonymous),
|
2425 | item: item,
|
2426 | index: i,
|
2427 | }, innerHTML);
|
2428 |
|
2429 | // mount the tag
|
2430 | tag.mount();
|
2431 |
|
2432 | if (mustAppend)
|
2433 | { append.apply(tag, [frag || root, isVirtual]); }
|
2434 | else
|
2435 | { insert.apply(tag, [root, tags[i], isVirtual]); }
|
2436 |
|
2437 | if (!mustAppend) { oldItems.splice(i, 0, item); }
|
2438 | tags.splice(i, 0, tag);
|
2439 | if (child) { arrayishAdd(parent.tags, tagName, tag, true); }
|
2440 | } else if (pos !== i && doReorder) {
|
2441 | // move
|
2442 | if (keyAttr || contains(items, oldItems[pos])) {
|
2443 | move.apply(tag, [root, tags[i], isVirtual]);
|
2444 | // move the old tag instance
|
2445 | tags.splice(i, 0, tags.splice(pos, 1)[0]);
|
2446 | // move the old item
|
2447 | oldItems.splice(i, 0, oldItems.splice(pos, 1)[0]);
|
2448 | }
|
2449 |
|
2450 | // update the position attribute if it exists
|
2451 | if (expr.pos) { tag[expr.pos] = i; }
|
2452 |
|
2453 | // if the loop tags are not custom
|
2454 | // we need to move all their custom tags into the right position
|
2455 | if (!child && tag.tags) { moveNestedTags.call(tag, i); }
|
2456 | }
|
2457 |
|
2458 | // cache the original item to use it in the events bound to this node
|
2459 | // and its children
|
2460 | extend(tag.__, {
|
2461 | item: item,
|
2462 | index: i,
|
2463 | parent: parent
|
2464 | });
|
2465 |
|
2466 | tmpItems[i] = itemId;
|
2467 |
|
2468 | if (!mustCreate) { tag.update(item); }
|
2469 | });
|
2470 |
|
2471 | // remove the redundant tags
|
2472 | unmountRedundant(items, tags, filteredItemsCount);
|
2473 |
|
2474 | // clone the items array
|
2475 | oldItems = tmpItems.slice();
|
2476 |
|
2477 | root.insertBefore(frag, placeholder);
|
2478 | };
|
2479 |
|
2480 | expr.unmount = function () {
|
2481 | each(tags, function (t) { t.unmount(); });
|
2482 | };
|
2483 |
|
2484 | return expr
|
2485 | }
|
2486 |
|
2487 | var RefExpr = {
|
2488 | init: function init(dom, parent, attrName, attrValue) {
|
2489 | this.dom = dom;
|
2490 | this.attr = attrName;
|
2491 | this.rawValue = attrValue;
|
2492 | this.parent = parent;
|
2493 | this.hasExp = tmpl.hasExpr(attrValue);
|
2494 | return this
|
2495 | },
|
2496 | update: function update() {
|
2497 | var old = this.value;
|
2498 | var customParent = this.parent && getImmediateCustomParent(this.parent);
|
2499 | // if the referenced element is a custom tag, then we set the tag itself, rather than DOM
|
2500 | var tagOrDom = this.dom.__ref || this.tag || this.dom;
|
2501 |
|
2502 | this.value = this.hasExp ? tmpl(this.rawValue, this.parent) : this.rawValue;
|
2503 |
|
2504 | // the name changed, so we need to remove it from the old key (if present)
|
2505 | if (!isBlank(old) && customParent) { arrayishRemove(customParent.refs, old, tagOrDom); }
|
2506 | if (!isBlank(this.value) && isString(this.value)) {
|
2507 | // add it to the refs of parent tag (this behavior was changed >=3.0)
|
2508 | if (customParent) { arrayishAdd(
|
2509 | customParent.refs,
|
2510 | this.value,
|
2511 | tagOrDom,
|
2512 | // use an array if it's a looped node and the ref is not an expression
|
2513 | null,
|
2514 | this.parent.__.index
|
2515 | ); }
|
2516 |
|
2517 | if (this.value !== old) {
|
2518 | setAttribute(this.dom, this.attr, this.value);
|
2519 | }
|
2520 | } else {
|
2521 | removeAttribute(this.dom, this.attr);
|
2522 | }
|
2523 |
|
2524 | // cache the ref bound to this dom node
|
2525 | // to reuse it in future (see also #2329)
|
2526 | if (!this.dom.__ref) { this.dom.__ref = tagOrDom; }
|
2527 | },
|
2528 | unmount: function unmount() {
|
2529 | var tagOrDom = this.tag || this.dom;
|
2530 | var customParent = this.parent && getImmediateCustomParent(this.parent);
|
2531 | if (!isBlank(this.value) && customParent)
|
2532 | { arrayishRemove(customParent.refs, this.value, tagOrDom); }
|
2533 | }
|
2534 | };
|
2535 |
|
2536 | /**
|
2537 | * Create a new ref directive
|
2538 | * @param { HTMLElement } dom - dom node having the ref attribute
|
2539 | * @param { Tag } context - tag instance where the DOM node is located
|
2540 | * @param { String } attrName - either 'ref' or 'data-ref'
|
2541 | * @param { String } attrValue - value of the ref attribute
|
2542 | * @returns { RefExpr } a new RefExpr object
|
2543 | */
|
2544 | function createRefDirective(dom, tag, attrName, attrValue) {
|
2545 | return create(RefExpr).init(dom, tag, attrName, attrValue)
|
2546 | }
|
2547 |
|
2548 | /**
|
2549 | * Trigger the unmount method on all the expressions
|
2550 | * @param { Array } expressions - DOM expressions
|
2551 | */
|
2552 | function unmountAll(expressions) {
|
2553 | each(expressions, function (expr) {
|
2554 | if (expr.unmount) { expr.unmount(true); }
|
2555 | else if (expr.tagName) { expr.tag.unmount(true); }
|
2556 | else if (expr.unmount) { expr.unmount(); }
|
2557 | });
|
2558 | }
|
2559 |
|
2560 | var IfExpr = {
|
2561 | init: function init(dom, tag, expr) {
|
2562 | removeAttribute(dom, CONDITIONAL_DIRECTIVE);
|
2563 | extend(this, { tag: tag, expr: expr, stub: createDOMPlaceholder(), pristine: dom });
|
2564 | var p = dom.parentNode;
|
2565 | p.insertBefore(this.stub, dom);
|
2566 | p.removeChild(dom);
|
2567 |
|
2568 | return this
|
2569 | },
|
2570 | update: function update$$1() {
|
2571 | this.value = tmpl(this.expr, this.tag);
|
2572 |
|
2573 | if (!this.stub.parentNode) { return }
|
2574 |
|
2575 | if (this.value && !this.current) { // insert
|
2576 | this.current = this.pristine.cloneNode(true);
|
2577 | this.stub.parentNode.insertBefore(this.current, this.stub);
|
2578 | this.expressions = parseExpressions.apply(this.tag, [this.current, true]);
|
2579 | } else if (!this.value && this.current) { // remove
|
2580 | this.unmount();
|
2581 | this.current = null;
|
2582 | this.expressions = [];
|
2583 | }
|
2584 |
|
2585 | if (this.value) { update.call(this.tag, this.expressions); }
|
2586 | },
|
2587 | unmount: function unmount() {
|
2588 | if (this.current) {
|
2589 | if (this.current._tag) {
|
2590 | this.current._tag.unmount();
|
2591 | } else if (this.current.parentNode) {
|
2592 | this.current.parentNode.removeChild(this.current);
|
2593 | }
|
2594 | }
|
2595 |
|
2596 | unmountAll(this.expressions || []);
|
2597 | }
|
2598 | };
|
2599 |
|
2600 | /**
|
2601 | * Create a new if directive
|
2602 | * @param { HTMLElement } dom - if root dom node
|
2603 | * @param { Tag } context - tag instance where the DOM node is located
|
2604 | * @param { String } attr - if expression
|
2605 | * @returns { IFExpr } a new IfExpr object
|
2606 | */
|
2607 | function createIfDirective(dom, tag, attr) {
|
2608 | return create(IfExpr).init(dom, tag, attr)
|
2609 | }
|
2610 |
|
2611 | /**
|
2612 | * Walk the tag DOM to detect the expressions to evaluate
|
2613 | * @this Tag
|
2614 | * @param { HTMLElement } root - root tag where we will start digging the expressions
|
2615 | * @param { Boolean } mustIncludeRoot - flag to decide whether the root must be parsed as well
|
2616 | * @returns { Array } all the expressions found
|
2617 | */
|
2618 | function parseExpressions(root, mustIncludeRoot) {
|
2619 | var this$1 = this;
|
2620 |
|
2621 | var expressions = [];
|
2622 |
|
2623 | walkNodes(root, function (dom) {
|
2624 | var type = dom.nodeType;
|
2625 | var attr;
|
2626 | var tagImpl;
|
2627 |
|
2628 | if (!mustIncludeRoot && dom === root) { return }
|
2629 |
|
2630 | // text node
|
2631 | if (type === 3 && dom.parentNode.tagName !== 'STYLE' && tmpl.hasExpr(dom.nodeValue))
|
2632 | { expressions.push({dom: dom, expr: dom.nodeValue}); }
|
2633 |
|
2634 | if (type !== 1) { return }
|
2635 |
|
2636 | var isVirtual = dom.tagName === 'VIRTUAL';
|
2637 |
|
2638 | // loop. each does it's own thing (for now)
|
2639 | if (attr = getAttribute(dom, LOOP_DIRECTIVE)) {
|
2640 | if(isVirtual) { setAttribute(dom, 'loopVirtual', true); } // ignore here, handled in _each
|
2641 | expressions.push(_each(dom, this$1, attr));
|
2642 | return false
|
2643 | }
|
2644 |
|
2645 | // if-attrs become the new parent. Any following expressions (either on the current
|
2646 | // element, or below it) become children of this expression.
|
2647 | if (attr = getAttribute(dom, CONDITIONAL_DIRECTIVE)) {
|
2648 | expressions.push(createIfDirective(dom, this$1, attr));
|
2649 | return false
|
2650 | }
|
2651 |
|
2652 | if (attr = getAttribute(dom, IS_DIRECTIVE)) {
|
2653 | if (tmpl.hasExpr(attr)) {
|
2654 | expressions.push({
|
2655 | isRtag: true,
|
2656 | expr: attr,
|
2657 | dom: dom,
|
2658 | attrs: [].slice.call(dom.attributes)
|
2659 | });
|
2660 |
|
2661 | return false
|
2662 | }
|
2663 | }
|
2664 |
|
2665 | // if this is a tag, stop traversing here.
|
2666 | // we ignore the root, since parseExpressions is called while we're mounting that root
|
2667 | tagImpl = get(dom);
|
2668 |
|
2669 | if(isVirtual) {
|
2670 | if(getAttribute(dom, 'virtualized')) {dom.parentElement.removeChild(dom); } // tag created, remove from dom
|
2671 | if(!tagImpl && !getAttribute(dom, 'virtualized') && !getAttribute(dom, 'loopVirtual')) // ok to create virtual tag
|
2672 | { tagImpl = { tmpl: dom.outerHTML }; }
|
2673 | }
|
2674 |
|
2675 | if (tagImpl && (dom !== root || mustIncludeRoot)) {
|
2676 | var hasIsDirective = getAttribute(dom, IS_DIRECTIVE);
|
2677 | if(isVirtual && !hasIsDirective) { // handled in update
|
2678 | // can not remove attribute like directives
|
2679 | // so flag for removal after creation to prevent maximum stack error
|
2680 | setAttribute(dom, 'virtualized', true);
|
2681 | var tag = createTag(
|
2682 | {tmpl: dom.outerHTML},
|
2683 | {root: dom, parent: this$1},
|
2684 | dom.innerHTML
|
2685 | );
|
2686 |
|
2687 | expressions.push(tag); // no return, anonymous tag, keep parsing
|
2688 | } else {
|
2689 | if (hasIsDirective && isVirtual)
|
2690 | { warn(("Virtual tags shouldn't be used together with the \"" + IS_DIRECTIVE + "\" attribute - https://github.com/riot/riot/issues/2511")); }
|
2691 |
|
2692 | expressions.push(
|
2693 | initChild(
|
2694 | tagImpl,
|
2695 | {
|
2696 | root: dom,
|
2697 | parent: this$1
|
2698 | },
|
2699 | dom.innerHTML,
|
2700 | this$1
|
2701 | )
|
2702 | );
|
2703 | return false
|
2704 | }
|
2705 | }
|
2706 |
|
2707 | // attribute expressions
|
2708 | parseAttributes.apply(this$1, [dom, dom.attributes, function (attr, expr) {
|
2709 | if (!expr) { return }
|
2710 | expressions.push(expr);
|
2711 | }]);
|
2712 | });
|
2713 |
|
2714 | return expressions
|
2715 | }
|
2716 |
|
2717 | /**
|
2718 | * Calls `fn` for every attribute on an element. If that attr has an expression,
|
2719 | * it is also passed to fn.
|
2720 | * @this Tag
|
2721 | * @param { HTMLElement } dom - dom node to parse
|
2722 | * @param { Array } attrs - array of attributes
|
2723 | * @param { Function } fn - callback to exec on any iteration
|
2724 | */
|
2725 | function parseAttributes(dom, attrs, fn) {
|
2726 | var this$1 = this;
|
2727 |
|
2728 | each(attrs, function (attr) {
|
2729 | if (!attr) { return false }
|
2730 |
|
2731 | var name = attr.name;
|
2732 | var bool = isBoolAttr(name);
|
2733 | var expr;
|
2734 |
|
2735 | if (contains(REF_DIRECTIVES, name) && dom.tagName.toLowerCase() !== YIELD_TAG) {
|
2736 | expr = createRefDirective(dom, this$1, name, attr.value);
|
2737 | } else if (tmpl.hasExpr(attr.value)) {
|
2738 | expr = {dom: dom, expr: attr.value, attr: name, bool: bool};
|
2739 | }
|
2740 |
|
2741 | fn(attr, expr);
|
2742 | });
|
2743 | }
|
2744 |
|
2745 | /**
|
2746 | * Manage the mount state of a tag triggering also the observable events
|
2747 | * @this Tag
|
2748 | * @param { Boolean } value - ..of the isMounted flag
|
2749 | */
|
2750 | function setMountState(value) {
|
2751 | var ref = this.__;
|
2752 | var isAnonymous = ref.isAnonymous;
|
2753 | var skipAnonymous = ref.skipAnonymous;
|
2754 |
|
2755 | define(this, 'isMounted', value);
|
2756 |
|
2757 | if (!isAnonymous || !skipAnonymous) {
|
2758 | if (value) { this.trigger('mount'); }
|
2759 | else {
|
2760 | this.trigger('unmount');
|
2761 | this.off('*');
|
2762 | this.__.wasCreated = false;
|
2763 | }
|
2764 | }
|
2765 | }
|
2766 |
|
2767 | /**
|
2768 | * Mount the current tag instance
|
2769 | * @returns { Tag } the current tag instance
|
2770 | */
|
2771 | function componentMount(tag$$1, dom, expressions, opts) {
|
2772 | var __ = tag$$1.__;
|
2773 | var root = __.root;
|
2774 | root._tag = tag$$1; // keep a reference to the tag just created
|
2775 |
|
2776 | // Read all the attrs on this instance. This give us the info we need for updateOpts
|
2777 | parseAttributes.apply(__.parent, [root, root.attributes, function (attr, expr) {
|
2778 | if (!__.isAnonymous && RefExpr.isPrototypeOf(expr)) { expr.tag = tag$$1; }
|
2779 | attr.expr = expr;
|
2780 | __.instAttrs.push(attr);
|
2781 | }]);
|
2782 |
|
2783 | // update the root adding custom attributes coming from the compiler
|
2784 | walkAttributes(__.impl.attrs, function (k, v) { __.implAttrs.push({name: k, value: v}); });
|
2785 | parseAttributes.apply(tag$$1, [root, __.implAttrs, function (attr, expr) {
|
2786 | if (expr) { expressions.push(expr); }
|
2787 | else { setAttribute(root, attr.name, attr.value); }
|
2788 | }]);
|
2789 |
|
2790 | // initialiation
|
2791 | updateOpts.apply(tag$$1, [__.isLoop, __.parent, __.isAnonymous, opts, __.instAttrs]);
|
2792 |
|
2793 | // add global mixins
|
2794 | var globalMixin = mixin(GLOBAL_MIXIN);
|
2795 |
|
2796 | if (globalMixin && !__.skipAnonymous) {
|
2797 | for (var i in globalMixin) {
|
2798 | if (globalMixin.hasOwnProperty(i)) {
|
2799 | tag$$1.mixin(globalMixin[i]);
|
2800 | }
|
2801 | }
|
2802 | }
|
2803 |
|
2804 | if (__.impl.fn) { __.impl.fn.call(tag$$1, opts); }
|
2805 |
|
2806 | if (!__.skipAnonymous) { tag$$1.trigger('before-mount'); }
|
2807 |
|
2808 | // parse layout after init. fn may calculate args for nested custom tags
|
2809 | each(parseExpressions.apply(tag$$1, [dom, __.isAnonymous]), function (e) { return expressions.push(e); });
|
2810 |
|
2811 | tag$$1.update(__.item);
|
2812 |
|
2813 | if (!__.isAnonymous && !__.isInline) {
|
2814 | while (dom.firstChild) { root.appendChild(dom.firstChild); }
|
2815 | }
|
2816 |
|
2817 | define(tag$$1, 'root', root);
|
2818 |
|
2819 | // if we need to wait that the parent "mount" or "updated" event gets triggered
|
2820 | if (!__.skipAnonymous && tag$$1.parent) {
|
2821 | var p = getImmediateCustomParent(tag$$1.parent);
|
2822 | p.one(!p.isMounted ? 'mount' : 'updated', function () {
|
2823 | setMountState.call(tag$$1, true);
|
2824 | });
|
2825 | } else {
|
2826 | // otherwise it's not a child tag we can trigger its mount event
|
2827 | setMountState.call(tag$$1, true);
|
2828 | }
|
2829 |
|
2830 | tag$$1.__.wasCreated = true;
|
2831 |
|
2832 | return tag$$1
|
2833 | }
|
2834 |
|
2835 | /**
|
2836 | * Unmount the tag instance
|
2837 | * @param { Boolean } mustKeepRoot - if it's true the root node will not be removed
|
2838 | * @returns { Tag } the current tag instance
|
2839 | */
|
2840 | function tagUnmount(tag, mustKeepRoot, expressions) {
|
2841 | var __ = tag.__;
|
2842 | var root = __.root;
|
2843 | var tagIndex = __TAGS_CACHE.indexOf(tag);
|
2844 | var p = root.parentNode;
|
2845 |
|
2846 | if (!__.skipAnonymous) { tag.trigger('before-unmount'); }
|
2847 |
|
2848 | // clear all attributes coming from the mounted tag
|
2849 | walkAttributes(__.impl.attrs, function (name) {
|
2850 | if (startsWith(name, ATTRS_PREFIX))
|
2851 | { name = name.slice(ATTRS_PREFIX.length); }
|
2852 |
|
2853 | removeAttribute(root, name);
|
2854 | });
|
2855 |
|
2856 | // remove all the event listeners
|
2857 | tag.__.listeners.forEach(function (dom) {
|
2858 | Object.keys(dom[RIOT_EVENTS_KEY]).forEach(function (eventName) {
|
2859 | dom.removeEventListener(eventName, dom[RIOT_EVENTS_KEY][eventName]);
|
2860 | });
|
2861 | });
|
2862 |
|
2863 | // remove tag instance from the global tags cache collection
|
2864 | if (tagIndex !== -1) { __TAGS_CACHE.splice(tagIndex, 1); }
|
2865 |
|
2866 | // clean up the parent tags object
|
2867 | if (__.parent && !__.isAnonymous) {
|
2868 | var ptag = getImmediateCustomParent(__.parent);
|
2869 |
|
2870 | if (__.isVirtual) {
|
2871 | Object
|
2872 | .keys(tag.tags)
|
2873 | .forEach(function (tagName) { return arrayishRemove(ptag.tags, tagName, tag.tags[tagName]); });
|
2874 | } else {
|
2875 | arrayishRemove(ptag.tags, __.tagName, tag);
|
2876 | }
|
2877 | }
|
2878 |
|
2879 | // unmount all the virtual directives
|
2880 | if (tag.__.virts) {
|
2881 | each(tag.__.virts, function (v) {
|
2882 | if (v.parentNode) { v.parentNode.removeChild(v); }
|
2883 | });
|
2884 | }
|
2885 |
|
2886 | // allow expressions to unmount themselves
|
2887 | unmountAll(expressions);
|
2888 | each(__.instAttrs, function (a) { return a.expr && a.expr.unmount && a.expr.unmount(); });
|
2889 |
|
2890 | // clear the tag html if it's necessary
|
2891 | if (mustKeepRoot) { setInnerHTML(root, ''); }
|
2892 | // otherwise detach the root tag from the DOM
|
2893 | else if (p) { p.removeChild(root); }
|
2894 |
|
2895 | // custom internal unmount function to avoid relying on the observable
|
2896 | if (__.onUnmount) { __.onUnmount(); }
|
2897 |
|
2898 | // weird fix for a weird edge case #2409 and #2436
|
2899 | // some users might use your software not as you've expected
|
2900 | // so I need to add these dirty hacks to mitigate unexpected issues
|
2901 | if (!tag.isMounted) { setMountState.call(tag, true); }
|
2902 |
|
2903 | setMountState.call(tag, false);
|
2904 |
|
2905 | delete root._tag;
|
2906 |
|
2907 | return tag
|
2908 | }
|
2909 |
|
2910 | /**
|
2911 | * Tag creation factory function
|
2912 | * @constructor
|
2913 | * @param { Object } impl - it contains the tag template, and logic
|
2914 | * @param { Object } conf - tag options
|
2915 | * @param { String } innerHTML - html that eventually we need to inject in the tag
|
2916 | */
|
2917 | function createTag(impl, conf, innerHTML) {
|
2918 | if ( impl === void 0 ) impl = {};
|
2919 | if ( conf === void 0 ) conf = {};
|
2920 |
|
2921 | var tag = conf.context || {};
|
2922 | var opts = conf.opts || {};
|
2923 | var parent = conf.parent;
|
2924 | var isLoop = conf.isLoop;
|
2925 | var isAnonymous = !!conf.isAnonymous;
|
2926 | var skipAnonymous = settings.skipAnonymousTags && isAnonymous;
|
2927 | var item = conf.item;
|
2928 | // available only for the looped nodes
|
2929 | var index = conf.index;
|
2930 | // All attributes on the Tag when it's first parsed
|
2931 | var instAttrs = [];
|
2932 | // expressions on this type of Tag
|
2933 | var implAttrs = [];
|
2934 | var tmpl = impl.tmpl;
|
2935 | var expressions = [];
|
2936 | var root = conf.root;
|
2937 | var tagName = conf.tagName || getName(root);
|
2938 | var isVirtual = tagName === 'virtual';
|
2939 | var isInline = !isVirtual && !tmpl;
|
2940 | var dom;
|
2941 |
|
2942 | if (isInline || isLoop && isAnonymous) {
|
2943 | dom = root;
|
2944 | } else {
|
2945 | if (!isVirtual) { root.innerHTML = ''; }
|
2946 | dom = mkdom(tmpl, innerHTML, isSvg(root));
|
2947 | }
|
2948 |
|
2949 | // make this tag observable
|
2950 | if (!skipAnonymous) { observable(tag); }
|
2951 |
|
2952 | // only call unmount if we have a valid __TAG_IMPL (has name property)
|
2953 | if (impl.name && root._tag) { root._tag.unmount(true); }
|
2954 |
|
2955 | define(tag, '__', {
|
2956 | impl: impl,
|
2957 | root: root,
|
2958 | skipAnonymous: skipAnonymous,
|
2959 | implAttrs: implAttrs,
|
2960 | isAnonymous: isAnonymous,
|
2961 | instAttrs: instAttrs,
|
2962 | innerHTML: innerHTML,
|
2963 | tagName: tagName,
|
2964 | index: index,
|
2965 | isLoop: isLoop,
|
2966 | isInline: isInline,
|
2967 | item: item,
|
2968 | parent: parent,
|
2969 | // tags having event listeners
|
2970 | // it would be better to use weak maps here but we can not introduce breaking changes now
|
2971 | listeners: [],
|
2972 | // these vars will be needed only for the virtual tags
|
2973 | virts: [],
|
2974 | wasCreated: false,
|
2975 | tail: null,
|
2976 | head: null
|
2977 | });
|
2978 |
|
2979 | // tag protected properties
|
2980 | return [
|
2981 | ['isMounted', false],
|
2982 | // create a unique id to this tag
|
2983 | // it could be handy to use it also to improve the virtual dom rendering speed
|
2984 | ['_riot_id', uid()],
|
2985 | ['root', root],
|
2986 | ['opts', opts, { writable: true, enumerable: true }],
|
2987 | ['parent', parent || null],
|
2988 | // protect the "tags" and "refs" property from being overridden
|
2989 | ['tags', {}],
|
2990 | ['refs', {}],
|
2991 | ['update', function (data) { return componentUpdate(tag, data, expressions); }],
|
2992 | ['mixin', function () {
|
2993 | var mixins = [], len = arguments.length;
|
2994 | while ( len-- ) mixins[ len ] = arguments[ len ];
|
2995 |
|
2996 | return componentMixin.apply(void 0, [ tag ].concat( mixins ));
|
2997 | }],
|
2998 | ['mount', function () { return componentMount(tag, dom, expressions, opts); }],
|
2999 | ['unmount', function (mustKeepRoot) { return tagUnmount(tag, mustKeepRoot, expressions); }]
|
3000 | ].reduce(function (acc, ref) {
|
3001 | var key = ref[0];
|
3002 | var value = ref[1];
|
3003 | var opts = ref[2];
|
3004 |
|
3005 | define(tag, key, value, opts);
|
3006 | return acc
|
3007 | }, extend(tag, item))
|
3008 | }
|
3009 |
|
3010 | /**
|
3011 | * Mount a tag creating new Tag instance
|
3012 | * @param { Object } root - dom node where the tag will be mounted
|
3013 | * @param { String } tagName - name of the riot tag we want to mount
|
3014 | * @param { Object } opts - options to pass to the Tag instance
|
3015 | * @param { Object } ctx - optional context that will be used to extend an existing class ( used in riot.Tag )
|
3016 | * @returns { Tag } a new Tag instance
|
3017 | */
|
3018 | function mount$1(root, tagName, opts, ctx) {
|
3019 | var impl = __TAG_IMPL[tagName];
|
3020 | var implClass = __TAG_IMPL[tagName].class;
|
3021 | var context = ctx || (implClass ? create(implClass.prototype) : {});
|
3022 | // cache the inner HTML to fix #855
|
3023 | var innerHTML = root._innerHTML = root._innerHTML || root.innerHTML;
|
3024 | var conf = extend({ root: root, opts: opts, context: context }, { parent: opts ? opts.parent : null });
|
3025 | var tag;
|
3026 |
|
3027 | if (impl && root) { tag = createTag(impl, conf, innerHTML); }
|
3028 |
|
3029 | if (tag && tag.mount) {
|
3030 | tag.mount(true);
|
3031 | // add this tag to the virtualDom variable
|
3032 | if (!contains(__TAGS_CACHE, tag)) { __TAGS_CACHE.push(tag); }
|
3033 | }
|
3034 |
|
3035 | return tag
|
3036 | }
|
3037 |
|
3038 |
|
3039 |
|
3040 | var tags = /*#__PURE__*/Object.freeze({
|
3041 | arrayishAdd: arrayishAdd,
|
3042 | getTagName: getName,
|
3043 | inheritParentProps: inheritParentProps,
|
3044 | mountTo: mount$1,
|
3045 | selectTags: query,
|
3046 | arrayishRemove: arrayishRemove,
|
3047 | getTag: get,
|
3048 | initChildTag: initChild,
|
3049 | moveChildTag: moveChild,
|
3050 | makeReplaceVirtual: makeReplaceVirtual,
|
3051 | getImmediateCustomParentTag: getImmediateCustomParent,
|
3052 | makeVirtual: makeVirtual,
|
3053 | moveVirtual: moveVirtual,
|
3054 | unmountAll: unmountAll,
|
3055 | createIfDirective: createIfDirective,
|
3056 | createRefDirective: createRefDirective
|
3057 | });
|
3058 |
|
3059 | /**
|
3060 | * Riot public api
|
3061 | */
|
3062 | var settings$1 = settings;
|
3063 | var util = {
|
3064 | tmpl: tmpl,
|
3065 | brackets: brackets,
|
3066 | styleManager: styleManager,
|
3067 | vdom: __TAGS_CACHE,
|
3068 | styleNode: styleManager.styleNode,
|
3069 | // export the riot internal utils as well
|
3070 | dom: dom,
|
3071 | check: check,
|
3072 | misc: misc,
|
3073 | tags: tags
|
3074 | };
|
3075 |
|
3076 | // export the core props/methods
|
3077 | var Tag$1 = Tag;
|
3078 | var tag$1 = tag;
|
3079 | var tag2$1 = tag2;
|
3080 | var mount$2 = mount;
|
3081 | var mixin$1 = mixin;
|
3082 | var update$2 = update$1;
|
3083 | var unregister$1 = unregister;
|
3084 | var version$1 = version;
|
3085 | var observable$1 = observable;
|
3086 |
|
3087 | var riot$1 = extend({}, core, {
|
3088 | observable: observable,
|
3089 | settings: settings$1,
|
3090 | util: util,
|
3091 | });
|
3092 |
|
3093 | exports.settings = settings$1;
|
3094 | exports.util = util;
|
3095 | exports.Tag = Tag$1;
|
3096 | exports.tag = tag$1;
|
3097 | exports.tag2 = tag2$1;
|
3098 | exports.mount = mount$2;
|
3099 | exports.mixin = mixin$1;
|
3100 | exports.update = update$2;
|
3101 | exports.unregister = unregister$1;
|
3102 | exports.version = version$1;
|
3103 | exports.observable = observable$1;
|
3104 | exports.default = riot$1;
|
3105 |
|
3106 | Object.defineProperty(exports, '__esModule', { value: true });
|
3107 |
|
3108 | })));
|