Skip to content

Commit dc80fc5

Browse files
authored
Add support for passing unadjusted tag names
See: * <https://html.spec.whatwg.org/multipage/parsing.html#tag-name-state> The HTML tokenizer consumes ASCII upper alpha as lower alpha * <https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign> SVG in HTML is therefore first lowercased, and afterwards has to be adjusted * <https://github.com/syntax-tree/hast#element> The hast spec already described the local name must be used on elements Closes GH-11. Closes GH-12.
1 parent 73963b1 commit dc80fc5

File tree

6 files changed

+126
-4
lines changed

6 files changed

+126
-4
lines changed

build.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
'use strict'
2+
3+
var fs = require('fs')
4+
var tagNames = require('svg-tag-names')
5+
6+
var casing = tagNames.filter(function(d) {
7+
return d !== d.toLowerCase()
8+
})
9+
10+
var doc = JSON.stringify(casing, null, 2) + '\n'
11+
12+
fs.writeFileSync('./svg-case-sensitive-tag-names.json', doc)

factory.js

+22-1
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,22 @@ var commas = require('comma-separated-tokens').parse
88

99
module.exports = factory
1010

11-
function factory(schema, defaultTagName) {
11+
var own = {}.hasOwnProperty
12+
13+
function factory(schema, defaultTagName, caseSensitive) {
14+
var adjust = caseSensitive ? createAdjustMap(caseSensitive) : null
15+
1216
return h
1317

1418
// Hyperscript compatible DSL for creating virtual hast trees.
1519
function h(selector, properties) {
1620
var node = parseSelector(selector, defaultTagName)
1721
var children = Array.prototype.slice.call(arguments, 2)
22+
var name = node.tagName.toLowerCase()
1823
var property
1924

25+
node.tagName = adjust && own.call(adjust, name) ? adjust[name] : name
26+
2027
if (properties && isChildren(properties, node)) {
2128
children.unshift(properties)
2229
properties = null
@@ -189,3 +196,17 @@ function style(value) {
189196

190197
return result.join('; ')
191198
}
199+
200+
function createAdjustMap(values) {
201+
var length = values.length
202+
var index = -1
203+
var result = {}
204+
var value
205+
206+
while (++index < length) {
207+
value = values[index]
208+
result[value.toLowerCase()] = value
209+
}
210+
211+
return result
212+
}

package.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
"index.js",
2424
"factory.js",
2525
"html.js",
26-
"svg.js"
26+
"svg.js",
27+
"svg-case-sensitive-tag-names.json"
2728
],
2829
"dependencies": {
2930
"comma-separated-tokens": "^1.0.0",
@@ -37,18 +38,20 @@
3738
"prettier": "^1.0.0",
3839
"remark-cli": "^6.0.0",
3940
"remark-preset-wooorm": "^5.0.0",
41+
"svg-tag-names": "^2.0.0",
4042
"tape": "^4.0.0",
4143
"tinyify": "^2.0.0",
4244
"xo": "^0.24.0"
4345
},
4446
"scripts": {
47+
"generate": "node build",
4548
"format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix",
4649
"build-bundle": "browserify . -s hastscript > hastscript.js",
4750
"build-mangle": "browserify . -s hastscript -p tinyify > hastscript.min.js",
4851
"build": "npm run build-bundle && npm run build-mangle",
4952
"test-api": "node test",
5053
"test-coverage": "nyc --reporter lcov tape test.js",
51-
"test": "npm run format && npm run build && npm run test-coverage"
54+
"test": "npm run generate && npm run format && npm run build && npm run test-coverage"
5255
},
5356
"nyc": {
5457
"check-coverage": true,

svg-case-sensitive-tag-names.json

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
[
2+
"altGlyph",
3+
"altGlyphDef",
4+
"altGlyphItem",
5+
"animateColor",
6+
"animateMotion",
7+
"animateTransform",
8+
"clipPath",
9+
"feBlend",
10+
"feColorMatrix",
11+
"feComponentTransfer",
12+
"feComposite",
13+
"feConvolveMatrix",
14+
"feDiffuseLighting",
15+
"feDisplacementMap",
16+
"feDistantLight",
17+
"feDropShadow",
18+
"feFlood",
19+
"feFuncA",
20+
"feFuncB",
21+
"feFuncG",
22+
"feFuncR",
23+
"feGaussianBlur",
24+
"feImage",
25+
"feMerge",
26+
"feMergeNode",
27+
"feMorphology",
28+
"feOffset",
29+
"fePointLight",
30+
"feSpecularLighting",
31+
"feSpotLight",
32+
"feTile",
33+
"feTurbulence",
34+
"foreignObject",
35+
"glyphRef",
36+
"linearGradient",
37+
"radialGradient",
38+
"solidColor",
39+
"textArea",
40+
"textPath"
41+
]

svg.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use strict'
22

33
var schema = require('property-information/svg')
4+
var caseSensitive = require('./svg-case-sensitive-tag-names.json')
45
var factory = require('./factory')
56

6-
var svg = factory(schema, 'g')
7+
var svg = factory(schema, 'g', caseSensitive)
78
svg.displayName = 'svg'
89

910
module.exports = svg

test.js

+44
Original file line numberDiff line numberDiff line change
@@ -1121,5 +1121,49 @@ test('hastscript', function(t) {
11211121
st.end()
11221122
})
11231123

1124+
t.test('tag names', function(st) {
1125+
st.deepEqual(
1126+
h(null, [h('DIV'), h('dIv'), h('div')]),
1127+
{
1128+
type: 'element',
1129+
tagName: 'div',
1130+
properties: {},
1131+
children: [
1132+
{type: 'element', tagName: 'div', properties: {}, children: []},
1133+
{type: 'element', tagName: 'div', properties: {}, children: []},
1134+
{type: 'element', tagName: 'div', properties: {}, children: []}
1135+
]
1136+
},
1137+
'should create lowercase tag names'
1138+
)
1139+
1140+
st.deepEqual(
1141+
s(null, [
1142+
s('RECT'),
1143+
s('rEcT'),
1144+
s('rect'),
1145+
s('feFuncA'),
1146+
s('FEFUNCA'),
1147+
s('fefunca')
1148+
]),
1149+
{
1150+
type: 'element',
1151+
tagName: 'g',
1152+
properties: {},
1153+
children: [
1154+
{type: 'element', tagName: 'rect', properties: {}, children: []},
1155+
{type: 'element', tagName: 'rect', properties: {}, children: []},
1156+
{type: 'element', tagName: 'rect', properties: {}, children: []},
1157+
{type: 'element', tagName: 'feFuncA', properties: {}, children: []},
1158+
{type: 'element', tagName: 'feFuncA', properties: {}, children: []},
1159+
{type: 'element', tagName: 'feFuncA', properties: {}, children: []}
1160+
]
1161+
},
1162+
'should create lowercase SVG tag names, and fix certain cases'
1163+
)
1164+
1165+
st.end()
1166+
})
1167+
11241168
t.end()
11251169
})

0 commit comments

Comments
 (0)