sortier
Version:
An opinionated code sorter
80 lines (79 loc) • 3.38 kB
JavaScript
import { parse } from "angular-html-parser/lib/angular-html-parser/src/index.js";
import { CssReprinter } from "../../language-css/index.js";
import { JavascriptReprinter } from "../../language-js/index.js";
import { StringUtils } from "../../utilities/string-utils.js";
import { sortAttributes } from "../sortAttributes/index.js";
export class Reprinter {
static EXTENSIONS = [".html", ".html.txt"];
// private options: BaseSortierOptions;
getRewrittenContents(filename, fileContents, options) {
const ast = parse(fileContents, { canSelfClose: true });
if (ast.errors.length > 0) {
throw new Error(ast.errors[0].msg);
}
return this.sortNode(options, {
children: ast.rootNodes,
}, fileContents);
}
isFileSupported(filename) {
return StringUtils.stringEndsWithAny(filename, Reprinter.EXTENSIONS);
}
sortNode(options, node, fileContents) {
fileContents = sortAttributes(node, fileContents);
if (node.children != null) {
for (const child of node.children) {
fileContents = this.sortNode(options, child, fileContents);
}
}
if (node.name === "style") {
fileContents = this.sortStyleTagContents(options, node, fileContents);
}
if (node.name === "script") {
fileContents = this.sortScriptTagContents(options, node, fileContents);
}
return fileContents;
}
sortStyleTagContents(options, node, fileContents) {
const isCssType = this.cantFindOrMatchesAttributeKeyValue(node, "type", ["text/css"]);
if (!isCssType) {
return fileContents;
}
for (let x = 0; x < node.children.length; x++) {
const child = node.children[x];
fileContents = this.sortSubstring(fileContents, child.sourceSpan.start.offset, child.sourceSpan.end.offset, (text) => new CssReprinter().getRewrittenContents("example.css", text, options));
}
return fileContents;
}
sortScriptTagContents(options, node, fileContents) {
const isJavascriptType = this.cantFindOrMatchesAttributeKeyValue(node, "type", [
"text/javascript",
"application/javascript",
]);
if (!isJavascriptType) {
return fileContents;
}
for (let x = 0; x < node.children.length; x++) {
const child = node.children[x];
fileContents = this.sortSubstring(fileContents, child.sourceSpan.start.offset, child.sourceSpan.end.offset, (text) => new JavascriptReprinter().getRewrittenContents("example.js", text, options));
}
return fileContents;
}
cantFindOrMatchesAttributeKeyValue(node, key, value) {
const typeAttrs = node.attrs.filter((attr) => {
return attr.name === key;
});
if (typeAttrs.length !== 0) {
return value.indexOf(typeAttrs[0].value) !== -1;
}
else {
return true;
}
}
sortSubstring(fileContents, start, end, sortFunc) {
const textBefore = fileContents.substring(0, start);
const textToSort = fileContents.substring(start, end);
const textAfter = fileContents.substring(end);
const newContents = sortFunc(textToSort);
return textBefore + newContents + textAfter;
}
}