hastscript
Advanced tools
Comparing version 3.1.0 to 4.0.0
181
index.js
@@ -1,180 +0,3 @@ | ||
'use strict'; | ||
'use strict' | ||
var parseSelector = require('hast-util-parse-selector'); | ||
var camelcase = require('camelcase'); | ||
var propertyInformation = require('property-information'); | ||
var spaces = require('space-separated-tokens').parse; | ||
var commas = require('comma-separated-tokens').parse; | ||
module.exports = h; | ||
/* Hyperscript compatible DSL for creating virtual HAST | ||
* trees. */ | ||
function h(selector, properties, children) { | ||
var node = parseSelector(selector); | ||
var property; | ||
if ( | ||
properties && | ||
!children && | ||
( | ||
typeof properties === 'string' || | ||
'length' in properties || | ||
isNode(node.tagName, properties) | ||
) | ||
) { | ||
children = properties; | ||
properties = null; | ||
} | ||
if (properties) { | ||
for (property in properties) { | ||
addProperty(node.properties, property, properties[property]); | ||
} | ||
} | ||
addChild(node.children, children); | ||
if (node.tagName === 'template') { | ||
node.content = {type: 'root', children: node.children}; | ||
node.children = []; | ||
} | ||
return node; | ||
} | ||
/* Check if `value` is a valid child node of `tagName`. */ | ||
function isNode(tagName, value) { | ||
var type = value.type; | ||
if (typeof type === 'string') { | ||
type = type.toLowerCase(); | ||
} | ||
if (tagName === 'input' || !type || typeof type !== 'string') { | ||
return false; | ||
} | ||
if (typeof value.children === 'object' && 'length' in value.children) { | ||
return true; | ||
} | ||
if (tagName === 'button') { | ||
return type !== 'menu' && | ||
type !== 'submit' && | ||
type !== 'reset' && | ||
type !== 'button'; | ||
} | ||
return 'value' in value; | ||
} | ||
/* Add `value` as a child to `nodes`. */ | ||
function addChild(nodes, value) { | ||
var index; | ||
var length; | ||
if (value === null || value === undefined) { | ||
return; | ||
} | ||
if (typeof value === 'string' || typeof value === 'number') { | ||
value = {type: 'text', value: String(value)}; | ||
} | ||
if (typeof value === 'object' && 'length' in value) { | ||
index = -1; | ||
length = value.length; | ||
while (++index < length) { | ||
addChild(nodes, value[index]); | ||
} | ||
return; | ||
} | ||
if (typeof value !== 'object' || !('type' in value)) { | ||
throw new Error('Expected node, nodes, or string, got `' + value + '`'); | ||
} | ||
nodes.push(value); | ||
} | ||
/* Add `name` and its `value` to `properties`. `properties` can | ||
* be prefilled by `parseSelector`: it can have `id` and `className` | ||
* properties. */ | ||
function addProperty(properties, name, value) { | ||
var info = propertyInformation(name) || {}; | ||
var result = value; | ||
var key; | ||
/* Ignore nully and NaN values. */ | ||
if (value === null || value === undefined || value !== value) { | ||
return; | ||
} | ||
/* Handle values. */ | ||
if (name === 'style') { | ||
/* Accept `object`. */ | ||
if (typeof value !== 'string') { | ||
result = []; | ||
for (key in value) { | ||
result.push([key, value[key]].join(': ')); | ||
} | ||
result = result.join('; '); | ||
} | ||
} else if (info.spaceSeparated) { | ||
/* Accept both `string` and `Array`. */ | ||
result = typeof value === 'string' ? spaces(result) : result; | ||
/* Class-names (which can be added both on | ||
* the `selector` and here). */ | ||
if (name === 'class' && properties.className) { | ||
result = properties.className.concat(result); | ||
} | ||
} else if (info.commaSeparated) { | ||
/* Accept both `string` and `Array`. */ | ||
result = typeof value === 'string' ? commas(result) : result; | ||
} | ||
result = parsePrimitive(info, name, result); | ||
properties[info.propertyName || camelcase(name)] = result; | ||
} | ||
/* Parse a (list of) primitives. */ | ||
function parsePrimitive(info, name, value) { | ||
var result = value; | ||
var index; | ||
var length; | ||
if (typeof value === 'object' && 'length' in value) { | ||
length = value.length; | ||
index = -1; | ||
result = []; | ||
while (++index < length) { | ||
result[index] = parsePrimitive(info, name, value[index]); | ||
} | ||
return result; | ||
} | ||
if (info.numeric || info.positiveNumeric) { | ||
if (!isNaN(result) && result !== '') { | ||
result = Number(result); | ||
} | ||
} else if (info.boolean || info.overloadedBoolean) { | ||
/* Accept `boolean` and `string`. */ | ||
if ( | ||
typeof result === 'string' && | ||
(result === '' || value.toLowerCase() === name) | ||
) { | ||
result = true; | ||
} | ||
} | ||
return result; | ||
} | ||
module.exports = require('./html') |
{ | ||
"name": "hastscript", | ||
"version": "3.1.0", | ||
"version": "4.0.0", | ||
"description": "Hyperscript compatible DSL for creating virtual HAST trees", | ||
@@ -16,3 +16,3 @@ "license": "MIT", | ||
], | ||
"repository": "https://github.com/syntax-tree/hastscript", | ||
"repository": "syntax-tree/hastscript", | ||
"bugs": "https://github.com/syntax-tree/hastscript/issues", | ||
@@ -24,29 +24,31 @@ "author": "Titus Wormer <tituswormer@gmail.com> (http://wooorm.com)", | ||
"files": [ | ||
"index.js" | ||
"index.js", | ||
"factory.js", | ||
"html.js", | ||
"svg.js" | ||
], | ||
"dependencies": { | ||
"camelcase": "^3.0.0", | ||
"comma-separated-tokens": "^1.0.0", | ||
"hast-util-parse-selector": "^2.0.0", | ||
"property-information": "^3.0.0", | ||
"hast-util-parse-selector": "^2.2.0", | ||
"property-information": "^4.0.0", | ||
"space-separated-tokens": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"browserify": "^14.3.0", | ||
"browserify": "^16.0.0", | ||
"esmangle": "^1.0.0", | ||
"nyc": "^11.0.0", | ||
"remark-cli": "^4.0.0", | ||
"remark-preset-wooorm": "^3.0.0", | ||
"nyc": "^12.0.0", | ||
"prettier": "^1.13.5", | ||
"remark-cli": "^5.0.0", | ||
"remark-preset-wooorm": "^4.0.0", | ||
"tape": "^4.0.0", | ||
"xo": "^0.18.0" | ||
"xo": "^0.21.0" | ||
}, | ||
"scripts": { | ||
"build-md": "remark . -qfo", | ||
"format": "remark . -qfo && prettier --write '**/*.js' && xo --fix", | ||
"build-bundle": "browserify index.js --bare -s hastscript > hastscript.js", | ||
"build-mangle": "esmangle hastscript.js > hastscript.min.js", | ||
"build": "npm run build-md && npm run build-bundle && npm run build-mangle", | ||
"lint": "xo", | ||
"build": "npm run build-bundle && npm run build-mangle", | ||
"test-api": "node test", | ||
"test-coverage": "nyc --reporter lcov tape test.js", | ||
"test": "npm run build && npm run lint && npm run test-coverage" | ||
"test": "npm run format && npm run build && npm run test-coverage" | ||
}, | ||
@@ -59,4 +61,12 @@ "nyc": { | ||
}, | ||
"prettier": { | ||
"tabWidth": 2, | ||
"useTabs": false, | ||
"singleQuote": true, | ||
"bracketSpacing": false, | ||
"semi": false, | ||
"trailingComma": "none" | ||
}, | ||
"xo": { | ||
"space": true, | ||
"prettier": true, | ||
"esnext": false, | ||
@@ -63,0 +73,0 @@ "rules": { |
# hastscript [![Build Status][travis-badge]][travis] [![Coverage Status][codecov-badge]][codecov] | ||
[Hyperscript][] (and [`virtual-hyperscript`][virtual-hyperscript]) | ||
compatible DSL for creating virtual [HAST][] trees. | ||
compatible DSL for creating virtual [HAST][] trees in HTML and SVG. | ||
@@ -17,12 +17,22 @@ ## Installation | ||
```javascript | ||
var h = require('hastscript'); | ||
var h = require('hastscript') | ||
var s = require('hastscript/svg') | ||
var tree = h('.foo#some-id', [ | ||
h('span', 'some text'), | ||
h('input', {type: 'text', value: 'foo'}), | ||
h('a.alpha', { | ||
class: 'bravo charlie', | ||
download: 'download' | ||
}, ['delta', 'echo']) | ||
]); | ||
console.log( | ||
h('.foo#some-id', [ | ||
h('span', 'some text'), | ||
h('input', {type: 'text', value: 'foo'}), | ||
h('a.alpha', {class: 'bravo charlie', download: 'download'}, [ | ||
'delta', | ||
'echo' | ||
]) | ||
]) | ||
) | ||
console.log( | ||
s('svg', {xmlns: 'http://www.w3.org/2000/svg', viewbox: '0 0 500 500'}, [ | ||
s('title', 'SVG `<circle>` element'), | ||
s('circle', {cx: 120, cy: 120, r: 100}) | ||
]) | ||
) | ||
``` | ||
@@ -35,3 +45,3 @@ | ||
tagName: 'div', | ||
properties: { id: 'some-id', className: [ 'foo' ] }, | ||
properties: { className: [ 'foo' ], id: 'some-id' }, | ||
children: | ||
@@ -52,2 +62,14 @@ [ { type: 'element', | ||
{ type: 'text', value: 'echo' } ] } ] } | ||
{ type: 'element', | ||
tagName: 'svg', | ||
properties: { xmlns: 'http://www.w3.org/2000/svg', viewBox: '0 0 500 500' }, | ||
children: | ||
[ { type: 'element', | ||
tagName: 'title', | ||
properties: {}, | ||
children: [ { type: 'text', value: 'SVG `<circle>` element' } ] }, | ||
{ type: 'element', | ||
tagName: 'circle', | ||
properties: { cx: 120, cy: 120, r: 100 }, | ||
children: [] } ] } | ||
``` | ||
@@ -59,4 +81,6 @@ | ||
DSL for creating virtual [HAST][] trees. | ||
### `s(selector?[, properties][, children])` | ||
DSL to create virtual [HAST][] trees for HTML or SVG. | ||
##### Parameters | ||
@@ -67,7 +91,9 @@ | ||
Simple CSS selector (`string`, optional). Can contain a tag name (`foo`), IDs | ||
(`#bar`), and classes (`.baz`), defaults to a `div` element. | ||
(`#bar`), and classes (`.baz`). | ||
If there is no tag name in the selector, `h` defaults to a `div` element, | ||
and `s` to a `g` element. | ||
###### `properties` | ||
Map of properties (`Object.<string, *>`, optional). | ||
Map of properties (`Object.<*>`, optional). | ||
@@ -83,2 +109,10 @@ ###### `children` | ||
## Contribute | ||
See [`contributing.md` in `syntax-tree/hast`][contributing] for ways to get | ||
started. | ||
This organisation has a [Code of Conduct][coc]. By interacting with this | ||
repository, organisation, or community you agree to abide by its terms. | ||
## License | ||
@@ -113,1 +147,5 @@ | ||
[text]: https://github.com/syntax-tree/unist#text | ||
[contributing]: https://github.com/syntax-tree/hast/blob/master/contributing.md | ||
[coc]: https://github.com/syntax-tree/hast/blob/master/code-of-conduct.md |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
11442
4
7
166
145
8
1
+ Addedproperty-information@4.2.0(transitive)
+ Addedxtend@4.0.2(transitive)
- Removedcamelcase@^3.0.0
- Removedcamelcase@3.0.0(transitive)
- Removedproperty-information@3.2.0(transitive)
Updatedproperty-information@^4.0.0