forked from atom/autocomplete-html
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fetch-global-attribute-docs.js
113 lines (98 loc) · 3.52 KB
/
fetch-global-attribute-docs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
const path = require('path')
const fs = require('fs')
const request = require('request')
const mdnHTMLURL = 'https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes'
const mdnJSONAPI = 'https://developer.mozilla.org/en-US/search.json?topic=html&highlight=false'
const AttributesURL = 'https://raw.githubusercontent.com/adobe/brackets/master/src/extensions/default/HTMLCodeHints/HtmlAttributes.json'
const fetch = () => {
const attributesPromise = new Promise((resolve) => {
request({json: true, url: AttributesURL}, (error, response, attributes) => {
if (error) {
console.error(error.message)
resolve(null)
}
if (response.statusCode !== 200) {
console.error(`Request for HtmlAttributes.json failed: ${response.statusCode}`)
resolve(null)
}
resolve(attributes)
})
})
attributesPromise.then((attributes) => {
if (!attributes) return
const MAX = 10
const queue = []
for (let attribute in attributes) {
// MDN is missing docs for aria attributes and on* event handlers
const options = attributes[attribute]
if (options.global && !attribute.startsWith('aria') && !attribute.startsWith('on') && (attribute !== 'role')) {
queue.push(attribute)
}
}
const running = []
const docs = {}
return new Promise((resolve) => {
const checkEnd = () => {
if ((queue.length === 0) && (running.length === 0)) resolve(docs)
}
const removeRunning = (attributeName) => {
const index = running.indexOf(attributeName)
if (index > -1) { running.splice(index, 1) }
}
const runNext = () => {
checkEnd()
if (queue.length !== 0) {
const attributeName = queue.pop()
running.push(attributeName)
run(attributeName)
}
}
var run = (attributeName) => {
const url = `${mdnJSONAPI}&q=${attributeName}`
request({json: true, url}, (error, response, searchResults) => {
if (!error && response.statusCode === 200) {
handleRequest(attributeName, searchResults)
} else {
console.error(`Req failed ${url}; ${response.statusCode}, ${error}`)
}
removeRunning(attributeName)
runNext()
})
}
var handleRequest = (attributeName, searchResults) => {
if (searchResults.documents) {
for (let doc of searchResults.documents) {
if (doc.url === `${mdnHTMLURL}/${attributeName}`) {
docs[attributeName] = filterExcerpt(attributeName, doc.excerpt)
return
}
}
}
console.log(`Could not find documentation for ${attributeName}`)
}
for (let i = 0; i <= MAX; i++) runNext()
})
})
}
var filterExcerpt = (attributeName, excerpt) => {
const beginningPattern = /^the [a-z-]+ global attribute (is )?(\w+)/i
excerpt = excerpt.replace(beginningPattern, (match) => {
const matches = beginningPattern.exec(match)
const firstWord = matches[2]
return firstWord[0].toUpperCase() + firstWord.slice(1)
})
const periodIndex = excerpt.indexOf('.')
if (periodIndex > -1) { excerpt = excerpt.slice(0, periodIndex + 1) }
return excerpt
}
// Save a file if run from the command line
if (require.main === module) {
fetch().then((docs) => {
if (docs) {
fs.writeFileSync(path.join(__dirname, 'global-attribute-docs.json'), `${JSON.stringify(docs, null, ' ')}\n`)
} else {
console.error('No docs')
}
})
}
module.exports = fetch