mirror of
https://github.com/Funkoala14/knowledgebase_law.git
synced 2025-06-08 20:48:15 +08:00
213 lines
4.6 KiB
JavaScript
213 lines
4.6 KiB
JavaScript
|
'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 nullish 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
|
||
|
}
|