-
Notifications
You must be signed in to change notification settings - Fork 1
/
replace-attrs.js
43 lines (37 loc) · 1.27 KB
/
replace-attrs.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
class AttrReplacer {
constructor(parser, tag, attrs) {
this.parser = parser;
this.attrs = attrs;
this.tagWithAttrs = new RegExp(`<${tag}([^>]*)>`, 'g');
this.hasTag = this.nodeHasTag.bind(this);
this.tagWithNewAttrs = this.getTagWithNewAttrs.bind(this);
}
nodeHasTag(path) {
return this.parser(path.node).toSource().match(this.tagWithAttrs);
}
getTagWithNewAttrs(path) {
const source = this.parser(path).toSource();
return this.replaceAttrs(source);
}
replaceAttrs(source) {
return source.replace(this.tagWithAttrs, (m) => {
for (const [from, to] of Object.entries(this.attrs)) {
const attribute = new RegExp(`${from}( *=)`, 'g');
// eslint-disable-next-line no-param-reassign
m = m.replace(attribute, (f) => f.replace(from, to));
}
return m;
});
}
}
export default function transform(file, api, options) {
const j = api.jscodeshift;
const { tag, attrs, tabWidth = 4, useTabs = false } = options;
const tagAttrReplacer = new AttrReplacer(j, tag, attrs);
const { hasTag, tagWithNewAttrs } = tagAttrReplacer;
return j(file.source)
.find(j.TaggedTemplateExpression, { tag: { name: 'html' } })
.filter(hasTag)
.replaceWith(tagWithNewAttrs)
.toSource({ tabWidth, useTabs });
}