Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Nov 1, 2021
1 parent 1a58aea commit 41e0502
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 104 deletions.
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.DS_Store
*.d.ts
*.log
coverage/
node_modules/
*.d.ts
*.log
.DS_Store
yarn.lock
164 changes: 75 additions & 89 deletions build.js
Original file line number Diff line number Diff line change
@@ -1,108 +1,94 @@
import fs from 'node:fs'
import https from 'node:https'
import concat from 'concat-stream'
import concatStream from 'concat-stream'
import {bail} from 'bail'
import {unified} from 'unified'
import html from 'rehype-parse'
import rehypeParse from 'rehype-parse'
import {selectAll} from 'hast-util-select'
import {toString} from 'hast-util-to-string'
import {htmlElementAttributes} from './index.js'

const processor = unified().use(html)
const own = {}.hasOwnProperty

// Global attributes.
let globals = htmlElementAttributes['*']
const processor = unified().use(rehypeParse)

if (!globals) {
globals = []
htmlElementAttributes['*'] = globals
if (!('*' in htmlElementAttributes)) {
htmlElementAttributes['*'] = []
}

// Global attributes.
const globals = htmlElementAttributes['*']

// Crawl WHATWG HTML.
https.get('https://html.spec.whatwg.org/multipage/indices.html', onhtml)

/**
* @param {import('http').IncomingMessage} response
*/
function onhtml(response) {
response.pipe(concat(onconcat)).on('error', bail)

/**
* @param {Buffer} buf
*/
function onconcat(buf) {
const nodes = selectAll('#attributes-1 tbody tr', processor.parse(buf))
let index = -1
const result = {}
/** @type {string} */
let key
/** @type {string} */
let name
/** @type {string} */
let value
/** @type {string[]} */
let elements
/** @type {string} */
let tagName
/** @type {string[]} */
let attributes
/** @type {number} */
let offset

// Throw if we didn’t match, e.g., when the spec updates.
if (nodes.length === 0) {
throw new Error('Missing results in html')
}

while (++index < nodes.length) {
name = toString(nodes[index].children[0]).trim()
value = toString(nodes[index].children[1]).trim()

if (/custom elements/i.test(value)) {
continue
}

offset = -1
elements = /HTML elements/.test(value)
? ['*']
: value.split(/;/g).map((d) => d.replace(/\([^)]+\)/g, '').trim())

while (++offset < elements.length) {
tagName = elements[offset].toLowerCase().trim()
attributes =
htmlElementAttributes[tagName] ||
(htmlElementAttributes[tagName] = [])

if (!attributes.includes(name)) {
attributes.push(name)
https.get('https://html.spec.whatwg.org/multipage/indices.html', (response) => {
response
.pipe(
concatStream((buf) => {
const nodes = selectAll('#attributes-1 tbody tr', processor.parse(buf))
const result = {}
let index = -1

// Throw if we didn’t match, e.g., when the spec updates.
if (nodes.length === 0) {
throw new Error('Missing results in html')
}

while (++index < nodes.length) {
const name = toString(nodes[index].children[0]).trim()
const value = toString(nodes[index].children[1]).trim()

if (/custom elements/i.test(value)) {
continue
}

const elements = /HTML elements/.test(value)
? ['*']
: value.split(/;/g).map((d) => d.replace(/\([^)]+\)/g, '').trim())
let offset = -1

while (++offset < elements.length) {
const tagName = elements[offset].toLowerCase().trim()

if (!own.call(htmlElementAttributes, tagName)) {
htmlElementAttributes[tagName] = []
}

/** @type {string[]} */
const attributes = htmlElementAttributes[tagName]

if (!attributes.includes(name)) {
attributes.push(name)
}
}
}
}
}

const keys = Object.keys(htmlElementAttributes).sort()
index = -1
const keys = Object.keys(htmlElementAttributes).sort()
index = -1

while (++index < keys.length) {
const key = keys[index]

while (++index < keys.length) {
key = keys[index]
htmlElementAttributes[key].sort()
htmlElementAttributes[key].sort()

if (key !== '*') {
htmlElementAttributes[key] = htmlElementAttributes[key].filter(
(/** @type {string} */ d) => !globals.includes(d)
if (key !== '*') {
htmlElementAttributes[key] = htmlElementAttributes[key].filter(
(/** @type {string} */ d) => !globals.includes(d)
)
}

if (htmlElementAttributes[key].length > 0) {
result[key] = htmlElementAttributes[key]
}
}

fs.writeFile(
'index.js',
'export const htmlElementAttributes = ' +
JSON.stringify(result, null, 2) +
'\n',
bail
)
}

if (htmlElementAttributes[key].length > 0) {
result[key] = htmlElementAttributes[key]
}
}

fs.writeFile(
'index.js',
'export const htmlElementAttributes = ' +
JSON.stringify(result, null, 2) +
'\n',
bail
})
)
}
}
.on('error', bail)
})
16 changes: 4 additions & 12 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,15 @@ test('htmlElementAttributes', function (t) {
t.doesNotThrow(function () {
/** @type {string} */
let key
/** @type {string[]} */
let props
/** @type {number} */
let index
/** @type {string} */
let prop
/** @type {string} */
let label

for (key in htmlElementAttributes) {
if (own.call(htmlElementAttributes, key)) {
props = htmlElementAttributes[key]
index = -1
const props = htmlElementAttributes[key]
let index = -1

while (++index < props.length) {
prop = props[index]
label = prop + ' in ' + key
const prop = props[index]
const label = prop + ' in ' + key

assert.strictEqual(typeof prop, 'string', label + ' should be string')
assert.strictEqual(
Expand Down

0 comments on commit 41e0502

Please sign in to comment.