Skip to content

Commit 095df24

Browse files
committed
.
0 parents  commit 095df24

10 files changed

+571
-0
lines changed

Diff for: .editorconfig

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 2
6+
end_of_line = lf
7+
charset = utf-8
8+
trim_trailing_whitespace = true
9+
insert_final_newline = true

Diff for: .gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
*.log
3+
.nyc_output/
4+
coverage/
5+
node_modules/
6+
yarn.lock

Diff for: .npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package-lock=false

Diff for: .prettierignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.DS_Store
2+
*.log
3+
.nyc_output/
4+
coverage/
5+
node_modules/
6+
yarn.lock

Diff for: .travis.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
language: node_js
2+
node_js:
3+
- lts/dubnium
4+
- node
5+
after_script: bash <(curl -s https://codecov.io/bash)

Diff for: index.js

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
'use strict'
2+
3+
module.exports = fromSelector
4+
5+
var h = require('hastscript')
6+
var s = require('hastscript/svg')
7+
var zwitch = require('zwitch')
8+
var Parser = require('css-selector-parser').CssSelectorParser
9+
10+
var compile = zwitch('type')
11+
var handlers = compile.handlers
12+
13+
handlers.selectors = selectors
14+
handlers.ruleSet = ruleSet
15+
handlers.rule = rule
16+
17+
var parser = new Parser()
18+
19+
parser.registerNestingOperators('>', '+', '~')
20+
// Register these so we can throw nicer errors.
21+
parser.registerAttrEqualityMods('~', '|', '^', '$', '*')
22+
23+
function fromSelector(selector, space) {
24+
var opts = (typeof space === 'string' ? {space: space} : space) || {}
25+
var result = parser.parse(selector || '')
26+
var config = {space: opts.space || 'html', root: true}
27+
28+
return compile(result, config) || build(config.space)()
29+
}
30+
31+
function selectors() {
32+
throw new Error('Cannot handle selector list')
33+
}
34+
35+
function ruleSet(query, config) {
36+
return compile(query.rule, config)
37+
}
38+
39+
function rule(query, config) {
40+
var subrule = query.rule
41+
var name = query.tagName
42+
var parentSpace = config.space
43+
var space = parentSpace
44+
var sibling = false
45+
var operator
46+
var node
47+
48+
if (name === '*') {
49+
name = ''
50+
}
51+
52+
if (subrule) {
53+
operator = subrule.nestingOperator
54+
sibling = operator === '+' || operator === '~'
55+
56+
if (sibling && config.root) {
57+
throw new Error(
58+
'Cannot handle sibling combinator `' + operator + '` at root'
59+
)
60+
}
61+
}
62+
63+
// Switch to SVG when needed.
64+
if (space === 'html' && name === 'svg') {
65+
space = 'svg'
66+
}
67+
68+
node = build(space)(
69+
name,
70+
Object.assign(
71+
{id: query.id, className: query.classNames},
72+
pseudosToHast(query.pseudos || []),
73+
attrsToHast(query.attrs || [])
74+
),
75+
!subrule || sibling ? [] : compile(subrule, {space: space})
76+
)
77+
78+
return sibling ? [node, compile(subrule, {space: parentSpace})] : node
79+
}
80+
81+
function pseudosToHast(pseudos) {
82+
var props = {}
83+
var length = pseudos.length
84+
var index = -1
85+
var pseudo
86+
var name
87+
88+
while (++index < length) {
89+
pseudo = pseudos[index]
90+
name = pseudo.name
91+
92+
if (name) {
93+
throw new Error('Cannot handle pseudo-selector `' + name + '`')
94+
} else {
95+
throw new Error('Cannot handle pseudo-element or empty pseudo-class')
96+
}
97+
}
98+
99+
return props
100+
}
101+
102+
function attrsToHast(attrs) {
103+
var props = {}
104+
var length = attrs.length
105+
var index = -1
106+
var attr
107+
var name
108+
var operator
109+
110+
while (++index < length) {
111+
attr = attrs[index]
112+
name = attr.name
113+
operator = attr.operator
114+
115+
if (operator) {
116+
if (operator === '=') {
117+
props[name] = attr.value
118+
} else {
119+
throw new Error(
120+
'Cannot handle attribute equality modifier `' + operator + '`'
121+
)
122+
}
123+
} else {
124+
props[name] = true
125+
}
126+
}
127+
128+
return props
129+
}
130+
131+
function build(space) {
132+
return space === 'html' ? h : s
133+
}

Diff for: license

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
(The MIT License)
2+
3+
Copyright (c) 2019 Titus Wormer <tituswormer@gmail.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining
6+
a copy of this software and associated documentation files (the
7+
'Software'), to deal in the Software without restriction, including
8+
without limitation the rights to use, copy, modify, merge, publish,
9+
distribute, sublicense, and/or sell copies of the Software, and to
10+
permit persons to whom the Software is furnished to do so, subject to
11+
the following conditions:
12+
13+
The above copyright notice and this permission notice shall be
14+
included in all copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Diff for: package.json

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
{
2+
"name": "hast-util-from-selector",
3+
"version": "0.0.0",
4+
"description": "hast utility to parse CSS selectors to hast nodes",
5+
"license": "MIT",
6+
"keywords": [
7+
"hast",
8+
"rehype",
9+
"selector",
10+
"parse",
11+
"css",
12+
"hyperscript",
13+
"html",
14+
"svg"
15+
],
16+
"repository": "syntax-tree/hast-util-from-selector",
17+
"bugs": "https://github.com/syntax-tree/hast-util-from-selector/issues",
18+
"funding": {
19+
"type": "opencollective",
20+
"url": "https://opencollective.com/unified"
21+
},
22+
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)",
23+
"contributors": [
24+
"Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
25+
],
26+
"files": [
27+
"index.js"
28+
],
29+
"dependencies": {
30+
"css-selector-parser": "^1.3.0",
31+
"hastscript": "^5.0.0",
32+
"zwitch": "^1.0.4"
33+
},
34+
"devDependencies": {
35+
"nyc": "^14.0.0",
36+
"prettier": "^1.0.0",
37+
"remark-cli": "^7.0.0",
38+
"remark-preset-wooorm": "^6.0.0",
39+
"tape": "^4.0.0",
40+
"unist-builder": "^2.0.0",
41+
"xo": "^0.25.0"
42+
},
43+
"scripts": {
44+
"format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix",
45+
"test-api": "node test",
46+
"test-coverage": "nyc --reporter lcov tape test.js",
47+
"test": "npm run format && npm run test-coverage"
48+
},
49+
"prettier": {
50+
"tabWidth": 2,
51+
"useTabs": false,
52+
"singleQuote": true,
53+
"bracketSpacing": false,
54+
"semi": false,
55+
"trailingComma": "none"
56+
},
57+
"xo": {
58+
"prettier": true,
59+
"esnext": false,
60+
"rules": {
61+
"unicorn/prefer-includes": "off"
62+
}
63+
},
64+
"nyc": {
65+
"check-coverage": true,
66+
"lines": 100,
67+
"functions": 100,
68+
"branches": 100
69+
},
70+
"remarkConfig": {
71+
"plugins": [
72+
"preset-wooorm"
73+
]
74+
}
75+
}

0 commit comments

Comments
 (0)