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
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
|