-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path0591-tag-validator.js
More file actions
92 lines (86 loc) · 2.49 KB
/
0591-tag-validator.js
File metadata and controls
92 lines (86 loc) · 2.49 KB
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
/**
* Tag Validator
* Time Complexity: O(N)
* Space Complexity: O(N)
*/
var isValid = function (snippetContent) {
const tagRepository = [];
let currentReadPosition = 0;
const contentLength = snippetContent.length;
while (currentReadPosition < contentLength) {
const isOutsideAnyTag =
currentReadPosition > 0 && tagRepository.length === 0;
if (isOutsideAnyTag) {
return false;
}
const cdataStartSequence = "<![CDATA[";
if (snippetContent.startsWith(cdataStartSequence, currentReadPosition)) {
if (tagRepository.length === 0) {
return false;
}
const cdataContentStartIndex =
currentReadPosition + cdataStartSequence.length;
const cdataEndSequenceIndex = snippetContent.indexOf(
"]]>",
cdataContentStartIndex,
);
if (cdataEndSequenceIndex === -1) {
return false;
}
currentReadPosition = cdataEndSequenceIndex + 3;
continue;
}
const closingTagStartSequence = "</";
if (
snippetContent.startsWith(closingTagStartSequence, currentReadPosition)
) {
const tagNameIdentifierStart =
currentReadPosition + closingTagStartSequence.length;
const tagNameIdentifierEnd = snippetContent.indexOf(
">",
tagNameIdentifierStart,
);
if (tagNameIdentifierEnd === -1) {
return false;
}
const extractedTagString = snippetContent.slice(
tagNameIdentifierStart,
tagNameIdentifierEnd,
);
if (!/^[A-Z]{1,9}$/.test(extractedTagString)) {
return false;
}
if (
tagRepository.length === 0 ||
tagRepository.pop() !== extractedTagString
) {
return false;
}
currentReadPosition = tagNameIdentifierEnd + 1;
continue;
}
const openingTagCharacter = "<";
if (snippetContent[currentReadPosition] === openingTagCharacter) {
const tagContentStart = currentReadPosition + 1;
const tagContentEnd = snippetContent.indexOf(">", tagContentStart);
if (tagContentEnd === -1) {
return false;
}
const tagTextContent = snippetContent.slice(
tagContentStart,
tagContentEnd,
);
if (!/^[A-Z]{1,9}$/.test(tagTextContent)) {
return false;
}
tagRepository.push(tagTextContent);
currentReadPosition = tagContentEnd + 1;
continue;
}
if (tagRepository.length === 0) {
return false;
}
currentReadPosition++;
}
return tagRepository.length === 0;
};