riot_js-rails 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +9 -1
- data/lib/riot_js/rails/processors/processor.rb +91 -11
- data/lib/riot_js/rails/railtie.rb +8 -6
- data/lib/riot_js/rails/version.rb +1 -1
- data/vendor/assets/javascripts/compiler/brackets.js +7 -5
- data/vendor/assets/javascripts/compiler/compiler.js +129 -102
- data/vendor/assets/javascripts/compiler/parsers.js +129 -169
- data/vendor/assets/javascripts/compiler/parsers/_utils.js +47 -0
- data/vendor/assets/javascripts/compiler/parsers/buble.js +18 -0
- data/vendor/assets/javascripts/compiler/parsers/coffee.js +19 -0
- data/vendor/assets/javascripts/compiler/parsers/es6.js +18 -0
- data/vendor/assets/javascripts/compiler/parsers/jade.js +27 -0
- data/vendor/assets/javascripts/compiler/parsers/less.js +31 -0
- data/vendor/assets/javascripts/compiler/parsers/livescript.js +20 -0
- data/vendor/assets/javascripts/compiler/parsers/pug.js +23 -0
- data/vendor/assets/javascripts/compiler/parsers/sass.js +34 -0
- data/vendor/assets/javascripts/compiler/parsers/scss.js +25 -0
- data/vendor/assets/javascripts/compiler/parsers/stylus.js +26 -0
- data/vendor/assets/javascripts/compiler/parsers/typescript.js +9 -0
- data/vendor/assets/javascripts/compiler/safe-regex.js +19 -0
- data/vendor/assets/javascripts/riot.js +1870 -1876
- metadata +16 -5
- data/lib/riot_js/rails/processors/sprockets_processor_v2.rb +0 -26
- data/lib/riot_js/rails/processors/sprockets_processor_v3.rb +0 -39
@@ -0,0 +1,31 @@
|
|
1
|
+
/*
|
2
|
+
Less CSS plugin.
|
3
|
+
Part of the riot-compiler, license MIT
|
4
|
+
|
5
|
+
History
|
6
|
+
-------
|
7
|
+
2016-03-09: Initital release
|
8
|
+
*/
|
9
|
+
var
|
10
|
+
mixobj = require('./_utils').mixobj,
|
11
|
+
parser = require('less')
|
12
|
+
|
13
|
+
var defopts = {
|
14
|
+
sync: true,
|
15
|
+
syncImport: true,
|
16
|
+
compress: true
|
17
|
+
}
|
18
|
+
|
19
|
+
module.exports = function _less (tag, css, opts, url) {
|
20
|
+
var ret
|
21
|
+
|
22
|
+
opts = mixobj(defopts, { filename: url }, opts)
|
23
|
+
|
24
|
+
parser.render(css, opts, function (err, result) {
|
25
|
+
// istanbul ignore next
|
26
|
+
if (err) throw err
|
27
|
+
ret = result.css
|
28
|
+
})
|
29
|
+
|
30
|
+
return ret
|
31
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
/*
|
2
|
+
LiveScript JS plugin.
|
3
|
+
Part of the riot-compiler, license MIT
|
4
|
+
|
5
|
+
History
|
6
|
+
-------
|
7
|
+
2016-03-09: Initital release
|
8
|
+
*/
|
9
|
+
var
|
10
|
+
mixobj = require('./_utils').mixobj,
|
11
|
+
parser = require('livescript')
|
12
|
+
|
13
|
+
var defopts = {
|
14
|
+
bare: true,
|
15
|
+
header: false
|
16
|
+
}
|
17
|
+
|
18
|
+
module.exports = function _livescript (js, opts) {
|
19
|
+
return parser.compile(js, mixobj(defopts, opts))
|
20
|
+
}
|
@@ -0,0 +1,23 @@
|
|
1
|
+
/*
|
2
|
+
Jade HTML plugin.
|
3
|
+
Part of the riot-compiler, license MIT
|
4
|
+
|
5
|
+
History
|
6
|
+
-------
|
7
|
+
2016-03-09: Initital release
|
8
|
+
*/
|
9
|
+
var
|
10
|
+
mixobj = require('./_utils').mixobj,
|
11
|
+
parser = require('pug')
|
12
|
+
|
13
|
+
var defopts = {
|
14
|
+
pretty: true,
|
15
|
+
doctype: 'html'
|
16
|
+
}
|
17
|
+
|
18
|
+
module.exports = function _pug (html, opts, url) {
|
19
|
+
|
20
|
+
opts = mixobj(defopts, { filename: url }, opts)
|
21
|
+
|
22
|
+
return parser.render(html, opts)
|
23
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
/*
|
2
|
+
Sass CSS plugin.
|
3
|
+
Part of the riot-compiler, license MIT
|
4
|
+
|
5
|
+
History
|
6
|
+
-------
|
7
|
+
2016-03-09: Initital release
|
8
|
+
2016-08-30: Fixed issues with indentation
|
9
|
+
*/
|
10
|
+
var
|
11
|
+
mixobj = require('./_utils').mixobj,
|
12
|
+
getdir = require('path').dirname,
|
13
|
+
parser = require('node-sass')
|
14
|
+
|
15
|
+
var defopts = {
|
16
|
+
indentedSyntax: true,
|
17
|
+
omitSourceMapUrl: true,
|
18
|
+
outputStyle: 'compact'
|
19
|
+
}
|
20
|
+
|
21
|
+
module.exports = function _sass (tag, css, opts, url) {
|
22
|
+
var spc = css.match(/^\s+/)
|
23
|
+
|
24
|
+
if (spc) {
|
25
|
+
css = css.replace(RegExp('^' + spc[0], 'gm'), '')
|
26
|
+
if (/^\t/gm.test(css)) {
|
27
|
+
opts.indentType = 'tab'
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
opts = mixobj(defopts, { data: css, includePaths: [getdir(url)] }, opts)
|
32
|
+
|
33
|
+
return parser.renderSync(opts).css + ''
|
34
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
/*
|
2
|
+
Scss CSS plugin.
|
3
|
+
Part of the riot-compiler, license MIT
|
4
|
+
|
5
|
+
History
|
6
|
+
-------
|
7
|
+
2016-03-09: Initital release
|
8
|
+
*/
|
9
|
+
var
|
10
|
+
mixobj = require('./_utils').mixobj,
|
11
|
+
getdir = require('path').dirname,
|
12
|
+
parser = require('node-sass')
|
13
|
+
|
14
|
+
var defopts = {
|
15
|
+
indentedSyntax: false,
|
16
|
+
omitSourceMapUrl: true,
|
17
|
+
outputStyle: 'compact'
|
18
|
+
}
|
19
|
+
|
20
|
+
module.exports = function _scss (tag, css, opts, url) {
|
21
|
+
|
22
|
+
opts = mixobj(defopts, { data: css, includePaths: [getdir(url)] }, opts)
|
23
|
+
|
24
|
+
return parser.renderSync(opts).css + ''
|
25
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
/*
|
2
|
+
Stylus CSS plugin, with optional nib support.
|
3
|
+
Part of the riot-compiler, license MIT
|
4
|
+
|
5
|
+
History
|
6
|
+
-------
|
7
|
+
2016-03-09: Initital release
|
8
|
+
*/
|
9
|
+
var
|
10
|
+
mixobj = require('./_utils').mixobj,
|
11
|
+
tryreq = require('./_utils').tryreq,
|
12
|
+
parser = require('stylus')
|
13
|
+
|
14
|
+
// Optional nib support
|
15
|
+
var nib = tryreq('nib')
|
16
|
+
|
17
|
+
// istanbul ignore next: can't run both
|
18
|
+
module.exports = nib
|
19
|
+
? function _stylus (tag, css, opts, url) {
|
20
|
+
opts = mixobj({ filename: url }, opts)
|
21
|
+
return parser(css, opts).use(nib()).import('nib').render()
|
22
|
+
}
|
23
|
+
: function _stylus (tag, css, opts, url) {
|
24
|
+
opts = mixobj({ filename: url }, opts)
|
25
|
+
return parser.render(css, opts)
|
26
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
'use strict'
|
3
|
+
|
4
|
+
// istanbul ignore next
|
5
|
+
function safeRegex (re) {
|
6
|
+
var src = re.source
|
7
|
+
var opt = re.global ? 'g' : ''
|
8
|
+
|
9
|
+
if (re.ignoreCase) opt += 'i'
|
10
|
+
if (re.multiline) opt += 'm'
|
11
|
+
|
12
|
+
for (var i = 1; i < arguments.length; i++) {
|
13
|
+
src = src.replace('@', '\\' + arguments[i])
|
14
|
+
}
|
15
|
+
|
16
|
+
return new RegExp(src, opt)
|
17
|
+
}
|
18
|
+
|
19
|
+
module.exports = safeRegex
|
@@ -1,539 +1,377 @@
|
|
1
|
-
/* Riot
|
2
|
-
|
3
|
-
|
4
|
-
'
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
// detect firefox to fix #1374
|
43
|
-
FIREFOX = window && !!window.InstallTrigger
|
44
|
-
/* istanbul ignore next */
|
45
|
-
riot.observable = function(el) {
|
46
|
-
|
47
|
-
/**
|
48
|
-
* Extend the original object or create a new empty one
|
49
|
-
* @type { Object }
|
50
|
-
*/
|
51
|
-
|
52
|
-
el = el || {}
|
53
|
-
|
54
|
-
/**
|
55
|
-
* Private variables
|
56
|
-
*/
|
57
|
-
var callbacks = {},
|
58
|
-
slice = Array.prototype.slice
|
59
|
-
|
60
|
-
/**
|
61
|
-
* Private Methods
|
62
|
-
*/
|
63
|
-
|
64
|
-
/**
|
65
|
-
* Helper function needed to get and loop all the events in a string
|
66
|
-
* @param { String } e - event string
|
67
|
-
* @param {Function} fn - callback
|
68
|
-
*/
|
69
|
-
function onEachEvent(e, fn) {
|
70
|
-
var es = e.split(' '), l = es.length, i = 0
|
71
|
-
for (; i < l; i++) {
|
72
|
-
var name = es[i]
|
73
|
-
if (name) fn(name, i)
|
74
|
-
}
|
75
|
-
}
|
76
|
-
|
77
|
-
/**
|
78
|
-
* Public Api
|
79
|
-
*/
|
80
|
-
|
81
|
-
// extend the el object adding the observable methods
|
82
|
-
Object.defineProperties(el, {
|
83
|
-
/**
|
84
|
-
* Listen to the given space separated list of `events` and
|
85
|
-
* execute the `callback` each time an event is triggered.
|
86
|
-
* @param { String } events - events ids
|
87
|
-
* @param { Function } fn - callback function
|
88
|
-
* @returns { Object } el
|
89
|
-
*/
|
90
|
-
on: {
|
91
|
-
value: function(events, fn) {
|
92
|
-
if (typeof fn != 'function') return el
|
93
|
-
|
94
|
-
onEachEvent(events, function(name, pos) {
|
95
|
-
(callbacks[name] = callbacks[name] || []).push(fn)
|
96
|
-
fn.typed = pos > 0
|
97
|
-
})
|
98
|
-
|
99
|
-
return el
|
100
|
-
},
|
101
|
-
enumerable: false,
|
102
|
-
writable: false,
|
103
|
-
configurable: false
|
104
|
-
},
|
105
|
-
|
106
|
-
/**
|
107
|
-
* Removes the given space separated list of `events` listeners
|
108
|
-
* @param { String } events - events ids
|
109
|
-
* @param { Function } fn - callback function
|
110
|
-
* @returns { Object } el
|
111
|
-
*/
|
112
|
-
off: {
|
113
|
-
value: function(events, fn) {
|
114
|
-
if (events == '*' && !fn) callbacks = {}
|
115
|
-
else {
|
116
|
-
onEachEvent(events, function(name, pos) {
|
117
|
-
if (fn) {
|
118
|
-
var arr = callbacks[name]
|
119
|
-
for (var i = 0, cb; cb = arr && arr[i]; ++i) {
|
120
|
-
if (cb == fn) arr.splice(i--, 1)
|
121
|
-
}
|
122
|
-
} else delete callbacks[name]
|
123
|
-
})
|
124
|
-
}
|
125
|
-
return el
|
126
|
-
},
|
127
|
-
enumerable: false,
|
128
|
-
writable: false,
|
129
|
-
configurable: false
|
130
|
-
},
|
131
|
-
|
132
|
-
/**
|
133
|
-
* Listen to the given space separated list of `events` and
|
134
|
-
* execute the `callback` at most once
|
135
|
-
* @param { String } events - events ids
|
136
|
-
* @param { Function } fn - callback function
|
137
|
-
* @returns { Object } el
|
138
|
-
*/
|
139
|
-
one: {
|
140
|
-
value: function(events, fn) {
|
141
|
-
function on() {
|
142
|
-
el.off(events, on)
|
143
|
-
fn.apply(el, arguments)
|
144
|
-
}
|
145
|
-
return el.on(events, on)
|
146
|
-
},
|
147
|
-
enumerable: false,
|
148
|
-
writable: false,
|
149
|
-
configurable: false
|
150
|
-
},
|
151
|
-
|
152
|
-
/**
|
153
|
-
* Execute all callback functions that listen to
|
154
|
-
* the given space separated list of `events`
|
155
|
-
* @param { String } events - events ids
|
156
|
-
* @returns { Object } el
|
157
|
-
*/
|
158
|
-
trigger: {
|
159
|
-
value: function(events) {
|
160
|
-
|
161
|
-
// getting the arguments
|
162
|
-
var arglen = arguments.length - 1,
|
163
|
-
args = new Array(arglen),
|
164
|
-
fns
|
165
|
-
|
166
|
-
for (var i = 0; i < arglen; i++) {
|
167
|
-
args[i] = arguments[i + 1] // skip first argument
|
168
|
-
}
|
169
|
-
|
170
|
-
onEachEvent(events, function(name, pos) {
|
171
|
-
|
172
|
-
fns = slice.call(callbacks[name] || [], 0)
|
173
|
-
|
174
|
-
for (var i = 0, fn; fn = fns[i]; ++i) {
|
175
|
-
if (fn.busy) continue
|
176
|
-
fn.busy = 1
|
177
|
-
fn.apply(el, fn.typed ? [name].concat(args) : args)
|
178
|
-
if (fns[i] !== fn) { i-- }
|
179
|
-
fn.busy = 0
|
180
|
-
}
|
181
|
-
|
182
|
-
if (callbacks['*'] && name != '*')
|
183
|
-
el.trigger.apply(el, ['*', name].concat(args))
|
184
|
-
|
185
|
-
})
|
186
|
-
|
187
|
-
return el
|
188
|
-
},
|
189
|
-
enumerable: false,
|
190
|
-
writable: false,
|
191
|
-
configurable: false
|
192
|
-
}
|
193
|
-
})
|
194
|
-
|
195
|
-
return el
|
196
|
-
|
1
|
+
/* Riot v3.0.7, @license MIT */
|
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 = global.riot || {})));
|
6
|
+
}(this, (function (exports) { 'use strict';
|
7
|
+
|
8
|
+
var __TAGS_CACHE = [];
|
9
|
+
var __TAG_IMPL = {};
|
10
|
+
var GLOBAL_MIXIN = '__global_mixin';
|
11
|
+
var ATTRS_PREFIX = 'riot-';
|
12
|
+
var REF_DIRECTIVES = ['data-ref', 'ref'];
|
13
|
+
var IS_DIRECTIVE = 'data-is';
|
14
|
+
var CONDITIONAL_DIRECTIVE = 'if';
|
15
|
+
var LOOP_DIRECTIVE = 'each';
|
16
|
+
var LOOP_NO_REORDER_DIRECTIVE = 'no-reorder';
|
17
|
+
var SHOW_DIRECTIVE = 'show';
|
18
|
+
var HIDE_DIRECTIVE = 'hide';
|
19
|
+
var T_STRING = 'string';
|
20
|
+
var T_OBJECT = 'object';
|
21
|
+
var T_UNDEF = 'undefined';
|
22
|
+
var T_FUNCTION = 'function';
|
23
|
+
var XLINK_NS = 'http://www.w3.org/1999/xlink';
|
24
|
+
var XLINK_REGEX = /^xlink:(\w+)/;
|
25
|
+
var WIN = typeof window === T_UNDEF ? undefined : window;
|
26
|
+
var RE_SPECIAL_TAGS = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?|opt(?:ion|group))$/;
|
27
|
+
var RE_SPECIAL_TAGS_NO_OPTION = /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/;
|
28
|
+
var RE_RESERVED_NAMES = /^(?:_(?:item|id|parent)|update|root|(?:un)?mount|mixin|is(?:Mounted|Loop)|tags|refs|parent|opts|trigger|o(?:n|ff|ne))$/;
|
29
|
+
var RE_SVG_TAGS = /^(altGlyph|animate(?:Color)?|circle|clipPath|defs|ellipse|fe(?:Blend|ColorMatrix|ComponentTransfer|Composite|ConvolveMatrix|DiffuseLighting|DisplacementMap|Flood|GaussianBlur|Image|Merge|Morphology|Offset|SpecularLighting|Tile|Turbulence)|filter|font|foreignObject|g(?:lyph)?(?:Ref)?|image|line(?:arGradient)?|ma(?:rker|sk)|missing-glyph|path|pattern|poly(?:gon|line)|radialGradient|rect|stop|svg|switch|symbol|text(?:Path)?|tref|tspan|use)$/;
|
30
|
+
var RE_HTML_ATTRS = /([-\w]+) ?= ?(?:"([^"]*)|'([^']*)|({[^}]*}))/g;
|
31
|
+
var CASE_SENSITIVE_ATTRIBUTES = { 'viewbox': 'viewBox' };
|
32
|
+
var 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)$/;
|
33
|
+
var IE_VERSION = (WIN && WIN.document || {}).documentMode | 0;
|
34
|
+
|
35
|
+
/**
|
36
|
+
* Check whether a DOM node must be considered a part of an svg document
|
37
|
+
* @param { String } name -
|
38
|
+
* @returns { Boolean } -
|
39
|
+
*/
|
40
|
+
function isSVGTag(name) {
|
41
|
+
return RE_SVG_TAGS.test(name)
|
197
42
|
}
|
198
|
-
/* istanbul ignore next */
|
199
|
-
;(function(riot) {
|
200
43
|
|
201
44
|
/**
|
202
|
-
*
|
203
|
-
* @
|
45
|
+
* Check Check if the passed argument is undefined
|
46
|
+
* @param { String } value -
|
47
|
+
* @returns { Boolean } -
|
204
48
|
*/
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
EVENT_LISTENER = 'EventListener',
|
209
|
-
REMOVE_EVENT_LISTENER = 'remove' + EVENT_LISTENER,
|
210
|
-
ADD_EVENT_LISTENER = 'add' + EVENT_LISTENER,
|
211
|
-
HAS_ATTRIBUTE = 'hasAttribute',
|
212
|
-
REPLACE = 'replace',
|
213
|
-
POPSTATE = 'popstate',
|
214
|
-
HASHCHANGE = 'hashchange',
|
215
|
-
TRIGGER = 'trigger',
|
216
|
-
MAX_EMIT_STACK_LEVEL = 3,
|
217
|
-
win = typeof window != 'undefined' && window,
|
218
|
-
doc = typeof document != 'undefined' && document,
|
219
|
-
hist = win && history,
|
220
|
-
loc = win && (hist.location || win.location), // see html5-history-api
|
221
|
-
prot = Router.prototype, // to minify more
|
222
|
-
clickEvent = doc && doc.ontouchstart ? 'touchstart' : 'click',
|
223
|
-
started = false,
|
224
|
-
central = riot.observable(),
|
225
|
-
routeFound = false,
|
226
|
-
debouncedEmit,
|
227
|
-
base, current, parser, secondParser, emitStack = [], emitStackLevel = 0
|
49
|
+
function isBoolAttr(value) {
|
50
|
+
return RE_BOOL_ATTRS.test(value)
|
51
|
+
}
|
228
52
|
|
229
53
|
/**
|
230
|
-
*
|
231
|
-
* @param
|
232
|
-
* @returns {
|
54
|
+
* Check if passed argument is a function
|
55
|
+
* @param { * } value -
|
56
|
+
* @returns { Boolean } -
|
233
57
|
*/
|
234
|
-
function
|
235
|
-
return
|
58
|
+
function isFunction(value) {
|
59
|
+
return typeof value === T_FUNCTION
|
236
60
|
}
|
237
61
|
|
238
62
|
/**
|
239
|
-
*
|
240
|
-
*
|
241
|
-
* @param
|
242
|
-
* @returns {
|
63
|
+
* Check if passed argument is an object, exclude null
|
64
|
+
* NOTE: use isObject(x) && !isArray(x) to excludes arrays.
|
65
|
+
* @param { * } value -
|
66
|
+
* @returns { Boolean } -
|
243
67
|
*/
|
244
|
-
function
|
245
|
-
|
246
|
-
args = path.match(re)
|
247
|
-
|
248
|
-
if (args) return args.slice(1)
|
68
|
+
function isObject(value) {
|
69
|
+
return value && typeof value === T_OBJECT // typeof null is 'object'
|
249
70
|
}
|
250
71
|
|
251
72
|
/**
|
252
|
-
*
|
253
|
-
* @param {
|
254
|
-
* @
|
255
|
-
* @returns {function} debounced function
|
73
|
+
* Check if passed argument is undefined
|
74
|
+
* @param { * } value -
|
75
|
+
* @returns { Boolean } -
|
256
76
|
*/
|
257
|
-
function
|
258
|
-
|
259
|
-
return function () {
|
260
|
-
clearTimeout(t)
|
261
|
-
t = setTimeout(fn, delay)
|
262
|
-
}
|
77
|
+
function isUndefined(value) {
|
78
|
+
return typeof value === T_UNDEF
|
263
79
|
}
|
264
80
|
|
265
81
|
/**
|
266
|
-
*
|
267
|
-
* @param
|
82
|
+
* Check if passed argument is a string
|
83
|
+
* @param { * } value -
|
84
|
+
* @returns { Boolean } -
|
268
85
|
*/
|
269
|
-
function
|
270
|
-
|
271
|
-
win[ADD_EVENT_LISTENER](POPSTATE, debouncedEmit)
|
272
|
-
win[ADD_EVENT_LISTENER](HASHCHANGE, debouncedEmit)
|
273
|
-
doc[ADD_EVENT_LISTENER](clickEvent, click)
|
274
|
-
if (autoExec) emit(true)
|
86
|
+
function isString(value) {
|
87
|
+
return typeof value === T_STRING
|
275
88
|
}
|
276
89
|
|
277
90
|
/**
|
278
|
-
*
|
91
|
+
* Check if passed argument is empty. Different from falsy, because we dont consider 0 or false to be blank
|
92
|
+
* @param { * } value -
|
93
|
+
* @returns { Boolean } -
|
279
94
|
*/
|
280
|
-
function
|
281
|
-
|
282
|
-
riot.observable(this) // make it observable
|
283
|
-
central.on('stop', this.s.bind(this))
|
284
|
-
central.on('emit', this.e.bind(this))
|
285
|
-
}
|
286
|
-
|
287
|
-
function normalize(path) {
|
288
|
-
return path[REPLACE](/^\/|\/$/, '')
|
289
|
-
}
|
290
|
-
|
291
|
-
function isString(str) {
|
292
|
-
return typeof str == 'string'
|
95
|
+
function isBlank(value) {
|
96
|
+
return isUndefined(value) || value === null || value === ''
|
293
97
|
}
|
294
98
|
|
295
99
|
/**
|
296
|
-
*
|
297
|
-
* @param
|
298
|
-
* @returns {
|
100
|
+
* Check if passed argument is a kind of array
|
101
|
+
* @param { * } value -
|
102
|
+
* @returns { Boolean } -
|
299
103
|
*/
|
300
|
-
function
|
301
|
-
return (
|
104
|
+
function isArray(value) {
|
105
|
+
return Array.isArray(value) || value instanceof Array
|
302
106
|
}
|
303
107
|
|
304
108
|
/**
|
305
|
-
*
|
306
|
-
* @param
|
307
|
-
* @
|
109
|
+
* Check whether object's property could be overridden
|
110
|
+
* @param { Object } obj - source object
|
111
|
+
* @param { String } key - object property
|
112
|
+
* @returns { Boolean } -
|
308
113
|
*/
|
309
|
-
function
|
310
|
-
|
311
|
-
|
312
|
-
: (loc ? getPathFromRoot(href) : href || '')[REPLACE](base, '')
|
114
|
+
function isWritable(obj, key) {
|
115
|
+
var descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
116
|
+
return isUndefined(obj[key]) || descriptor && descriptor.writable
|
313
117
|
}
|
314
118
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
var path = getPathFromBase()
|
323
|
-
if (force || path != current) {
|
324
|
-
central[TRIGGER]('emit', path)
|
325
|
-
current = path
|
326
|
-
}
|
327
|
-
})
|
328
|
-
if (isRoot) {
|
329
|
-
while (first = emitStack.shift()) first() // stack increses within this call
|
330
|
-
emitStackLevel = 0
|
331
|
-
}
|
119
|
+
/**
|
120
|
+
* Check if passed argument is a reserved name
|
121
|
+
* @param { String } value -
|
122
|
+
* @returns { Boolean } -
|
123
|
+
*/
|
124
|
+
function isReservedName(value) {
|
125
|
+
return RE_RESERVED_NAMES.test(value)
|
332
126
|
}
|
333
127
|
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
128
|
+
var check = Object.freeze({
|
129
|
+
isSVGTag: isSVGTag,
|
130
|
+
isBoolAttr: isBoolAttr,
|
131
|
+
isFunction: isFunction,
|
132
|
+
isObject: isObject,
|
133
|
+
isUndefined: isUndefined,
|
134
|
+
isString: isString,
|
135
|
+
isBlank: isBlank,
|
136
|
+
isArray: isArray,
|
137
|
+
isWritable: isWritable,
|
138
|
+
isReservedName: isReservedName
|
139
|
+
});
|
343
140
|
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
if (el.href != loc.href
|
353
|
-
&& (
|
354
|
-
el.href.split('#')[0] == loc.href.split('#')[0] // internal jump
|
355
|
-
|| base[0] != '#' && getPathFromRoot(el.href).indexOf(base) !== 0 // outside of base
|
356
|
-
|| base[0] == '#' && el.href.split(base)[0] != loc.href.split(base)[0] // outside of #base
|
357
|
-
|| !go(getPathFromBase(el.href), el.title || doc.title) // route not found
|
358
|
-
)) return
|
359
|
-
|
360
|
-
e.preventDefault()
|
141
|
+
/**
|
142
|
+
* Shorter and fast way to select multiple nodes in the DOM
|
143
|
+
* @param { String } selector - DOM selector
|
144
|
+
* @param { Object } ctx - DOM node where the targets of our search will is located
|
145
|
+
* @returns { Object } dom nodes found
|
146
|
+
*/
|
147
|
+
function $$(selector, ctx) {
|
148
|
+
return (ctx || document).querySelectorAll(selector)
|
361
149
|
}
|
362
150
|
|
363
151
|
/**
|
364
|
-
*
|
365
|
-
* @param
|
366
|
-
* @param
|
367
|
-
* @
|
368
|
-
* @returns {boolean} - route not found flag
|
152
|
+
* Shorter and fast way to select a single node in the DOM
|
153
|
+
* @param { String } selector - unique dom selector
|
154
|
+
* @param { Object } ctx - DOM node where the target of our search will is located
|
155
|
+
* @returns { Object } dom node found
|
369
156
|
*/
|
370
|
-
function
|
371
|
-
|
372
|
-
if (!hist) return central[TRIGGER]('emit', getPathFromBase(path))
|
373
|
-
|
374
|
-
path = base + normalize(path)
|
375
|
-
title = title || doc.title
|
376
|
-
// browsers ignores the second parameter `title`
|
377
|
-
shouldReplace
|
378
|
-
? hist.replaceState(null, title, path)
|
379
|
-
: hist.pushState(null, title, path)
|
380
|
-
// so we need to set it manually
|
381
|
-
doc.title = title
|
382
|
-
routeFound = false
|
383
|
-
emit()
|
384
|
-
return routeFound
|
157
|
+
function $(selector, ctx) {
|
158
|
+
return (ctx || document).querySelector(selector)
|
385
159
|
}
|
386
160
|
|
387
161
|
/**
|
388
|
-
*
|
389
|
-
*
|
390
|
-
* two strings: go there with setting a title
|
391
|
-
* two strings and boolean: replace history with setting a title
|
392
|
-
* a single function: set an action on the default route
|
393
|
-
* a string/RegExp and a function: set an action on the route
|
394
|
-
* @param {(string|function)} first - path / action / filter
|
395
|
-
* @param {(string|RegExp|function)} second - title / action
|
396
|
-
* @param {boolean} third - replace flag
|
162
|
+
* Create a document fragment
|
163
|
+
* @returns { Object } document fragment
|
397
164
|
*/
|
398
|
-
|
399
|
-
|
400
|
-
else if (second) this.r(first, second)
|
401
|
-
else this.r('@', first)
|
165
|
+
function createFrag() {
|
166
|
+
return document.createDocumentFragment()
|
402
167
|
}
|
403
168
|
|
404
169
|
/**
|
405
|
-
*
|
170
|
+
* Create a document text node
|
171
|
+
* @returns { Object } create a text node to use as placeholder
|
406
172
|
*/
|
407
|
-
|
408
|
-
|
409
|
-
this.$ = []
|
173
|
+
function createDOMPlaceholder() {
|
174
|
+
return document.createTextNode('')
|
410
175
|
}
|
411
176
|
|
412
177
|
/**
|
413
|
-
*
|
414
|
-
* @param
|
178
|
+
* Create a generic DOM node
|
179
|
+
* @param { String } name - name of the DOM node we want to create
|
180
|
+
* @param { Boolean } isSvg - should we use a SVG as parent node?
|
181
|
+
* @returns { Object } DOM node just created
|
415
182
|
*/
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
this[TRIGGER].apply(null, [filter].concat(args))
|
421
|
-
return routeFound = true // exit from loop
|
422
|
-
}
|
423
|
-
}, this)
|
183
|
+
function mkEl(name, isSvg) {
|
184
|
+
return isSvg ?
|
185
|
+
document.createElementNS('http://www.w3.org/2000/svg', 'svg') :
|
186
|
+
document.createElement(name)
|
424
187
|
}
|
425
188
|
|
426
189
|
/**
|
427
|
-
*
|
428
|
-
* @param
|
429
|
-
* @
|
190
|
+
* Get the outer html of any DOM node SVGs included
|
191
|
+
* @param { Object } el - DOM node to parse
|
192
|
+
* @returns { String } el.outerHTML
|
430
193
|
*/
|
431
|
-
|
432
|
-
if (
|
433
|
-
|
434
|
-
|
194
|
+
function getOuterHTML(el) {
|
195
|
+
if (el.outerHTML)
|
196
|
+
{ return el.outerHTML }
|
197
|
+
// some browsers do not support outerHTML on the SVGs tags
|
198
|
+
else {
|
199
|
+
var container = mkEl('div');
|
200
|
+
container.appendChild(el.cloneNode(true));
|
201
|
+
return container.innerHTML
|
435
202
|
}
|
436
|
-
this.on(filter, action)
|
437
203
|
}
|
438
204
|
|
439
|
-
var mainRouter = new Router()
|
440
|
-
var route = mainRouter.m.bind(mainRouter)
|
441
|
-
|
442
205
|
/**
|
443
|
-
*
|
444
|
-
* @
|
206
|
+
* Set the inner html of any DOM node SVGs included
|
207
|
+
* @param { Object } container - DOM node where we'll inject new html
|
208
|
+
* @param { String } html - html to inject
|
445
209
|
*/
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
210
|
+
function setInnerHTML(container, html) {
|
211
|
+
if (!isUndefined(container.innerHTML))
|
212
|
+
{ container.innerHTML = html; }
|
213
|
+
// some browsers do not support innerHTML on the SVGs tags
|
214
|
+
else {
|
215
|
+
var doc = new DOMParser().parseFromString(html, 'application/xml');
|
216
|
+
var node = container.ownerDocument.importNode(doc.documentElement, true);
|
217
|
+
container.appendChild(node);
|
218
|
+
}
|
453
219
|
}
|
454
220
|
|
455
221
|
/**
|
456
|
-
*
|
457
|
-
* @param
|
222
|
+
* Remove any DOM attribute from a node
|
223
|
+
* @param { Object } dom - DOM node we want to update
|
224
|
+
* @param { String } name - name of the property we want to remove
|
458
225
|
*/
|
459
|
-
|
460
|
-
|
461
|
-
current = getPathFromBase() // recalculate current path
|
226
|
+
function remAttr(dom, name) {
|
227
|
+
dom.removeAttribute(name);
|
462
228
|
}
|
463
229
|
|
464
|
-
/**
|
465
|
-
|
466
|
-
|
230
|
+
/**
|
231
|
+
* Get the value of any DOM attribute on a node
|
232
|
+
* @param { Object } dom - DOM node we want to parse
|
233
|
+
* @param { String } name - name of the attribute we want to get
|
234
|
+
* @returns { String | undefined } name of the node attribute whether it exists
|
235
|
+
*/
|
236
|
+
function getAttr(dom, name) {
|
237
|
+
return dom.getAttribute(name)
|
467
238
|
}
|
468
239
|
|
469
240
|
/**
|
470
|
-
*
|
471
|
-
* @param {
|
472
|
-
* @param {
|
241
|
+
* Set any DOM attribute
|
242
|
+
* @param { Object } dom - DOM node we want to update
|
243
|
+
* @param { String } name - name of the property we want to set
|
244
|
+
* @param { String } val - value of the property we want to set
|
473
245
|
*/
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
if (fn) parser = fn
|
481
|
-
if (fn2) secondParser = fn2
|
246
|
+
function setAttr(dom, name, val) {
|
247
|
+
var xlink = XLINK_REGEX.exec(name);
|
248
|
+
if (xlink && xlink[1])
|
249
|
+
{ dom.setAttributeNS(XLINK_NS, xlink[1], val); }
|
250
|
+
else
|
251
|
+
{ dom.setAttribute(name, val); }
|
482
252
|
}
|
483
253
|
|
484
254
|
/**
|
485
|
-
*
|
486
|
-
* @
|
255
|
+
* Insert safely a tag to fix #1962 #1649
|
256
|
+
* @param { HTMLElement } root - children container
|
257
|
+
* @param { HTMLElement } curr - node to insert
|
258
|
+
* @param { HTMLElement } next - node that should preceed the current node inserted
|
487
259
|
*/
|
488
|
-
|
489
|
-
|
490
|
-
var href = loc.href || current
|
491
|
-
href[REPLACE](/[?&](.+?)=([^&]*)/g, function(_, k, v) { q[k] = v })
|
492
|
-
return q
|
260
|
+
function safeInsert(root, curr, next) {
|
261
|
+
root.insertBefore(curr, next.parentNode && next);
|
493
262
|
}
|
494
263
|
|
495
|
-
/**
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
}
|
503
|
-
|
504
|
-
|
505
|
-
|
264
|
+
/**
|
265
|
+
* Minimize risk: only zero or one _space_ between attr & value
|
266
|
+
* @param { String } html - html string we want to parse
|
267
|
+
* @param { Function } fn - callback function to apply on any attribute found
|
268
|
+
*/
|
269
|
+
function walkAttrs(html, fn) {
|
270
|
+
if (!html)
|
271
|
+
{ return }
|
272
|
+
var m;
|
273
|
+
while (m = RE_HTML_ATTRS.exec(html))
|
274
|
+
{ fn(m[1].toLowerCase(), m[2] || m[3] || m[4]); }
|
506
275
|
}
|
507
276
|
|
508
277
|
/**
|
509
|
-
*
|
510
|
-
* @param
|
278
|
+
* Walk down recursively all the children tags starting dom node
|
279
|
+
* @param { Object } dom - starting node where we will start the recursion
|
280
|
+
* @param { Function } fn - callback to transform the child node just found
|
281
|
+
* @param { Object } context - fn can optionally return an object, which is passed to children
|
511
282
|
*/
|
512
|
-
|
513
|
-
if (
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
283
|
+
function walkNodes(dom, fn, context) {
|
284
|
+
if (dom) {
|
285
|
+
var res = fn(dom, context);
|
286
|
+
var next;
|
287
|
+
// stop the recursion
|
288
|
+
if (res === false) { return }
|
289
|
+
|
290
|
+
dom = dom.firstChild;
|
291
|
+
|
292
|
+
while (dom) {
|
293
|
+
next = dom.nextSibling;
|
294
|
+
walkNodes(dom, fn, res);
|
295
|
+
dom = next;
|
521
296
|
}
|
522
|
-
started = true
|
523
297
|
}
|
524
298
|
}
|
525
299
|
|
526
|
-
|
527
|
-
|
528
|
-
|
300
|
+
var dom = Object.freeze({
|
301
|
+
$$: $$,
|
302
|
+
$: $,
|
303
|
+
createFrag: createFrag,
|
304
|
+
createDOMPlaceholder: createDOMPlaceholder,
|
305
|
+
mkEl: mkEl,
|
306
|
+
getOuterHTML: getOuterHTML,
|
307
|
+
setInnerHTML: setInnerHTML,
|
308
|
+
remAttr: remAttr,
|
309
|
+
getAttr: getAttr,
|
310
|
+
setAttr: setAttr,
|
311
|
+
safeInsert: safeInsert,
|
312
|
+
walkAttrs: walkAttrs,
|
313
|
+
walkNodes: walkNodes
|
314
|
+
});
|
315
|
+
|
316
|
+
var styleNode;
|
317
|
+
var cssTextProp;
|
318
|
+
var byName = {};
|
319
|
+
var remainder = [];
|
320
|
+
var needsInject = false;
|
321
|
+
|
322
|
+
// skip the following code on the server
|
323
|
+
if (WIN) {
|
324
|
+
styleNode = (function () {
|
325
|
+
// create a new style element with the correct type
|
326
|
+
var newNode = mkEl('style');
|
327
|
+
setAttr(newNode, 'type', 'text/css');
|
328
|
+
|
329
|
+
// replace any user node or insert the new one into the head
|
330
|
+
var userNode = $('style[type=riot]');
|
331
|
+
if (userNode) {
|
332
|
+
if (userNode.id) { newNode.id = userNode.id; }
|
333
|
+
userNode.parentNode.replaceChild(newNode, userNode);
|
334
|
+
}
|
335
|
+
else { document.getElementsByTagName('head')[0].appendChild(newNode); }
|
336
|
+
|
337
|
+
return newNode
|
338
|
+
})();
|
339
|
+
cssTextProp = styleNode.styleSheet;
|
340
|
+
}
|
529
341
|
|
530
|
-
|
531
|
-
|
532
|
-
|
342
|
+
/**
|
343
|
+
* Object that will be used to inject and manage the css of every tag instance
|
344
|
+
*/
|
345
|
+
var styleManager = {
|
346
|
+
styleNode: styleNode,
|
347
|
+
/**
|
348
|
+
* Save a tag style to be later injected into DOM
|
349
|
+
* @param { String } css - css string
|
350
|
+
* @param { String } name - if it's passed we will map the css to a tagname
|
351
|
+
*/
|
352
|
+
add: function add(css, name) {
|
353
|
+
if (name) { byName[name] = css; }
|
354
|
+
else { remainder.push(css); }
|
355
|
+
needsInject = true;
|
356
|
+
},
|
357
|
+
/**
|
358
|
+
* Inject all previously saved tag styles into DOM
|
359
|
+
* innerHTML seems slow: http://jsperf.com/riot-insert-style
|
360
|
+
*/
|
361
|
+
inject: function inject() {
|
362
|
+
if (!WIN || !needsInject) { return }
|
363
|
+
needsInject = false;
|
364
|
+
var style = Object.keys(byName)
|
365
|
+
.map(function(k) { return byName[k] })
|
366
|
+
.concat(remainder).join('\n');
|
367
|
+
if (cssTextProp) { cssTextProp.cssText = style; }
|
368
|
+
else { styleNode.innerHTML = style; }
|
369
|
+
}
|
370
|
+
};
|
533
371
|
|
534
372
|
/**
|
535
373
|
* The riot template engine
|
536
|
-
* @version
|
374
|
+
* @version v3.0.1
|
537
375
|
*/
|
538
376
|
/**
|
539
377
|
* riot.util.brackets
|
@@ -544,6 +382,8 @@ riot.route = route
|
|
544
382
|
* @module
|
545
383
|
*/
|
546
384
|
|
385
|
+
/* global riot */
|
386
|
+
|
547
387
|
var brackets = (function (UNDEF) {
|
548
388
|
|
549
389
|
var
|
@@ -567,7 +407,7 @@ var brackets = (function (UNDEF) {
|
|
567
407
|
'{': RegExp('([{}])|' + S_QBLOCKS, REGLOB)
|
568
408
|
},
|
569
409
|
|
570
|
-
DEFAULT = '{ }'
|
410
|
+
DEFAULT = '{ }';
|
571
411
|
|
572
412
|
var _pairs = [
|
573
413
|
'{', '}',
|
@@ -579,38 +419,38 @@ var brackets = (function (UNDEF) {
|
|
579
419
|
DEFAULT,
|
580
420
|
/^\s*{\^?\s*([$\w]+)(?:\s*,\s*(\S+))?\s+in\s+(\S.*)\s*}/,
|
581
421
|
/(^|[^\\]){=[\S\s]*?}/
|
582
|
-
]
|
422
|
+
];
|
583
423
|
|
584
424
|
var
|
585
425
|
cachedBrackets = UNDEF,
|
586
426
|
_regex,
|
587
427
|
_cache = [],
|
588
|
-
_settings
|
428
|
+
_settings;
|
589
429
|
|
590
430
|
function _loopback (re) { return re }
|
591
431
|
|
592
432
|
function _rewrite (re, bp) {
|
593
|
-
if (!bp) bp = _cache
|
433
|
+
if (!bp) { bp = _cache; }
|
594
434
|
return new RegExp(
|
595
435
|
re.source.replace(/{/g, bp[2]).replace(/}/g, bp[3]), re.global ? REGLOB : ''
|
596
436
|
)
|
597
437
|
}
|
598
438
|
|
599
439
|
function _create (pair) {
|
600
|
-
if (pair === DEFAULT) return _pairs
|
440
|
+
if (pair === DEFAULT) { return _pairs }
|
601
441
|
|
602
|
-
var arr = pair.split(' ')
|
442
|
+
var arr = pair.split(' ');
|
603
443
|
|
604
444
|
if (arr.length !== 2 || UNSUPPORTED.test(pair)) {
|
605
445
|
throw new Error('Unsupported brackets "' + pair + '"')
|
606
446
|
}
|
607
|
-
arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' '))
|
447
|
+
arr = arr.concat(pair.replace(NEED_ESCAPE, '\\').split(' '));
|
608
448
|
|
609
|
-
arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr)
|
610
|
-
arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr)
|
611
|
-
arr[6] = _rewrite(_pairs[6], arr)
|
612
|
-
arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB)
|
613
|
-
arr[8] = pair
|
449
|
+
arr[4] = _rewrite(arr[1].length > 1 ? /{[\S\s]*?}/ : _pairs[4], arr);
|
450
|
+
arr[5] = _rewrite(pair.length > 3 ? /\\({|})/g : _pairs[5], arr);
|
451
|
+
arr[6] = _rewrite(_pairs[6], arr);
|
452
|
+
arr[7] = RegExp('\\\\(' + arr[3] + ')|([[({])|(' + arr[3] + ')|' + S_QBLOCKS, REGLOB);
|
453
|
+
arr[8] = pair;
|
614
454
|
return arr
|
615
455
|
}
|
616
456
|
|
@@ -620,7 +460,7 @@ var brackets = (function (UNDEF) {
|
|
620
460
|
|
621
461
|
_brackets.split = function split (str, tmpl, _bp) {
|
622
462
|
// istanbul ignore next: _bp is for the compiler
|
623
|
-
if (!_bp) _bp = _cache
|
463
|
+
if (!_bp) { _bp = _cache; }
|
624
464
|
|
625
465
|
var
|
626
466
|
parts = [],
|
@@ -628,18 +468,18 @@ var brackets = (function (UNDEF) {
|
|
628
468
|
isexpr,
|
629
469
|
start,
|
630
470
|
pos,
|
631
|
-
re = _bp[6]
|
471
|
+
re = _bp[6];
|
632
472
|
|
633
|
-
isexpr = start = re.lastIndex = 0
|
473
|
+
isexpr = start = re.lastIndex = 0;
|
634
474
|
|
635
475
|
while ((match = re.exec(str))) {
|
636
476
|
|
637
|
-
pos = match.index
|
477
|
+
pos = match.index;
|
638
478
|
|
639
479
|
if (isexpr) {
|
640
480
|
|
641
481
|
if (match[2]) {
|
642
|
-
re.lastIndex = skipBraces(str, match[2], re.lastIndex)
|
482
|
+
re.lastIndex = skipBraces(str, match[2], re.lastIndex);
|
643
483
|
continue
|
644
484
|
}
|
645
485
|
if (!match[3]) {
|
@@ -648,97 +488,97 @@ var brackets = (function (UNDEF) {
|
|
648
488
|
}
|
649
489
|
|
650
490
|
if (!match[1]) {
|
651
|
-
unescapeStr(str.slice(start, pos))
|
652
|
-
start = re.lastIndex
|
653
|
-
re = _bp[6 + (isexpr ^= 1)]
|
654
|
-
re.lastIndex = start
|
491
|
+
unescapeStr(str.slice(start, pos));
|
492
|
+
start = re.lastIndex;
|
493
|
+
re = _bp[6 + (isexpr ^= 1)];
|
494
|
+
re.lastIndex = start;
|
655
495
|
}
|
656
496
|
}
|
657
497
|
|
658
498
|
if (str && start < str.length) {
|
659
|
-
unescapeStr(str.slice(start))
|
499
|
+
unescapeStr(str.slice(start));
|
660
500
|
}
|
661
501
|
|
662
502
|
return parts
|
663
503
|
|
664
504
|
function unescapeStr (s) {
|
665
505
|
if (tmpl || isexpr) {
|
666
|
-
parts.push(s && s.replace(_bp[5], '$1'))
|
506
|
+
parts.push(s && s.replace(_bp[5], '$1'));
|
667
507
|
} else {
|
668
|
-
parts.push(s)
|
508
|
+
parts.push(s);
|
669
509
|
}
|
670
510
|
}
|
671
511
|
|
672
512
|
function skipBraces (s, ch, ix) {
|
673
513
|
var
|
674
514
|
match,
|
675
|
-
recch = FINDBRACES[ch]
|
515
|
+
recch = FINDBRACES[ch];
|
676
516
|
|
677
|
-
recch.lastIndex = ix
|
678
|
-
ix = 1
|
517
|
+
recch.lastIndex = ix;
|
518
|
+
ix = 1;
|
679
519
|
while ((match = recch.exec(s))) {
|
680
520
|
if (match[1] &&
|
681
|
-
!(match[1] === ch ? ++ix : --ix)) break
|
521
|
+
!(match[1] === ch ? ++ix : --ix)) { break }
|
682
522
|
}
|
683
523
|
return ix ? s.length : recch.lastIndex
|
684
524
|
}
|
685
|
-
}
|
525
|
+
};
|
686
526
|
|
687
527
|
_brackets.hasExpr = function hasExpr (str) {
|
688
528
|
return _cache[4].test(str)
|
689
|
-
}
|
529
|
+
};
|
690
530
|
|
691
531
|
_brackets.loopKeys = function loopKeys (expr) {
|
692
|
-
var m = expr.match(_cache[9])
|
532
|
+
var m = expr.match(_cache[9]);
|
693
533
|
|
694
534
|
return m
|
695
535
|
? { key: m[1], pos: m[2], val: _cache[0] + m[3].trim() + _cache[1] }
|
696
536
|
: { val: expr.trim() }
|
697
|
-
}
|
537
|
+
};
|
698
538
|
|
699
539
|
_brackets.array = function array (pair) {
|
700
540
|
return pair ? _create(pair) : _cache
|
701
|
-
}
|
541
|
+
};
|
702
542
|
|
703
543
|
function _reset (pair) {
|
704
544
|
if ((pair || (pair = DEFAULT)) !== _cache[8]) {
|
705
|
-
_cache = _create(pair)
|
706
|
-
_regex = pair === DEFAULT ? _loopback : _rewrite
|
707
|
-
_cache[9] = _regex(_pairs[9])
|
545
|
+
_cache = _create(pair);
|
546
|
+
_regex = pair === DEFAULT ? _loopback : _rewrite;
|
547
|
+
_cache[9] = _regex(_pairs[9]);
|
708
548
|
}
|
709
|
-
cachedBrackets = pair
|
549
|
+
cachedBrackets = pair;
|
710
550
|
}
|
711
551
|
|
712
552
|
function _setSettings (o) {
|
713
|
-
var b
|
553
|
+
var b;
|
714
554
|
|
715
|
-
o = o || {}
|
716
|
-
b = o.brackets
|
555
|
+
o = o || {};
|
556
|
+
b = o.brackets;
|
717
557
|
Object.defineProperty(o, 'brackets', {
|
718
558
|
set: _reset,
|
719
559
|
get: function () { return cachedBrackets },
|
720
560
|
enumerable: true
|
721
|
-
})
|
722
|
-
_settings = o
|
723
|
-
_reset(b)
|
561
|
+
});
|
562
|
+
_settings = o;
|
563
|
+
_reset(b);
|
724
564
|
}
|
725
565
|
|
726
566
|
Object.defineProperty(_brackets, 'settings', {
|
727
567
|
set: _setSettings,
|
728
568
|
get: function () { return _settings }
|
729
|
-
})
|
569
|
+
});
|
730
570
|
|
731
571
|
/* istanbul ignore next: in the browser riot is always in the scope */
|
732
|
-
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {}
|
733
|
-
_brackets.set = _reset
|
572
|
+
_brackets.settings = typeof riot !== 'undefined' && riot.settings || {};
|
573
|
+
_brackets.set = _reset;
|
734
574
|
|
735
|
-
_brackets.R_STRINGS = R_STRINGS
|
736
|
-
_brackets.R_MLCOMMS = R_MLCOMMS
|
737
|
-
_brackets.S_QBLOCKS = S_QBLOCKS
|
575
|
+
_brackets.R_STRINGS = R_STRINGS;
|
576
|
+
_brackets.R_MLCOMMS = R_MLCOMMS;
|
577
|
+
_brackets.S_QBLOCKS = S_QBLOCKS;
|
738
578
|
|
739
579
|
return _brackets
|
740
580
|
|
741
|
-
})()
|
581
|
+
})();
|
742
582
|
|
743
583
|
/**
|
744
584
|
* @module tmpl
|
@@ -750,64 +590,69 @@ var brackets = (function (UNDEF) {
|
|
750
590
|
|
751
591
|
var tmpl = (function () {
|
752
592
|
|
753
|
-
var _cache = {}
|
593
|
+
var _cache = {};
|
754
594
|
|
755
595
|
function _tmpl (str, data) {
|
756
|
-
if (!str) return str
|
596
|
+
if (!str) { return str }
|
757
597
|
|
758
598
|
return (_cache[str] || (_cache[str] = _create(str))).call(data, _logErr)
|
759
599
|
}
|
760
600
|
|
761
|
-
_tmpl.
|
601
|
+
_tmpl.hasExpr = brackets.hasExpr;
|
762
602
|
|
763
|
-
_tmpl.
|
764
|
-
|
765
|
-
_tmpl.loopKeys = brackets.loopKeys
|
603
|
+
_tmpl.loopKeys = brackets.loopKeys;
|
766
604
|
|
767
605
|
// istanbul ignore next
|
768
|
-
_tmpl.clearCache = function () { _cache = {} }
|
606
|
+
_tmpl.clearCache = function () { _cache = {}; };
|
769
607
|
|
770
|
-
_tmpl.errorHandler = null
|
608
|
+
_tmpl.errorHandler = null;
|
771
609
|
|
772
610
|
function _logErr (err, ctx) {
|
773
611
|
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
|
612
|
+
err.riotData = {
|
613
|
+
tagName: ctx && ctx.root && ctx.root.tagName,
|
614
|
+
_riot_id: ctx && ctx._riot_id //eslint-disable-line camelcase
|
615
|
+
};
|
616
|
+
|
617
|
+
if (_tmpl.errorHandler) { _tmpl.errorHandler(err); }
|
618
|
+
else if (
|
619
|
+
typeof console !== 'undefined' &&
|
620
|
+
typeof console.error === 'function'
|
621
|
+
) {
|
622
|
+
if (err.riotData.tagName) {
|
623
|
+
console.error('Riot template error thrown in the <%s> tag', err.riotData.tagName.toLowerCase());
|
779
624
|
}
|
780
|
-
|
625
|
+
console.error(err);
|
781
626
|
}
|
782
627
|
}
|
783
628
|
|
784
629
|
function _create (str) {
|
785
|
-
var expr = _getTmpl(str)
|
630
|
+
var expr = _getTmpl(str);
|
786
631
|
|
787
|
-
if (expr.slice(0, 11) !== 'try{return ') expr = 'return ' + expr
|
632
|
+
if (expr.slice(0, 11) !== 'try{return ') { expr = 'return ' + expr; }
|
788
633
|
|
789
634
|
return new Function('E', expr + ';') // eslint-disable-line no-new-func
|
790
635
|
}
|
791
636
|
|
792
637
|
var
|
793
|
-
CH_IDEXPR =
|
638
|
+
CH_IDEXPR = String.fromCharCode(0x2057),
|
794
639
|
RE_CSNAME = /^(?:(-?[_A-Za-z\xA0-\xFF][-\w\xA0-\xFF]*)|\u2057(\d+)~):/,
|
795
640
|
RE_QBLOCK = RegExp(brackets.S_QBLOCKS, 'g'),
|
796
641
|
RE_DQUOTE = /\u2057/g,
|
797
|
-
RE_QBMARK = /\u2057(\d+)~/g
|
642
|
+
RE_QBMARK = /\u2057(\d+)~/g;
|
798
643
|
|
799
644
|
function _getTmpl (str) {
|
800
645
|
var
|
801
646
|
qstr = [],
|
802
647
|
expr,
|
803
|
-
parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1)
|
648
|
+
parts = brackets.split(str.replace(RE_DQUOTE, '"'), 1);
|
804
649
|
|
805
650
|
if (parts.length > 2 || parts[0]) {
|
806
|
-
var i, j, list = []
|
651
|
+
var i, j, list = [];
|
807
652
|
|
808
653
|
for (i = j = 0; i < parts.length; ++i) {
|
809
654
|
|
810
|
-
expr = parts[i]
|
655
|
+
expr = parts[i];
|
811
656
|
|
812
657
|
if (expr && (expr = i & 1
|
813
658
|
|
@@ -819,16 +664,16 @@ var tmpl = (function () {
|
|
819
664
|
.replace(/"/g, '\\"') +
|
820
665
|
'"'
|
821
666
|
|
822
|
-
)) list[j++] = expr
|
667
|
+
)) { list[j++] = expr; }
|
823
668
|
|
824
669
|
}
|
825
670
|
|
826
671
|
expr = j < 2 ? list[0]
|
827
|
-
: '[' + list.join(',') + '].join("")'
|
672
|
+
: '[' + list.join(',') + '].join("")';
|
828
673
|
|
829
674
|
} else {
|
830
675
|
|
831
|
-
expr = _parseExpr(parts[1], 0, qstr)
|
676
|
+
expr = _parseExpr(parts[1], 0, qstr);
|
832
677
|
}
|
833
678
|
|
834
679
|
if (qstr[0]) {
|
@@ -836,7 +681,7 @@ var tmpl = (function () {
|
|
836
681
|
return qstr[pos]
|
837
682
|
.replace(/\r/g, '\\r')
|
838
683
|
.replace(/\n/g, '\\n')
|
839
|
-
})
|
684
|
+
});
|
840
685
|
}
|
841
686
|
return expr
|
842
687
|
}
|
@@ -846,7 +691,7 @@ var tmpl = (function () {
|
|
846
691
|
'(': /[()]/g,
|
847
692
|
'[': /[[\]]/g,
|
848
693
|
'{': /[{}]/g
|
849
|
-
}
|
694
|
+
};
|
850
695
|
|
851
696
|
function _parseExpr (expr, asText, qstr) {
|
852
697
|
|
@@ -855,13 +700,13 @@ var tmpl = (function () {
|
|
855
700
|
return s.length > 2 && !div ? CH_IDEXPR + (qstr.push(s) - 1) + '~' : s
|
856
701
|
})
|
857
702
|
.replace(/\s+/g, ' ').trim()
|
858
|
-
.replace(/\ ?([[\({},?\.:])\ ?/g, '$1')
|
703
|
+
.replace(/\ ?([[\({},?\.:])\ ?/g, '$1');
|
859
704
|
|
860
705
|
if (expr) {
|
861
706
|
var
|
862
707
|
list = [],
|
863
708
|
cnt = 0,
|
864
|
-
match
|
709
|
+
match;
|
865
710
|
|
866
711
|
while (expr &&
|
867
712
|
(match = expr.match(RE_CSNAME)) &&
|
@@ -870,21 +715,21 @@ var tmpl = (function () {
|
|
870
715
|
var
|
871
716
|
key,
|
872
717
|
jsb,
|
873
|
-
re = /,|([[{(])|$/g
|
718
|
+
re = /,|([[{(])|$/g;
|
874
719
|
|
875
|
-
expr = RegExp.rightContext
|
876
|
-
key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1]
|
720
|
+
expr = RegExp.rightContext;
|
721
|
+
key = match[2] ? qstr[match[2]].slice(1, -1).trim().replace(/\s+/g, ' ') : match[1];
|
877
722
|
|
878
|
-
while (jsb = (match = re.exec(expr))[1]) skipBraces(jsb, re)
|
723
|
+
while (jsb = (match = re.exec(expr))[1]) { skipBraces(jsb, re); }
|
879
724
|
|
880
|
-
jsb = expr.slice(0, match.index)
|
881
|
-
expr = RegExp.rightContext
|
725
|
+
jsb = expr.slice(0, match.index);
|
726
|
+
expr = RegExp.rightContext;
|
882
727
|
|
883
|
-
list[cnt++] = _wrapExpr(jsb, 1, key)
|
728
|
+
list[cnt++] = _wrapExpr(jsb, 1, key);
|
884
729
|
}
|
885
730
|
|
886
731
|
expr = !cnt ? _wrapExpr(expr, asText)
|
887
|
-
: cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0]
|
732
|
+
: cnt > 1 ? '[' + list.join(',') + '].join(" ").trim()' : list[0];
|
888
733
|
}
|
889
734
|
return expr
|
890
735
|
|
@@ -892,173 +737,607 @@ var tmpl = (function () {
|
|
892
737
|
var
|
893
738
|
mm,
|
894
739
|
lv = 1,
|
895
|
-
ir = RE_BREND[ch]
|
740
|
+
ir = RE_BREND[ch];
|
896
741
|
|
897
|
-
ir.lastIndex = re.lastIndex
|
742
|
+
ir.lastIndex = re.lastIndex;
|
898
743
|
while (mm = ir.exec(expr)) {
|
899
|
-
if (mm[0] === ch) ++lv
|
900
|
-
else if (!--lv) break
|
744
|
+
if (mm[0] === ch) { ++lv; }
|
745
|
+
else if (!--lv) { break }
|
901
746
|
}
|
902
|
-
re.lastIndex = lv ? expr.length : ir.lastIndex
|
747
|
+
re.lastIndex = lv ? expr.length : ir.lastIndex;
|
903
748
|
}
|
904
749
|
}
|
905
750
|
|
906
751
|
// istanbul ignore next: not both
|
907
752
|
var // eslint-disable-next-line max-len
|
908
753
|
JS_CONTEXT = '"in this?this:' + (typeof window !== 'object' ? 'global' : 'window') + ').',
|
909
|
-
JS_VARNAME = /[,{][
|
910
|
-
JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)
|
754
|
+
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,
|
755
|
+
JS_NOPROPS = /^(?=(\.[$\w]+))\1(?:[^.[(]|$)/;
|
911
756
|
|
912
757
|
function _wrapExpr (expr, asText, key) {
|
913
|
-
var tb
|
758
|
+
var tb;
|
914
759
|
|
915
760
|
expr = expr.replace(JS_VARNAME, function (match, p, mvar, pos, s) {
|
916
761
|
if (mvar) {
|
917
|
-
pos = tb ? 0 : pos + match.length
|
762
|
+
pos = tb ? 0 : pos + match.length;
|
918
763
|
|
919
764
|
if (mvar !== 'this' && mvar !== 'global' && mvar !== 'window') {
|
920
|
-
match = p + '("' + mvar + JS_CONTEXT + mvar
|
921
|
-
if (pos) tb = (s = s[pos]) === '.' || s === '(' || s === '['
|
765
|
+
match = p + '("' + mvar + JS_CONTEXT + mvar;
|
766
|
+
if (pos) { tb = (s = s[pos]) === '.' || s === '(' || s === '['; }
|
922
767
|
} else if (pos) {
|
923
|
-
tb = !JS_NOPROPS.test(s.slice(pos))
|
768
|
+
tb = !JS_NOPROPS.test(s.slice(pos));
|
924
769
|
}
|
925
770
|
}
|
926
771
|
return match
|
927
|
-
})
|
772
|
+
});
|
928
773
|
|
929
774
|
if (tb) {
|
930
|
-
expr = 'try{return ' + expr + '}catch(e){E(e,this)}'
|
775
|
+
expr = 'try{return ' + expr + '}catch(e){E(e,this)}';
|
931
776
|
}
|
932
777
|
|
933
778
|
if (key) {
|
934
779
|
|
935
780
|
expr = (tb
|
936
781
|
? 'function(){' + expr + '}.call(this)' : '(' + expr + ')'
|
937
|
-
) + '?"' + key + '":""'
|
782
|
+
) + '?"' + key + '":""';
|
938
783
|
|
939
784
|
} else if (asText) {
|
940
785
|
|
941
786
|
expr = 'function(v){' + (tb
|
942
787
|
? expr.replace('return ', 'v=') : 'v=(' + expr + ')'
|
943
|
-
) + ';return v||v===0?v:""}.call(this)'
|
788
|
+
) + ';return v||v===0?v:""}.call(this)';
|
944
789
|
}
|
945
790
|
|
946
791
|
return expr
|
947
792
|
}
|
948
793
|
|
949
|
-
_tmpl.version = brackets.version = '
|
794
|
+
_tmpl.version = brackets.version = 'v3.0.1';
|
950
795
|
|
951
796
|
return _tmpl
|
952
797
|
|
953
|
-
})()
|
954
|
-
|
955
|
-
/*
|
956
|
-
lib/browser/tag/mkdom.js
|
798
|
+
})();
|
957
799
|
|
958
|
-
|
959
|
-
See: http://kangax.github.io/compat-table/es5/#ie8
|
960
|
-
http://codeplanet.io/dropping-ie8/
|
961
|
-
*/
|
962
|
-
var mkdom = (function _mkdom() {
|
963
|
-
var
|
964
|
-
reHasYield = /<yield\b/i,
|
965
|
-
reYieldAll = /<yield\s*(?:\/>|>([\S\s]*?)<\/yield\s*>|>)/ig,
|
966
|
-
reYieldSrc = /<yield\s+to=['"]([^'">]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig,
|
967
|
-
reYieldDest = /<yield\s+from=['"]?([-\w]+)['"]?\s*(?:\/>|>([\S\s]*?)<\/yield\s*>)/ig
|
968
|
-
var
|
969
|
-
rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' },
|
970
|
-
tblTags = IE_VERSION && IE_VERSION < 10
|
971
|
-
? SPECIAL_TAGS_REGEX : /^(?:t(?:body|head|foot|[rhd])|caption|col(?:group)?)$/
|
800
|
+
var observable$1 = function(el) {
|
972
801
|
|
973
802
|
/**
|
974
|
-
*
|
975
|
-
*
|
976
|
-
*
|
977
|
-
* @param {string} templ - The template coming from the custom tag definition
|
978
|
-
* @param {string} [html] - HTML content that comes from the DOM element where you
|
979
|
-
* will mount the tag, mostly the original tag in the page
|
980
|
-
* @returns {HTMLElement} DOM element with _templ_ merged through `YIELD` with the _html_.
|
803
|
+
* Extend the original object or create a new empty one
|
804
|
+
* @type { Object }
|
981
805
|
*/
|
982
|
-
function _mkdom(templ, html) {
|
983
|
-
var
|
984
|
-
match = templ && templ.match(/^\s*<([-\w]+)/),
|
985
|
-
tagName = match && match[1].toLowerCase(),
|
986
|
-
el = mkEl('div', isSVGTag(tagName))
|
987
|
-
|
988
|
-
// replace all the yield tags with the tag inner html
|
989
|
-
templ = replaceYield(templ, html)
|
990
|
-
|
991
|
-
/* istanbul ignore next */
|
992
|
-
if (tblTags.test(tagName))
|
993
|
-
el = specialTags(el, templ, tagName)
|
994
|
-
else
|
995
|
-
setInnerHTML(el, templ)
|
996
806
|
|
997
|
-
|
807
|
+
el = el || {};
|
998
808
|
|
999
|
-
|
1000
|
-
|
809
|
+
/**
|
810
|
+
* Private variables
|
811
|
+
*/
|
812
|
+
var callbacks = {},
|
813
|
+
slice = Array.prototype.slice;
|
1001
814
|
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
*/
|
1006
|
-
function specialTags(el, templ, tagName) {
|
1007
|
-
var
|
1008
|
-
select = tagName[0] === 'o',
|
1009
|
-
parent = select ? 'select>' : 'table>'
|
1010
|
-
|
1011
|
-
// trim() is important here, this ensures we don't have artifacts,
|
1012
|
-
// so we can check if we have only one element inside the parent
|
1013
|
-
el.innerHTML = '<' + parent + templ.trim() + '</' + parent
|
1014
|
-
parent = el.firstChild
|
1015
|
-
|
1016
|
-
// returns the immediate parent if tr/th/td/col is the only element, if not
|
1017
|
-
// returns the whole tree, as this can include additional elements
|
1018
|
-
if (select) {
|
1019
|
-
parent.selectedIndex = -1 // for IE9, compatible w/current riot behavior
|
1020
|
-
} else {
|
1021
|
-
// avoids insertion of cointainer inside container (ex: tbody inside tbody)
|
1022
|
-
var tname = rootEls[tagName]
|
1023
|
-
if (tname && parent.childElementCount === 1) parent = $(tname, parent)
|
1024
|
-
}
|
1025
|
-
return parent
|
1026
|
-
}
|
815
|
+
/**
|
816
|
+
* Public Api
|
817
|
+
*/
|
1027
818
|
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
819
|
+
// extend the el object adding the observable methods
|
820
|
+
Object.defineProperties(el, {
|
821
|
+
/**
|
822
|
+
* Listen to the given `event` ands
|
823
|
+
* execute the `callback` each time an event is triggered.
|
824
|
+
* @param { String } event - event id
|
825
|
+
* @param { Function } fn - callback function
|
826
|
+
* @returns { Object } el
|
827
|
+
*/
|
828
|
+
on: {
|
829
|
+
value: function(event, fn) {
|
830
|
+
if (typeof fn == 'function')
|
831
|
+
{ (callbacks[event] = callbacks[event] || []).push(fn); }
|
832
|
+
return el
|
833
|
+
},
|
834
|
+
enumerable: false,
|
835
|
+
writable: false,
|
836
|
+
configurable: false
|
837
|
+
},
|
838
|
+
|
839
|
+
/**
|
840
|
+
* Removes the given `event` listeners
|
841
|
+
* @param { String } event - event id
|
842
|
+
* @param { Function } fn - callback function
|
843
|
+
* @returns { Object } el
|
844
|
+
*/
|
845
|
+
off: {
|
846
|
+
value: function(event, fn) {
|
847
|
+
if (event == '*' && !fn) { callbacks = {}; }
|
848
|
+
else {
|
849
|
+
if (fn) {
|
850
|
+
var arr = callbacks[event];
|
851
|
+
for (var i = 0, cb; cb = arr && arr[i]; ++i) {
|
852
|
+
if (cb == fn) { arr.splice(i--, 1); }
|
853
|
+
}
|
854
|
+
} else { delete callbacks[event]; }
|
855
|
+
}
|
856
|
+
return el
|
857
|
+
},
|
858
|
+
enumerable: false,
|
859
|
+
writable: false,
|
860
|
+
configurable: false
|
861
|
+
},
|
862
|
+
|
863
|
+
/**
|
864
|
+
* Listen to the given `event` and
|
865
|
+
* execute the `callback` at most once
|
866
|
+
* @param { String } event - event id
|
867
|
+
* @param { Function } fn - callback function
|
868
|
+
* @returns { Object } el
|
869
|
+
*/
|
870
|
+
one: {
|
871
|
+
value: function(event, fn) {
|
872
|
+
function on() {
|
873
|
+
el.off(event, on);
|
874
|
+
fn.apply(el, arguments);
|
875
|
+
}
|
876
|
+
return el.on(event, on)
|
877
|
+
},
|
878
|
+
enumerable: false,
|
879
|
+
writable: false,
|
880
|
+
configurable: false
|
881
|
+
},
|
882
|
+
|
883
|
+
/**
|
884
|
+
* Execute all callback functions that listen to
|
885
|
+
* the given `event`
|
886
|
+
* @param { String } event - event id
|
887
|
+
* @returns { Object } el
|
888
|
+
*/
|
889
|
+
trigger: {
|
890
|
+
value: function(event) {
|
891
|
+
var arguments$1 = arguments;
|
892
|
+
|
893
|
+
|
894
|
+
// getting the arguments
|
895
|
+
var arglen = arguments.length - 1,
|
896
|
+
args = new Array(arglen),
|
897
|
+
fns,
|
898
|
+
fn,
|
899
|
+
i;
|
900
|
+
|
901
|
+
for (i = 0; i < arglen; i++) {
|
902
|
+
args[i] = arguments$1[i + 1]; // skip first argument
|
903
|
+
}
|
904
|
+
|
905
|
+
fns = slice.call(callbacks[event] || [], 0);
|
906
|
+
|
907
|
+
for (i = 0; fn = fns[i]; ++i) {
|
908
|
+
fn.apply(el, args);
|
909
|
+
}
|
910
|
+
|
911
|
+
if (callbacks['*'] && event != '*')
|
912
|
+
{ el.trigger.apply(el, ['*', event].concat(args)); }
|
913
|
+
|
914
|
+
return el
|
915
|
+
},
|
916
|
+
enumerable: false,
|
917
|
+
writable: false,
|
918
|
+
configurable: false
|
919
|
+
}
|
920
|
+
});
|
921
|
+
|
922
|
+
return el
|
923
|
+
|
924
|
+
};
|
925
|
+
|
926
|
+
/**
|
927
|
+
* Specialized function for looping an array-like collection with `each={}`
|
928
|
+
* @param { Array } list - collection of items
|
929
|
+
* @param {Function} fn - callback function
|
930
|
+
* @returns { Array } the array looped
|
931
|
+
*/
|
932
|
+
function each(list, fn) {
|
933
|
+
var len = list ? list.length : 0;
|
934
|
+
|
935
|
+
for (var i = 0, el; i < len; ++i) {
|
936
|
+
el = list[i];
|
937
|
+
// return false -> current item was removed by fn during the loop
|
938
|
+
if (fn(el, i) === false)
|
939
|
+
{ i--; }
|
940
|
+
}
|
941
|
+
return list
|
942
|
+
}
|
943
|
+
|
944
|
+
/**
|
945
|
+
* Check whether an array contains an item
|
946
|
+
* @param { Array } array - target array
|
947
|
+
* @param { * } item - item to test
|
948
|
+
* @returns { Boolean } -
|
949
|
+
*/
|
950
|
+
function contains(array, item) {
|
951
|
+
return ~array.indexOf(item)
|
952
|
+
}
|
953
|
+
|
954
|
+
/**
|
955
|
+
* Convert a string containing dashes to camel case
|
956
|
+
* @param { String } str - input string
|
957
|
+
* @returns { String } my-string -> myString
|
958
|
+
*/
|
959
|
+
function toCamel(str) {
|
960
|
+
return str.replace(/-(\w)/g, function (_, c) { return c.toUpperCase(); })
|
961
|
+
}
|
962
|
+
|
963
|
+
/**
|
964
|
+
* Faster String startsWith alternative
|
965
|
+
* @param { String } str - source string
|
966
|
+
* @param { String } value - test string
|
967
|
+
* @returns { Boolean } -
|
968
|
+
*/
|
969
|
+
function startsWith(str, value) {
|
970
|
+
return str.slice(0, value.length) === value
|
971
|
+
}
|
972
|
+
|
973
|
+
/**
|
974
|
+
* Helper function to set an immutable property
|
975
|
+
* @param { Object } el - object where the new property will be set
|
976
|
+
* @param { String } key - object key where the new property will be stored
|
977
|
+
* @param { * } value - value of the new property
|
978
|
+
* @param { Object } options - set the propery overriding the default options
|
979
|
+
* @returns { Object } - the initial object
|
980
|
+
*/
|
981
|
+
function defineProperty(el, key, value, options) {
|
982
|
+
Object.defineProperty(el, key, extend({
|
983
|
+
value: value,
|
984
|
+
enumerable: false,
|
985
|
+
writable: false,
|
986
|
+
configurable: true
|
987
|
+
}, options));
|
988
|
+
return el
|
989
|
+
}
|
990
|
+
|
991
|
+
/**
|
992
|
+
* Extend any object with other properties
|
993
|
+
* @param { Object } src - source object
|
994
|
+
* @returns { Object } the resulting extended object
|
995
|
+
*
|
996
|
+
* var obj = { foo: 'baz' }
|
997
|
+
* extend(obj, {bar: 'bar', foo: 'bar'})
|
998
|
+
* console.log(obj) => {bar: 'bar', foo: 'bar'}
|
999
|
+
*
|
1000
|
+
*/
|
1001
|
+
function extend(src) {
|
1002
|
+
var obj, args = arguments;
|
1003
|
+
for (var i = 1; i < args.length; ++i) {
|
1004
|
+
if (obj = args[i]) {
|
1005
|
+
for (var key in obj) {
|
1006
|
+
// check if this property of the source object could be overridden
|
1007
|
+
if (isWritable(src, key))
|
1008
|
+
{ src[key] = obj[key]; }
|
1009
|
+
}
|
1010
|
+
}
|
1011
|
+
}
|
1012
|
+
return src
|
1013
|
+
}
|
1014
|
+
|
1015
|
+
var misc = Object.freeze({
|
1016
|
+
each: each,
|
1017
|
+
contains: contains,
|
1018
|
+
toCamel: toCamel,
|
1019
|
+
startsWith: startsWith,
|
1020
|
+
defineProperty: defineProperty,
|
1021
|
+
extend: extend
|
1022
|
+
});
|
1023
|
+
|
1024
|
+
var EVENTS_PREFIX_REGEX = /^on/;
|
1025
|
+
|
1026
|
+
/**
|
1027
|
+
* Trigger DOM events
|
1028
|
+
* @param { HTMLElement } dom - dom element target of the event
|
1029
|
+
* @param { Function } handler - user function
|
1030
|
+
* @param { Object } e - event object
|
1031
|
+
*/
|
1032
|
+
function handleEvent(dom, handler, e) {
|
1033
|
+
var ptag = this._parent,
|
1034
|
+
item = this._item;
|
1035
|
+
|
1036
|
+
if (!item)
|
1037
|
+
{ while (ptag && !item) {
|
1038
|
+
item = ptag._item;
|
1039
|
+
ptag = ptag._parent;
|
1040
|
+
} }
|
1041
|
+
|
1042
|
+
// override the event properties
|
1043
|
+
if (isWritable(e, 'currentTarget')) { e.currentTarget = dom; }
|
1044
|
+
if (isWritable(e, 'target')) { e.target = e.srcElement; }
|
1045
|
+
if (isWritable(e, 'which')) { e.which = e.charCode || e.keyCode; }
|
1046
|
+
|
1047
|
+
e.item = item;
|
1048
|
+
|
1049
|
+
handler.call(this, e);
|
1050
|
+
|
1051
|
+
if (!e.preventUpdate) {
|
1052
|
+
var p = getImmediateCustomParentTag(this);
|
1053
|
+
// fixes #2083
|
1054
|
+
if (p.isMounted) { p.update(); }
|
1055
|
+
}
|
1056
|
+
}
|
1057
|
+
|
1058
|
+
/**
|
1059
|
+
* Attach an event to a DOM node
|
1060
|
+
* @param { String } name - event name
|
1061
|
+
* @param { Function } handler - event callback
|
1062
|
+
* @param { Object } dom - dom node
|
1063
|
+
* @param { Tag } tag - tag instance
|
1064
|
+
*/
|
1065
|
+
function setEventHandler(name, handler, dom, tag) {
|
1066
|
+
var eventName,
|
1067
|
+
cb = handleEvent.bind(tag, dom, handler);
|
1068
|
+
|
1069
|
+
if (!dom.addEventListener) {
|
1070
|
+
dom[name] = cb;
|
1071
|
+
return
|
1051
1072
|
}
|
1052
1073
|
|
1053
|
-
|
1074
|
+
// avoid to bind twice the same event
|
1075
|
+
dom[name] = null;
|
1054
1076
|
|
1055
|
-
|
1077
|
+
// normalize event name
|
1078
|
+
eventName = name.replace(EVENTS_PREFIX_REGEX, '');
|
1079
|
+
|
1080
|
+
// cache the callback directly on the DOM node
|
1081
|
+
if (!dom._riotEvents) { dom._riotEvents = {}; }
|
1082
|
+
|
1083
|
+
if (dom._riotEvents[name])
|
1084
|
+
{ dom.removeEventListener(eventName, dom._riotEvents[name]); }
|
1085
|
+
|
1086
|
+
dom._riotEvents[name] = cb;
|
1087
|
+
dom.addEventListener(eventName, cb, false);
|
1088
|
+
}
|
1089
|
+
|
1090
|
+
/**
|
1091
|
+
* Update dynamically created data-is tags with changing expressions
|
1092
|
+
* @param { Object } expr - expression tag and expression info
|
1093
|
+
* @param { Tag } parent - parent for tag creation
|
1094
|
+
*/
|
1095
|
+
function updateDataIs(expr, parent) {
|
1096
|
+
var tagName = tmpl(expr.value, parent),
|
1097
|
+
conf;
|
1098
|
+
|
1099
|
+
if (expr.tag && expr.tagName === tagName) {
|
1100
|
+
expr.tag.update();
|
1101
|
+
return
|
1102
|
+
}
|
1103
|
+
|
1104
|
+
// sync _parent to accommodate changing tagnames
|
1105
|
+
if (expr.tag) {
|
1106
|
+
each(expr.attrs, function (a) { return setAttr(expr.tag.root, a.name, a.value); });
|
1107
|
+
expr.tag.unmount(true);
|
1108
|
+
}
|
1109
|
+
|
1110
|
+
expr.impl = __TAG_IMPL[tagName];
|
1111
|
+
conf = {root: expr.dom, parent: parent, hasImpl: true, tagName: tagName};
|
1112
|
+
expr.tag = initChildTag(expr.impl, conf, expr.dom.innerHTML, parent);
|
1113
|
+
expr.tagName = tagName;
|
1114
|
+
expr.tag.mount();
|
1115
|
+
|
1116
|
+
// parent is the placeholder tag, not the dynamic tag so clean up
|
1117
|
+
parent.on('unmount', function () {
|
1118
|
+
var delName = expr.tag.opts.dataIs,
|
1119
|
+
tags = expr.tag.parent.tags,
|
1120
|
+
_tags = expr.tag._parent.tags;
|
1121
|
+
arrayishRemove(tags, delName, expr.tag);
|
1122
|
+
arrayishRemove(_tags, delName, expr.tag);
|
1123
|
+
expr.tag.unmount();
|
1124
|
+
});
|
1125
|
+
}
|
1126
|
+
|
1127
|
+
/**
|
1128
|
+
* Update on single tag expression
|
1129
|
+
* @this Tag
|
1130
|
+
* @param { Object } expr - expression logic
|
1131
|
+
* @returns { undefined }
|
1132
|
+
*/
|
1133
|
+
function updateExpression(expr) {
|
1134
|
+
var dom = expr.dom,
|
1135
|
+
attrName = expr.attr,
|
1136
|
+
isToggle = contains([SHOW_DIRECTIVE, HIDE_DIRECTIVE], attrName),
|
1137
|
+
value = tmpl(expr.expr, this),
|
1138
|
+
isValueAttr = attrName === 'riot-value',
|
1139
|
+
isVirtual = expr.root && expr.root.tagName === 'VIRTUAL',
|
1140
|
+
parent = dom && (expr.parent || dom.parentNode),
|
1141
|
+
old;
|
1142
|
+
|
1143
|
+
if (expr.bool)
|
1144
|
+
{ value = value ? attrName : false; }
|
1145
|
+
else if (isUndefined(value) || value === null)
|
1146
|
+
{ value = ''; }
|
1147
|
+
|
1148
|
+
if (expr._riot_id) { // if it's a tag
|
1149
|
+
if (expr.isMounted) {
|
1150
|
+
expr.update();
|
1151
|
+
|
1152
|
+
// if it hasn't been mounted yet, do that now.
|
1153
|
+
} else {
|
1154
|
+
expr.mount();
|
1155
|
+
|
1156
|
+
if (isVirtual) {
|
1157
|
+
var frag = document.createDocumentFragment();
|
1158
|
+
makeVirtual.call(expr, frag);
|
1159
|
+
expr.root.parentElement.replaceChild(frag, expr.root);
|
1160
|
+
}
|
1161
|
+
}
|
1162
|
+
return
|
1163
|
+
}
|
1164
|
+
|
1165
|
+
old = expr.value;
|
1166
|
+
expr.value = value;
|
1167
|
+
|
1168
|
+
if (expr.update) {
|
1169
|
+
expr.update();
|
1170
|
+
return
|
1171
|
+
}
|
1172
|
+
|
1173
|
+
if (expr.isRtag && value) { return updateDataIs(expr, this) }
|
1174
|
+
if (old === value) { return }
|
1175
|
+
// no change, so nothing more to do
|
1176
|
+
if (isValueAttr && dom.value === value) { return }
|
1177
|
+
|
1178
|
+
// textarea and text nodes have no attribute name
|
1179
|
+
if (!attrName) {
|
1180
|
+
// about #815 w/o replace: the browser converts the value to a string,
|
1181
|
+
// the comparison by "==" does too, but not in the server
|
1182
|
+
value += '';
|
1183
|
+
// test for parent avoids error with invalid assignment to nodeValue
|
1184
|
+
if (parent) {
|
1185
|
+
// cache the parent node because somehow it will become null on IE
|
1186
|
+
// on the next iteration
|
1187
|
+
expr.parent = parent;
|
1188
|
+
if (parent.tagName === 'TEXTAREA') {
|
1189
|
+
parent.value = value; // #1113
|
1190
|
+
if (!IE_VERSION) { dom.nodeValue = value; } // #1625 IE throws here, nodeValue
|
1191
|
+
} // will be available on 'updated'
|
1192
|
+
else { dom.nodeValue = value; }
|
1193
|
+
}
|
1194
|
+
return
|
1195
|
+
}
|
1196
|
+
|
1197
|
+
// remove original attribute
|
1198
|
+
if (!expr.isAttrRemoved || !value) {
|
1199
|
+
remAttr(dom, attrName);
|
1200
|
+
expr.isAttrRemoved = true;
|
1201
|
+
}
|
1202
|
+
|
1203
|
+
// event handler
|
1204
|
+
if (isFunction(value)) {
|
1205
|
+
setEventHandler(attrName, value, dom, this);
|
1206
|
+
// show / hide
|
1207
|
+
} else if (isToggle) {
|
1208
|
+
if (attrName === HIDE_DIRECTIVE) { value = !value; }
|
1209
|
+
dom.style.display = value ? '' : 'none';
|
1210
|
+
// field value
|
1211
|
+
} else if (isValueAttr) {
|
1212
|
+
dom.value = value;
|
1213
|
+
// <img src="{ expr }">
|
1214
|
+
} else if (startsWith(attrName, ATTRS_PREFIX) && attrName !== IS_DIRECTIVE) {
|
1215
|
+
attrName = attrName.slice(ATTRS_PREFIX.length);
|
1216
|
+
if (CASE_SENSITIVE_ATTRIBUTES[attrName])
|
1217
|
+
{ attrName = CASE_SENSITIVE_ATTRIBUTES[attrName]; }
|
1218
|
+
if (value != null)
|
1219
|
+
{ setAttr(dom, attrName, value); }
|
1220
|
+
} else {
|
1221
|
+
// <select> <option selected={true}> </select>
|
1222
|
+
if (attrName === 'selected' && parent && /^(SELECT|OPTGROUP)$/.test(parent.tagName) && value) {
|
1223
|
+
parent.value = dom.value;
|
1224
|
+
} if (expr.bool) {
|
1225
|
+
dom[attrName] = value;
|
1226
|
+
if (!value) { return }
|
1227
|
+
} if (value === 0 || value && typeof value !== T_OBJECT) {
|
1228
|
+
setAttr(dom, attrName, value);
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
}
|
1232
|
+
|
1233
|
+
/**
|
1234
|
+
* Update all the expressions in a Tag instance
|
1235
|
+
* @this Tag
|
1236
|
+
* @param { Array } expressions - expression that must be re evaluated
|
1237
|
+
*/
|
1238
|
+
function updateAllExpressions(expressions) {
|
1239
|
+
each(expressions, updateExpression.bind(this));
|
1240
|
+
}
|
1241
|
+
|
1242
|
+
var IfExpr = {
|
1243
|
+
init: function init(dom, tag, expr) {
|
1244
|
+
remAttr(dom, CONDITIONAL_DIRECTIVE);
|
1245
|
+
this.tag = tag;
|
1246
|
+
this.expr = expr;
|
1247
|
+
this.stub = document.createTextNode('');
|
1248
|
+
this.pristine = dom;
|
1249
|
+
|
1250
|
+
var p = dom.parentNode;
|
1251
|
+
p.insertBefore(this.stub, dom);
|
1252
|
+
p.removeChild(dom);
|
1253
|
+
|
1254
|
+
return this
|
1255
|
+
},
|
1256
|
+
update: function update() {
|
1257
|
+
var newValue = tmpl(this.expr, this.tag);
|
1258
|
+
|
1259
|
+
if (newValue && !this.current) { // insert
|
1260
|
+
this.current = this.pristine.cloneNode(true);
|
1261
|
+
this.stub.parentNode.insertBefore(this.current, this.stub);
|
1262
|
+
|
1263
|
+
this.expressions = [];
|
1264
|
+
parseExpressions.apply(this.tag, [this.current, this.expressions, true]);
|
1265
|
+
} else if (!newValue && this.current) { // remove
|
1266
|
+
unmountAll(this.expressions);
|
1267
|
+
if (this.current._tag) {
|
1268
|
+
this.current._tag.unmount();
|
1269
|
+
} else if (this.current.parentNode)
|
1270
|
+
{ this.current.parentNode.removeChild(this.current); }
|
1271
|
+
this.current = null;
|
1272
|
+
this.expressions = [];
|
1273
|
+
}
|
1274
|
+
|
1275
|
+
if (newValue) { updateAllExpressions.call(this.tag, this.expressions); }
|
1276
|
+
},
|
1277
|
+
unmount: function unmount() {
|
1278
|
+
unmountAll(this.expressions || []);
|
1279
|
+
delete this.pristine;
|
1280
|
+
delete this.parentNode;
|
1281
|
+
delete this.stub;
|
1282
|
+
}
|
1283
|
+
};
|
1284
|
+
|
1285
|
+
var RefExpr = {
|
1286
|
+
init: function init(dom, parent, attrName, attrValue) {
|
1287
|
+
this.dom = dom;
|
1288
|
+
this.attr = attrName;
|
1289
|
+
this.rawValue = attrValue;
|
1290
|
+
this.parent = parent;
|
1291
|
+
this.hasExp = tmpl.hasExpr(attrValue);
|
1292
|
+
this.firstRun = true;
|
1293
|
+
|
1294
|
+
return this
|
1295
|
+
},
|
1296
|
+
update: function update() {
|
1297
|
+
var value = this.rawValue;
|
1298
|
+
if (this.hasExp)
|
1299
|
+
{ value = tmpl(this.rawValue, this.parent); }
|
1300
|
+
|
1301
|
+
// if nothing changed, we're done
|
1302
|
+
if (!this.firstRun && value === this.value) { return }
|
1303
|
+
|
1304
|
+
var customParent = this.parent && getImmediateCustomParentTag(this.parent);
|
1305
|
+
|
1306
|
+
// if the referenced element is a custom tag, then we set the tag itself, rather than DOM
|
1307
|
+
var tagOrDom = this.tag || this.dom;
|
1308
|
+
|
1309
|
+
// the name changed, so we need to remove it from the old key (if present)
|
1310
|
+
if (!isBlank(this.value) && customParent)
|
1311
|
+
{ arrayishRemove(customParent.refs, this.value, tagOrDom); }
|
1312
|
+
|
1313
|
+
if (isBlank(value)) {
|
1314
|
+
// if the value is blank, we remove it
|
1315
|
+
remAttr(this.dom, this.attr);
|
1316
|
+
} else {
|
1317
|
+
// add it to the refs of parent tag (this behavior was changed >=3.0)
|
1318
|
+
if (customParent) { arrayishAdd(customParent.refs, value, tagOrDom); }
|
1319
|
+
// set the actual DOM attr
|
1320
|
+
setAttr(this.dom, this.attr, value);
|
1321
|
+
}
|
1322
|
+
this.value = value;
|
1323
|
+
this.firstRun = false;
|
1324
|
+
},
|
1325
|
+
unmount: function unmount() {
|
1326
|
+
var tagOrDom = this.tag || this.dom;
|
1327
|
+
var customParent = this.parent && getImmediateCustomParentTag(this.parent);
|
1328
|
+
if (!isBlank(this.value) && customParent)
|
1329
|
+
{ arrayishRemove(customParent.refs, this.value, tagOrDom); }
|
1330
|
+
delete this.dom;
|
1331
|
+
delete this.parent;
|
1332
|
+
}
|
1333
|
+
};
|
1056
1334
|
|
1057
1335
|
/**
|
1058
1336
|
* Convert the item looped into an object used to extend the child tag properties
|
1059
1337
|
* @param { Object } expr - object containing the keys used to extend the children tags
|
1060
1338
|
* @param { * } key - value to assign to the new object returned
|
1061
1339
|
* @param { * } val - value containing the position of the item in the array
|
1340
|
+
* @param { Object } base - prototype object for the new item
|
1062
1341
|
* @returns { Object } - new object containing the values of the original item
|
1063
1342
|
*
|
1064
1343
|
* The variables 'key' and 'val' are arbitrary.
|
@@ -1066,10 +1345,10 @@ var mkdom = (function _mkdom() {
|
|
1066
1345
|
* and on the expression used on the each tag
|
1067
1346
|
*
|
1068
1347
|
*/
|
1069
|
-
function mkitem(expr, key, val) {
|
1070
|
-
var item = {}
|
1071
|
-
item[expr.key] = key
|
1072
|
-
if (expr.pos) item[expr.pos] = val
|
1348
|
+
function mkitem(expr, key, val, base) {
|
1349
|
+
var item = base ? Object.create(base) : {};
|
1350
|
+
item[expr.key] = key;
|
1351
|
+
if (expr.pos) { item[expr.pos] = val; }
|
1073
1352
|
return item
|
1074
1353
|
}
|
1075
1354
|
|
@@ -1077,973 +1356,927 @@ function mkitem(expr, key, val) {
|
|
1077
1356
|
* Unmount the redundant tags
|
1078
1357
|
* @param { Array } items - array containing the current items to loop
|
1079
1358
|
* @param { Array } tags - array containing all the children tags
|
1359
|
+
* @param { String } tagName - key used to identify the type of tag
|
1080
1360
|
*/
|
1081
|
-
function unmountRedundant(items, tags) {
|
1082
|
-
|
1361
|
+
function unmountRedundant(items, tags, tagName) {
|
1083
1362
|
var i = tags.length,
|
1084
1363
|
j = items.length,
|
1085
|
-
t
|
1364
|
+
t;
|
1086
1365
|
|
1087
1366
|
while (i > j) {
|
1088
|
-
t = tags[--i]
|
1089
|
-
tags.splice(i, 1)
|
1090
|
-
t.unmount()
|
1367
|
+
t = tags[--i];
|
1368
|
+
tags.splice(i, 1);
|
1369
|
+
t.unmount();
|
1370
|
+
arrayishRemove(t.parent, tagName, t, true);
|
1091
1371
|
}
|
1092
1372
|
}
|
1093
1373
|
|
1094
1374
|
/**
|
1095
1375
|
* Move the nested custom tags in non custom loop tags
|
1096
|
-
* @
|
1376
|
+
* @this Tag
|
1097
1377
|
* @param { Number } i - current position of the loop tag
|
1098
1378
|
*/
|
1099
|
-
function moveNestedTags(
|
1100
|
-
|
1101
|
-
|
1379
|
+
function moveNestedTags(i) {
|
1380
|
+
var this$1 = this;
|
1381
|
+
|
1382
|
+
each(Object.keys(this.tags), function (tagName) {
|
1383
|
+
var tag = this$1.tags[tagName];
|
1102
1384
|
if (isArray(tag))
|
1103
|
-
each(tag, function (t) {
|
1104
|
-
moveChildTag(t, tagName, i)
|
1105
|
-
})
|
1385
|
+
{ each(tag, function (t) {
|
1386
|
+
moveChildTag.apply(t, [tagName, i]);
|
1387
|
+
}); }
|
1106
1388
|
else
|
1107
|
-
moveChildTag(tag, tagName, i)
|
1108
|
-
})
|
1389
|
+
{ moveChildTag.apply(tag, [tagName, i]); }
|
1390
|
+
});
|
1109
1391
|
}
|
1110
1392
|
|
1111
1393
|
/**
|
1112
|
-
*
|
1113
|
-
* @
|
1114
|
-
* @param
|
1115
|
-
* @param
|
1394
|
+
* Move a child tag
|
1395
|
+
* @this Tag
|
1396
|
+
* @param { HTMLElement } root - dom node containing all the loop children
|
1397
|
+
* @param { Tag } nextTag - instance of the next tag preceding the one we want to move
|
1398
|
+
* @param { Boolean } isVirtual - is it a virtual tag?
|
1116
1399
|
*/
|
1117
|
-
function
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
if (target)
|
1123
|
-
src.insertBefore(el, target._root)
|
1124
|
-
else
|
1125
|
-
src.appendChild(el)
|
1126
|
-
|
1127
|
-
tag._virts.push(el) // hold for unmounting
|
1128
|
-
el = sib
|
1129
|
-
}
|
1400
|
+
function move(root, nextTag, isVirtual) {
|
1401
|
+
if (isVirtual)
|
1402
|
+
{ moveVirtual.apply(this, [root, nextTag]); }
|
1403
|
+
else
|
1404
|
+
{ safeInsert(root, this.root, nextTag.root); }
|
1130
1405
|
}
|
1131
1406
|
|
1132
1407
|
/**
|
1133
|
-
*
|
1134
|
-
* @
|
1135
|
-
* @param
|
1136
|
-
* @param
|
1137
|
-
* @param
|
1138
|
-
*/
|
1139
|
-
function
|
1140
|
-
|
1141
|
-
|
1142
|
-
|
1143
|
-
|
1144
|
-
el = sib
|
1145
|
-
}
|
1408
|
+
* Insert and mount a child tag
|
1409
|
+
* @this Tag
|
1410
|
+
* @param { HTMLElement } root - dom node containing all the loop children
|
1411
|
+
* @param { Tag } nextTag - instance of the next tag preceding the one we want to insert
|
1412
|
+
* @param { Boolean } isVirtual - is it a virtual tag?
|
1413
|
+
*/
|
1414
|
+
function insert(root, nextTag, isVirtual) {
|
1415
|
+
if (isVirtual)
|
1416
|
+
{ makeVirtual.apply(this, [root, nextTag]); }
|
1417
|
+
else
|
1418
|
+
{ safeInsert(root, this.root, nextTag.root); }
|
1146
1419
|
}
|
1147
1420
|
|
1421
|
+
/**
|
1422
|
+
* Append a new tag into the DOM
|
1423
|
+
* @this Tag
|
1424
|
+
* @param { HTMLElement } root - dom node containing all the loop children
|
1425
|
+
* @param { Boolean } isVirtual - is it a virtual tag?
|
1426
|
+
*/
|
1427
|
+
function append(root, isVirtual) {
|
1428
|
+
if (isVirtual)
|
1429
|
+
{ makeVirtual.call(this, root); }
|
1430
|
+
else
|
1431
|
+
{ root.appendChild(this.root); }
|
1432
|
+
}
|
1148
1433
|
|
1149
1434
|
/**
|
1150
1435
|
* Manage tags having the 'each'
|
1151
|
-
* @param {
|
1436
|
+
* @param { HTMLElement } dom - DOM node we need to loop
|
1152
1437
|
* @param { Tag } parent - parent tag instance where the dom node is contained
|
1153
1438
|
* @param { String } expr - string contained in the 'each' attribute
|
1439
|
+
* @returns { Object } expression object for this each loop
|
1154
1440
|
*/
|
1155
1441
|
function _each(dom, parent, expr) {
|
1156
1442
|
|
1157
1443
|
// remove the each property from the original tag
|
1158
|
-
remAttr(dom,
|
1444
|
+
remAttr(dom, LOOP_DIRECTIVE);
|
1159
1445
|
|
1160
|
-
var mustReorder = typeof getAttr(dom,
|
1446
|
+
var mustReorder = typeof getAttr(dom, LOOP_NO_REORDER_DIRECTIVE) !== T_STRING || remAttr(dom, LOOP_NO_REORDER_DIRECTIVE),
|
1161
1447
|
tagName = getTagName(dom),
|
1162
|
-
impl =
|
1163
|
-
useRoot =
|
1164
|
-
|
1165
|
-
ref =
|
1448
|
+
impl = __TAG_IMPL[tagName] || { tmpl: getOuterHTML(dom) },
|
1449
|
+
useRoot = RE_SPECIAL_TAGS.test(tagName),
|
1450
|
+
parentNode = dom.parentNode,
|
1451
|
+
ref = createDOMPlaceholder(),
|
1166
1452
|
child = getTag(dom),
|
1167
|
-
|
1453
|
+
ifExpr = getAttr(dom, CONDITIONAL_DIRECTIVE),
|
1168
1454
|
tags = [],
|
1169
1455
|
oldItems = [],
|
1170
1456
|
hasKeys,
|
1171
|
-
|
1457
|
+
isLoop = true,
|
1458
|
+
isAnonymous = !__TAG_IMPL[tagName],
|
1459
|
+
isVirtual = dom.tagName === 'VIRTUAL';
|
1172
1460
|
|
1173
1461
|
// parse the each expression
|
1174
|
-
expr = tmpl.loopKeys(expr)
|
1462
|
+
expr = tmpl.loopKeys(expr);
|
1463
|
+
expr.isLoop = true;
|
1175
1464
|
|
1176
|
-
|
1177
|
-
root.insertBefore(ref, dom)
|
1465
|
+
if (ifExpr) { remAttr(dom, CONDITIONAL_DIRECTIVE); }
|
1178
1466
|
|
1179
|
-
//
|
1180
|
-
|
1467
|
+
// insert a marked where the loop tags will be injected
|
1468
|
+
parentNode.insertBefore(ref, dom);
|
1469
|
+
parentNode.removeChild(dom);
|
1181
1470
|
|
1182
|
-
|
1183
|
-
dom.parentNode.removeChild(dom)
|
1184
|
-
if (root.stub) root = parent.root
|
1471
|
+
expr.update = function updateEach() {
|
1185
1472
|
|
1186
|
-
}).on('update', function () {
|
1187
1473
|
// get the new items collection
|
1188
1474
|
var items = tmpl(expr.val, parent),
|
1189
|
-
|
1190
|
-
|
1475
|
+
frag = createFrag(),
|
1476
|
+
isObject$$1 = !isArray(items),
|
1477
|
+
root = ref.parentNode;
|
1191
1478
|
|
1192
1479
|
// object loop. any changes cause full redraw
|
1193
|
-
if (
|
1194
|
-
hasKeys = items || false
|
1480
|
+
if (isObject$$1) {
|
1481
|
+
hasKeys = items || false;
|
1195
1482
|
items = hasKeys ?
|
1196
1483
|
Object.keys(items).map(function (key) {
|
1197
|
-
return mkitem(expr, key,
|
1198
|
-
}) : []
|
1484
|
+
return mkitem(expr, items[key], key)
|
1485
|
+
}) : [];
|
1486
|
+
} else {
|
1487
|
+
hasKeys = false;
|
1199
1488
|
}
|
1200
1489
|
|
1201
|
-
|
1202
|
-
|
1203
|
-
|
1490
|
+
if (ifExpr) {
|
1491
|
+
items = items.filter(function(item, i) {
|
1492
|
+
if (expr.key && !isObject$$1)
|
1493
|
+
{ return !!tmpl(ifExpr, mkitem(expr, item, i, parent)) }
|
1204
1494
|
|
1205
|
-
|
1495
|
+
return !!tmpl(ifExpr, extend(Object.create(parent), item))
|
1496
|
+
});
|
1497
|
+
}
|
1498
|
+
|
1499
|
+
// loop all the new items
|
1500
|
+
each(items, function(item, i) {
|
1206
1501
|
// reorder only if the items are objects
|
1207
1502
|
var
|
1208
|
-
|
1209
|
-
_mustReorder = mustReorder && typeof item == T_OBJECT && !hasKeys,
|
1503
|
+
doReorder = mustReorder && typeof item === T_OBJECT && !hasKeys,
|
1210
1504
|
oldPos = oldItems.indexOf(item),
|
1211
|
-
|
1505
|
+
isNew = !~oldPos,
|
1506
|
+
mustAppend = i <= tags.length,
|
1507
|
+
pos = !isNew && doReorder ? oldPos : i,
|
1212
1508
|
// does a tag exist in this position?
|
1213
|
-
tag = tags[pos]
|
1509
|
+
tag = tags[pos];
|
1214
1510
|
|
1215
|
-
item = !hasKeys && expr.key ? mkitem(expr, item, i) : item
|
1511
|
+
item = !hasKeys && expr.key ? mkitem(expr, item, i) : item;
|
1216
1512
|
|
1217
1513
|
// new tag
|
1218
1514
|
if (
|
1219
|
-
|
1515
|
+
doReorder && isNew // by default we always try to reorder the DOM elements
|
1220
1516
|
||
|
1221
|
-
|
1517
|
+
!doReorder && !tag // with no-reorder we just update the old tags
|
1222
1518
|
) {
|
1223
|
-
|
1224
|
-
tag = new Tag(impl, {
|
1519
|
+
tag = new Tag$1(impl, {
|
1225
1520
|
parent: parent,
|
1226
|
-
isLoop:
|
1227
|
-
|
1521
|
+
isLoop: isLoop,
|
1522
|
+
isAnonymous: isAnonymous,
|
1228
1523
|
root: useRoot ? root : dom.cloneNode(),
|
1229
1524
|
item: item
|
1230
|
-
}, dom.innerHTML)
|
1525
|
+
}, dom.innerHTML);
|
1231
1526
|
|
1232
|
-
tag
|
1527
|
+
// mount the tag
|
1528
|
+
tag.mount();
|
1233
1529
|
|
1234
|
-
if (
|
1235
|
-
|
1236
|
-
|
1237
|
-
|
1238
|
-
addVirtual(tag, frag)
|
1239
|
-
else frag.appendChild(tag.root)
|
1240
|
-
}
|
1241
|
-
// this tag must be insert
|
1242
|
-
else {
|
1243
|
-
if (isVirtual)
|
1244
|
-
addVirtual(tag, root, tags[i])
|
1245
|
-
else root.insertBefore(tag.root, tags[i].root) // #1374 some browsers reset selected here
|
1246
|
-
oldItems.splice(i, 0, item)
|
1247
|
-
}
|
1530
|
+
if (mustAppend)
|
1531
|
+
{ append.apply(tag, [frag || root, isVirtual]); }
|
1532
|
+
else
|
1533
|
+
{ insert.apply(tag, [root, tags[i], isVirtual]); }
|
1248
1534
|
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1535
|
+
if (!mustAppend) { oldItems.splice(i, 0, item); }
|
1536
|
+
tags.splice(i, 0, tag);
|
1537
|
+
if (child) { arrayishAdd(parent.tags, tagName, tag, true); }
|
1538
|
+
pos = i; // handled here so no move
|
1539
|
+
} else { tag.update(item); }
|
1252
1540
|
|
1253
1541
|
// reorder the tag if it's not located in its previous position
|
1254
|
-
if (
|
1255
|
-
|
1256
|
-
|
1257
|
-
|
1258
|
-
|
1259
|
-
if (isVirtual)
|
1260
|
-
moveVirtual(tag, root, tags[i], dom.childNodes.length)
|
1261
|
-
else if (tags[i].root.parentNode) root.insertBefore(tag.root, tags[i].root)
|
1542
|
+
if (pos !== i && doReorder) {
|
1543
|
+
// #closes 2040
|
1544
|
+
if (contains(items, oldItems[i])) {
|
1545
|
+
move.apply(tag, [root, tags[i], isVirtual]);
|
1546
|
+
}
|
1262
1547
|
// update the position attribute if it exists
|
1263
|
-
if (expr.pos)
|
1264
|
-
tag[expr.pos] = i
|
1548
|
+
if (expr.pos) { tag[expr.pos] = i; }
|
1265
1549
|
// move the old tag instance
|
1266
|
-
tags.splice(i, 0, tags.splice(pos, 1)[0])
|
1550
|
+
tags.splice(i, 0, tags.splice(pos, 1)[0]);
|
1267
1551
|
// move the old item
|
1268
|
-
oldItems.splice(i, 0, oldItems.splice(pos, 1)[0])
|
1552
|
+
oldItems.splice(i, 0, oldItems.splice(pos, 1)[0]);
|
1269
1553
|
// if the loop tags are not custom
|
1270
1554
|
// we need to move all their custom tags into the right position
|
1271
|
-
if (!child && tag.tags) moveNestedTags(tag, i)
|
1555
|
+
if (!child && tag.tags) { moveNestedTags.call(tag, i); }
|
1272
1556
|
}
|
1273
1557
|
|
1274
1558
|
// cache the original item to use it in the events bound to this node
|
1275
1559
|
// and its children
|
1276
|
-
tag._item = item
|
1560
|
+
tag._item = item;
|
1277
1561
|
// cache the real parent tag internally
|
1278
|
-
defineProperty(tag, '_parent', parent)
|
1279
|
-
}
|
1562
|
+
defineProperty(tag, '_parent', parent);
|
1563
|
+
});
|
1280
1564
|
|
1281
1565
|
// remove the redundant tags
|
1282
|
-
unmountRedundant(items, tags)
|
1283
|
-
|
1284
|
-
//
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1566
|
+
unmountRedundant(items, tags, tagName);
|
1567
|
+
|
1568
|
+
// clone the items array
|
1569
|
+
oldItems = items.slice();
|
1570
|
+
|
1571
|
+
root.insertBefore(frag, ref);
|
1572
|
+
};
|
1573
|
+
|
1574
|
+
expr.unmount = function() {
|
1575
|
+
each(tags, function(t) { t.unmount(); });
|
1576
|
+
};
|
1577
|
+
|
1578
|
+
return expr
|
1579
|
+
}
|
1580
|
+
|
1581
|
+
/**
|
1582
|
+
* Walk the tag DOM to detect the expressions to evaluate
|
1583
|
+
* @this Tag
|
1584
|
+
* @param { HTMLElement } root - root tag where we will start digging the expressions
|
1585
|
+
* @param { Array } expressions - empty array where the expressions will be added
|
1586
|
+
* @param { Boolean } mustIncludeRoot - flag to decide whether the root must be parsed as well
|
1587
|
+
* @returns { Object } an object containing the root noode and the dom tree
|
1588
|
+
*/
|
1589
|
+
function parseExpressions(root, expressions, mustIncludeRoot) {
|
1590
|
+
var this$1 = this;
|
1591
|
+
|
1592
|
+
var tree = {parent: {children: expressions}};
|
1593
|
+
|
1594
|
+
walkNodes(root, function (dom, ctx) {
|
1595
|
+
var type = dom.nodeType, parent = ctx.parent, attr, expr, tagImpl;
|
1596
|
+
if (!mustIncludeRoot && dom === root) { return {parent: parent} }
|
1597
|
+
|
1598
|
+
// text node
|
1599
|
+
if (type === 3 && dom.parentNode.tagName !== 'STYLE' && tmpl.hasExpr(dom.nodeValue))
|
1600
|
+
{ parent.children.push({dom: dom, expr: dom.nodeValue}); }
|
1601
|
+
|
1602
|
+
if (type !== 1) { return ctx } // not an element
|
1603
|
+
|
1604
|
+
// loop. each does it's own thing (for now)
|
1605
|
+
if (attr = getAttr(dom, LOOP_DIRECTIVE)) {
|
1606
|
+
parent.children.push(_each(dom, this$1, attr));
|
1607
|
+
return false
|
1608
|
+
}
|
1609
|
+
|
1610
|
+
// if-attrs become the new parent. Any following expressions (either on the current
|
1611
|
+
// element, or below it) become children of this expression.
|
1612
|
+
if (attr = getAttr(dom, CONDITIONAL_DIRECTIVE)) {
|
1613
|
+
parent.children.push(Object.create(IfExpr).init(dom, this$1, attr));
|
1614
|
+
return false
|
1615
|
+
}
|
1616
|
+
|
1617
|
+
if (expr = getAttr(dom, IS_DIRECTIVE)) {
|
1618
|
+
if (tmpl.hasExpr(expr)) {
|
1619
|
+
parent.children.push({isRtag: true, expr: expr, dom: dom, attrs: [].slice.call(dom.attributes)});
|
1620
|
+
return false
|
1297
1621
|
}
|
1298
1622
|
}
|
1299
1623
|
|
1300
|
-
//
|
1301
|
-
//
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1624
|
+
// if this is a tag, stop traversing here.
|
1625
|
+
// we ignore the root, since parseExpressions is called while we're mounting that root
|
1626
|
+
tagImpl = getTag(dom);
|
1627
|
+
if (tagImpl && (dom !== root || mustIncludeRoot)) {
|
1628
|
+
var conf = {root: dom, parent: this$1, hasImpl: true};
|
1629
|
+
parent.children.push(initChildTag(tagImpl, conf, dom.innerHTML, this$1));
|
1630
|
+
return false
|
1631
|
+
}
|
1306
1632
|
|
1307
|
-
//
|
1308
|
-
|
1633
|
+
// attribute expressions
|
1634
|
+
parseAttributes.apply(this$1, [dom, dom.attributes, function(attr, expr) {
|
1635
|
+
if (!expr) { return }
|
1636
|
+
parent.children.push(expr);
|
1637
|
+
}]);
|
1309
1638
|
|
1310
|
-
|
1639
|
+
// whatever the parent is, all child elements get the same parent.
|
1640
|
+
// If this element had an if-attr, that's the parent for all child elements
|
1641
|
+
return {parent: parent}
|
1642
|
+
}, tree);
|
1311
1643
|
|
1644
|
+
return { tree: tree, root: root }
|
1312
1645
|
}
|
1646
|
+
|
1313
1647
|
/**
|
1314
|
-
*
|
1648
|
+
* Calls `fn` for every attribute on an element. If that attr has an expression,
|
1649
|
+
* it is also passed to fn.
|
1650
|
+
* @this Tag
|
1651
|
+
* @param { HTMLElement } dom - dom node to parse
|
1652
|
+
* @param { Array } attrs - array of attributes
|
1653
|
+
* @param { Function } fn - callback to exec on any iteration
|
1654
|
+
*/
|
1655
|
+
function parseAttributes(dom, attrs, fn) {
|
1656
|
+
var this$1 = this;
|
1657
|
+
|
1658
|
+
each(attrs, function (attr) {
|
1659
|
+
var name = attr.name, bool = isBoolAttr(name), expr;
|
1660
|
+
|
1661
|
+
if (contains(REF_DIRECTIVES, name)) {
|
1662
|
+
expr = Object.create(RefExpr).init(dom, this$1, name, attr.value);
|
1663
|
+
} else if (tmpl.hasExpr(attr.value)) {
|
1664
|
+
expr = {dom: dom, expr: attr.value, attr: attr.name, bool: bool};
|
1665
|
+
}
|
1666
|
+
|
1667
|
+
fn(attr, expr);
|
1668
|
+
});
|
1669
|
+
}
|
1670
|
+
|
1671
|
+
/*
|
1672
|
+
Includes hacks needed for the Internet Explorer version 9 and below
|
1673
|
+
See: http://kangax.github.io/compat-table/es5/#ie8
|
1674
|
+
http://codeplanet.io/dropping-ie8/
|
1675
|
+
*/
|
1676
|
+
|
1677
|
+
var reHasYield = /<yield\b/i;
|
1678
|
+
var reYieldAll = /<yield\s*(?:\/>|>([\S\s]*?)<\/yield\s*>|>)/ig;
|
1679
|
+
var reYieldSrc = /<yield\s+to=['"]([^'">]*)['"]\s*>([\S\s]*?)<\/yield\s*>/ig;
|
1680
|
+
var reYieldDest = /<yield\s+from=['"]?([-\w]+)['"]?\s*(?:\/>|>([\S\s]*?)<\/yield\s*>)/ig;
|
1681
|
+
var rootEls = { tr: 'tbody', th: 'tr', td: 'tr', col: 'colgroup' };
|
1682
|
+
var tblTags = IE_VERSION && IE_VERSION < 10 ? RE_SPECIAL_TAGS : RE_SPECIAL_TAGS_NO_OPTION;
|
1683
|
+
var GENERIC = 'div';
|
1684
|
+
|
1685
|
+
|
1686
|
+
/*
|
1687
|
+
Creates the root element for table or select child elements:
|
1688
|
+
tr/th/td/thead/tfoot/tbody/caption/col/colgroup/option/optgroup
|
1689
|
+
*/
|
1690
|
+
function specialTags(el, tmpl, tagName) {
|
1691
|
+
|
1692
|
+
var
|
1693
|
+
select = tagName[0] === 'o',
|
1694
|
+
parent = select ? 'select>' : 'table>';
|
1695
|
+
|
1696
|
+
// trim() is important here, this ensures we don't have artifacts,
|
1697
|
+
// so we can check if we have only one element inside the parent
|
1698
|
+
el.innerHTML = '<' + parent + tmpl.trim() + '</' + parent;
|
1699
|
+
parent = el.firstChild;
|
1700
|
+
|
1701
|
+
// returns the immediate parent if tr/th/td/col is the only element, if not
|
1702
|
+
// returns the whole tree, as this can include additional elements
|
1703
|
+
if (select) {
|
1704
|
+
parent.selectedIndex = -1; // for IE9, compatible w/current riot behavior
|
1705
|
+
} else {
|
1706
|
+
// avoids insertion of cointainer inside container (ex: tbody inside tbody)
|
1707
|
+
var tname = rootEls[tagName];
|
1708
|
+
if (tname && parent.childElementCount === 1) { parent = $(tname, parent); }
|
1709
|
+
}
|
1710
|
+
return parent
|
1711
|
+
}
|
1712
|
+
|
1713
|
+
/*
|
1714
|
+
Replace the yield tag from any tag template with the innerHTML of the
|
1715
|
+
original tag in the page
|
1716
|
+
*/
|
1717
|
+
function replaceYield(tmpl, html) {
|
1718
|
+
// do nothing if no yield
|
1719
|
+
if (!reHasYield.test(tmpl)) { return tmpl }
|
1720
|
+
|
1721
|
+
// be careful with #1343 - string on the source having `$1`
|
1722
|
+
var src = {};
|
1723
|
+
|
1724
|
+
html = html && html.replace(reYieldSrc, function (_, ref, text) {
|
1725
|
+
src[ref] = src[ref] || text; // preserve first definition
|
1726
|
+
return ''
|
1727
|
+
}).trim();
|
1728
|
+
|
1729
|
+
return tmpl
|
1730
|
+
.replace(reYieldDest, function (_, ref, def) { // yield with from - to attrs
|
1731
|
+
return src[ref] || def || ''
|
1732
|
+
})
|
1733
|
+
.replace(reYieldAll, function (_, def) { // yield without any "from"
|
1734
|
+
return html || def || ''
|
1735
|
+
})
|
1736
|
+
}
|
1737
|
+
|
1738
|
+
/**
|
1739
|
+
* Creates a DOM element to wrap the given content. Normally an `DIV`, but can be
|
1740
|
+
* also a `TABLE`, `SELECT`, `TBODY`, `TR`, or `COLGROUP` element.
|
1741
|
+
*
|
1742
|
+
* @param { String } tmpl - The template coming from the custom tag definition
|
1743
|
+
* @param { String } html - HTML content that comes from the DOM element where you
|
1744
|
+
* will mount the tag, mostly the original tag in the page
|
1745
|
+
* @param { Boolean } checkSvg - flag needed to know if we need to force the svg rendering in case of loop nodes
|
1746
|
+
* @returns { HTMLElement } DOM element with _tmpl_ merged through `YIELD` with the _html_.
|
1747
|
+
*/
|
1748
|
+
function mkdom(tmpl, html, checkSvg) {
|
1749
|
+
var match = tmpl && tmpl.match(/^\s*<([-\w]+)/),
|
1750
|
+
tagName = match && match[1].toLowerCase(),
|
1751
|
+
el = mkEl(GENERIC, checkSvg && isSVGTag(tagName));
|
1752
|
+
|
1753
|
+
// replace all the yield tags with the tag inner html
|
1754
|
+
tmpl = replaceYield(tmpl, html);
|
1755
|
+
|
1756
|
+
/* istanbul ignore next */
|
1757
|
+
if (tblTags.test(tagName))
|
1758
|
+
{ el = specialTags(el, tmpl, tagName); }
|
1759
|
+
else
|
1760
|
+
{ setInnerHTML(el, tmpl); }
|
1761
|
+
|
1762
|
+
el.stub = true;
|
1763
|
+
|
1764
|
+
return el
|
1765
|
+
}
|
1766
|
+
|
1767
|
+
/**
|
1768
|
+
* Another way to create a riot tag a bit more es6 friendly
|
1769
|
+
* @param { HTMLElement } el - tag DOM selector or DOM node/s
|
1770
|
+
* @param { Object } opts - tag logic
|
1771
|
+
* @returns { Tag } new riot tag instance
|
1772
|
+
*/
|
1773
|
+
function Tag$2(el, opts) {
|
1774
|
+
// get the tag properties from the class constructor
|
1775
|
+
var ref = this;
|
1776
|
+
var name = ref.name;
|
1777
|
+
var tmpl = ref.tmpl;
|
1778
|
+
var css = ref.css;
|
1779
|
+
var attrs = ref.attrs;
|
1780
|
+
var onCreate = ref.onCreate;
|
1781
|
+
// register a new tag and cache the class prototype
|
1782
|
+
if (!__TAG_IMPL[name]) {
|
1783
|
+
tag$1(name, tmpl, css, attrs, onCreate);
|
1784
|
+
// cache the class constructor
|
1785
|
+
__TAG_IMPL[name].class = this.constructor;
|
1786
|
+
}
|
1787
|
+
|
1788
|
+
// mount the tag using the class instance
|
1789
|
+
mountTo(el, name, opts, this);
|
1790
|
+
// inject the component css
|
1791
|
+
if (css) { styleManager.inject(); }
|
1792
|
+
|
1793
|
+
return this
|
1794
|
+
}
|
1795
|
+
|
1796
|
+
/**
|
1797
|
+
* Create a new riot tag implementation
|
1798
|
+
* @param { String } name - name/id of the new riot tag
|
1799
|
+
* @param { String } tmpl - tag template
|
1800
|
+
* @param { String } css - custom tag css
|
1801
|
+
* @param { String } attrs - root tag attributes
|
1802
|
+
* @param { Function } fn - user function
|
1803
|
+
* @returns { String } name/id of the tag just created
|
1804
|
+
*/
|
1805
|
+
function tag$1(name, tmpl, css, attrs, fn) {
|
1806
|
+
if (isFunction(attrs)) {
|
1807
|
+
fn = attrs;
|
1808
|
+
|
1809
|
+
if (/^[\w\-]+\s?=/.test(css)) {
|
1810
|
+
attrs = css;
|
1811
|
+
css = '';
|
1812
|
+
} else
|
1813
|
+
{ attrs = ''; }
|
1814
|
+
}
|
1815
|
+
|
1816
|
+
if (css) {
|
1817
|
+
if (isFunction(css))
|
1818
|
+
{ fn = css; }
|
1819
|
+
else
|
1820
|
+
{ styleManager.add(css); }
|
1821
|
+
}
|
1822
|
+
|
1823
|
+
name = name.toLowerCase();
|
1824
|
+
__TAG_IMPL[name] = { name: name, tmpl: tmpl, attrs: attrs, fn: fn };
|
1825
|
+
|
1826
|
+
return name
|
1827
|
+
}
|
1828
|
+
|
1829
|
+
/**
|
1830
|
+
* Create a new riot tag implementation (for use by the compiler)
|
1831
|
+
* @param { String } name - name/id of the new riot tag
|
1832
|
+
* @param { String } tmpl - tag template
|
1833
|
+
* @param { String } css - custom tag css
|
1834
|
+
* @param { String } attrs - root tag attributes
|
1835
|
+
* @param { Function } fn - user function
|
1836
|
+
* @returns { String } name/id of the tag just created
|
1837
|
+
*/
|
1838
|
+
function tag2$1(name, tmpl, css, attrs, fn) {
|
1839
|
+
if (css)
|
1840
|
+
{ styleManager.add(css, name); }
|
1841
|
+
|
1842
|
+
var exists = !!__TAG_IMPL[name];
|
1843
|
+
__TAG_IMPL[name] = { name: name, tmpl: tmpl, attrs: attrs, fn: fn };
|
1844
|
+
|
1845
|
+
if (exists && util.hotReloader)
|
1846
|
+
{ util.hotReloader(name); }
|
1847
|
+
|
1848
|
+
return name
|
1849
|
+
}
|
1850
|
+
|
1851
|
+
/**
|
1852
|
+
* Mount a tag using a specific tag implementation
|
1853
|
+
* @param { * } selector - tag DOM selector or DOM node/s
|
1854
|
+
* @param { String } tagName - tag implementation name
|
1855
|
+
* @param { Object } opts - tag logic
|
1856
|
+
* @returns { Array } new tags instances
|
1315
1857
|
*/
|
1316
|
-
|
1317
|
-
|
1318
|
-
if (!window) return { // skip injection on the server
|
1319
|
-
add: function () {},
|
1320
|
-
inject: function () {}
|
1321
|
-
}
|
1858
|
+
function mount$1(selector, tagName, opts) {
|
1859
|
+
var tags = [];
|
1322
1860
|
|
1323
|
-
|
1324
|
-
|
1325
|
-
|
1326
|
-
setAttr(newNode, 'type', 'text/css')
|
1861
|
+
function pushTagsTo(root) {
|
1862
|
+
if (root.tagName) {
|
1863
|
+
var riotTag = getAttr(root, IS_DIRECTIVE);
|
1327
1864
|
|
1328
|
-
|
1329
|
-
|
1330
|
-
|
1331
|
-
|
1332
|
-
|
1333
|
-
}
|
1334
|
-
else document.getElementsByTagName('head')[0].appendChild(newNode)
|
1865
|
+
// have tagName? force riot-tag to be the same
|
1866
|
+
if (tagName && riotTag !== tagName) {
|
1867
|
+
riotTag = tagName;
|
1868
|
+
setAttr(root, IS_DIRECTIVE, tagName);
|
1869
|
+
}
|
1335
1870
|
|
1336
|
-
|
1337
|
-
})()
|
1871
|
+
var tag$$1 = mountTo(root, riotTag || root.tagName.toLowerCase(), opts);
|
1338
1872
|
|
1339
|
-
|
1340
|
-
|
1341
|
-
|
1873
|
+
if (tag$$1)
|
1874
|
+
{ tags.push(tag$$1); }
|
1875
|
+
} else if (root.length)
|
1876
|
+
{ each(root, pushTagsTo); } // assume nodeList
|
1877
|
+
}
|
1342
1878
|
|
1343
|
-
//
|
1344
|
-
|
1345
|
-
value: styleNode,
|
1346
|
-
writable: true
|
1347
|
-
})
|
1879
|
+
// inject styles into DOM
|
1880
|
+
styleManager.inject();
|
1348
1881
|
|
1349
|
-
|
1350
|
-
|
1351
|
-
|
1352
|
-
return {
|
1353
|
-
/**
|
1354
|
-
* Save a tag style to be later injected into DOM
|
1355
|
-
* @param { String } css [description]
|
1356
|
-
*/
|
1357
|
-
add: function(css) {
|
1358
|
-
stylesToInject += css
|
1359
|
-
},
|
1360
|
-
/**
|
1361
|
-
* Inject all previously saved tag styles into DOM
|
1362
|
-
* innerHTML seems slow: http://jsperf.com/riot-insert-style
|
1363
|
-
*/
|
1364
|
-
inject: function() {
|
1365
|
-
if (stylesToInject) {
|
1366
|
-
if (cssTextProp) cssTextProp.cssText += stylesToInject
|
1367
|
-
else styleNode.innerHTML += stylesToInject
|
1368
|
-
stylesToInject = ''
|
1369
|
-
}
|
1370
|
-
}
|
1882
|
+
if (isObject(tagName)) {
|
1883
|
+
opts = tagName;
|
1884
|
+
tagName = 0;
|
1371
1885
|
}
|
1372
1886
|
|
1373
|
-
|
1887
|
+
var elem;
|
1888
|
+
var allTags;
|
1374
1889
|
|
1890
|
+
// crawl the DOM to find the tag
|
1891
|
+
if (isString(selector)) {
|
1892
|
+
selector = selector === '*' ?
|
1893
|
+
// select all registered tags
|
1894
|
+
// & tags found with the riot-tag attribute set
|
1895
|
+
allTags = selectTags() :
|
1896
|
+
// or just the ones named like the selector
|
1897
|
+
selector + selectTags(selector.split(/, */));
|
1375
1898
|
|
1376
|
-
|
1377
|
-
|
1378
|
-
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
1899
|
+
// make sure to pass always a selector
|
1900
|
+
// to the querySelectorAll function
|
1901
|
+
elem = selector ? $$(selector) : [];
|
1902
|
+
}
|
1903
|
+
else
|
1904
|
+
// probably you have passed already a tag or a NodeList
|
1905
|
+
{ elem = selector; }
|
1383
1906
|
|
1384
|
-
|
1385
|
-
|
1386
|
-
|
1907
|
+
// select all the registered and mount them inside their root elements
|
1908
|
+
if (tagName === '*') {
|
1909
|
+
// get all custom tags
|
1910
|
+
tagName = allTags || selectTags();
|
1911
|
+
// if the root els it's just a single tag
|
1912
|
+
if (elem.tagName)
|
1913
|
+
{ elem = $$(tagName, elem); }
|
1914
|
+
else {
|
1915
|
+
// select all the children for all the different root elements
|
1916
|
+
var nodeList = [];
|
1387
1917
|
|
1388
|
-
|
1389
|
-
childTags.push(initChildTag(child, {root: dom, parent: tag}, dom.innerHTML, tag))
|
1390
|
-
}
|
1918
|
+
each(elem, function (_el) { return nodeList.push($$(tagName, _el)); });
|
1391
1919
|
|
1392
|
-
|
1393
|
-
setNamed(dom, tag, [])
|
1920
|
+
elem = nodeList;
|
1394
1921
|
}
|
1922
|
+
// get rid of the tagName
|
1923
|
+
tagName = 0;
|
1924
|
+
}
|
1395
1925
|
|
1396
|
-
|
1926
|
+
pushTagsTo(elem);
|
1397
1927
|
|
1928
|
+
return tags
|
1398
1929
|
}
|
1399
1930
|
|
1400
|
-
|
1931
|
+
// Create a mixin that could be globally shared across all the tags
|
1932
|
+
var mixins = {};
|
1933
|
+
var globals = mixins[GLOBAL_MIXIN] = {};
|
1934
|
+
var _id = 0;
|
1401
1935
|
|
1402
|
-
|
1403
|
-
|
1404
|
-
|
1405
|
-
|
1936
|
+
/**
|
1937
|
+
* Create/Return a mixin by its name
|
1938
|
+
* @param { String } name - mixin name (global mixin if object)
|
1939
|
+
* @param { Object } mix - mixin logic
|
1940
|
+
* @param { Boolean } g - is global?
|
1941
|
+
* @returns { Object } the mixin logic
|
1942
|
+
*/
|
1943
|
+
function mixin$1(name, mix, g) {
|
1944
|
+
// Unnamed global
|
1945
|
+
if (isObject(name)) {
|
1946
|
+
mixin$1(("__unnamed_" + (_id++)), name, true);
|
1947
|
+
return
|
1406
1948
|
}
|
1407
1949
|
|
1408
|
-
|
1409
|
-
var type = dom.nodeType,
|
1410
|
-
attr
|
1950
|
+
var store = g ? globals : mixins;
|
1411
1951
|
|
1412
|
-
|
1413
|
-
|
1414
|
-
if (
|
1952
|
+
// Getter
|
1953
|
+
if (!mix) {
|
1954
|
+
if (isUndefined(store[name]))
|
1955
|
+
{ throw new Error('Unregistered mixin: ' + name) }
|
1415
1956
|
|
1416
|
-
|
1957
|
+
return store[name]
|
1958
|
+
}
|
1417
1959
|
|
1418
|
-
|
1419
|
-
|
1960
|
+
// Setter
|
1961
|
+
store[name] = isFunction(mix) ?
|
1962
|
+
extend(mix.prototype, store[name] || {}) && mix :
|
1963
|
+
extend(store[name] || {}, mix);
|
1964
|
+
}
|
1420
1965
|
|
1421
|
-
|
1966
|
+
/**
|
1967
|
+
* Update all the tags instances created
|
1968
|
+
* @returns { Array } all the tags instances
|
1969
|
+
*/
|
1970
|
+
function update$1() {
|
1971
|
+
return each(__TAGS_CACHE, function (tag$$1) { return tag$$1.update(); })
|
1972
|
+
}
|
1422
1973
|
|
1423
|
-
|
1424
|
-
|
1425
|
-
|
1426
|
-
bool = name.split('__')[1]
|
1974
|
+
function unregister$1(name) {
|
1975
|
+
delete __TAG_IMPL[name];
|
1976
|
+
}
|
1427
1977
|
|
1428
|
-
|
1429
|
-
|
1978
|
+
// counter to give a unique id to all the Tag instances
|
1979
|
+
var __uid = 0;
|
1430
1980
|
|
1431
|
-
|
1981
|
+
/**
|
1982
|
+
* We need to update opts for this tag. That requires updating the expressions
|
1983
|
+
* in any attributes on the tag, and then copying the result onto opts.
|
1984
|
+
* @this Tag
|
1985
|
+
* @param {Boolean} isLoop - is it a loop tag?
|
1986
|
+
* @param { Tag } parent - parent tag node
|
1987
|
+
* @param { Boolean } isAnonymous - is it a tag without any impl? (a tag not registered)
|
1988
|
+
* @param { Object } opts - tag options
|
1989
|
+
* @param { Array } instAttrs - tag attributes array
|
1990
|
+
*/
|
1991
|
+
function updateOpts(isLoop, parent, isAnonymous, opts, instAttrs) {
|
1992
|
+
// isAnonymous `each` tags treat `dom` and `root` differently. In this case
|
1993
|
+
// (and only this case) we don't need to do updateOpts, because the regular parse
|
1994
|
+
// will update those attrs. Plus, isAnonymous tags don't need opts anyway
|
1995
|
+
if (isLoop && isAnonymous) { return }
|
1432
1996
|
|
1433
|
-
|
1434
|
-
|
1997
|
+
var ctx = !isAnonymous && isLoop ? this : parent || this;
|
1998
|
+
each(instAttrs, function (attr) {
|
1999
|
+
if (attr.expr) { updateAllExpressions.call(ctx, [attr.expr]); }
|
2000
|
+
opts[toCamel(attr.name)] = attr.expr ? attr.expr.value : attr.value;
|
2001
|
+
});
|
2002
|
+
}
|
1435
2003
|
|
1436
|
-
})
|
1437
2004
|
|
1438
|
-
|
1439
|
-
|
2005
|
+
/**
|
2006
|
+
* Tag class
|
2007
|
+
* @constructor
|
2008
|
+
* @param { Object } impl - it contains the tag template, and logic
|
2009
|
+
* @param { Object } conf - tag options
|
2010
|
+
* @param { String } innerHTML - html that eventually we need to inject in the tag
|
2011
|
+
*/
|
2012
|
+
function Tag$1(impl, conf, innerHTML) {
|
1440
2013
|
|
1441
|
-
var
|
1442
|
-
opts = inherit(conf.opts) || {},
|
2014
|
+
var opts = extend({}, conf.opts),
|
1443
2015
|
parent = conf.parent,
|
1444
2016
|
isLoop = conf.isLoop,
|
1445
|
-
|
2017
|
+
isAnonymous = conf.isAnonymous,
|
1446
2018
|
item = cleanUpData(conf.item),
|
2019
|
+
instAttrs = [], // All attributes on the Tag when it's first parsed
|
2020
|
+
implAttrs = [], // expressions on this type of Tag
|
1447
2021
|
expressions = [],
|
1448
|
-
childTags = [],
|
1449
2022
|
root = conf.root,
|
1450
|
-
tagName =
|
1451
|
-
|
2023
|
+
tagName = conf.tagName || getTagName(root),
|
2024
|
+
isVirtual = tagName === 'virtual',
|
1452
2025
|
propsInSyncWithParent = [],
|
1453
|
-
dom
|
2026
|
+
dom;
|
1454
2027
|
|
1455
|
-
//
|
1456
|
-
|
2028
|
+
// make this tag observable
|
2029
|
+
observable$1(this);
|
2030
|
+
// only call unmount if we have a valid __TAG_IMPL (has name property)
|
2031
|
+
if (impl.name && root._tag) { root._tag.unmount(true); }
|
1457
2032
|
|
1458
2033
|
// not yet mounted
|
1459
|
-
this.isMounted = false
|
1460
|
-
root.isLoop = isLoop
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
2034
|
+
this.isMounted = false;
|
2035
|
+
root.isLoop = isLoop;
|
2036
|
+
|
2037
|
+
defineProperty(this, '_internal', {
|
2038
|
+
isAnonymous: isAnonymous,
|
2039
|
+
instAttrs: instAttrs,
|
2040
|
+
innerHTML: innerHTML,
|
2041
|
+
// these vars will be needed only for the virtual tags
|
2042
|
+
virts: [],
|
2043
|
+
tail: null,
|
2044
|
+
head: null
|
2045
|
+
});
|
1465
2046
|
|
1466
2047
|
// create a unique id to this tag
|
1467
2048
|
// it could be handy to use it also to improve the virtual dom rendering speed
|
1468
|
-
defineProperty(this, '_riot_id', ++__uid) // base 1 allows test !t._riot_id
|
1469
|
-
|
1470
|
-
extend(this, { parent: parent, root: root, opts: opts}, item)
|
1471
|
-
// protect the "tags" property from being overridden
|
1472
|
-
defineProperty(this, 'tags', {})
|
1473
|
-
|
1474
|
-
// grab attributes
|
1475
|
-
each(root.attributes, function(el) {
|
1476
|
-
var val = el.value
|
1477
|
-
// remember attributes with expressions only
|
1478
|
-
if (tmpl.hasExpr(val)) attr[el.name] = val
|
1479
|
-
})
|
1480
|
-
|
1481
|
-
dom = mkdom(impl.tmpl, innerHTML)
|
1482
|
-
|
1483
|
-
// options
|
1484
|
-
function updateOpts() {
|
1485
|
-
var ctx = hasImpl && isLoop ? self : parent || self
|
1486
|
-
|
1487
|
-
// update opts from current DOM attributes
|
1488
|
-
each(root.attributes, function(el) {
|
1489
|
-
var val = el.value
|
1490
|
-
opts[toCamel(el.name)] = tmpl.hasExpr(val) ? tmpl(val, ctx) : val
|
1491
|
-
})
|
1492
|
-
// recover those with expressions
|
1493
|
-
each(Object.keys(attr), function(name) {
|
1494
|
-
opts[toCamel(name)] = tmpl(attr[name], ctx)
|
1495
|
-
})
|
1496
|
-
}
|
1497
|
-
|
1498
|
-
function normalizeData(data) {
|
1499
|
-
for (var key in item) {
|
1500
|
-
if (typeof self[key] !== T_UNDEF && isWritable(self, key))
|
1501
|
-
self[key] = data[key]
|
1502
|
-
}
|
1503
|
-
}
|
2049
|
+
defineProperty(this, '_riot_id', ++__uid); // base 1 allows test !t._riot_id
|
1504
2050
|
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
2051
|
+
extend(this, { root: root, opts: opts }, item);
|
2052
|
+
// protect the "tags" and "refs" property from being overridden
|
2053
|
+
defineProperty(this, 'parent', parent || null);
|
2054
|
+
defineProperty(this, 'tags', {});
|
2055
|
+
defineProperty(this, 'refs', {});
|
1509
2056
|
|
1510
|
-
|
1511
|
-
// track the property to keep in sync
|
1512
|
-
// so we can keep it updated
|
1513
|
-
if (!mustSync) propsInSyncWithParent.push(k)
|
1514
|
-
self[k] = target[k]
|
1515
|
-
}
|
1516
|
-
})
|
1517
|
-
}
|
2057
|
+
dom = mkdom(impl.tmpl, innerHTML, isLoop);
|
1518
2058
|
|
1519
2059
|
/**
|
1520
2060
|
* Update the tag expressions and options
|
1521
2061
|
* @param { * } data - data we want to use to extend the tag properties
|
1522
|
-
* @
|
1523
|
-
* @returns { self }
|
2062
|
+
* @returns { Tag } the current tag instance
|
1524
2063
|
*/
|
1525
|
-
defineProperty(this, 'update', function(data
|
2064
|
+
defineProperty(this, 'update', function tagUpdate(data) {
|
2065
|
+
if (isFunction(this.shouldUpdate) && !this.shouldUpdate(data)) { return this }
|
1526
2066
|
|
1527
2067
|
// make sure the data passed will not override
|
1528
2068
|
// the component core methods
|
1529
|
-
data = cleanUpData(data)
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
if (
|
1536
|
-
|
1537
|
-
|
1538
|
-
}
|
1539
|
-
extend(self, data)
|
1540
|
-
updateOpts()
|
1541
|
-
self.trigger('update', data)
|
1542
|
-
update(expressions, self)
|
1543
|
-
|
1544
|
-
// the updated event will be triggered
|
1545
|
-
// once the DOM will be ready and all the re-flows are completed
|
1546
|
-
// this is useful if you want to get the "real" root properties
|
1547
|
-
// 4 ex: root.offsetWidth ...
|
1548
|
-
if (isInherited && self.parent)
|
1549
|
-
// closes #1599
|
1550
|
-
self.parent.one('updated', function() { self.trigger('updated') })
|
1551
|
-
else rAF(function() { self.trigger('updated') })
|
2069
|
+
data = cleanUpData(data);
|
2070
|
+
|
2071
|
+
// inherit properties from the parent, but only for isAnonymous tags
|
2072
|
+
if (isLoop && isAnonymous) { inheritFrom.apply(this, [this.parent, propsInSyncWithParent]); }
|
2073
|
+
extend(this, data);
|
2074
|
+
updateOpts.apply(this, [isLoop, parent, isAnonymous, opts, instAttrs]);
|
2075
|
+
if (this.isMounted) { this.trigger('update', data); }
|
2076
|
+
updateAllExpressions.call(this, expressions);
|
2077
|
+
if (this.isMounted) { this.trigger('updated'); }
|
1552
2078
|
|
1553
2079
|
return this
|
1554
|
-
})
|
1555
2080
|
|
1556
|
-
|
1557
|
-
|
2081
|
+
}.bind(this));
|
2082
|
+
|
2083
|
+
/**
|
2084
|
+
* Add a mixin to this tag
|
2085
|
+
* @returns { Tag } the current tag instance
|
2086
|
+
*/
|
2087
|
+
defineProperty(this, 'mixin', function tagMixin() {
|
2088
|
+
var this$1 = this;
|
2089
|
+
|
2090
|
+
each(arguments, function (mix) {
|
1558
2091
|
var instance,
|
1559
2092
|
props = [],
|
1560
|
-
obj
|
2093
|
+
obj;
|
1561
2094
|
|
1562
|
-
mix =
|
2095
|
+
mix = isString(mix) ? mixin$1(mix) : mix;
|
1563
2096
|
|
1564
2097
|
// check if the mixin is a function
|
1565
2098
|
if (isFunction(mix)) {
|
1566
2099
|
// create the new mixin instance
|
1567
|
-
instance = new mix()
|
1568
|
-
} else instance = mix
|
2100
|
+
instance = new mix();
|
2101
|
+
} else { instance = mix; }
|
2102
|
+
|
2103
|
+
var proto = Object.getPrototypeOf(instance);
|
1569
2104
|
|
1570
2105
|
// build multilevel prototype inheritance chain property list
|
1571
|
-
do props = props.concat(Object.getOwnPropertyNames(obj || instance))
|
2106
|
+
do { props = props.concat(Object.getOwnPropertyNames(obj || instance)); }
|
1572
2107
|
while (obj = Object.getPrototypeOf(obj || instance))
|
1573
2108
|
|
1574
2109
|
// loop the keys in the function prototype or the all object keys
|
1575
|
-
each(props, function(key) {
|
1576
|
-
// bind methods to
|
2110
|
+
each(props, function (key) {
|
2111
|
+
// bind methods to this
|
1577
2112
|
// allow mixins to override other properties/parent mixins
|
1578
|
-
if (key
|
2113
|
+
if (key !== 'init') {
|
1579
2114
|
// check for getters/setters
|
1580
|
-
var descriptor = Object.getOwnPropertyDescriptor(instance, key)
|
1581
|
-
var hasGetterSetter = descriptor && (descriptor.get || descriptor.set)
|
2115
|
+
var descriptor = Object.getOwnPropertyDescriptor(instance, key) || Object.getOwnPropertyDescriptor(proto, key);
|
2116
|
+
var hasGetterSetter = descriptor && (descriptor.get || descriptor.set);
|
1582
2117
|
|
1583
2118
|
// apply method only if it does not already exist on the instance
|
1584
|
-
if (!
|
1585
|
-
Object.defineProperty(
|
2119
|
+
if (!this$1.hasOwnProperty(key) && hasGetterSetter) {
|
2120
|
+
Object.defineProperty(this$1, key, descriptor);
|
1586
2121
|
} else {
|
1587
|
-
|
1588
|
-
instance[key].bind(
|
1589
|
-
instance[key]
|
2122
|
+
this$1[key] = isFunction(instance[key]) ?
|
2123
|
+
instance[key].bind(this$1) :
|
2124
|
+
instance[key];
|
1590
2125
|
}
|
1591
2126
|
}
|
1592
|
-
})
|
2127
|
+
});
|
1593
2128
|
|
1594
2129
|
// init method will be called automatically
|
1595
|
-
if (instance.init)
|
1596
|
-
|
2130
|
+
if (instance.init)
|
2131
|
+
{ instance.init.bind(this$1)(); }
|
2132
|
+
});
|
1597
2133
|
return this
|
1598
|
-
})
|
2134
|
+
}.bind(this));
|
1599
2135
|
|
1600
|
-
|
2136
|
+
/**
|
2137
|
+
* Mount the current tag instance
|
2138
|
+
* @returns { Tag } the current tag instance
|
2139
|
+
*/
|
2140
|
+
defineProperty(this, 'mount', function tagMount() {
|
2141
|
+
var this$1 = this;
|
1601
2142
|
|
1602
|
-
|
2143
|
+
root._tag = this; // keep a reference to the tag just created
|
1603
2144
|
|
1604
|
-
//
|
1605
|
-
|
2145
|
+
// Read all the attrs on this instance. This give us the info we need for updateOpts
|
2146
|
+
parseAttributes.apply(parent, [root, root.attributes, function (attr, expr) {
|
2147
|
+
if (!isAnonymous && RefExpr.isPrototypeOf(expr)) { expr.tag = this$1; }
|
2148
|
+
attr.expr = expr;
|
2149
|
+
instAttrs.push(attr);
|
2150
|
+
}]);
|
1606
2151
|
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
2152
|
+
// update the root adding custom attributes coming from the compiler
|
2153
|
+
implAttrs = [];
|
2154
|
+
walkAttrs(impl.attrs, function (k, v) { implAttrs.push({name: k, value: v}); });
|
2155
|
+
parseAttributes.apply(this, [root, implAttrs, function (attr, expr) {
|
2156
|
+
if (expr) { expressions.push(expr); }
|
2157
|
+
else { setAttr(root, attr.name, attr.value); }
|
2158
|
+
}]);
|
1611
2159
|
|
1612
2160
|
// children in loop should inherit from true parent
|
1613
|
-
if (
|
1614
|
-
inheritFrom(self._parent)
|
1615
|
-
}
|
2161
|
+
if (this._parent && isAnonymous) { inheritFrom.apply(this, [this._parent, propsInSyncWithParent]); }
|
1616
2162
|
|
1617
2163
|
// initialiation
|
1618
|
-
|
2164
|
+
updateOpts.apply(this, [isLoop, parent, isAnonymous, opts, instAttrs]);
|
1619
2165
|
|
1620
|
-
//
|
1621
|
-
|
2166
|
+
// add global mixins
|
2167
|
+
var globalMixin = mixin$1(GLOBAL_MIXIN);
|
2168
|
+
|
2169
|
+
if (globalMixin) {
|
2170
|
+
for (var i in globalMixin) {
|
2171
|
+
if (globalMixin.hasOwnProperty(i)) {
|
2172
|
+
this$1.mixin(globalMixin[i]);
|
2173
|
+
}
|
2174
|
+
}
|
2175
|
+
}
|
1622
2176
|
|
1623
|
-
|
1624
|
-
toggle(true)
|
2177
|
+
if (impl.fn) { impl.fn.call(this, opts); }
|
1625
2178
|
|
1626
|
-
|
1627
|
-
// it fixes also #1087
|
1628
|
-
if (impl.attrs)
|
1629
|
-
walkAttributes(impl.attrs, function (k, v) { setAttr(root, k, v) })
|
1630
|
-
if (impl.attrs || hasImpl)
|
1631
|
-
parseExpressions(self.root, self, expressions)
|
2179
|
+
this.trigger('before-mount');
|
1632
2180
|
|
1633
|
-
|
2181
|
+
// parse layout after init. fn may calculate args for nested custom tags
|
2182
|
+
parseExpressions.apply(this, [dom, expressions, false]);
|
1634
2183
|
|
1635
|
-
|
1636
|
-
self.trigger('before-mount')
|
2184
|
+
this.update(item);
|
1637
2185
|
|
1638
|
-
if (isLoop &&
|
2186
|
+
if (isLoop && isAnonymous) {
|
1639
2187
|
// update the root attribute for the looped elements
|
1640
|
-
root = dom.firstChild
|
2188
|
+
this.root = root = dom.firstChild;
|
1641
2189
|
} else {
|
1642
|
-
while (dom.firstChild) root.appendChild(dom.firstChild)
|
1643
|
-
if (root.stub) root = parent.root
|
2190
|
+
while (dom.firstChild) { root.appendChild(dom.firstChild); }
|
2191
|
+
if (root.stub) { root = parent.root; }
|
1644
2192
|
}
|
1645
2193
|
|
1646
|
-
defineProperty(
|
1647
|
-
|
1648
|
-
// parse the named dom nodes in the looped child
|
1649
|
-
// adding them to the parent as well
|
1650
|
-
if (isLoop)
|
1651
|
-
parseNamedElements(self.root, self.parent, null, true)
|
2194
|
+
defineProperty(this, 'root', root);
|
2195
|
+
this.isMounted = true;
|
1652
2196
|
|
1653
2197
|
// if it's not a child tag we can trigger its mount event
|
1654
|
-
if (!
|
1655
|
-
|
1656
|
-
self.trigger('mount')
|
2198
|
+
if (!this.parent || this.parent.isMounted) {
|
2199
|
+
this.trigger('mount');
|
1657
2200
|
}
|
1658
2201
|
// otherwise we need to wait that the parent event gets triggered
|
1659
|
-
else
|
1660
|
-
|
1661
|
-
|
1662
|
-
if (!isInStub(self.root)) {
|
1663
|
-
self.parent.isMounted = self.isMounted = true
|
1664
|
-
self.trigger('mount')
|
1665
|
-
}
|
1666
|
-
})
|
1667
|
-
})
|
2202
|
+
else { this.parent.one('mount', function () {
|
2203
|
+
this$1.trigger('mount');
|
2204
|
+
}); }
|
1668
2205
|
|
2206
|
+
return this
|
2207
|
+
|
2208
|
+
}.bind(this));
|
2209
|
+
|
2210
|
+
/**
|
2211
|
+
* Unmount the tag instance
|
2212
|
+
* @param { Boolean } mustKeepRoot - if it's true the root node will not be removed
|
2213
|
+
* @returns { Tag } the current tag instance
|
2214
|
+
*/
|
2215
|
+
defineProperty(this, 'unmount', function tagUnmount(mustKeepRoot) {
|
2216
|
+
var this$1 = this;
|
1669
2217
|
|
1670
|
-
|
1671
|
-
var el = root,
|
2218
|
+
var el = this.root,
|
1672
2219
|
p = el.parentNode,
|
1673
2220
|
ptag,
|
1674
|
-
tagIndex =
|
2221
|
+
tagIndex = __TAGS_CACHE.indexOf(this);
|
2222
|
+
|
2223
|
+
this.trigger('before-unmount');
|
1675
2224
|
|
1676
|
-
|
2225
|
+
// clear all attributes coming from the mounted tag
|
2226
|
+
walkAttrs(impl.attrs, function (name) {
|
2227
|
+
if (startsWith(name, ATTRS_PREFIX))
|
2228
|
+
{ name = name.slice(ATTRS_PREFIX.length); }
|
2229
|
+
remAttr(root, name);
|
2230
|
+
});
|
1677
2231
|
|
1678
2232
|
// remove this tag instance from the global virtualDom variable
|
1679
2233
|
if (~tagIndex)
|
1680
|
-
|
2234
|
+
{ __TAGS_CACHE.splice(tagIndex, 1); }
|
1681
2235
|
|
1682
2236
|
if (p) {
|
1683
|
-
|
1684
|
-
if (parent) {
|
1685
|
-
ptag = getImmediateCustomParentTag(parent)
|
1686
|
-
// remove this tag from the parent tags object
|
1687
|
-
// if there are multiple nested tags with same name..
|
1688
|
-
// remove this element form the array
|
1689
|
-
if (isArray(ptag.tags[tagName]))
|
1690
|
-
each(ptag.tags[tagName], function(tag, i) {
|
1691
|
-
if (tag._riot_id == self._riot_id)
|
1692
|
-
ptag.tags[tagName].splice(i, 1)
|
1693
|
-
})
|
1694
|
-
else
|
1695
|
-
// otherwise just delete the tag instance
|
1696
|
-
ptag.tags[tagName] = undefined
|
1697
|
-
}
|
1698
|
-
|
1699
|
-
else
|
1700
|
-
while (el.firstChild) el.removeChild(el.firstChild)
|
1701
|
-
|
1702
|
-
if (!keepRootTag)
|
1703
|
-
p.removeChild(el)
|
1704
|
-
else {
|
1705
|
-
// the riot-tag and the data-is attributes aren't needed anymore, remove them
|
1706
|
-
remAttr(p, RIOT_TAG_IS)
|
1707
|
-
remAttr(p, RIOT_TAG) // this will be removed in riot 3.0.0
|
1708
|
-
}
|
1709
|
-
|
1710
|
-
}
|
1711
|
-
|
1712
|
-
if (this._virts) {
|
1713
|
-
each(this._virts, function(v) {
|
1714
|
-
if (v.parentNode) v.parentNode.removeChild(v)
|
1715
|
-
})
|
1716
|
-
}
|
1717
|
-
|
1718
|
-
self.trigger('unmount')
|
1719
|
-
toggle()
|
1720
|
-
self.off('*')
|
1721
|
-
self.isMounted = false
|
1722
|
-
delete root._tag
|
1723
|
-
|
1724
|
-
})
|
1725
|
-
|
1726
|
-
// proxy function to bind updates
|
1727
|
-
// dispatched from a parent tag
|
1728
|
-
function onChildUpdate(data) { self.update(data, true) }
|
1729
|
-
|
1730
|
-
function toggle(isMount) {
|
1731
|
-
|
1732
|
-
// mount/unmount children
|
1733
|
-
each(childTags, function(child) { child[isMount ? 'mount' : 'unmount']() })
|
1734
|
-
|
1735
|
-
// listen/unlisten parent (events flow one way from parent to children)
|
1736
|
-
if (!parent) return
|
1737
|
-
var evt = isMount ? 'on' : 'off'
|
1738
|
-
|
1739
|
-
// the loop tags will be always in sync with the parent automatically
|
1740
|
-
if (isLoop)
|
1741
|
-
parent[evt]('unmount', self.unmount)
|
1742
|
-
else {
|
1743
|
-
parent[evt]('update', onChildUpdate)[evt]('unmount', self.unmount)
|
1744
|
-
}
|
1745
|
-
}
|
1746
|
-
|
1747
|
-
|
1748
|
-
// named elements available for fn
|
1749
|
-
parseNamedElements(dom, this, childTags)
|
1750
|
-
|
1751
|
-
}
|
1752
|
-
/**
|
1753
|
-
* Attach an event to a DOM node
|
1754
|
-
* @param { String } name - event name
|
1755
|
-
* @param { Function } handler - event callback
|
1756
|
-
* @param { Object } dom - dom node
|
1757
|
-
* @param { Tag } tag - tag instance
|
1758
|
-
*/
|
1759
|
-
function setEventHandler(name, handler, dom, tag) {
|
1760
|
-
|
1761
|
-
dom[name] = function(e) {
|
1762
|
-
|
1763
|
-
var ptag = tag._parent,
|
1764
|
-
item = tag._item,
|
1765
|
-
el
|
1766
|
-
|
1767
|
-
if (!item)
|
1768
|
-
while (ptag && !item) {
|
1769
|
-
item = ptag._item
|
1770
|
-
ptag = ptag._parent
|
1771
|
-
}
|
1772
|
-
|
1773
|
-
// cross browser event fix
|
1774
|
-
e = e || window.event
|
1775
|
-
|
1776
|
-
// override the event properties
|
1777
|
-
if (isWritable(e, 'currentTarget')) e.currentTarget = dom
|
1778
|
-
if (isWritable(e, 'target')) e.target = e.srcElement
|
1779
|
-
if (isWritable(e, 'which')) e.which = e.charCode || e.keyCode
|
1780
|
-
|
1781
|
-
e.item = item
|
1782
|
-
|
1783
|
-
// prevent default behaviour (by default)
|
1784
|
-
if (handler.call(tag, e) !== true && !/radio|check/.test(dom.type)) {
|
1785
|
-
if (e.preventDefault) e.preventDefault()
|
1786
|
-
e.returnValue = false
|
1787
|
-
}
|
1788
|
-
|
1789
|
-
if (!e.preventUpdate) {
|
1790
|
-
el = item ? getImmediateCustomParentTag(ptag) : tag
|
1791
|
-
el.update()
|
1792
|
-
}
|
1793
|
-
|
1794
|
-
}
|
1795
|
-
|
1796
|
-
}
|
1797
|
-
|
1798
|
-
|
1799
|
-
/**
|
1800
|
-
* Insert a DOM node replacing another one (used by if- attribute)
|
1801
|
-
* @param { Object } root - parent node
|
1802
|
-
* @param { Object } node - node replaced
|
1803
|
-
* @param { Object } before - node added
|
1804
|
-
*/
|
1805
|
-
function insertTo(root, node, before) {
|
1806
|
-
if (!root) return
|
1807
|
-
root.insertBefore(before, node)
|
1808
|
-
root.removeChild(node)
|
1809
|
-
}
|
1810
|
-
|
1811
|
-
/**
|
1812
|
-
* Update the expressions in a Tag instance
|
1813
|
-
* @param { Array } expressions - expression that must be re evaluated
|
1814
|
-
* @param { Tag } tag - tag instance
|
1815
|
-
*/
|
1816
|
-
function update(expressions, tag) {
|
1817
|
-
|
1818
|
-
each(expressions, function(expr, i) {
|
1819
|
-
|
1820
|
-
var dom = expr.dom,
|
1821
|
-
attrName = expr.attr,
|
1822
|
-
value = tmpl(expr.expr, tag),
|
1823
|
-
parent = expr.parent || expr.dom.parentNode
|
1824
|
-
|
1825
|
-
if (expr.bool) {
|
1826
|
-
value = !!value
|
1827
|
-
} else if (value == null) {
|
1828
|
-
value = ''
|
1829
|
-
}
|
1830
|
-
|
1831
|
-
// #1638: regression of #1612, update the dom only if the value of the
|
1832
|
-
// expression was changed
|
1833
|
-
if (expr.value === value) {
|
1834
|
-
return
|
1835
|
-
}
|
1836
|
-
expr.value = value
|
1837
|
-
|
1838
|
-
// textarea and text nodes has no attribute name
|
1839
|
-
if (!attrName) {
|
1840
|
-
// about #815 w/o replace: the browser converts the value to a string,
|
1841
|
-
// the comparison by "==" does too, but not in the server
|
1842
|
-
value += ''
|
1843
|
-
// test for parent avoids error with invalid assignment to nodeValue
|
1844
2237
|
if (parent) {
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
|
1850
|
-
|
1851
|
-
}
|
1852
|
-
|
1853
|
-
|
1854
|
-
|
1855
|
-
}
|
1856
|
-
|
1857
|
-
// ~~#1612: look for changes in dom.value when updating the value~~
|
1858
|
-
if (attrName === 'value') {
|
1859
|
-
if (dom.value !== value) {
|
1860
|
-
dom.value = value
|
1861
|
-
setAttr(dom, attrName, value)
|
1862
|
-
}
|
1863
|
-
return
|
1864
|
-
} else {
|
1865
|
-
// remove original attribute
|
1866
|
-
remAttr(dom, attrName)
|
1867
|
-
}
|
1868
|
-
|
1869
|
-
// event handler
|
1870
|
-
if (isFunction(value)) {
|
1871
|
-
setEventHandler(attrName, value, dom, tag)
|
1872
|
-
|
1873
|
-
// if- conditional
|
1874
|
-
} else if (attrName == 'if') {
|
1875
|
-
var stub = expr.stub,
|
1876
|
-
add = function() { insertTo(stub.parentNode, stub, dom) },
|
1877
|
-
remove = function() { insertTo(dom.parentNode, dom, stub) }
|
1878
|
-
|
1879
|
-
// add to DOM
|
1880
|
-
if (value) {
|
1881
|
-
if (stub) {
|
1882
|
-
add()
|
1883
|
-
dom.inStub = false
|
1884
|
-
// avoid to trigger the mount event if the tags is not visible yet
|
1885
|
-
// maybe we can optimize this avoiding to mount the tag at all
|
1886
|
-
if (!isInStub(dom)) {
|
1887
|
-
walk(dom, function(el) {
|
1888
|
-
if (el._tag && !el._tag.isMounted)
|
1889
|
-
el._tag.isMounted = !!el._tag.trigger('mount')
|
1890
|
-
})
|
1891
|
-
}
|
2238
|
+
ptag = getImmediateCustomParentTag(parent);
|
2239
|
+
|
2240
|
+
if (isVirtual) {
|
2241
|
+
Object.keys(this.tags).forEach(function (tagName) {
|
2242
|
+
arrayishRemove(ptag.tags, tagName, this$1.tags[tagName]);
|
2243
|
+
});
|
2244
|
+
} else {
|
2245
|
+
arrayishRemove(ptag.tags, tagName, this);
|
2246
|
+
if(parent !== ptag) // remove from _parent too
|
2247
|
+
{ arrayishRemove(parent.tags, tagName, this); }
|
1892
2248
|
}
|
1893
|
-
// remove from DOM
|
1894
2249
|
} else {
|
1895
|
-
|
1896
|
-
// if the parentNode is defined we can easily replace the tag
|
1897
|
-
if (dom.parentNode)
|
1898
|
-
remove()
|
1899
|
-
// otherwise we need to wait the updated event
|
1900
|
-
else (tag.parent || tag).one('updated', remove)
|
1901
|
-
|
1902
|
-
dom.inStub = true
|
1903
|
-
}
|
1904
|
-
// show / hide
|
1905
|
-
} else if (attrName === 'show') {
|
1906
|
-
dom.style.display = value ? '' : 'none'
|
1907
|
-
|
1908
|
-
} else if (attrName === 'hide') {
|
1909
|
-
dom.style.display = value ? 'none' : ''
|
1910
|
-
|
1911
|
-
} else if (expr.bool) {
|
1912
|
-
dom[attrName] = value
|
1913
|
-
if (value) setAttr(dom, attrName, attrName)
|
1914
|
-
if (FIREFOX && attrName === 'selected' && dom.tagName === 'OPTION') {
|
1915
|
-
dom.__riot1374 = value // #1374
|
2250
|
+
while (el.firstChild) { el.removeChild(el.firstChild); }
|
1916
2251
|
}
|
1917
2252
|
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
2253
|
+
if (!mustKeepRoot) {
|
2254
|
+
p.removeChild(el);
|
2255
|
+
} else {
|
2256
|
+
// the riot-tag and the data-is attributes aren't needed anymore, remove them
|
2257
|
+
remAttr(p, IS_DIRECTIVE);
|
1922
2258
|
}
|
1923
|
-
setAttr(dom, attrName, value)
|
1924
2259
|
}
|
1925
2260
|
|
1926
|
-
|
1927
|
-
|
1928
|
-
}
|
1929
|
-
|
1930
|
-
|
1931
|
-
* @param { Array } els - collection of items
|
1932
|
-
* @param {Function} fn - callback function
|
1933
|
-
* @returns { Array } the array looped
|
1934
|
-
*/
|
1935
|
-
function each(els, fn) {
|
1936
|
-
var len = els ? els.length : 0
|
1937
|
-
|
1938
|
-
for (var i = 0, el; i < len; i++) {
|
1939
|
-
el = els[i]
|
1940
|
-
// return false -> current item was removed by fn during the loop
|
1941
|
-
if (el != null && fn(el, i) === false) i--
|
1942
|
-
}
|
1943
|
-
return els
|
1944
|
-
}
|
1945
|
-
|
1946
|
-
/**
|
1947
|
-
* Detect if the argument passed is a function
|
1948
|
-
* @param { * } v - whatever you want to pass to this function
|
1949
|
-
* @returns { Boolean } -
|
1950
|
-
*/
|
1951
|
-
function isFunction(v) {
|
1952
|
-
return typeof v === T_FUNCTION || false // avoid IE problems
|
1953
|
-
}
|
1954
|
-
|
1955
|
-
/**
|
1956
|
-
* Get the outer html of any DOM node SVGs included
|
1957
|
-
* @param { Object } el - DOM node to parse
|
1958
|
-
* @returns { String } el.outerHTML
|
1959
|
-
*/
|
1960
|
-
function getOuterHTML(el) {
|
1961
|
-
if (el.outerHTML) return el.outerHTML
|
1962
|
-
// some browsers do not support outerHTML on the SVGs tags
|
1963
|
-
else {
|
1964
|
-
var container = mkEl('div')
|
1965
|
-
container.appendChild(el.cloneNode(true))
|
1966
|
-
return container.innerHTML
|
1967
|
-
}
|
1968
|
-
}
|
1969
|
-
|
1970
|
-
/**
|
1971
|
-
* Set the inner html of any DOM node SVGs included
|
1972
|
-
* @param { Object } container - DOM node where we will inject the new html
|
1973
|
-
* @param { String } html - html to inject
|
1974
|
-
*/
|
1975
|
-
function setInnerHTML(container, html) {
|
1976
|
-
if (typeof container.innerHTML != T_UNDEF) container.innerHTML = html
|
1977
|
-
// some browsers do not support innerHTML on the SVGs tags
|
1978
|
-
else {
|
1979
|
-
var doc = new DOMParser().parseFromString(html, 'application/xml')
|
1980
|
-
container.appendChild(
|
1981
|
-
container.ownerDocument.importNode(doc.documentElement, true)
|
1982
|
-
)
|
1983
|
-
}
|
1984
|
-
}
|
1985
|
-
|
1986
|
-
/**
|
1987
|
-
* Checks wether a DOM node must be considered part of an svg document
|
1988
|
-
* @param { String } name - tag name
|
1989
|
-
* @returns { Boolean } -
|
1990
|
-
*/
|
1991
|
-
function isSVGTag(name) {
|
1992
|
-
return ~SVG_TAGS_LIST.indexOf(name)
|
1993
|
-
}
|
2261
|
+
if (this._internal.virts) {
|
2262
|
+
each(this._internal.virts, function (v) {
|
2263
|
+
if (v.parentNode) { v.parentNode.removeChild(v); }
|
2264
|
+
});
|
2265
|
+
}
|
1994
2266
|
|
1995
|
-
|
1996
|
-
|
1997
|
-
|
1998
|
-
* @param { * } v - whatever you want to pass to this function
|
1999
|
-
* @returns { Boolean } -
|
2000
|
-
*/
|
2001
|
-
function isObject(v) {
|
2002
|
-
return v && typeof v === T_OBJECT // typeof null is 'object'
|
2003
|
-
}
|
2267
|
+
// allow expressions to unmount themselves
|
2268
|
+
unmountAll(expressions);
|
2269
|
+
each(instAttrs, function (a) { return a.expr && a.expr.unmount && a.expr.unmount(); });
|
2004
2270
|
|
2005
|
-
|
2006
|
-
|
2007
|
-
|
2008
|
-
* @param { String } name - name of the property we want to remove
|
2009
|
-
*/
|
2010
|
-
function remAttr(dom, name) {
|
2011
|
-
dom.removeAttribute(name)
|
2012
|
-
}
|
2271
|
+
this.trigger('unmount');
|
2272
|
+
this.off('*');
|
2273
|
+
this.isMounted = false;
|
2013
2274
|
|
2014
|
-
|
2015
|
-
* Convert a string containing dashes to camel case
|
2016
|
-
* @param { String } string - input string
|
2017
|
-
* @returns { String } my-string -> myString
|
2018
|
-
*/
|
2019
|
-
function toCamel(string) {
|
2020
|
-
return string.replace(/-(\w)/g, function(_, c) {
|
2021
|
-
return c.toUpperCase()
|
2022
|
-
})
|
2023
|
-
}
|
2275
|
+
delete this.root._tag;
|
2024
2276
|
|
2025
|
-
|
2026
|
-
* Get the value of any DOM attribute on a node
|
2027
|
-
* @param { Object } dom - DOM node we want to parse
|
2028
|
-
* @param { String } name - name of the attribute we want to get
|
2029
|
-
* @returns { String | undefined } name of the node attribute whether it exists
|
2030
|
-
*/
|
2031
|
-
function getAttr(dom, name) {
|
2032
|
-
return dom.getAttribute(name)
|
2033
|
-
}
|
2277
|
+
return this
|
2034
2278
|
|
2035
|
-
|
2036
|
-
* Set any DOM/SVG attribute
|
2037
|
-
* @param { Object } dom - DOM node we want to update
|
2038
|
-
* @param { String } name - name of the property we want to set
|
2039
|
-
* @param { String } val - value of the property we want to set
|
2040
|
-
*/
|
2041
|
-
function setAttr(dom, name, val) {
|
2042
|
-
var xlink = XLINK_REGEX.exec(name)
|
2043
|
-
if (xlink && xlink[1])
|
2044
|
-
dom.setAttributeNS(XLINK_NS, xlink[1], val)
|
2045
|
-
else
|
2046
|
-
dom.setAttribute(name, val)
|
2279
|
+
}.bind(this));
|
2047
2280
|
}
|
2048
2281
|
|
2049
2282
|
/**
|
@@ -2052,51 +2285,49 @@ function setAttr(dom, name, val) {
|
|
2052
2285
|
* @returns { Object } it returns an object containing the implementation of a custom tag (template and boot function)
|
2053
2286
|
*/
|
2054
2287
|
function getTag(dom) {
|
2055
|
-
return dom.tagName &&
|
2056
|
-
getAttr(dom,
|
2057
|
-
}
|
2058
|
-
|
2059
|
-
|
2060
|
-
*
|
2061
|
-
* @
|
2062
|
-
* @param {
|
2063
|
-
|
2064
|
-
|
2065
|
-
|
2066
|
-
|
2067
|
-
|
2068
|
-
|
2069
|
-
//
|
2070
|
-
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
}
|
2079
|
-
parent.tags[tagName] = tag
|
2080
|
-
}
|
2288
|
+
return dom.tagName && __TAG_IMPL[getAttr(dom, IS_DIRECTIVE) ||
|
2289
|
+
getAttr(dom, IS_DIRECTIVE) || dom.tagName.toLowerCase()]
|
2290
|
+
}
|
2291
|
+
|
2292
|
+
/**
|
2293
|
+
* Inherit properties from a target tag instance
|
2294
|
+
* @this Tag
|
2295
|
+
* @param { Tag } target - tag where we will inherit properties
|
2296
|
+
* @param { Array } propsInSyncWithParent - array of properties to sync with the target
|
2297
|
+
*/
|
2298
|
+
function inheritFrom(target, propsInSyncWithParent) {
|
2299
|
+
var this$1 = this;
|
2300
|
+
|
2301
|
+
each(Object.keys(target), function (k) {
|
2302
|
+
// some properties must be always in sync with the parent tag
|
2303
|
+
var mustSync = !isReservedName(k) && contains(propsInSyncWithParent, k);
|
2304
|
+
|
2305
|
+
if (isUndefined(this$1[k]) || mustSync) {
|
2306
|
+
// track the property to keep in sync
|
2307
|
+
// so we can keep it updated
|
2308
|
+
if (!mustSync) { propsInSyncWithParent.push(k); }
|
2309
|
+
this$1[k] = target[k];
|
2310
|
+
}
|
2311
|
+
});
|
2081
2312
|
}
|
2082
2313
|
|
2083
2314
|
/**
|
2084
2315
|
* Move the position of a custom tag in its parent tag
|
2085
|
-
* @
|
2316
|
+
* @this Tag
|
2086
2317
|
* @param { String } tagName - key where the tag was stored
|
2087
2318
|
* @param { Number } newPos - index where the new tag will be stored
|
2088
2319
|
*/
|
2089
|
-
function moveChildTag(
|
2090
|
-
var parent =
|
2091
|
-
tags
|
2320
|
+
function moveChildTag(tagName, newPos) {
|
2321
|
+
var parent = this.parent,
|
2322
|
+
tags;
|
2092
2323
|
// no parent no move
|
2093
|
-
if (!parent) return
|
2324
|
+
if (!parent) { return }
|
2094
2325
|
|
2095
|
-
tags = parent.tags[tagName]
|
2326
|
+
tags = parent.tags[tagName];
|
2096
2327
|
|
2097
2328
|
if (isArray(tags))
|
2098
|
-
tags.splice(newPos, 0, tags.splice(tags.indexOf(
|
2099
|
-
else
|
2329
|
+
{ tags.splice(newPos, 0, tags.splice(tags.indexOf(this), 1)[0]); }
|
2330
|
+
else { arrayishAdd(parent.tags, tagName, this); }
|
2100
2331
|
}
|
2101
2332
|
|
2102
2333
|
/**
|
@@ -2108,24 +2339,26 @@ function moveChildTag(tag, tagName, newPos) {
|
|
2108
2339
|
* @returns { Object } instance of the new child tag just created
|
2109
2340
|
*/
|
2110
2341
|
function initChildTag(child, opts, innerHTML, parent) {
|
2111
|
-
var tag = new Tag(child, opts, innerHTML),
|
2112
|
-
tagName = getTagName(opts.root),
|
2113
|
-
ptag = getImmediateCustomParentTag(parent)
|
2342
|
+
var tag = new Tag$1(child, opts, innerHTML),
|
2343
|
+
tagName = opts.tagName || getTagName(opts.root, true),
|
2344
|
+
ptag = getImmediateCustomParentTag(parent);
|
2114
2345
|
// fix for the parent attribute in the looped elements
|
2115
|
-
tag
|
2346
|
+
defineProperty(tag, 'parent', ptag);
|
2116
2347
|
// store the real parent tag
|
2117
2348
|
// in some cases this could be different from the custom parent tag
|
2118
2349
|
// for example in nested loops
|
2119
|
-
tag._parent = parent
|
2350
|
+
tag._parent = parent;
|
2120
2351
|
|
2121
2352
|
// add this tag to the custom parent tag
|
2122
|
-
|
2353
|
+
arrayishAdd(ptag.tags, tagName, tag);
|
2354
|
+
|
2123
2355
|
// and also to the real parent tag
|
2124
2356
|
if (ptag !== parent)
|
2125
|
-
|
2357
|
+
{ arrayishAdd(parent.tags, tagName, tag); }
|
2358
|
+
|
2126
2359
|
// empty the child node once we got its template
|
2127
2360
|
// to avoid that its children get compiled multiple times
|
2128
|
-
opts.root.innerHTML = ''
|
2361
|
+
opts.root.innerHTML = '';
|
2129
2362
|
|
2130
2363
|
return tag
|
2131
2364
|
}
|
@@ -2136,148 +2369,96 @@ function initChildTag(child, opts, innerHTML, parent) {
|
|
2136
2369
|
* @returns { Object } the instance of the first custom parent tag found
|
2137
2370
|
*/
|
2138
2371
|
function getImmediateCustomParentTag(tag) {
|
2139
|
-
var ptag = tag
|
2140
|
-
while (
|
2141
|
-
if (!ptag.parent) break
|
2142
|
-
ptag = ptag.parent
|
2372
|
+
var ptag = tag;
|
2373
|
+
while (ptag._internal.isAnonymous) {
|
2374
|
+
if (!ptag.parent) { break }
|
2375
|
+
ptag = ptag.parent;
|
2143
2376
|
}
|
2144
2377
|
return ptag
|
2145
2378
|
}
|
2146
2379
|
|
2147
2380
|
/**
|
2148
|
-
*
|
2149
|
-
* @param {
|
2150
|
-
* @param { String } key - object key where the new property will be stored
|
2151
|
-
* @param { * } value - value of the new property
|
2152
|
-
* @param { Object } options - set the propery overriding the default options
|
2153
|
-
* @returns { Object } - the initial object
|
2381
|
+
* Trigger the unmount method on all the expressions
|
2382
|
+
* @param { Array } expressions - DOM expressions
|
2154
2383
|
*/
|
2155
|
-
function
|
2156
|
-
|
2157
|
-
|
2158
|
-
|
2159
|
-
|
2160
|
-
configurable: true
|
2161
|
-
}, options))
|
2162
|
-
return el
|
2384
|
+
function unmountAll(expressions) {
|
2385
|
+
each(expressions, function(expr) {
|
2386
|
+
if (expr instanceof Tag$1) { expr.unmount(true); }
|
2387
|
+
else if (expr.unmount) { expr.unmount(); }
|
2388
|
+
});
|
2163
2389
|
}
|
2164
2390
|
|
2165
2391
|
/**
|
2166
2392
|
* Get the tag name of any DOM node
|
2167
2393
|
* @param { Object } dom - DOM node we want to parse
|
2394
|
+
* @param { Boolean } skipDataIs - hack to ignore the data-is attribute when attaching to parent
|
2168
2395
|
* @returns { String } name to identify this dom node in riot
|
2169
2396
|
*/
|
2170
|
-
function getTagName(dom) {
|
2397
|
+
function getTagName(dom, skipDataIs) {
|
2171
2398
|
var child = getTag(dom),
|
2172
|
-
namedTag = getAttr(dom,
|
2173
|
-
|
2399
|
+
namedTag = !skipDataIs && getAttr(dom, IS_DIRECTIVE);
|
2400
|
+
return namedTag && !tmpl.hasExpr(namedTag) ?
|
2174
2401
|
namedTag :
|
2175
2402
|
child ? child.name : dom.tagName.toLowerCase()
|
2176
|
-
|
2177
|
-
return tagName
|
2178
|
-
}
|
2179
|
-
|
2180
|
-
/**
|
2181
|
-
* Extend any object with other properties
|
2182
|
-
* @param { Object } src - source object
|
2183
|
-
* @returns { Object } the resulting extended object
|
2184
|
-
*
|
2185
|
-
* var obj = { foo: 'baz' }
|
2186
|
-
* extend(obj, {bar: 'bar', foo: 'bar'})
|
2187
|
-
* console.log(obj) => {bar: 'bar', foo: 'bar'}
|
2188
|
-
*
|
2189
|
-
*/
|
2190
|
-
function extend(src) {
|
2191
|
-
var obj, args = arguments
|
2192
|
-
for (var i = 1; i < args.length; ++i) {
|
2193
|
-
if (obj = args[i]) {
|
2194
|
-
for (var key in obj) {
|
2195
|
-
// check if this property of the source object could be overridden
|
2196
|
-
if (isWritable(src, key))
|
2197
|
-
src[key] = obj[key]
|
2198
|
-
}
|
2199
|
-
}
|
2200
|
-
}
|
2201
|
-
return src
|
2202
|
-
}
|
2203
|
-
|
2204
|
-
/**
|
2205
|
-
* Check whether an array contains an item
|
2206
|
-
* @param { Array } arr - target array
|
2207
|
-
* @param { * } item - item to test
|
2208
|
-
* @returns { Boolean } Does 'arr' contain 'item'?
|
2209
|
-
*/
|
2210
|
-
function contains(arr, item) {
|
2211
|
-
return ~arr.indexOf(item)
|
2212
|
-
}
|
2213
|
-
|
2214
|
-
/**
|
2215
|
-
* Check whether an object is a kind of array
|
2216
|
-
* @param { * } a - anything
|
2217
|
-
* @returns {Boolean} is 'a' an array?
|
2218
|
-
*/
|
2219
|
-
function isArray(a) { return Array.isArray(a) || a instanceof Array }
|
2220
|
-
|
2221
|
-
/**
|
2222
|
-
* Detect whether a property of an object could be overridden
|
2223
|
-
* @param { Object } obj - source object
|
2224
|
-
* @param { String } key - object property
|
2225
|
-
* @returns { Boolean } is this property writable?
|
2226
|
-
*/
|
2227
|
-
function isWritable(obj, key) {
|
2228
|
-
var props = Object.getOwnPropertyDescriptor(obj, key)
|
2229
|
-
return typeof obj[key] === T_UNDEF || props && props.writable
|
2230
2403
|
}
|
2231
2404
|
|
2232
|
-
|
2233
2405
|
/**
|
2234
2406
|
* With this function we avoid that the internal Tag methods get overridden
|
2235
2407
|
* @param { Object } data - options we want to use to extend the tag instance
|
2236
2408
|
* @returns { Object } clean object without containing the riot internal reserved words
|
2237
2409
|
*/
|
2238
2410
|
function cleanUpData(data) {
|
2239
|
-
if (!(data instanceof Tag) && !(data &&
|
2240
|
-
return data
|
2411
|
+
if (!(data instanceof Tag$1) && !(data && isFunction(data.trigger)))
|
2412
|
+
{ return data }
|
2241
2413
|
|
2242
|
-
var o = {}
|
2414
|
+
var o = {};
|
2243
2415
|
for (var key in data) {
|
2244
|
-
if (!
|
2416
|
+
if (!RE_RESERVED_NAMES.test(key)) { o[key] = data[key]; }
|
2245
2417
|
}
|
2246
2418
|
return o
|
2247
2419
|
}
|
2248
2420
|
|
2249
2421
|
/**
|
2250
|
-
*
|
2251
|
-
*
|
2252
|
-
* @param
|
2422
|
+
* Set the property of an object for a given key. If something already
|
2423
|
+
* exists there, then it becomes an array containing both the old and new value.
|
2424
|
+
* @param { Object } obj - object on which to set the property
|
2425
|
+
* @param { String } key - property name
|
2426
|
+
* @param { Object } value - the value of the property to be set
|
2427
|
+
* @param { Boolean } ensureArray - ensure that the property remains an array
|
2253
2428
|
*/
|
2254
|
-
function
|
2255
|
-
|
2256
|
-
|
2257
|
-
if (fn(dom) === false) return
|
2258
|
-
else {
|
2259
|
-
dom = dom.firstChild
|
2429
|
+
function arrayishAdd(obj, key, value, ensureArray) {
|
2430
|
+
var dest = obj[key];
|
2431
|
+
var isArr = isArray(dest);
|
2260
2432
|
|
2261
|
-
|
2262
|
-
|
2263
|
-
|
2264
|
-
|
2265
|
-
|
2433
|
+
if (dest && dest === value) { return }
|
2434
|
+
|
2435
|
+
// if the key was never set, set it once
|
2436
|
+
if (!dest && ensureArray) { obj[key] = [value]; }
|
2437
|
+
else if (!dest) { obj[key] = value; }
|
2438
|
+
// if it was an array and not yet set
|
2439
|
+
else if (!isArr || isArr && !contains(dest, value)) {
|
2440
|
+
if (isArr) { dest.push(value); }
|
2441
|
+
else { obj[key] = [dest, value]; }
|
2266
2442
|
}
|
2267
2443
|
}
|
2268
2444
|
|
2269
2445
|
/**
|
2270
|
-
*
|
2271
|
-
*
|
2272
|
-
* @param
|
2273
|
-
|
2274
|
-
|
2275
|
-
|
2276
|
-
|
2277
|
-
|
2278
|
-
|
2279
|
-
|
2280
|
-
|
2446
|
+
* Removes an item from an object at a given key. If the key points to an array,
|
2447
|
+
* then the item is just removed from the array.
|
2448
|
+
* @param { Object } obj - object on which to remove the property
|
2449
|
+
* @param { String } key - property name
|
2450
|
+
* @param { Object } value - the value of the property to be removed
|
2451
|
+
* @param { Boolean } ensureArray - ensure that the property remains an array
|
2452
|
+
*/
|
2453
|
+
function arrayishRemove(obj, key, value, ensureArray) {
|
2454
|
+
if (isArray(obj[key])) {
|
2455
|
+
each(obj[key], function(item, i) {
|
2456
|
+
if (item === value) { obj[key].splice(i, 1); }
|
2457
|
+
});
|
2458
|
+
if (!obj[key].length) { delete obj[key]; }
|
2459
|
+
else if (obj[key].length === 1 && !ensureArray) { obj[key] = obj[key][0]; }
|
2460
|
+
} else
|
2461
|
+
{ delete obj[key]; } // otherwise just delete the key
|
2281
2462
|
}
|
2282
2463
|
|
2283
2464
|
/**
|
@@ -2287,383 +2468,196 @@ function walkAttributes(html, fn) {
|
|
2287
2468
|
*/
|
2288
2469
|
function isInStub(dom) {
|
2289
2470
|
while (dom) {
|
2290
|
-
if (dom.inStub)
|
2291
|
-
|
2471
|
+
if (dom.inStub)
|
2472
|
+
{ return true }
|
2473
|
+
dom = dom.parentNode;
|
2292
2474
|
}
|
2293
2475
|
return false
|
2294
2476
|
}
|
2295
2477
|
|
2296
|
-
/**
|
2297
|
-
* Create a generic DOM node
|
2298
|
-
* @param { String } name - name of the DOM node we want to create
|
2299
|
-
* @param { Boolean } isSvg - should we use a SVG as parent node?
|
2300
|
-
* @returns { Object } DOM node just created
|
2301
|
-
*/
|
2302
|
-
function mkEl(name, isSvg) {
|
2303
|
-
return isSvg ?
|
2304
|
-
document.createElementNS('http://www.w3.org/2000/svg', 'svg') :
|
2305
|
-
document.createElement(name)
|
2306
|
-
}
|
2307
|
-
|
2308
|
-
/**
|
2309
|
-
* Shorter and fast way to select multiple nodes in the DOM
|
2310
|
-
* @param { String } selector - DOM selector
|
2311
|
-
* @param { Object } ctx - DOM node where the targets of our search will is located
|
2312
|
-
* @returns { Object } dom nodes found
|
2313
|
-
*/
|
2314
|
-
function $$(selector, ctx) {
|
2315
|
-
return (ctx || document).querySelectorAll(selector)
|
2316
|
-
}
|
2317
|
-
|
2318
|
-
/**
|
2319
|
-
* Shorter and fast way to select a single node in the DOM
|
2320
|
-
* @param { String } selector - unique dom selector
|
2321
|
-
* @param { Object } ctx - DOM node where the target of our search will is located
|
2322
|
-
* @returns { Object } dom node found
|
2323
|
-
*/
|
2324
|
-
function $(selector, ctx) {
|
2325
|
-
return (ctx || document).querySelector(selector)
|
2326
|
-
}
|
2327
|
-
|
2328
|
-
/**
|
2329
|
-
* Simple object prototypal inheritance
|
2330
|
-
* @param { Object } parent - parent object
|
2331
|
-
* @returns { Object } child instance
|
2332
|
-
*/
|
2333
|
-
function inherit(parent) {
|
2334
|
-
function Child() {}
|
2335
|
-
Child.prototype = parent
|
2336
|
-
return new Child()
|
2337
|
-
}
|
2338
|
-
|
2339
|
-
/**
|
2340
|
-
* Get the name property needed to identify a DOM node in riot
|
2341
|
-
* @param { Object } dom - DOM node we need to parse
|
2342
|
-
* @returns { String | undefined } give us back a string to identify this dom node
|
2343
|
-
*/
|
2344
|
-
function getNamedKey(dom) {
|
2345
|
-
return getAttr(dom, 'id') || getAttr(dom, 'name')
|
2346
|
-
}
|
2347
|
-
|
2348
|
-
/**
|
2349
|
-
* Set the named properties of a tag element
|
2350
|
-
* @param { Object } dom - DOM node we need to parse
|
2351
|
-
* @param { Object } parent - tag instance where the named dom element will be eventually added
|
2352
|
-
* @param { Array } keys - list of all the tag instance properties
|
2353
|
-
*/
|
2354
|
-
function setNamed(dom, parent, keys) {
|
2355
|
-
// get the key value we want to add to the tag instance
|
2356
|
-
var key = getNamedKey(dom),
|
2357
|
-
isArr,
|
2358
|
-
// add the node detected to a tag instance using the named property
|
2359
|
-
add = function(value) {
|
2360
|
-
// avoid to override the tag properties already set
|
2361
|
-
if (contains(keys, key)) return
|
2362
|
-
// check whether this value is an array
|
2363
|
-
isArr = isArray(value)
|
2364
|
-
// if the key was never set
|
2365
|
-
if (!value)
|
2366
|
-
// set it once on the tag instance
|
2367
|
-
parent[key] = dom
|
2368
|
-
// if it was an array and not yet set
|
2369
|
-
else if (!isArr || isArr && !contains(value, dom)) {
|
2370
|
-
// add the dom node into the array
|
2371
|
-
if (isArr)
|
2372
|
-
value.push(dom)
|
2373
|
-
else
|
2374
|
-
parent[key] = [value, dom]
|
2375
|
-
}
|
2376
|
-
}
|
2377
|
-
|
2378
|
-
// skip the elements with no named properties
|
2379
|
-
if (!key) return
|
2380
|
-
|
2381
|
-
// check whether this key has been already evaluated
|
2382
|
-
if (tmpl.hasExpr(key))
|
2383
|
-
// wait the first updated event only once
|
2384
|
-
parent.one('mount', function() {
|
2385
|
-
key = getNamedKey(dom)
|
2386
|
-
add(parent[key])
|
2387
|
-
})
|
2388
|
-
else
|
2389
|
-
add(parent[key])
|
2390
|
-
|
2391
|
-
}
|
2392
|
-
|
2393
|
-
/**
|
2394
|
-
* Faster String startsWith alternative
|
2395
|
-
* @param { String } src - source string
|
2396
|
-
* @param { String } str - test string
|
2397
|
-
* @returns { Boolean } -
|
2398
|
-
*/
|
2399
|
-
function startsWith(src, str) {
|
2400
|
-
return src.slice(0, str.length) === str
|
2401
|
-
}
|
2402
|
-
|
2403
|
-
/**
|
2404
|
-
* requestAnimationFrame function
|
2405
|
-
* Adapted from https://gist.github.com/paulirish/1579671, license MIT
|
2406
|
-
*/
|
2407
|
-
var rAF = (function (w) {
|
2408
|
-
var raf = w.requestAnimationFrame ||
|
2409
|
-
w.mozRequestAnimationFrame || w.webkitRequestAnimationFrame
|
2410
|
-
|
2411
|
-
if (!raf || /iP(ad|hone|od).*OS 6/.test(w.navigator.userAgent)) { // buggy iOS6
|
2412
|
-
var lastTime = 0
|
2413
|
-
|
2414
|
-
raf = function (cb) {
|
2415
|
-
var nowtime = Date.now(), timeout = Math.max(16 - (nowtime - lastTime), 0)
|
2416
|
-
setTimeout(function () { cb(lastTime = nowtime + timeout) }, timeout)
|
2417
|
-
}
|
2418
|
-
}
|
2419
|
-
return raf
|
2420
|
-
|
2421
|
-
})(window || {})
|
2422
|
-
|
2423
2478
|
/**
|
2424
2479
|
* Mount a tag creating new Tag instance
|
2425
2480
|
* @param { Object } root - dom node where the tag will be mounted
|
2426
2481
|
* @param { String } tagName - name of the riot tag we want to mount
|
2427
2482
|
* @param { Object } opts - options to pass to the Tag instance
|
2483
|
+
* @param { Object } ctx - optional context that will be used to extend an existing class ( used in riot.Tag )
|
2428
2484
|
* @returns { Tag } a new Tag instance
|
2429
2485
|
*/
|
2430
|
-
function mountTo(root, tagName, opts) {
|
2431
|
-
var
|
2486
|
+
function mountTo(root, tagName, opts, ctx) {
|
2487
|
+
var impl = __TAG_IMPL[tagName],
|
2488
|
+
implClass = __TAG_IMPL[tagName].class,
|
2489
|
+
tag = ctx || (implClass ? Object.create(implClass.prototype) : {}),
|
2432
2490
|
// cache the inner HTML to fix #855
|
2433
|
-
innerHTML = root._innerHTML = root._innerHTML || root.innerHTML
|
2491
|
+
innerHTML = root._innerHTML = root._innerHTML || root.innerHTML;
|
2434
2492
|
|
2435
2493
|
// clear the inner html
|
2436
|
-
root.innerHTML = ''
|
2494
|
+
root.innerHTML = '';
|
2495
|
+
|
2496
|
+
var conf = { root: root, opts: opts };
|
2497
|
+
if (opts && opts.parent) { conf.parent = opts.parent; }
|
2437
2498
|
|
2438
|
-
if (
|
2499
|
+
if (impl && root) { Tag$1.apply(tag, [impl, conf, innerHTML]); }
|
2439
2500
|
|
2440
2501
|
if (tag && tag.mount) {
|
2441
|
-
tag.mount()
|
2502
|
+
tag.mount(true);
|
2442
2503
|
// add this tag to the virtualDom variable
|
2443
|
-
if (!contains(
|
2504
|
+
if (!contains(__TAGS_CACHE, tag)) { __TAGS_CACHE.push(tag); }
|
2444
2505
|
}
|
2445
2506
|
|
2446
2507
|
return tag
|
2447
2508
|
}
|
2448
|
-
/**
|
2449
|
-
* Riot public api
|
2450
|
-
*/
|
2451
2509
|
|
2452
|
-
// share methods for other riot parts, e.g. compiler
|
2453
|
-
riot.util = { brackets: brackets, tmpl: tmpl }
|
2454
2510
|
|
2455
2511
|
/**
|
2456
|
-
*
|
2512
|
+
* Adds the elements for a virtual tag
|
2513
|
+
* @this Tag
|
2514
|
+
* @param { Node } src - the node that will do the inserting or appending
|
2515
|
+
* @param { Tag } target - only if inserting, insert before this tag's first child
|
2457
2516
|
*/
|
2458
|
-
|
2459
|
-
var
|
2460
|
-
globals = mixins[GLOBAL_MIXIN] = {},
|
2461
|
-
_id = 0
|
2517
|
+
function makeVirtual(src, target) {
|
2518
|
+
var this$1 = this;
|
2462
2519
|
|
2463
|
-
|
2464
|
-
|
2465
|
-
|
2466
|
-
|
2467
|
-
* @param { Boolean } g - is global?
|
2468
|
-
* @returns { Object } the mixin logic
|
2469
|
-
*/
|
2470
|
-
return function(name, mixin, g) {
|
2471
|
-
// Unnamed global
|
2472
|
-
if (isObject(name)) {
|
2473
|
-
riot.mixin('__unnamed_'+_id++, name, true)
|
2474
|
-
return
|
2475
|
-
}
|
2476
|
-
|
2477
|
-
var store = g ? globals : mixins
|
2520
|
+
var head = createDOMPlaceholder(),
|
2521
|
+
tail = createDOMPlaceholder(),
|
2522
|
+
frag = createFrag(),
|
2523
|
+
sib, el;
|
2478
2524
|
|
2479
|
-
|
2480
|
-
|
2481
|
-
if (typeof store[name] === T_UNDEF) {
|
2482
|
-
throw new Error('Unregistered mixin: ' + name)
|
2483
|
-
}
|
2484
|
-
return store[name]
|
2485
|
-
}
|
2486
|
-
// Setter
|
2487
|
-
if (isFunction(mixin)) {
|
2488
|
-
extend(mixin.prototype, store[name] || {})
|
2489
|
-
store[name] = mixin
|
2490
|
-
}
|
2491
|
-
else {
|
2492
|
-
store[name] = extend(store[name] || {}, mixin)
|
2493
|
-
}
|
2494
|
-
}
|
2525
|
+
this._internal.head = this.root.insertBefore(head, this.root.firstChild);
|
2526
|
+
this._internal.tail = this.root.appendChild(tail);
|
2495
2527
|
|
2496
|
-
|
2528
|
+
el = this._internal.head;
|
2497
2529
|
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
* @param { String } attrs - root tag attributes
|
2504
|
-
* @param { Function } fn - user function
|
2505
|
-
* @returns { String } name/id of the tag just created
|
2506
|
-
*/
|
2507
|
-
riot.tag = function(name, html, css, attrs, fn) {
|
2508
|
-
if (isFunction(attrs)) {
|
2509
|
-
fn = attrs
|
2510
|
-
if (/^[\w\-]+\s?=/.test(css)) {
|
2511
|
-
attrs = css
|
2512
|
-
css = ''
|
2513
|
-
} else attrs = ''
|
2514
|
-
}
|
2515
|
-
if (css) {
|
2516
|
-
if (isFunction(css)) fn = css
|
2517
|
-
else styleManager.add(css)
|
2530
|
+
while (el) {
|
2531
|
+
sib = el.nextSibling;
|
2532
|
+
frag.appendChild(el);
|
2533
|
+
this$1._internal.virts.push(el); // hold for unmounting
|
2534
|
+
el = sib;
|
2518
2535
|
}
|
2519
|
-
name = name.toLowerCase()
|
2520
|
-
__tagImpl[name] = { name: name, tmpl: html, attrs: attrs, fn: fn }
|
2521
|
-
return name
|
2522
|
-
}
|
2523
2536
|
|
2524
|
-
|
2525
|
-
|
2526
|
-
|
2527
|
-
|
2528
|
-
* @param { String } css - custom tag css
|
2529
|
-
* @param { String } attrs - root tag attributes
|
2530
|
-
* @param { Function } fn - user function
|
2531
|
-
* @returns { String } name/id of the tag just created
|
2532
|
-
*/
|
2533
|
-
riot.tag2 = function(name, html, css, attrs, fn) {
|
2534
|
-
if (css) styleManager.add(css)
|
2535
|
-
//if (bpair) riot.settings.brackets = bpair
|
2536
|
-
__tagImpl[name] = { name: name, tmpl: html, attrs: attrs, fn: fn }
|
2537
|
-
return name
|
2537
|
+
if (target)
|
2538
|
+
{ src.insertBefore(frag, target._internal.head); }
|
2539
|
+
else
|
2540
|
+
{ src.appendChild(frag); }
|
2538
2541
|
}
|
2539
2542
|
|
2540
2543
|
/**
|
2541
|
-
*
|
2542
|
-
* @
|
2543
|
-
* @param
|
2544
|
-
* @param
|
2545
|
-
* @returns { Array } new tags instances
|
2544
|
+
* Move virtual tag and all child nodes
|
2545
|
+
* @this Tag
|
2546
|
+
* @param { Node } src - the node that will do the inserting
|
2547
|
+
* @param { Tag } target - insert before this tag's first child
|
2546
2548
|
*/
|
2547
|
-
|
2548
|
-
|
2549
|
-
var els,
|
2550
|
-
allTags,
|
2551
|
-
tags = []
|
2552
|
-
|
2553
|
-
// helper functions
|
2554
|
-
|
2555
|
-
function addRiotTags(arr) {
|
2556
|
-
var list = ''
|
2557
|
-
each(arr, function (e) {
|
2558
|
-
if (!/[^-\w]/.test(e)) {
|
2559
|
-
e = e.trim().toLowerCase()
|
2560
|
-
list += ',[' + RIOT_TAG_IS + '="' + e + '"],[' + RIOT_TAG + '="' + e + '"]'
|
2561
|
-
}
|
2562
|
-
})
|
2563
|
-
return list
|
2564
|
-
}
|
2565
|
-
|
2566
|
-
function selectAllTags() {
|
2567
|
-
var keys = Object.keys(__tagImpl)
|
2568
|
-
return keys + addRiotTags(keys)
|
2569
|
-
}
|
2570
|
-
|
2571
|
-
function pushTags(root) {
|
2572
|
-
if (root.tagName) {
|
2573
|
-
var riotTag = getAttr(root, RIOT_TAG_IS) || getAttr(root, RIOT_TAG)
|
2574
|
-
|
2575
|
-
// have tagName? force riot-tag to be the same
|
2576
|
-
if (tagName && riotTag !== tagName) {
|
2577
|
-
riotTag = tagName
|
2578
|
-
setAttr(root, RIOT_TAG_IS, tagName)
|
2579
|
-
setAttr(root, RIOT_TAG, tagName) // this will be removed in riot 3.0.0
|
2580
|
-
}
|
2581
|
-
var tag = mountTo(root, riotTag || root.tagName.toLowerCase(), opts)
|
2582
|
-
|
2583
|
-
if (tag) tags.push(tag)
|
2584
|
-
} else if (root.length) {
|
2585
|
-
each(root, pushTags) // assume nodeList
|
2586
|
-
}
|
2587
|
-
}
|
2588
|
-
|
2589
|
-
// ----- mount code -----
|
2590
|
-
|
2591
|
-
// inject styles into DOM
|
2592
|
-
styleManager.inject()
|
2593
|
-
|
2594
|
-
if (isObject(tagName)) {
|
2595
|
-
opts = tagName
|
2596
|
-
tagName = 0
|
2597
|
-
}
|
2598
|
-
|
2599
|
-
// crawl the DOM to find the tag
|
2600
|
-
if (typeof selector === T_STRING) {
|
2601
|
-
if (selector === '*')
|
2602
|
-
// select all the tags registered
|
2603
|
-
// and also the tags found with the riot-tag attribute set
|
2604
|
-
selector = allTags = selectAllTags()
|
2605
|
-
else
|
2606
|
-
// or just the ones named like the selector
|
2607
|
-
selector += addRiotTags(selector.split(/, */))
|
2549
|
+
function moveVirtual(src, target) {
|
2550
|
+
var this$1 = this;
|
2608
2551
|
|
2609
|
-
|
2610
|
-
|
2611
|
-
|
2612
|
-
}
|
2613
|
-
else
|
2614
|
-
// probably you have passed already a tag or a NodeList
|
2615
|
-
els = selector
|
2552
|
+
var el = this._internal.head,
|
2553
|
+
frag = createFrag(),
|
2554
|
+
sib;
|
2616
2555
|
|
2617
|
-
|
2618
|
-
|
2619
|
-
|
2620
|
-
|
2621
|
-
|
2622
|
-
|
2623
|
-
|
2624
|
-
|
2625
|
-
// select all the children for all the different root elements
|
2626
|
-
var nodeList = []
|
2627
|
-
each(els, function (_el) {
|
2628
|
-
nodeList.push($$(tagName, _el))
|
2629
|
-
})
|
2630
|
-
els = nodeList
|
2556
|
+
while (el) {
|
2557
|
+
sib = el.nextSibling;
|
2558
|
+
frag.appendChild(el);
|
2559
|
+
el = sib;
|
2560
|
+
if (el === this$1._internal.tail) {
|
2561
|
+
frag.appendChild(el);
|
2562
|
+
src.insertBefore(frag, target._internal.head);
|
2563
|
+
break
|
2631
2564
|
}
|
2632
|
-
// get rid of the tagName
|
2633
|
-
tagName = 0
|
2634
2565
|
}
|
2635
|
-
|
2636
|
-
pushTags(els)
|
2637
|
-
|
2638
|
-
return tags
|
2639
2566
|
}
|
2640
2567
|
|
2641
2568
|
/**
|
2642
|
-
*
|
2643
|
-
* @
|
2569
|
+
* Get selectors for tags
|
2570
|
+
* @param { Array } tags - tag names to select
|
2571
|
+
* @returns { String } selector
|
2644
2572
|
*/
|
2645
|
-
|
2646
|
-
|
2647
|
-
|
2648
|
-
|
2649
|
-
|
2573
|
+
function selectTags(tags) {
|
2574
|
+
// select all tags
|
2575
|
+
if (!tags) {
|
2576
|
+
var keys = Object.keys(__TAG_IMPL);
|
2577
|
+
return keys + selectTags(keys)
|
2578
|
+
}
|
2650
2579
|
|
2651
|
-
|
2652
|
-
|
2653
|
-
|
2654
|
-
|
2580
|
+
return tags
|
2581
|
+
.filter(function (t) { return !/[^-\w]/.test(t); })
|
2582
|
+
.reduce(function (list, t) {
|
2583
|
+
var name = t.trim().toLowerCase();
|
2584
|
+
return list + ",[" + IS_DIRECTIVE + "=\"" + name + "\"]"
|
2585
|
+
}, '')
|
2586
|
+
}
|
2587
|
+
|
2588
|
+
|
2589
|
+
var tags = Object.freeze({
|
2590
|
+
getTag: getTag,
|
2591
|
+
inheritFrom: inheritFrom,
|
2592
|
+
moveChildTag: moveChildTag,
|
2593
|
+
initChildTag: initChildTag,
|
2594
|
+
getImmediateCustomParentTag: getImmediateCustomParentTag,
|
2595
|
+
unmountAll: unmountAll,
|
2596
|
+
getTagName: getTagName,
|
2597
|
+
cleanUpData: cleanUpData,
|
2598
|
+
arrayishAdd: arrayishAdd,
|
2599
|
+
arrayishRemove: arrayishRemove,
|
2600
|
+
isInStub: isInStub,
|
2601
|
+
mountTo: mountTo,
|
2602
|
+
makeVirtual: makeVirtual,
|
2603
|
+
moveVirtual: moveVirtual,
|
2604
|
+
selectTags: selectTags
|
2605
|
+
});
|
2655
2606
|
|
2656
2607
|
/**
|
2657
|
-
*
|
2608
|
+
* Riot public api
|
2658
2609
|
*/
|
2659
|
-
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
|
2668
|
-
|
2669
|
-
|
2610
|
+
var settings = Object.create(brackets.settings);
|
2611
|
+
|
2612
|
+
var util = {
|
2613
|
+
tmpl: tmpl,
|
2614
|
+
brackets: brackets,
|
2615
|
+
styleManager: styleManager,
|
2616
|
+
vdom: __TAGS_CACHE,
|
2617
|
+
styleNode: styleManager.styleNode,
|
2618
|
+
// export the riot internal utils as well
|
2619
|
+
dom: dom,
|
2620
|
+
check: check,
|
2621
|
+
misc: misc,
|
2622
|
+
tags: tags
|
2623
|
+
};
|
2624
|
+
|
2625
|
+
// export the core props/methods
|
2626
|
+
var Tag$$1 = Tag$2;
|
2627
|
+
var tag$$1 = tag$1;
|
2628
|
+
var tag2$$1 = tag2$1;
|
2629
|
+
var mount$$1 = mount$1;
|
2630
|
+
var mixin$$1 = mixin$1;
|
2631
|
+
var update$$1 = update$1;
|
2632
|
+
var unregister$$1 = unregister$1;
|
2633
|
+
var observable = observable$1;
|
2634
|
+
|
2635
|
+
var riot$1 = {
|
2636
|
+
settings: settings,
|
2637
|
+
util: util,
|
2638
|
+
// core
|
2639
|
+
Tag: Tag$$1,
|
2640
|
+
tag: tag$$1,
|
2641
|
+
tag2: tag2$$1,
|
2642
|
+
mount: mount$$1,
|
2643
|
+
mixin: mixin$$1,
|
2644
|
+
update: update$$1,
|
2645
|
+
unregister: unregister$$1,
|
2646
|
+
observable: observable
|
2647
|
+
};
|
2648
|
+
|
2649
|
+
exports.settings = settings;
|
2650
|
+
exports.util = util;
|
2651
|
+
exports.Tag = Tag$$1;
|
2652
|
+
exports.tag = tag$$1;
|
2653
|
+
exports.tag2 = tag2$$1;
|
2654
|
+
exports.mount = mount$$1;
|
2655
|
+
exports.mixin = mixin$$1;
|
2656
|
+
exports.update = update$$1;
|
2657
|
+
exports.unregister = unregister$$1;
|
2658
|
+
exports.observable = observable;
|
2659
|
+
exports['default'] = riot$1;
|
2660
|
+
|
2661
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
2662
|
+
|
2663
|
+
})));
|