Socket
Socket
Sign inDemoInstall

hyperx

Package Overview
Dependencies
1
Maintainers
27
Versions
33
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.5.4 to 3.0.0

215

index.js
var attrToProp = require('hyperscript-attribute-to-property')
var VAR = 0, TEXT = 1, OPEN = 2, CLOSE = 3, ATTR = 4

@@ -10,13 +11,17 @@ var ATTR_KEY = 5, ATTR_KEY_W = 6

module.exports = function (h, opts) {
if (!opts) opts = {}
if (!opts) opts = { }
var concat = opts.concat || function (a, b) {
return String(a) + String(b)
}
if (opts.attrToProp !== false) {
if (opts.attrToProp !== false)
h = attrToProp(h)
}
return function (strings) {
var state = TEXT, reg = ''
var state = TEXT, reg = '', isSelfClosing = false
var arglen = arguments.length

@@ -26,2 +31,3 @@ var parts = []

for (var i = 0; i < strings.length; i++) {
if (i < arglen - 1) {

@@ -48,23 +54,27 @@ var arg = arguments[i+1]

parts.push.apply(parts, p)
} else parts.push.apply(parts, parse(strings[i]))
} else {
parts.push.apply(parts, parse(strings[i]))
}
}
var tree = [null,{},[]]
var stack = [[tree,-1]]
var tree = [ null, {}, [] ]
var stack = [ [ tree, -1 ] ]
for (var i = 0; i < parts.length; i++) {
var cur = stack[stack.length-1][0]
var p = parts[i], s = p[0]
if (s === OPEN && /^\//.test(p[1])) {
var p = parts[i], state = p[0]
if (state === OPEN && /^\//.test(p[1])) {
var ix = stack[stack.length-1][1]
if (stack.length > 1) {
stack.pop()
stack[stack.length-1][0][2][ix] = h(
cur[0], cur[1], cur[2].length ? cur[2] : undefined
)
stack[stack.length-1][0][2][ix] = h(cur[0], cur[1], cur[2].length ? cur[2] : undefined)
}
} else if (s === OPEN) {
} else if (state === OPEN) {
var c = [p[1],{},[]]
cur[2].push(c)
stack.push([c,cur[2].length-1])
} else if (s === ATTR_KEY || (s === VAR && p[1] === ATTR_KEY)) {
} else if (state === ATTR_KEY || (state === VAR && p[1] === ATTR_KEY)) {
var key = ''

@@ -75,27 +85,38 @@ var copyKey

key = concat(key, parts[i][1])
} else if (parts[i][0] === VAR && parts[i][1] === ATTR_KEY) {
if (typeof parts[i][2] === 'object' && !key) {
for (copyKey in parts[i][2]) {
if (parts[i][2].hasOwnProperty(copyKey) && !cur[1][copyKey]) {
for (copyKey in parts[i][2])
if (parts[i][2].hasOwnProperty(copyKey) && !cur[1][copyKey])
cur[1][copyKey] = parts[i][2][copyKey]
}
}
} else {
key = concat(key, parts[i][2])
}
} else break
} else {
break
}
}
if (parts[i][0] === ATTR_EQ) i++
if (parts[i][0] === ATTR_EQ)
i++
var j = i
for (; i < parts.length; i++) {
if (parts[i][0] === ATTR_VALUE || parts[i][0] === ATTR_KEY) {
if (!cur[1][key]) cur[1][key] = strfn(parts[i][1])
else parts[i][1]==="" || (cur[1][key] = concat(cur[1][key], parts[i][1]));
} else if (parts[i][0] === VAR
&& (parts[i][1] === ATTR_VALUE || parts[i][1] === ATTR_KEY)) {
if (!cur[1][key]) cur[1][key] = strfn(parts[i][2])
else parts[i][2]==="" || (cur[1][key] = concat(cur[1][key], parts[i][2]));
if (!cur[1][key])
cur[1][key] = strfn(parts[i][1])
else
parts[i][1]==="" || (cur[1][key] = concat(cur[1][key], parts[i][1]));
} else if (parts[i][0] === VAR && (parts[i][1] === ATTR_VALUE || parts[i][1] === ATTR_KEY)) {
if (!cur[1][key])
cur[1][key] = strfn(parts[i][2])
else
parts[i][2]==="" || (cur[1][key] = concat(cur[1][key], parts[i][2]));
} else {
if (key.length && !cur[1][key] && i === j
&& (parts[i][0] === CLOSE || parts[i][0] === ATTR_BREAK)) {
if (key.length && !cur[1][key] && i === j && (parts[i][0] === CLOSE || parts[i][0] === ATTR_BREAK)) {
// https://html.spec.whatwg.org/multipage/infrastructure.html#boolean-attributes

@@ -105,44 +126,56 @@ // empty string is falsy, not well behaved value in browser

}
if (parts[i][0] === CLOSE) {
if (parts[i][0] === CLOSE)
i--
}
break
}
}
} else if (s === ATTR_KEY) {
} else if (state === ATTR_KEY) {
cur[1][p[1]] = true
} else if (s === VAR && p[1] === ATTR_KEY) {
} else if (state === VAR && p[1] === ATTR_KEY) {
cur[1][p[2]] = true
} else if (s === CLOSE) {
if (selfClosing(cur[0]) && stack.length) {
} else if (state === CLOSE) {
const isSelfClosing = p[1] || selfClosingVoid(cur[0])
//if (selfClosing(cur[0]) && stack.length) {
if (isSelfClosing && stack.length) {
var ix = stack[stack.length-1][1]
stack.pop()
stack[stack.length-1][0][2][ix] = h(
cur[0], cur[1], cur[2].length ? cur[2] : undefined
)
stack[stack.length-1][0][2][ix] = h(cur[0], cur[1], cur[2].length ? cur[2] : undefined)
}
} else if (s === VAR && p[1] === TEXT) {
if (p[2] === undefined || p[2] === null) p[2] = ''
else if (!p[2]) p[2] = concat('', p[2])
if (Array.isArray(p[2][0])) {
} else if (state === VAR && p[1] === TEXT) {
if (p[2] === undefined || p[2] === null)
p[2] = ''
else if (!p[2])
p[2] = concat('', p[2])
if (Array.isArray(p[2][0]))
cur[2].push.apply(cur[2], p[2])
} else {
else
cur[2].push(p[2])
}
} else if (s === TEXT) {
} else if (state === TEXT) {
cur[2].push(p[1])
} else if (s === ATTR_EQ || s === ATTR_BREAK) {
} else if (state === ATTR_EQ || state === ATTR_BREAK) {
// no-op
} else {
throw new Error('unhandled: ' + s)
throw new Error('unhandled: ' + state)
}
}
if (tree[2].length > 1 && /^\s*$/.test(tree[2][0])) {
if (tree[2].length > 1 && /^\s*$/.test(tree[2][0]))
tree[2].shift()
}
if (tree[2].length > 2
|| (tree[2].length === 2 && /\S/.test(tree[2][1]))) {
if (opts.createFragment) return opts.createFragment(tree[2])
if (tree[2].length > 2 || (tree[2].length === 2 && /\S/.test(tree[2][1]))) {
if (opts.createFragment)
return opts.createFragment(tree[2])
throw new Error(

@@ -152,20 +185,35 @@ 'multiple root elements must be wrapped in an enclosing tag'

}
if (Array.isArray(tree[2][0]) && typeof tree[2][0][0] === 'string'
&& Array.isArray(tree[2][0][2])) {
if (Array.isArray(tree[2][0]) && typeof tree[2][0][0] === 'string' && Array.isArray(tree[2][0][2]))
tree[2][0] = h(tree[2][0][0], tree[2][0][1], tree[2][0][2])
}
return tree[2][0]
function parse (str) {
var res = []
if (state === ATTR_VALUE_W) state = ATTR
var res = [ ]
var isInStyleTag = false
if (state === ATTR_VALUE_W)
state = ATTR
for (var i = 0; i < str.length; i++) {
var c = str.charAt(i)
if (state === TEXT && c === '<') {
if (reg.length) res.push([TEXT, reg])
if (reg.length)
res.push([TEXT, reg])
reg = ''
state = OPEN
isInStyleTag = false
} else if (c === '>' && !quot(state) && state !== COMMENT) {
if (state === OPEN && reg.length) {
res.push([OPEN,reg])
if (reg === 'style')
isInStyleTag = true
else if (reg === '/style')
isInStyleTag = false
} else if (state === ATTR_KEY) {

@@ -176,5 +224,15 @@ res.push([ATTR_KEY,reg])

}
res.push([CLOSE])
reg = ''
if (state === TEXT && isInStyleTag) {
// the css descendant selector within <style> tags shouldn't close
// e.g., <style> ul > .test { color: blue }</style>
reg += c
} else {
res.push([CLOSE, isSelfClosing])
isSelfClosing = false
reg = ''
}
state = TEXT
} else if (state === COMMENT && /-$/.test(reg) && c === '-') {

@@ -185,2 +243,3 @@ if (opts.comments) {

reg = ''
isSelfClosing = true
state = TEXT

@@ -196,7 +255,14 @@ } else if (state === OPEN && /^!--$/.test(reg)) {

} else if (state === OPEN && c === '/' && reg.length) {
// no-op, self closing tag without a space <br/>
// self closing tag without a space <br/>
isSelfClosing = true
} else if (state === OPEN && /\s/.test(c)) {
if (reg.length) {
if (reg.length)
res.push([OPEN, reg])
}
if (reg === 'style')
isInStyleTag = true
else if (reg === '/style')
isInStyleTag = false
reg = ''

@@ -210,3 +276,4 @@ state = ATTR

} else if (state === ATTR && /\s/.test(c)) {
if (reg.length) res.push([ATTR_KEY,reg])
if (reg.length)
res.push([ATTR_KEY,reg])
res.push([ATTR_BREAK])

@@ -221,2 +288,6 @@ } else if (state === ATTR_KEY && /\s/.test(c)) {

state = ATTR_VALUE_W
} else if (state === ATTR_KEY && c === '/') {
isSelfClosing = true
reg=''
state = ATTR
} else if (state === ATTR_KEY) {

@@ -232,3 +303,7 @@ reg += c

state = ATTR_KEY
} else state = ATTR
} else if (c === '/') {
isSelfClosing = true
} else {
state = ATTR
}
} else if (state === ATTR_VALUE_W && c === '"') {

@@ -291,2 +366,12 @@ state = ATTR_VALUE_DQ

//area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr
var voidCloseRE = RegExp('^(' + [
'area', 'base', 'br', 'col', 'command', 'embed',
'hr', 'img', 'input', 'keygen', 'link', 'meta', 'param',
'source', 'track', 'wbr'
].join('|') + ')(?:[\.#][a-zA-Z0-9\u007F-\uFFFF_:-]+)*$')
function selfClosingVoid (tag) { return voidCloseRE.test(tag) }
/*
var closeRE = RegExp('^(' + [

@@ -308,2 +393,4 @@ 'area', 'base', 'basefont', 'bgsound', 'br', 'col', 'command', 'embed',

].join('|') + ')(?:[\.#][a-zA-Z0-9\u007F-\uFFFF_:-]+)*$')
function selfClosing (tag) { return closeRE.test(tag) }
*/
{
"name": "hyperx",
"version": "2.5.4",
"version": "3.0.0",
"description": "tagged template string virtual dom builder",

@@ -24,4 +24,4 @@ "main": "index.js",

"covert": "^1.1.0",
"hyperscript": "^1.4.7",
"tape": "^4.4.0",
"hyperscript": "^2.0.2",
"tape": "^5.4.0",
"virtual-dom": "^2.1.1"

@@ -38,8 +38,8 @@ },

"type": "git",
"url": "git+https://github.com/substack/hyperx.git"
"url": "git+https://github.com/mreinstein/hyperx.git"
},
"bugs": {
"url": "https://github.com/substack/hyperx/issues"
"url": "https://github.com/mreinstein/hyperx/issues"
},
"homepage": "https://github.com/substack/hyperx#readme"
"homepage": "https://github.com/mreinstein/hyperx#readme"
}

@@ -18,1 +18,40 @@ var test = require('tape')

})
test('embedded style', function (t) {
var key = 'type'
var value = 'text'
var tree = hx`<style>
.test > ul {
background-color: red;
}
</style>`
t.equal(
vdom.create(tree).toString(),
`<style>
.test &gt; ul {
background-color: red;
}
</style>`
)
t.end()
})
test('embedded style with attributes', function (t) {
var key = 'type'
var value = 'text'
var tree = hx`<style id="test1">
.test > ul {
background-color: red;
}
</style>`
t.equal(
vdom.create(tree).toString(),
`<style id="test1">
.test &gt; ul {
background-color: red;
}
</style>`
)
t.end()
})

@@ -22,1 +22,26 @@ var test = require('tape')

})
test('svg mixed with html and close / self-closing tags', function (t) {
var expected = `<div>
<h3>test</h3>
<svg width="150" height="100" viewBox="0 0 3 2">
<use id="test"></use>
<rect width="1" height="2" x="0" fill="#008d46"></rect>
<use id="test"></use>
<rect width="1" height="2" x="0" fill="#008d46"></rect>
<use id="test"></use>
</svg>
</div>`
var tree = hx`<div>
<h3>test</h3>
<svg width="150" height="100" viewBox="0 0 3 2">
<use id="test"></use>
<rect width="1" height="2" x="0" fill="#008d46"></rect>
<use id="test"/>
<rect width="1" height="2" x="0" fill="#008d46"/>
<use id="test"></use>
</svg>
</div>`
t.equal(vdom.create(tree).toString(), expected)
t.end()
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc