Skip to content

Commit

Permalink
Upgrade to v1.3.0
Browse files Browse the repository at this point in the history
  • Loading branch information
DenisPower1 committed Oct 16, 2024
1 parent 627f8ae commit 0afdea1
Show file tree
Hide file tree
Showing 7 changed files with 402 additions and 67 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"url": "https://github.com/interjs/inter-intellisense.git"
},
"module": "esnext",
"version": "1.2.1",
"version": "1.3.0",
"engines": {
"vscode": "^1.57.1"
},
Expand Down
43 changes: 43 additions & 0 deletions src/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
export function runUnregisteredConditionalPropError(prop: string): string {

return ` ${prop} is not a registered conditional property. Register it like:
<!--conditional = ${prop}-->
`

}

export function runIllegalValueError(value: string): string {

return `${value} seems to be a reference's name, avoid this please!`

}

export function runHasNoreThanOneConditionalAttrsError(tagName: string | undefined): string {


return ` This ${tagName} tag has more than one conditional attribute, it's forbidden.`

}

export function runInvalidConditionalAttrNameError(attr: string): string {

return ` Attribute ${attr} is invalid here, because it has an empty value, assign a value to it.`

}

export function runInvalidElseValueWarning(value: string): string {

return ` Remove ${value}, _else is not supposed to have a value.`


}

export function runUnregisteredRefName(refName: string): string {

return `${refName} is an unregistered reference's name. Register it like this:
<!--ref = ${refName}-->
`

}
153 changes: 88 additions & 65 deletions src/extension.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import * as vscode from "vscode";
import { commentsParser, parserInfoInterface } from "./htmlcommentsparser";
import { parseHTML } from "./hop/index"
import { runHasNoreThanOneConditionalAttrsError, runIllegalValueError, runInvalidConditionalAttrNameError, runInvalidElseValueWarning, runUnregisteredConditionalPropError, runUnregisteredRefName } from "./errors"

const extensionVersion: string = "1.2.1";
const extensionVersion: string = "1.3.0";
const openTagRegExp = /<(:?[A-Z]+)>/gi;
interface configI {
text: string;

start: number;
end: number;
justWarning?: boolean;
type: registeredT;
errorMessage: string
}

