adonisjs-ui
Version:
[](https://npmjs.com/package/adonisjs-ui) [](https://npm.chart.dev/adonisjs-ui)
95 lines (94 loc) • 3.83 kB
JavaScript
export class UiTagCompiler {
edge;
constructor(edge) {
this.edge = edge;
}
static make(edge) {
return new UiTagCompiler(edge);
}
compile(value) {
return this.compileTags(value);
}
compileTags(value) {
value = this.compileSelfClosingTags(value);
value = this.compileOpeningTags(value);
value = this.compileClosingTags(value);
return value;
}
compileSelfClosingTags(value) {
const pattern = /<\s*ui:([\w-:.]*)\s*(?<attributes>(?:\s+[:@]?[\w-:.]+(?:=(?:"[^"]*"|'[^']*'|\{\{[^}]*\}\}|[^'"=<>\s]+))?)*)\s*\/>/g;
value = value.replace(pattern, (_match, tagName, attributeString) => {
const attributes = this.getAttributesFromAttributeString(attributeString);
return this.componentString(tagName, attributes) + "\n@end\n";
});
return value;
}
compileOpeningTags(value) {
const pattern = /<\s*ui:([\w-:.]*)\s*(?<attributes>(?:\s+[:@]?[\w-:.]+(?:=(?:"[^"]*"|'[^']*'|\{\{[^}]*\}\}|[^'"=<>\s]+))?)*)\s*>/g;
value = value.replace(pattern, (_match, tagName, attributeString) => {
const attributes = this.getAttributesFromAttributeString(attributeString);
return this.componentString(tagName, attributes) + "\n";
});
return value;
}
compileClosingTags(value) {
return value.replace(/<\/\s*ui:[\w\-:.]*\s*>/g, "\n@end\n");
}
getEdgeComponents() {
return (this.edge.loader
.listComponents()
.find((l) => l.diskName === "ui")
?.components.map((c) => c.componentName) || []);
}
componentString(tagName, attributes = {}) {
const diskName = "ui";
const prefix = `${diskName}::`;
const components = this.getEdgeComponents();
let componentPath = tagName.replace(/\./g, "/");
if (components.includes(prefix + componentPath)) {
componentPath = prefix + tagName.replace(/\./g, "/");
}
else if (components.includes(prefix + `components/${componentPath}`)) {
componentPath = prefix + `components/${componentPath}`;
}
else if (components.includes(prefix + `${componentPath}/index`)) {
componentPath = prefix + `${componentPath}/index`;
}
else if (components.includes(prefix + `components/${componentPath}/index`)) {
componentPath = prefix + `components/${componentPath}/index`;
}
return `\n@component("${componentPath}", { ${this.attributesToString(attributes)} })`;
}
attributesToString(attributes) {
return Object.entries(attributes)
.map(([key, value]) => `"${key}": ${value}`)
.join(", ");
}
getAttributesFromAttributeString(attributeString) {
if (!attributeString)
return {};
const attributes = {};
const attrPattern = /\s([:@]?[\w-:.]+)(?:=(?:"([^"]*)"|'([^']*)'|([^'"=<>\s]+)))?/g;
let attrMatch;
while ((attrMatch = attrPattern.exec(" " + attributeString)) !== null) {
const attrName = attrMatch[1];
if (!attrName)
continue;
const attrValue = attrMatch[2] || attrMatch[3] || attrMatch[4];
const isBound = attrName.startsWith(":");
if (isBound) {
attributes[attrName.slice(1)] = attrValue;
}
else if (attrValue) {
const isCurly = attrValue.match(/(\\)?{{(.*?)}}/);
attributes[attrName] = isCurly
? "`" + attrValue.replace(/{{\s*([^}]+)\s*}}/g, "${$1}") + "`"
: `"${attrValue}"`;
}
else {
attributes[attrName] = `true`;
}
}
return attributes;
}
}