Rewrite HTML template parser.
This commit is contained in:
parent
7a7e90037b
commit
f7b90c4c19
@ -7,25 +7,62 @@ module.exports = (grunt) ->
|
|||||||
importHTML = (filename) ->
|
importHTML = (filename) ->
|
||||||
"(innerHTML: #{json grunt.file.read("src/General/html/#{filename}.html").replace(/^ +| +$</gm, '').replace(/\r?\n/g, '')})"
|
"(innerHTML: #{json grunt.file.read("src/General/html/#{filename}.html").replace(/^ +| +$</gm, '').replace(/\r?\n/g, '')})"
|
||||||
|
|
||||||
|
checkHTML = (text, context) ->
|
||||||
|
while text
|
||||||
|
switch context
|
||||||
|
when ''
|
||||||
|
if part = text.match /^[^'"<>]+/ # plain text
|
||||||
|
else if part = text.match /^<\/\w+>/ # HTML end tag
|
||||||
|
else if part = text.match /^<\w+/ # start of HTML tag
|
||||||
|
context = '<'
|
||||||
|
when '<'
|
||||||
|
if part = text.match /^ [\w-]+(?![\w-=])/ # boolean attribute
|
||||||
|
else if part = text.match /^ [\w-]+=(['"])/ # start of attribute value
|
||||||
|
context = part[1]
|
||||||
|
else if part = text.match /^>/ # end of HTML tag
|
||||||
|
context = ''
|
||||||
|
when "'", '"'
|
||||||
|
if part = text.match /^[^'"<>]+/ # attribute value
|
||||||
|
else if part = text.match /^['"]/ # end of attribute value
|
||||||
|
throw new Error 'Inconsistent quoting' if part[0] isnt context
|
||||||
|
context = '<'
|
||||||
|
unless part
|
||||||
|
throw new Error "HTML template is ill-formed (at #{text})"
|
||||||
|
text = text[part[0].length..]
|
||||||
|
context
|
||||||
|
|
||||||
|
parseTemplate = (template, context='') ->
|
||||||
|
context0 = context
|
||||||
|
parts = []
|
||||||
|
text = template
|
||||||
|
while text
|
||||||
|
if part = text.match /^[^{}]+(?!{)/
|
||||||
|
try
|
||||||
|
context = checkHTML part[0], context
|
||||||
|
catch err
|
||||||
|
throw new Error "#{err.message}: #{template}"
|
||||||
|
parts.push json part[0]
|
||||||
|
else if part = text.match /^([^}]){([^}`]*)}/
|
||||||
|
unless context is '' or (part[1] is '$' and context isnt '<')
|
||||||
|
throw new Error "Illegal insertion into HTML template: #{template}"
|
||||||
|
parts.push switch part[1]
|
||||||
|
when '$' then "E(`#{part[2]}`)"
|
||||||
|
when '&' then "`#{part[2]}`.innerHTML"
|
||||||
|
when '@' then "`#{part[2]}`.map((x) -> x.innerHTML).join('')"
|
||||||
|
else
|
||||||
|
throw new Error "Unrecognized substitution operator (#{part[1]}): #{template}"
|
||||||
|
else
|
||||||
|
break
|
||||||
|
text = text[part[0].length..]
|
||||||
|
if context isnt context0
|
||||||
|
throw new Error "HTML template not properly terminated: #{template}"
|
||||||
|
output = if parts.length is 0 then '""' else parts.join ' + '
|
||||||
|
[output, text]
|
||||||
|
|
||||||
html = (template) ->
|
html = (template) ->
|
||||||
parts = template.split /([\$&@]){([^}`]*)}/
|
[output, remaining] = parseTemplate template
|
||||||
parts2 = []
|
if remaining
|
||||||
checkText = ''
|
throw new Error "Unexpected characters in template (#{remaining}): #{template}"
|
||||||
for part, i in parts
|
|
||||||
switch i % 3
|
|
||||||
when 0
|
|
||||||
parts2.push json part unless part is ''
|
|
||||||
checkText += part
|
|
||||||
when 1
|
|
||||||
if /<[^>]*$/.test(checkText) and not (part is '$' and /\=['"][^"'<>]*$/.test checkText)
|
|
||||||
throw new Error "Illegal insertion into HTML template: #{template}"
|
|
||||||
parts2.push switch part
|
|
||||||
when '$' then "E(`#{parts[i+1]}`)"
|
|
||||||
when '&' then "`#{parts[i+1]}`.innerHTML"
|
|
||||||
when '@' then "`#{parts[i+1]}`.map((x) -> x.innerHTML).join('')"
|
|
||||||
unless /^(<\w+( [\w-]+(='[^"'<>]*'|="[^"'<>]*")?)*>|<\/\w+>|[^"'<>]*)*$/.test checkText
|
|
||||||
throw new Error "HTML template is ill-formed: #{template}"
|
|
||||||
output = if parts2.length is 0 then '""' else parts2.join ' + '
|
|
||||||
"(innerHTML: #{output})"
|
"(innerHTML: #{output})"
|
||||||
|
|
||||||
assert = (statement, objs...) ->
|
assert = (statement, objs...) ->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user