type registeredT = "ref" | "conditional";
Expand All @@ -18,7 +21,7 @@ function getRegistered(
type: registeredT
): parserInfoInterface | undefined {
const registered = new commentsParser().parse(document);


let returnValue;
if (registered[0]?.type == type) returnValue = registered[0];
Expand All @@ -41,19 +44,20 @@ function findUnregisteredRef(
const text = ref.replace("{", "").replace("}", "").trim();
const start = documentContent.indexOf(ref) + 1;
const position = document.positionAt(start);


const refSet = new Set(registered ? registered.content : []);

if (refSet.has(text)) continue;
else if (outOfCompletionArea(document, position)) continue;

const config: configI = {
text: text,

start: start,
end: documentContent.indexOf(ref) + ref.length,
justWarning: true,
type: "ref",
errorMessage: runUnregisteredRefName(text)
};

unregistered.push(config);
Expand All @@ -62,45 +66,93 @@ function findUnregisteredRef(
return unregistered;
}

function findUnregisteredConditionalProps(documentContent: string): configI[] | undefined {
const attrsReg: RegExp =
/_if="(:?\s)*(:?[A-Z]+)(:?\s)*"|_elseIf="(:?\s)*(:?[A-Z]+)(:?\s)*"|_ifNot="(:?\s)*(:?[A-Z]+)(:?\s)*"|_else="(:?\s)*(:?[A-Z]+)(:?\s)*"/gi;
const allAttrs = documentContent.match(attrsReg) || [];
const unregistered = [];
const registered = getRegistered(documentContent, "conditional");

if (!registered) return;

for (const attr of allAttrs) {
let theConditionalAttrsLength: number = 0;
let attrName: string = "";
function generateConditionalConfig(start: number, end: number, error: string, warning?: boolean): configI {

return {
type: "conditional",
start: start,
end: end,
errorMessage: error,
justWarning: warning
}

}

function findErrorInConditionalRendering(documentContent: string): configI[] {

const domLikeObject = parseHTML(documentContent);
const registeredC = getRegistered(documentContent, "conditional")
const conditionalProps = new Set(registeredC ? registeredC.content : []);
const conditionalAttrsNames = new Set(["_if", "_elseIf", "_else", "_ifNot"])
const errorsCollection = []

for (const element of domLikeObject) {

let conditionalAttrsCounter = 0;


if (Array.isArray(element.attrs) && element.attrs.length > 0) {

if (conditionalProps.size == 0) break;

for (const attr of element.attrs) {

const { name, nameStart, nameEnd, value, valueSart, valueEnd } = attr
const { tag, tagStart, tagEnd } = element;
const refReg = /\{(:?\s+)*(:?[A-Z]+)(:?\s+)*\}/gi;

if (conditionalAttrsNames.has(name)) {
conditionalAttrsCounter++;

if (conditionalAttrsCounter > 1) {
errorsCollection.push(
generateConditionalConfig(tagStart, tagEnd, runHasNoreThanOneConditionalAttrsError(tag))
)
break
}
else if (name !== "_else" && refReg.test(value)) {
const refName = value.replace("{", "").replace("}", "").trim();
errorsCollection.push(generateConditionalConfig(valueSart, valueEnd, runIllegalValueError(refName)));
break;

}
else if (name == "_else" && value.trim().length > 0) {
errorsCollection.push(generateConditionalConfig(valueSart, valueEnd, runInvalidElseValueWarning(value), true));
break;
}
else if (name !== "_else" && value.trim().length == 0) {
errorsCollection.push(generateConditionalConfig(nameStart, nameEnd, runInvalidConditionalAttrNameError(name)));
break;
}
else if (!conditionalProps.has(value)) {
errorsCollection.push(generateConditionalConfig(valueSart, valueEnd, runUnregisteredConditionalPropError(value)));
break

}

}



}

}

const text = attr
.replace(/_if="|_elseIf="|_ifNot="|_else="/, (prop) => {
theConditionalAttrsLength = prop.length;
attrName = prop.replace('="', "");

return "";
})
.replace('"', "")
.trim();
const conditionalSet = new Set(registered?.content);
if (conditionalSet.has(text) && attrName !== "_else") continue;

const config: configI = {
text: text,
start: documentContent.indexOf(attr) + theConditionalAttrsLength,
end: documentContent.indexOf(attr) + attr.length,
justWarning: attrName == "_else",
type: "conditional",
};

unregistered.push(config);
}

return unregistered;
return errorsCollection;




}


function getHoveredToken(cursorPosition: number, lineText: string): string {
let body: string = "";

Expand Down Expand Up @@ -183,21 +235,6 @@ function outOfCompletionArea(
return noCompletion;
}

function isConditionalAttr(
document: vscode.TextDocument,
position: vscode.Position
): boolean {
const lineText = document.lineAt(position).text;
const conditionalAttrRegExp = /_if=""|_elseIf=""|_ifNot=""/g;
let result: boolean = false;
const tagWithAttrsRegExp = /<(?:[\s\S]+)>/g;

if (tagWithAttrsRegExp.test(lineText)) {
if (conditionalAttrRegExp.test(lineText)) result = true;
}

return result;
}

function isReferenceSuggestionRequest(
textLine: string,
Expand Down Expand Up @@ -382,24 +419,11 @@ export function activate(context: vscode.ExtensionContext) {
const start = toPosition(prop.start);
const end = toPosition(prop.end);
const diagnosticSeverity = vscode.DiagnosticSeverity;
const notRegisteredPropError = !prop.justWarning
? `
${prop.text} is not a registered conditional property. Register it like:
<!--conditional = ${prop.text}-->
`
: "Nothing is wrong here, but _else does not expect a value!";
const notRegisteredRefWarning = `
${prop.text} is not a registered reference's name. Register it like:
<!--ref = ${prop.text}--->

`;

const diagnostic = new vscode.Diagnostic(
new vscode.Range(start, end),
prop.type == "ref" ? notRegisteredRefWarning : notRegisteredPropError,
prop.errorMessage,
prop.justWarning ? diagnosticSeverity.Warning : diagnosticSeverity.Error
);

Expand All @@ -411,8 +435,7 @@ export function activate(context: vscode.ExtensionContext) {
const documentContent = document.getText();
const toPosition = (offset: number) => document.positionAt(offset);
const diagnostics: vscode.Diagnostic[] = [];
const unregisteredConditional =
findUnregisteredConditionalProps(documentContent);
const unregisteredConditional = findErrorInConditionalRendering(documentContent);
const unregisteredRef = findUnregisteredRef(documentContent, document);

if (unregisteredConditional) runDiagnosticLoop(unregisteredConditional, diagnostics, toPosition);
Expand Down
39 changes: 39 additions & 0 deletions src/hop/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { attrsI, htmlStructureI } from "./types";

export function isACharacter(arg: string): boolean {
return /^[A-z]|\d$/i.test(arg);
}

export function isASpace(arg: string): boolean {
return /^\s$/.test(arg);
}

export function mergeAttr(attribute: attrsI<string>, html: htmlStructureI, attrValue: string): void {

attribute.value = attrValue

html.attrs.push(
Object.assign({}, attribute)
);

attribute.name = "";
attribute.value = "";

}

export function hasProps(obj: Object): boolean {

return Object.keys(obj).length > 0;

}

export function resetElementProps(element: htmlStructureI): void {

element.tag = "";
element.type = null;
element.tagStart = 0;
element.tagEnd = 0;
element.attrs = [];


}
Loading

0 comments on commit 0afdea1

Please sign in to comment.