riot_js-rails 0.6.2 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +9 -1
- data/lib/riot_js/rails/processors/processor.rb +91 -11
- data/lib/riot_js/rails/railtie.rb +8 -6
- data/lib/riot_js/rails/version.rb +1 -1
- data/vendor/assets/javascripts/compiler/brackets.js +7 -5
- data/vendor/assets/javascripts/compiler/compiler.js +129 -102
- data/vendor/assets/javascripts/compiler/parsers.js +129 -169
- data/vendor/assets/javascripts/compiler/parsers/_utils.js +47 -0
- data/vendor/assets/javascripts/compiler/parsers/buble.js +18 -0
- data/vendor/assets/javascripts/compiler/parsers/coffee.js +19 -0
- data/vendor/assets/javascripts/compiler/parsers/es6.js +18 -0
- data/vendor/assets/javascripts/compiler/parsers/jade.js +27 -0
- data/vendor/assets/javascripts/compiler/parsers/less.js +31 -0
- data/vendor/assets/javascripts/compiler/parsers/livescript.js +20 -0
- data/vendor/assets/javascripts/compiler/parsers/pug.js +23 -0
- data/vendor/assets/javascripts/compiler/parsers/sass.js +34 -0
- data/vendor/assets/javascripts/compiler/parsers/scss.js +25 -0
- data/vendor/assets/javascripts/compiler/parsers/stylus.js +26 -0
- data/vendor/assets/javascripts/compiler/parsers/typescript.js +9 -0
- data/vendor/assets/javascripts/compiler/safe-regex.js +19 -0
- data/vendor/assets/javascripts/riot.js +1870 -1876
- metadata +16 -5
- data/lib/riot_js/rails/processors/sprockets_processor_v2.rb +0 -26
- data/lib/riot_js/rails/processors/sprockets_processor_v3.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7f1f3ab924a0ddd2a63b4a9d73614ab08a2792a9
|
4
|
+
data.tar.gz: 07c38e96e874e3c56b6f7ddae718680ab7b569bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eb2e719eebf5c16705da093042c667b4d88bdc438875adffb4cc54208d827509ba6c2c57fa4a8c1ac464980d973bb37c168fd2b03e5bd25363ff239303abd24
|
7
|
+
data.tar.gz: d0a18d5eeb06494ad0c28bba921f814cb4c9b24e73040a8fe7d4b82f1a60eb792ec29b71072379303fe0b45f40a418bc76776170b39d6ac4832555f7a687a1e7
|
data/Rakefile
CHANGED
@@ -7,4 +7,12 @@ Rake::TestTask.new do |t|
|
|
7
7
|
end
|
8
8
|
|
9
9
|
desc "Run tests"
|
10
|
-
task :default => :test
|
10
|
+
task :default => :test
|
11
|
+
|
12
|
+
namespace :test do
|
13
|
+
desc "Test with various versions of sprockets"
|
14
|
+
task :sprockets_versions do
|
15
|
+
sh "bash test/test_sprockets_versions.sh"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -1,23 +1,103 @@
|
|
1
1
|
require 'riot_js/rails/processors/compiler'
|
2
2
|
|
3
|
-
if Gem::Version.new(Sprockets::VERSION) < Gem::Version.new('3.0.0')
|
4
|
-
require 'riot_js/rails/processors/sprockets_processor_v2'
|
5
|
-
else
|
6
|
-
require 'riot_js/rails/processors/sprockets_processor_v3'
|
7
|
-
end
|
8
|
-
|
9
3
|
module RiotJs
|
10
4
|
module Rails
|
11
|
-
class Processor < SprocketsProcessor
|
12
5
|
|
13
|
-
|
14
|
-
|
6
|
+
# Sprockets 2, 3 & 4 interface
|
7
|
+
class SprocketsExtensionBase
|
8
|
+
attr_reader :default_mime_type
|
9
|
+
|
10
|
+
def initialize(filename, &block)
|
11
|
+
@filename = filename
|
12
|
+
@source = block.call
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(context, empty_hash_wtf)
|
16
|
+
self.class.run(@filename, @source, context)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.run(filename, source, context)
|
20
|
+
raise 'Not implemented'
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.call(input)
|
24
|
+
if input.is_a?(String)
|
25
|
+
run("", input, nil)
|
26
|
+
else
|
27
|
+
filename = input[:filename]
|
28
|
+
source = input[:data]
|
29
|
+
context = input[:environment].context_class.new(input)
|
30
|
+
|
31
|
+
result = run(filename, source, context)
|
32
|
+
context.metadata.merge(data: result)
|
33
|
+
end
|
15
34
|
end
|
16
35
|
|
17
36
|
private
|
18
37
|
|
19
|
-
def
|
20
|
-
|
38
|
+
def self.register_self_helper(app, config, file_ext, mime_type_from, mime_type_to, charset=nil)
|
39
|
+
|
40
|
+
if config.respond_to?(:assets)
|
41
|
+
config.assets.configure do |env|
|
42
|
+
if env.respond_to?(:register_transformer)
|
43
|
+
# Sprockets 3 and 4
|
44
|
+
env.register_mime_type mime_type_from, extensions: [file_ext], charset: charset
|
45
|
+
env.register_transformer mime_type_from, mime_type_to, self
|
46
|
+
elsif env.respond_to?(:register_engine)
|
47
|
+
if Sprockets::VERSION.start_with?("3")
|
48
|
+
# Sprockets 3 ... is this needed?
|
49
|
+
env.register_engine file_ext, self, { mime_type: mime_type_to, silence_deprecation: true }
|
50
|
+
else
|
51
|
+
# Sprockets 2.12.4
|
52
|
+
@default_mime_type = mime_type_to
|
53
|
+
env.register_engine file_ext, self
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
else
|
58
|
+
# Sprockets 2.2.3
|
59
|
+
@default_mime_type = mime_type_to
|
60
|
+
app.assets.register_engine file_ext, self
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
class Processor < SprocketsExtensionBase
|
67
|
+
|
68
|
+
def self.run(filename, source, context)
|
69
|
+
::RiotJs::Rails::Compiler.compile(source)
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.register_self(app, config)
|
73
|
+
# app is a YourApp::Application
|
74
|
+
# config is Rails::Railtie::Configuration that belongs to RiotJs::Rails::Railtie
|
75
|
+
register_self_helper(app, config, '.tag', 'text/riot-tag', 'application/javascript', :html)
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.register_nested(app, config, type, charset, tilt_template)
|
79
|
+
extention = '.' + type
|
80
|
+
if config.respond_to?(:assets)
|
81
|
+
config.assets.configure do |env|
|
82
|
+
if env.respond_to?(:register_transformer)
|
83
|
+
# Sprockets 3 and 4
|
84
|
+
env.register_mime_type 'text/riot-tag+'+type, extensions: ['.tag'+extention], charset: charset
|
85
|
+
env.register_transformer 'text/riot-tag+'+type, 'application/javascript',
|
86
|
+
Proc.new{ |input| Processor.call(tilt_template.new{input[:data]}.render) }
|
87
|
+
elsif env.respond_to?(:register_engine)
|
88
|
+
if Sprockets::VERSION.start_with?("3")
|
89
|
+
# Sprockets 3 ... is this needed?
|
90
|
+
env.register_engine extention, tilt_template, { silence_deprecation: true }
|
91
|
+
else
|
92
|
+
# Sprockets 2.12.4
|
93
|
+
env.register_engine extention, tilt_template
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
else
|
98
|
+
# Sprockets 2
|
99
|
+
app.assets.register_engine extention, tilt_template
|
100
|
+
end
|
21
101
|
end
|
22
102
|
end
|
23
103
|
end
|
@@ -9,15 +9,18 @@ module RiotJs
|
|
9
9
|
config.riot.node_paths = []
|
10
10
|
|
11
11
|
initializer :setup_sprockets do |app|
|
12
|
-
|
12
|
+
# app is a YourApp::Application
|
13
|
+
# config is Rails::Railtie::Configuration that belongs to RiotJs::Rails::Railtie
|
14
|
+
Processor.register_self app, config
|
13
15
|
|
14
|
-
if defined?
|
16
|
+
if defined?(::Haml)
|
15
17
|
require 'tilt/haml'
|
16
|
-
|
18
|
+
Haml::Template.options[:format] = :html5
|
19
|
+
Processor.register_nested(app, config, 'haml', :html, ::Tilt::HamlTemplate)
|
17
20
|
end
|
18
21
|
|
19
|
-
if defined?
|
20
|
-
|
22
|
+
if defined?(::Slim)
|
23
|
+
Processor.register_nested(app, config, 'slim', :html, ::Slim::Template)
|
21
24
|
end
|
22
25
|
end
|
23
26
|
|
@@ -36,7 +39,6 @@ module RiotJs
|
|
36
39
|
ENV['NODE_PATH'] = node_paths.join(':')
|
37
40
|
end
|
38
41
|
|
39
|
-
|
40
42
|
def detect_node_global_path
|
41
43
|
prefix = `npm config get prefix`.to_s.chomp("\n")
|
42
44
|
possible_paths = [ "#{prefix}/lib/node", "#{prefix}/lib/node_modules" ]
|
@@ -1,7 +1,10 @@
|
|
1
|
+
'use strict'
|
2
|
+
|
1
3
|
/**
|
2
4
|
* Brackets support for the node.js version of the riot-compiler
|
3
5
|
* @module
|
4
6
|
*/
|
7
|
+
var safeRegex = require('./safe-regex.js')
|
5
8
|
|
6
9
|
/**
|
7
10
|
* Matches valid, multiline JavaScript comments in almost all its forms.
|
@@ -128,7 +131,7 @@ module.exports.split = function split (str, _, _bp) {
|
|
128
131
|
|
129
132
|
isexpr = start = re.lastIndex = 0 // re is reused, we must reset lastIndex
|
130
133
|
|
131
|
-
while (match = re.exec(str)) {
|
134
|
+
while ((match = re.exec(str))) {
|
132
135
|
|
133
136
|
pos = match.index
|
134
137
|
|
@@ -202,7 +205,7 @@ module.exports.split = function split (str, _, _bp) {
|
|
202
205
|
|
203
206
|
rr.lastIndex = ix
|
204
207
|
ix = 1
|
205
|
-
while (mm = rr.exec(s)) {
|
208
|
+
while ((mm = rr.exec(s))) {
|
206
209
|
if (mm[1] &&
|
207
210
|
!(mm[1] === ch ? ++ix : --ix)) break
|
208
211
|
}
|
@@ -214,9 +217,8 @@ module.exports.split = function split (str, _, _bp) {
|
|
214
217
|
}
|
215
218
|
}
|
216
219
|
|
217
|
-
var
|
218
|
-
|
219
|
-
ESCAPEDCH = /(?=[[\]()*+?.^$|])/g // this characters must be escaped
|
220
|
+
var INVALIDCH = safeRegex(/[@-@<>a-zA-Z0-9'",;\\]/, 'x00', 'x1F') // invalid characters for brackets
|
221
|
+
var ESCAPEDCH = /(?=[[\]()*+?.^$|])/g // this characters must be escaped
|
220
222
|
|
221
223
|
/**
|
222
224
|
* Returns an array with information for the given brackets using a cache for the
|
@@ -4,13 +4,17 @@
|
|
4
4
|
* @module compiler
|
5
5
|
* @version WIP
|
6
6
|
* @license MIT
|
7
|
-
* @copyright
|
7
|
+
* @copyright Muut Inc. + contributors
|
8
8
|
*/
|
9
9
|
'use strict'
|
10
10
|
|
11
|
-
var brackets
|
12
|
-
var parsers
|
13
|
-
var
|
11
|
+
var brackets = require('./brackets')
|
12
|
+
var parsers = require('./parsers')
|
13
|
+
var safeRegex = require('./safe-regex')
|
14
|
+
var path = require('path')
|
15
|
+
|
16
|
+
var extend = require('./parsers/_utils').mixobj
|
17
|
+
/* eslint-enable */
|
14
18
|
|
15
19
|
/**
|
16
20
|
* Source for creating regexes matching valid quoted, single-line JavaScript strings.
|
@@ -54,20 +58,14 @@ var HTML_COMMS = RegExp(/<!--(?!>)[\S\s]*?-->/.source + '|' + S_LINESTR, 'g')
|
|
54
58
|
* {@link module:compiler~parseAttribs|parseAttribs}
|
55
59
|
* @const {RegExp}
|
56
60
|
*/
|
57
|
-
var HTML_TAGS = /<([-\w]
|
61
|
+
var HTML_TAGS = /<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^"'\/>]*(?:(?:"[^"]*"|'[^']*'|\/[^>])[^'"\/>]*)*)|\s*)(\/?)>/g
|
58
62
|
|
59
63
|
/**
|
60
|
-
* Matches
|
61
|
-
* Used by
|
62
|
-
*
|
63
|
-
* @const {RegExp}
|
64
|
-
* @see [attributes.md](https://github.com/riot/compiler/blob/dev/doc/attributes.md)
|
64
|
+
* Matches spaces and tabs between HTML tags
|
65
|
+
* Used by the `compact` option.
|
66
|
+
* @const RegExp
|
65
67
|
*/
|
66
|
-
var
|
67
|
-
'^(?:disabled|checked|readonly|required|allowfullscreen|auto(?:focus|play)|' +
|
68
|
-
'compact|controls|default|formnovalidate|hidden|ismap|itemscope|loop|' +
|
69
|
-
'multiple|muted|no(?:resize|shade|validate|wrap)?|open|reversed|seamless|' +
|
70
|
-
'selected|sortable|truespeed|typemustmatch)$')
|
68
|
+
var HTML_PACK = />[ \t]+<(-?[A-Za-z]|\/[-A-Za-z])/g
|
71
69
|
|
72
70
|
/**
|
73
71
|
* These attributes give error when parsed on browsers with an expression in its value.
|
@@ -76,7 +74,7 @@ var BOOL_ATTRS = RegExp(
|
|
76
74
|
* @const {Array}
|
77
75
|
* @see [attributes.md](https://github.com/riot/compiler/blob/dev/doc/attributes.md)
|
78
76
|
*/
|
79
|
-
var RIOT_ATTRS = ['style', 'src', 'd']
|
77
|
+
var RIOT_ATTRS = ['style', 'src', 'd', 'value']
|
80
78
|
|
81
79
|
/**
|
82
80
|
* HTML5 void elements that cannot be auto-closed.
|
@@ -103,6 +101,12 @@ var PRE_TAGS = /<pre(?:\s+(?:[^">]*|"[^"]*")*)?>([\S\s]+?)<\/pre\s*>/gi
|
|
103
101
|
*/
|
104
102
|
var SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i
|
105
103
|
|
104
|
+
/**
|
105
|
+
* Matches the 'import' statement
|
106
|
+
* @const {RegExp}
|
107
|
+
*/
|
108
|
+
var IMPORT_STATEMENT = /^\s*import(?:(?:\s|[^\s'"])*)['|"].*\n?/gm
|
109
|
+
|
106
110
|
/**
|
107
111
|
* Matches trailing spaces and tabs by line.
|
108
112
|
* @const {RegExp}
|
@@ -110,6 +114,10 @@ var SPEC_TYPES = /^"(?:number|date(?:time)?|time|month|email|color)\b/i
|
|
110
114
|
var TRIM_TRAIL = /[ \t]+$/gm
|
111
115
|
|
112
116
|
var
|
117
|
+
RE_HASEXPR = safeRegex(/@#\d/, 'x01'),
|
118
|
+
RE_REPEXPR = safeRegex(/@#(\d+)/g, 'x01'),
|
119
|
+
CH_IDEXPR = '\x01#',
|
120
|
+
CH_DQCODE = '\u2057',
|
113
121
|
DQ = '"',
|
114
122
|
SQ = "'"
|
115
123
|
|
@@ -132,7 +140,7 @@ function cleanSource (src) {
|
|
132
140
|
}
|
133
141
|
|
134
142
|
re.lastIndex = 0
|
135
|
-
while (mm = re.exec(src)) {
|
143
|
+
while ((mm = re.exec(src))) {
|
136
144
|
if (mm[0][0] === '<') {
|
137
145
|
src = RegExp.leftContext + RegExp.rightContext
|
138
146
|
re.lastIndex = mm[3] + 1
|
@@ -160,7 +168,7 @@ function parseAttribs (str, pcex) {
|
|
160
168
|
|
161
169
|
str = str.replace(/\s+/g, ' ')
|
162
170
|
|
163
|
-
while (match = HTML_ATTRS.exec(str)) {
|
171
|
+
while ((match = HTML_ATTRS.exec(str))) {
|
164
172
|
var
|
165
173
|
k = match[1].toLowerCase(),
|
166
174
|
v = match[2]
|
@@ -176,11 +184,10 @@ function parseAttribs (str, pcex) {
|
|
176
184
|
if (k === 'type' && SPEC_TYPES.test(v)) {
|
177
185
|
type = v
|
178
186
|
} else {
|
179
|
-
if (
|
187
|
+
if (RE_HASEXPR.test(v)) {
|
180
188
|
|
181
189
|
if (k === 'value') vexp = 1
|
182
|
-
|
183
|
-
else if (~RIOT_ATTRS.indexOf(k)) k = 'riot-' + k
|
190
|
+
if (~RIOT_ATTRS.indexOf(k)) k = 'riot-' + k
|
184
191
|
}
|
185
192
|
|
186
193
|
list.push(k + '=' + v)
|
@@ -213,19 +220,17 @@ function splitHtml (html, opts, pcex) {
|
|
213
220
|
var
|
214
221
|
jsfn = opts.expr && (opts.parser || opts.type) ? _compileJS : 0,
|
215
222
|
list = brackets.split(html, 0, _bp),
|
216
|
-
expr
|
223
|
+
expr
|
217
224
|
|
218
225
|
for (var i = 1; i < list.length; i += 2) {
|
219
226
|
expr = list[i]
|
220
227
|
if (expr[0] === '^') {
|
221
228
|
expr = expr.slice(1)
|
222
229
|
} else if (jsfn) {
|
223
|
-
|
224
|
-
expr = jsfn(israw ? expr.slice(1) : expr, opts).trim()
|
230
|
+
expr = jsfn(expr, opts).trim()
|
225
231
|
if (expr.slice(-1) === ';') expr = expr.slice(0, -1)
|
226
|
-
if (israw) expr = '=' + expr
|
227
232
|
}
|
228
|
-
list[i] =
|
233
|
+
list[i] = CH_IDEXPR + (pcex.push(expr) - 1) + _bp[1]
|
229
234
|
}
|
230
235
|
html = list.join('')
|
231
236
|
}
|
@@ -242,20 +247,10 @@ function splitHtml (html, opts, pcex) {
|
|
242
247
|
*/
|
243
248
|
function restoreExpr (html, pcex) {
|
244
249
|
if (pcex.length) {
|
245
|
-
html = html
|
246
|
-
.replace(/\u0001(\d+)/g, function (_, d) {
|
247
|
-
var expr = pcex[d]
|
248
|
-
|
249
|
-
if (expr[0] === '=') {
|
250
|
-
expr = expr.replace(brackets.R_STRINGS, function (qs) {
|
251
|
-
return qs
|
252
|
-
.replace(/</g, '<')
|
253
|
-
.replace(/>/g, '>')
|
254
|
-
})
|
255
|
-
}
|
250
|
+
html = html.replace(RE_REPEXPR, function (_, d) {
|
256
251
|
|
257
|
-
|
258
|
-
|
252
|
+
return pcex._bp[0] + pcex[d].trim().replace(/[\r\n]+/g, ' ').replace(/"/g, CH_DQCODE)
|
253
|
+
})
|
259
254
|
}
|
260
255
|
return html
|
261
256
|
}
|
@@ -271,6 +266,7 @@ function restoreExpr (html, pcex) {
|
|
271
266
|
* @see {@link http://www.w3.org/TR/html5/syntax.html}
|
272
267
|
*/
|
273
268
|
function _compileHTML (html, opts, pcex) {
|
269
|
+
if (!/\S/.test(html)) return ''
|
274
270
|
|
275
271
|
html = splitHtml(html, opts, pcex)
|
276
272
|
.replace(HTML_TAGS, function (_, name, attr, ends) {
|
@@ -299,7 +295,7 @@ function _compileHTML (html, opts, pcex) {
|
|
299
295
|
if (p.length) html = html.replace(/\u0002/g, function () { return p.shift() })
|
300
296
|
}
|
301
297
|
|
302
|
-
if (opts.compact) html = html.replace(
|
298
|
+
if (opts.compact) html = html.replace(HTML_PACK, '><$1')
|
303
299
|
|
304
300
|
return restoreExpr(html, pcex).replace(TRIM_TRAIL, '')
|
305
301
|
}
|
@@ -377,7 +373,7 @@ function riotjs (js) {
|
|
377
373
|
|
378
374
|
if (~js.indexOf('/')) js = rmComms(js, JS_COMMS)
|
379
375
|
|
380
|
-
while (match = js.match(JS_ES6SIGN)) {
|
376
|
+
while ((match = js.match(JS_ES6SIGN))) {
|
381
377
|
|
382
378
|
parts.push(RE.leftContext)
|
383
379
|
js = RE.rightContext
|
@@ -396,7 +392,7 @@ function riotjs (js) {
|
|
396
392
|
|
397
393
|
function rmComms (s, r, m) {
|
398
394
|
r.lastIndex = 0
|
399
|
-
while (m = r.exec(s)) {
|
395
|
+
while ((m = r.exec(s))) {
|
400
396
|
if (m[0][0] === '/' && !m[1] && !m[2]) {
|
401
397
|
s = RE.leftContext + ' ' + RE.rightContext
|
402
398
|
r.lastIndex = m[3] + 1
|
@@ -434,11 +430,8 @@ function _compileJS (js, opts, type, parserOpts, url) {
|
|
434
430
|
if (!/\S/.test(js)) return ''
|
435
431
|
if (!type) type = opts.type
|
436
432
|
|
437
|
-
var parser = opts.parser ||
|
433
|
+
var parser = opts.parser || type && parsers._req('js.' + type, true) || riotjs
|
438
434
|
|
439
|
-
if (!parser) {
|
440
|
-
throw new Error('JS parser not found: "' + type + '"')
|
441
|
-
}
|
442
435
|
return parser(js, parserOpts, url).replace(/\r\n?/g, '\n').replace(TRIM_TRAIL, '')
|
443
436
|
}
|
444
437
|
|
@@ -478,7 +471,7 @@ function compileJS (js, opts, type, userOpts) {
|
|
478
471
|
return _compileJS(js, opts || {}, type, userOpts.parserOptions, userOpts.url)
|
479
472
|
}
|
480
473
|
|
481
|
-
var CSS_SELECTOR = RegExp('([{}]|^)[
|
474
|
+
var CSS_SELECTOR = RegExp('([{}]|^)[; ]*((?:[^@ ;{}][^{}]*)?[^@ ;{}:] ?)(?={)|' + S_LINESTR, 'g')
|
482
475
|
|
483
476
|
/**
|
484
477
|
* Parses styles enclosed in a "scoped" tag (`scoped` was removed from HTML5).
|
@@ -498,17 +491,21 @@ function scopedCSS (tag, css) {
|
|
498
491
|
p2 = p2.replace(/[^,]+/g, function (sel) {
|
499
492
|
var s = sel.trim()
|
500
493
|
|
494
|
+
if (s.indexOf(tag) === 0) {
|
495
|
+
return sel
|
496
|
+
}
|
497
|
+
|
501
498
|
if (!s || s === 'from' || s === 'to' || s.slice(-1) === '%') {
|
502
499
|
return sel
|
503
500
|
}
|
504
501
|
|
505
502
|
if (s.indexOf(scope) < 0) {
|
506
|
-
s = tag + ' ' + s + ',[
|
503
|
+
s = tag + ' ' + s + ',[data-is="' + tag + '"] ' + s
|
507
504
|
} else {
|
508
505
|
s = s.replace(scope, tag) + ',' +
|
509
|
-
s.replace(scope, '[
|
506
|
+
s.replace(scope, '[data-is="' + tag + '"]')
|
510
507
|
}
|
511
|
-
return
|
508
|
+
return s
|
512
509
|
})
|
513
510
|
|
514
511
|
return p1 ? p1 + ' ' + p2 : p2
|
@@ -530,26 +527,19 @@ function scopedCSS (tag, css) {
|
|
530
527
|
* @see {@link module:compiler.compileCSS|compileCSS}
|
531
528
|
*/
|
532
529
|
function _compileCSS (css, tag, type, opts) {
|
533
|
-
|
530
|
+
opts = opts || {}
|
534
531
|
|
535
532
|
if (type) {
|
536
|
-
if (type
|
537
|
-
|
538
|
-
|
539
|
-
css =
|
540
|
-
} else if (type !== 'css') {
|
541
|
-
throw new Error('CSS parser not found: "' + type + '"')
|
533
|
+
if (type !== 'css') {
|
534
|
+
|
535
|
+
var parser = parsers._req('css.' + type, true)
|
536
|
+
css = parser(tag, css, opts.parserOpts || {}, opts.url)
|
542
537
|
}
|
543
538
|
}
|
544
539
|
|
545
540
|
css = css.replace(brackets.R_MLCOMMS, '').replace(/\s+/g, ' ').trim()
|
541
|
+
if (tag) css = scopedCSS(tag, css)
|
546
542
|
|
547
|
-
if (scoped) {
|
548
|
-
if (!tag) {
|
549
|
-
throw new Error('Can not parse scoped CSS without a tagName')
|
550
|
-
}
|
551
|
-
css = scopedCSS(tag, css)
|
552
|
-
}
|
553
543
|
return css
|
554
544
|
}
|
555
545
|
|
@@ -624,7 +614,7 @@ var MISC_ATTR = '\\s*=\\s*(' + S_STRINGS + '|{[^}]+}|\\S+)'
|
|
624
614
|
* ```
|
625
615
|
* @const {RegExp}
|
626
616
|
*/
|
627
|
-
var END_TAGS = /\/>\n|^<(
|
617
|
+
var END_TAGS = /\/>\n|^<(?:\/?-?[A-Za-z][-\w\xA0-\xFF]*\s*|-?[A-Za-z][-\w\xA0-\xFF]*\s+[-\w:\xA0-\xFF][\S\s]*?)>\n/
|
628
618
|
|
629
619
|
/**
|
630
620
|
* Encloses the given string in single quotes.
|
@@ -646,25 +636,26 @@ function _q (s, r) {
|
|
646
636
|
/**
|
647
637
|
* Generates code to call the `riot.tag2` function with the processed parts.
|
648
638
|
*
|
649
|
-
* @param {string} name
|
650
|
-
* @param {string} html
|
651
|
-
* @param {string} css
|
652
|
-
* @param {string}
|
653
|
-
* @param {string} js
|
654
|
-
* @param {
|
639
|
+
* @param {string} name - The tag name
|
640
|
+
* @param {string} html - HTML (can contain embeded eols)
|
641
|
+
* @param {string} css - Styles
|
642
|
+
* @param {string} attr - Root attributes
|
643
|
+
* @param {string} js - JavaScript "constructor"
|
644
|
+
* @param {string} imports - Code containing 'import' statements
|
645
|
+
* @param {object} opts - Compiler options
|
655
646
|
* @returns {string} Code to call `riot.tag2`
|
656
647
|
*/
|
657
|
-
function mktag (name, html, css,
|
648
|
+
function mktag (name, html, css, attr, js, imports, opts) {
|
658
649
|
var
|
659
|
-
c = ', ',
|
660
|
-
s = '}
|
650
|
+
c = opts.debug ? ',\n ' : ', ',
|
651
|
+
s = '});'
|
661
652
|
|
662
653
|
if (js && js.slice(-1) !== '\n') s = '\n' + s
|
663
654
|
|
664
|
-
return 'riot.tag2(\'' + name + SQ +
|
655
|
+
return imports + 'riot.tag2(\'' + name + SQ +
|
665
656
|
c + _q(html, 1) +
|
666
657
|
c + _q(css) +
|
667
|
-
c + _q(
|
658
|
+
c + _q(attr) + ', function(opts) {\n' + js + s
|
668
659
|
}
|
669
660
|
|
670
661
|
/**
|
@@ -686,7 +677,9 @@ function splitBlocks (str) {
|
|
686
677
|
m = str.slice(k, n).match(END_TAGS)
|
687
678
|
if (m) {
|
688
679
|
k += m.index + m[0].length
|
689
|
-
|
680
|
+
m = str.slice(0, k)
|
681
|
+
if (m.slice(-5) === '<-/>\n') m = m.slice(0, -5)
|
682
|
+
return [m, str.slice(k)]
|
690
683
|
}
|
691
684
|
n = k
|
692
685
|
k = str.lastIndexOf('<', k - 1)
|
@@ -732,6 +725,20 @@ function getAttrib (attribs, name) {
|
|
732
725
|
return ''
|
733
726
|
}
|
734
727
|
|
728
|
+
/**
|
729
|
+
* Unescape any html string
|
730
|
+
* @param {string} str escaped html string
|
731
|
+
* @returns {string} unescaped html string
|
732
|
+
*/
|
733
|
+
function unescapeHTML (str) {
|
734
|
+
return str
|
735
|
+
.replace(/&/g, '&')
|
736
|
+
.replace(/</g, '<')
|
737
|
+
.replace(/>/g, '>')
|
738
|
+
.replace(/"/g, '"')
|
739
|
+
.replace(/'/g, '\'')
|
740
|
+
}
|
741
|
+
|
735
742
|
/**
|
736
743
|
* Gets the parser options from the "options" attribute.
|
737
744
|
*
|
@@ -739,7 +746,7 @@ function getAttrib (attribs, name) {
|
|
739
746
|
* @returns {object} Parsed options, or null if no options
|
740
747
|
*/
|
741
748
|
function getParserOptions (attribs) {
|
742
|
-
var opts = getAttrib(attribs, 'options')
|
749
|
+
var opts = unescapeHTML(getAttrib(attribs, 'options'))
|
743
750
|
|
744
751
|
return opts ? JSON.parse(opts) : null
|
745
752
|
}
|
@@ -756,9 +763,10 @@ function getParserOptions (attribs) {
|
|
756
763
|
* @returns {string} Parsed code
|
757
764
|
*/
|
758
765
|
function getCode (code, opts, attribs, base) {
|
759
|
-
var
|
760
|
-
|
761
|
-
|
766
|
+
var
|
767
|
+
type = getType(attribs),
|
768
|
+
src = getAttrib(attribs, 'src'),
|
769
|
+
jsParserOptions = extend({}, opts.parserOptions.js)
|
762
770
|
|
763
771
|
if (src) {
|
764
772
|
if (DEFER_ATTR.test(attribs)) return false
|
@@ -768,7 +776,14 @@ function getCode (code, opts, attribs, base) {
|
|
768
776
|
|
769
777
|
code = require('fs').readFileSync(file, charset || 'utf8')
|
770
778
|
}
|
771
|
-
|
779
|
+
|
780
|
+
return _compileJS(
|
781
|
+
code,
|
782
|
+
opts,
|
783
|
+
type,
|
784
|
+
extend(jsParserOptions, getParserOptions(attribs)),
|
785
|
+
base
|
786
|
+
)
|
772
787
|
}
|
773
788
|
|
774
789
|
/**
|
@@ -782,11 +797,12 @@ function getCode (code, opts, attribs, base) {
|
|
782
797
|
* @returns {string} Parsed styles
|
783
798
|
*/
|
784
799
|
function cssCode (code, opts, attribs, url, tag) {
|
785
|
-
var
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
800
|
+
var
|
801
|
+
parserStyleOptions = extend({}, opts.parserOptions.style),
|
802
|
+
extraOpts = {
|
803
|
+
parserOpts: extend(parserStyleOptions, getParserOptions(attribs)),
|
804
|
+
url: url
|
805
|
+
}
|
790
806
|
|
791
807
|
return _compileCSS(code, tag, getType(attribs) || opts.style, extraOpts)
|
792
808
|
}
|
@@ -803,11 +819,8 @@ function cssCode (code, opts, attribs, url, tag) {
|
|
803
819
|
* @throws Will throw "Template parser not found" if the HTML parser cannot be loaded.
|
804
820
|
*/
|
805
821
|
function compileTemplate (html, url, lang, opts) {
|
806
|
-
var parser = parsers.html[lang]
|
807
822
|
|
808
|
-
|
809
|
-
throw new Error('Template parser not found: "' + lang + '"')
|
810
|
-
}
|
823
|
+
var parser = parsers._req('html.' + lang, true)
|
811
824
|
return parser(html, opts, url)
|
812
825
|
}
|
813
826
|
|
@@ -820,7 +833,7 @@ var
|
|
820
833
|
* unquoted expressions, but disallows the character '>' within unquoted attribute values.
|
821
834
|
* @const {RegExp}
|
822
835
|
*/
|
823
|
-
CUST_TAG = RegExp(/^([ \t]*)<([-\w]
|
836
|
+
CUST_TAG = RegExp(/^([ \t]*)<(-?[A-Za-z][-\w\xA0-\xFF]*)(?:\s+([^'"\/>]+(?:(?:@|\/[^>])[^'"\/>]*)*)|\s*)?(?:\/>|>[ \t]*\n?([\S\s]*)^\1<\/\2\s*>|>(.*)<\/\2\s*>)/
|
824
837
|
.source.replace('@', S_STRINGS), 'gim'),
|
825
838
|
/**
|
826
839
|
* Matches `script` elements, capturing its attributes in $1 and its content in $2.
|
@@ -865,10 +878,18 @@ var
|
|
865
878
|
function compile (src, opts, url) {
|
866
879
|
var
|
867
880
|
parts = [],
|
868
|
-
included
|
881
|
+
included,
|
882
|
+
defaultParserptions = {
|
883
|
+
|
884
|
+
template: {},
|
885
|
+
js: {},
|
886
|
+
style: {}
|
887
|
+
}
|
869
888
|
|
870
889
|
if (!opts) opts = {}
|
871
890
|
|
891
|
+
opts.parserOptions = extend(defaultParserptions, opts.parserOptions || {})
|
892
|
+
|
872
893
|
included = opts.exclude
|
873
894
|
? function (s) { return opts.exclude.indexOf(s) < 0 } : function () { return 1 }
|
874
895
|
|
@@ -877,7 +898,7 @@ function compile (src, opts, url) {
|
|
877
898
|
var _bp = brackets.array(opts.brackets)
|
878
899
|
|
879
900
|
if (opts.template) {
|
880
|
-
src = compileTemplate(src, url, opts.template, opts.
|
901
|
+
src = compileTemplate(src, url, opts.template, opts.parserOptions.template)
|
881
902
|
}
|
882
903
|
|
883
904
|
src = cleanSource(src)
|
@@ -886,6 +907,7 @@ function compile (src, opts, url) {
|
|
886
907
|
jscode = '',
|
887
908
|
styles = '',
|
888
909
|
html = '',
|
910
|
+
imports = '',
|
889
911
|
pcex = []
|
890
912
|
|
891
913
|
pcex._bp = _bp
|
@@ -908,13 +930,6 @@ function compile (src, opts, url) {
|
|
908
930
|
|
909
931
|
body = body.replace(RegExp('^' + indent, 'gm'), '')
|
910
932
|
|
911
|
-
body = body.replace(STYLES, function (_m, _attrs, _style) {
|
912
|
-
if (included('css')) {
|
913
|
-
styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName)
|
914
|
-
}
|
915
|
-
return ''
|
916
|
-
})
|
917
|
-
|
918
933
|
body = body.replace(SCRIPTS, function (_m, _attrs, _script) {
|
919
934
|
if (included('js')) {
|
920
935
|
var code = getCode(_script, opts, _attrs, url)
|
@@ -925,6 +940,13 @@ function compile (src, opts, url) {
|
|
925
940
|
return ''
|
926
941
|
})
|
927
942
|
|
943
|
+
body = body.replace(STYLES, function (_m, _attrs, _style) {
|
944
|
+
if (included('css')) {
|
945
|
+
styles += (styles ? ' ' : '') + cssCode(_style, opts, _attrs, url, tagName)
|
946
|
+
}
|
947
|
+
return ''
|
948
|
+
})
|
949
|
+
|
928
950
|
var blocks = splitBlocks(body.replace(TRIM_TRAIL, ''))
|
929
951
|
|
930
952
|
if (included('html')) {
|
@@ -934,6 +956,10 @@ function compile (src, opts, url) {
|
|
934
956
|
if (included('js')) {
|
935
957
|
body = _compileJS(blocks[1], opts, null, null, url)
|
936
958
|
if (body) jscode += (jscode ? '\n' : '') + body
|
959
|
+
jscode = jscode.replace(IMPORT_STATEMENT, function (s) {
|
960
|
+
imports += s.trim() + '\n'
|
961
|
+
return ''
|
962
|
+
})
|
937
963
|
}
|
938
964
|
}
|
939
965
|
}
|
@@ -946,12 +972,13 @@ function compile (src, opts, url) {
|
|
946
972
|
html: html,
|
947
973
|
css: styles,
|
948
974
|
attribs: attribs,
|
949
|
-
js: jscode
|
975
|
+
js: jscode,
|
976
|
+
imports: imports
|
950
977
|
})
|
951
978
|
return ''
|
952
979
|
}
|
953
980
|
|
954
|
-
return mktag(tagName, html, styles, attribs, jscode,
|
981
|
+
return mktag(tagName, html, styles, attribs, jscode, imports, opts)
|
955
982
|
})
|
956
983
|
|
957
984
|
if (opts.entities) return parts
|