This commit is contained in:
212
node_modules/hastscript/factory.js
generated
vendored
Normal file
212
node_modules/hastscript/factory.js
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
'use strict'
|
||||
|
||||
var find = require('property-information/find')
|
||||
var normalize = require('property-information/normalize')
|
||||
var parseSelector = require('hast-util-parse-selector')
|
||||
var spaces = require('space-separated-tokens').parse
|
||||
var commas = require('comma-separated-tokens').parse
|
||||
|
||||
module.exports = factory
|
||||
|
||||
var own = {}.hasOwnProperty
|
||||
|
||||
function factory(schema, defaultTagName, caseSensitive) {
|
||||
var adjust = caseSensitive ? createAdjustMap(caseSensitive) : null
|
||||
|
||||
return h
|
||||
|
||||
// Hyperscript compatible DSL for creating virtual hast trees.
|
||||
function h(selector, properties) {
|
||||
var node = parseSelector(selector, defaultTagName)
|
||||
var children = Array.prototype.slice.call(arguments, 2)
|
||||
var name = node.tagName.toLowerCase()
|
||||
var property
|
||||
|
||||
node.tagName = adjust && own.call(adjust, name) ? adjust[name] : name
|
||||
|
||||
if (properties && isChildren(properties, node)) {
|
||||
children.unshift(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
|
||||
}
|
||||
|
||||
function addProperty(properties, key, value) {
|
||||
var info
|
||||
var property
|
||||
var result
|
||||
|
||||
// Ignore nully and NaN values.
|
||||
if (value === null || value === undefined || value !== value) {
|
||||
return
|
||||
}
|
||||
|
||||
info = find(schema, key)
|
||||
property = info.property
|
||||
result = value
|
||||
|
||||
// Handle list values.
|
||||
if (typeof result === 'string') {
|
||||
if (info.spaceSeparated) {
|
||||
result = spaces(result)
|
||||
} else if (info.commaSeparated) {
|
||||
result = commas(result)
|
||||
} else if (info.commaOrSpaceSeparated) {
|
||||
result = spaces(commas(result).join(' '))
|
||||
}
|
||||
}
|
||||
|
||||
// Accept `object` on style.
|
||||
if (property === 'style' && typeof value !== 'string') {
|
||||
result = style(result)
|
||||
}
|
||||
|
||||
// Class-names (which can be added both on the `selector` and here).
|
||||
if (property === 'className' && properties.className) {
|
||||
result = properties.className.concat(result)
|
||||
}
|
||||
|
||||
properties[property] = parsePrimitives(info, property, result)
|
||||
}
|
||||
}
|
||||
|
||||
function isChildren(value, node) {
|
||||
return (
|
||||
typeof value === 'string' ||
|
||||
'length' in value ||
|
||||
isNode(node.tagName, value)
|
||||
)
|
||||
}
|
||||
|
||||
function isNode(tagName, value) {
|
||||
var type = value.type
|
||||
|
||||
if (tagName === 'input' || !type || typeof type !== 'string') {
|
||||
return false
|
||||
}
|
||||
|
||||
if (typeof value.children === 'object' && 'length' in value.children) {
|
||||
return true
|
||||
}
|
||||
|
||||
type = type.toLowerCase()
|
||||
|
||||
if (tagName === 'button') {
|
||||
return (
|
||||
type !== 'menu' &&
|
||||
type !== 'submit' &&
|
||||
type !== 'reset' &&
|
||||
type !== 'button'
|
||||
)
|
||||
}
|
||||
|
||||
return 'value' in value
|
||||
}
|
||||
|
||||
function addChild(nodes, value) {
|
||||
var index
|
||||
var length
|
||||
|
||||
if (typeof value === 'string' || typeof value === 'number') {
|
||||
nodes.push({type: 'text', value: String(value)})
|
||||
return
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// Parse a (list of) primitives.
|
||||
function parsePrimitives(info, name, value) {
|
||||
var index
|
||||
var length
|
||||
var result
|
||||
|
||||
if (typeof value !== 'object' || !('length' in value)) {
|
||||
return parsePrimitive(info, name, value)
|
||||
}
|
||||
|
||||
length = value.length
|
||||
index = -1
|
||||
result = []
|
||||
|
||||
while (++index < length) {
|
||||
result[index] = parsePrimitive(info, name, value[index])
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Parse a single primitives.
|
||||
function parsePrimitive(info, name, value) {
|
||||
var result = value
|
||||
|
||||
if (info.number || info.positiveNumber) {
|
||||
if (!isNaN(result) && result !== '') {
|
||||
result = Number(result)
|
||||
}
|
||||
} else if (info.boolean || info.overloadedBoolean) {
|
||||
// Accept `boolean` and `string`.
|
||||
if (
|
||||
typeof result === 'string' &&
|
||||
(result === '' || normalize(value) === normalize(name))
|
||||
) {
|
||||
result = true
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
function style(value) {
|
||||
var result = []
|
||||
var key
|
||||
|
||||
for (key in value) {
|
||||
result.push([key, value[key]].join(': '))
|
||||
}
|
||||
|
||||
return result.join('; ')
|
||||
}
|
||||
|
||||
function createAdjustMap(values) {
|
||||
var length = values.length
|
||||
var index = -1
|
||||
var result = {}
|
||||
var value
|
||||
|
||||
while (++index < length) {
|
||||
value = values[index]
|
||||
result[value.toLowerCase()] = value
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user