riot_js-rails 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
})));
|