Premier commit déjà bien avancé

This commit is contained in:
2025-11-10 18:33:24 +01:00
commit db4f0508cb
652 changed files with 440521 additions and 0 deletions

69
frontend/node_modules/@lezer/html/test/mixed.txt generated vendored Normal file
View File

@ -0,0 +1,69 @@
# Doesn't parse VB as JS
<script type="text/visualbasic">let something = 20</script>
==>
Document(Element(OpenTag(StartTag,TagName,Attribute(AttributeName,Is,AttributeValue),EndTag),
ScriptText,
CloseTag(StartCloseTag,TagName,EndTag)))
# Does parse type-less script tags as JS
<script>/foo/</script>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Script(ExpressionStatement(RegExp)),
CloseTag(StartCloseTag,TagName,EndTag)))
# Still doesn't end script tags on closing tags
<script type=something></foo></script>
==>
Document(Element(OpenTag(StartTag,TagName,Attribute(AttributeName,Is,UnquotedAttributeValue),EndTag),
ScriptText,
CloseTag(StartCloseTag,TagName,EndTag)))
# Missing end tag
<html><script>null
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),
Script(ExpressionStatement(null)))))
# JS with script type
<script type="text/javascript">console.log(2)</script>
==>
Document(Element(OpenTag(StartTag,TagName,Attribute(AttributeName,Is,AttributeValue),EndTag),
Script(...),
CloseTag(StartCloseTag,TagName,EndTag)))
# JS with unquoted script type
<script type=module>console.log(2)</script>
==>
Document(Element(OpenTag(StartTag,TagName,Attribute(AttributeName,Is,UnquotedAttributeValue),EndTag),
Script(...),
CloseTag(StartCloseTag,TagName,EndTag)))
# Error in JS
<script>a b</script>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Script(...),
CloseTag(StartCloseTag,TagName,EndTag)))

370
frontend/node_modules/@lezer/html/test/tags.txt generated vendored Normal file
View File

@ -0,0 +1,370 @@
# Regular tag
<foo>bar</foo>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),Text,CloseTag(StartCloseTag,TagName,EndTag)))
# Nested tag
<a><b>c</b><br></a>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),Text,CloseTag(StartCloseTag,TagName,EndTag)),
Element(SelfClosingTag(StartTag,TagName,EndTag)),
CloseTag(StartCloseTag,TagName,EndTag)))
# Attribute
<br foo="bar">
==>
Document(Element(SelfClosingTag(StartTag,TagName,Attribute(AttributeName,Is,AttributeValue),EndTag)))
# Multiple attributes
<a x="one" y="two" z="three"></a>
==>
Document(Element(OpenTag(StartTag,TagName,
Attribute(AttributeName,Is,AttributeValue),
Attribute(AttributeName,Is,AttributeValue),
Attribute(AttributeName,Is,AttributeValue),EndTag),
CloseTag(StartCloseTag,TagName,EndTag)))
# Value-less attributes
<a x y="one" z></a>
==>
Document(Element(OpenTag(StartTag,TagName,
Attribute(AttributeName),
Attribute(AttributeName,Is,AttributeValue),
Attribute(AttributeName),EndTag),
CloseTag(StartCloseTag,TagName,EndTag)))
# Unquoted attributes
<a x=one y z=two></a>
==>
Document(Element(OpenTag(StartTag,TagName,
Attribute(AttributeName,Is,UnquotedAttributeValue),
Attribute(AttributeName),
Attribute(AttributeName,Is,UnquotedAttributeValue),EndTag),
CloseTag(StartCloseTag,TagName,EndTag)))
# Unquoted attributes with slashes
<link as=font crossorigin=anonymous href=/fonts/google-sans/regular/latin.woff2 rel=preload>
==>
Document(Element(SelfClosingTag(StartTag,TagName,
Attribute(AttributeName,Is,UnquotedAttributeValue),
Attribute(AttributeName,Is,UnquotedAttributeValue),
Attribute(AttributeName,Is,UnquotedAttributeValue),
Attribute(AttributeName,Is,UnquotedAttributeValue),
EndTag)))
# Single-quoted attributes
<link x='one' z='two&amp;'>
==>
Document(Element(SelfClosingTag(StartTag, TagName,
Attribute(AttributeName, Is, AttributeValue),
Attribute(AttributeName, Is, AttributeValue(EntityReference)),
EndTag)))
# Entities
<a attr="one&amp;two">&amp;&#67;</a>
==>
Document(Element(OpenTag(StartTag,TagName,
Attribute(AttributeName,Is,AttributeValue(EntityReference)),EndTag),
EntityReference,CharacterReference,
CloseTag(StartCloseTag,TagName,EndTag)))
# Doctype
<!doctype html>
<doc></doc>
==>
Document(DoctypeDecl,Text,Element(OpenTag(StartTag,TagName,EndTag),CloseTag(StartCloseTag,TagName,EndTag)))
# Processing instructions
<?foo?><bar><?baz?></bar>
==>
Document(ProcessingInst,Element(OpenTag(StartTag,TagName,EndTag),ProcessingInst,CloseTag(StartCloseTag,TagName,EndTag)))
# Comments
<!-- top comment -->
<element><!-- inner comment --> text</element>
<!---->
<!--
-->
==>
Document(Comment,Text,Element(OpenTag(StartTag,TagName,EndTag),Comment,Text,CloseTag(StartCloseTag,TagName,EndTag)),Text,Comment,Text,Comment)
# Mismatched tag
<a></b>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),MismatchedCloseTag(StartCloseTag,TagName,EndTag)))
# Unclosed tag
<a>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag)))
# Ignore pseudo-xml self-closers
<br/>
==>
Document(Element(SelfClosingTag(StartTag,TagName,EndTag)))
# Unclosed implicitly closed tag
<p>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag)))
# Nested mismatched tag
<a><b><c></c></x></a>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),CloseTag(StartCloseTag,TagName,EndTag)),
MismatchedCloseTag(StartCloseTag,TagName,EndTag),
⚠),
CloseTag(StartCloseTag,TagName,EndTag)))
# Incomplete close tag
<html><body></</html>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag), IncompleteCloseTag, ⚠),
CloseTag(StartCloseTag,TagName,EndTag)))
# Re-synchronize close tags
<a><b><c></x></c></a>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),
MismatchedCloseTag(StartCloseTag,TagName,EndTag),
CloseTag(StartCloseTag,TagName,EndTag)),
⚠),
CloseTag(StartCloseTag,TagName,EndTag)))
# Top-level mismatched close tag
<a></a></a>
==>
Document(
Element(OpenTag(StartTag,TagName,EndTag),CloseTag(StartCloseTag,TagName,EndTag)),
MismatchedCloseTag(StartCloseTag,TagName,EndTag))
# Self-closing tags
<a><img src=blah></a>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(SelfClosingTag(StartTag,TagName,Attribute(AttributeName,Is,UnquotedAttributeValue),EndTag)),
CloseTag(StartCloseTag,TagName,EndTag)))
# Implicitly closed
<dl><dd>Hello</dl>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),Text),
CloseTag(StartCloseTag,TagName,EndTag)))
# Closed by sibling
<div>
<p>Foo
<p>Bar
</div>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Text,
Element(OpenTag(StartTag,TagName,EndTag),Text),
Element(OpenTag(StartTag,TagName,EndTag),Text),
CloseTag(StartCloseTag,TagName,EndTag)))
# Closed by sibling at top
<p>Foo
<p>Bar
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),Text),Element(OpenTag(StartTag,TagName,EndTag),Text))
# Textarea
<p>Enter something: <textarea code-lang=javascript>function foo() {
return "</bar>"
}</textarea>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Text,
Element(OpenTag(StartTag,TagName,Attribute(AttributeName,Is,UnquotedAttributeValue),EndTag),
TextareaText,
CloseTag(StartCloseTag,TagName,EndTag))))
# Script
<script>This is not an entity: &lt;</script>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),ScriptText,CloseTag(StartCloseTag,TagName,EndTag)))
# Doesn't get confused by a stray ampersand
<html>a&b</html>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),Text,InvalidEntity,Text,CloseTag(StartCloseTag,TagName,EndTag)))
# Can ignore mismatches {"dialect": "noMatch"}
<div>foo</p>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),Text,CloseTag(StartCloseTag,TagName,EndTag)))
# Can handle lone close tags {"dialect": "noMatch"}
</strong>
==>
Document(CloseTag(StartCloseTag,TagName,EndTag))
# Parses ampersands in attributes
<img src="foo&bar">
==>
Document(Element(SelfClosingTag(StartTag, TagName, Attribute(AttributeName, Is, AttributeValue(InvalidEntity)), EndTag)))
# Supports self-closing dialect {"dialect": "selfClosing"}
<section><image id=i2 /></section>
==>
Document(Element(
OpenTag(StartTag,TagName,EndTag),
Element(SelfClosingTag(StartTag,TagName,Attribute(AttributeName,Is,UnquotedAttributeValue),SelfClosingEndTag)),
CloseTag(StartCloseTag,TagName,EndTag)))
# Allows self-closing in foreign elements
<div><svg><circle/></svg></div>
==>
Document(Element(OpenTag(StartTag,TagName,EndTag),
Element(OpenTag(StartTag,TagName,EndTag),
Element(SelfClosingTag(StartTag,TagName,SelfClosingEndTag)),
CloseTag(StartCloseTag,TagName,EndTag)),
CloseTag(StartCloseTag,TagName,EndTag)))
# Parses multiple unfinished tags in a row
<div
<div
<div
==>
Document(Element(OpenTag(StartTag,TagName,⚠),
Element(OpenTag(StartTag,TagName,⚠),
Element(OpenTag(StartTag,TagName,⚠),⚠),⚠),⚠))
# Allows self-closing on special tags {"dialect": "selfClosing"}
<body>
<br/>
<textarea/>
<script/>
<style/>
</body>
==>
Document(Element(
OpenTag(StartTag,TagName,EndTag),
Text,
Element(SelfClosingTag(StartTag,TagName,SelfClosingEndTag)),
Text,
Element(SelfClosingTag(StartTag,TagName,SelfClosingEndTag)),
Text,
Element(SelfClosingTag(StartTag,TagName,SelfClosingEndTag)),
Text,
Element(SelfClosingTag(StartTag,TagName,SelfClosingEndTag)),
Text,
CloseTag(StartCloseTag,TagName,EndTag)))
# Only treats less-than as opening a tag when followed by a name
< div>x
==>
Document(IncompleteTag,Text)

29
frontend/node_modules/@lezer/html/test/test-html.js generated vendored Normal file
View File

@ -0,0 +1,29 @@
import {parser, configureNesting} from "../dist/index.js"
import {parser as jsParser} from "@lezer/javascript"
import {fileTests} from "@lezer/generator/dist/test"
import * as fs from "fs"
import * as path from "path"
import {fileURLToPath} from "url"
let caseDir = path.dirname(fileURLToPath(import.meta.url))
let mixed = parser.configure({
wrap: configureNesting([{
tag: "script",
attrs(attrs) {
return !attrs.type || /^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i.test(attrs.type)
},
parser: jsParser
}])
})
for (let file of fs.readdirSync(caseDir)) {
if (!/\.txt$/.test(file)) continue
let name = /^[^\.]*/.exec(file)[0]
describe(name, () => {
let p = name == "mixed" ? mixed : parser
for (let {name, run} of fileTests(fs.readFileSync(path.join(caseDir, file), "utf8"), file))
it(name, () => run(p))
})
}

View File

@ -0,0 +1,97 @@
import {parser as baseParser} from "../dist/index.js"
import {TreeFragment} from "@lezer/common"
let parser = baseParser.configure({bufferLength: 2})
let r = n => Math.floor(Math.random() * n)
let tags = ["p", "ul", "li", "div", "span", "th", "tr", "body", "head", "title", "dd", "code", "em", "strong"]
function randomDoc(size) {
let doc = ""
if (!r(5)) doc += "<!doctype html>"
let scope = []
for (let i = 0; i < size; i++) {
let sel = r(20)
if (sel < 5) {
let tag = tags[r(tags.length)]
doc += `<${tag}${r(2) ? " a=b" : ""}>`
scope.push(tag)
} else if (sel < 10 && scope.length) {
let name = scope.pop()
doc += `</${r(5) ? name : "div"}>`
} else if (sel == 10) {
doc += `<img>`
} else if (sel == 11) {
doc += "<script>a()</script>"
} else if (sel == 12) {
doc += r(2) ? "&amp;" : "<!--@-->"
} else {
for (let i = r(6) + 1; i >= 0; i--)
doc += String.fromCharCode(97 + r(26))
}
}
while (scope.length) {
let name = scope.pop()
if (r(5)) doc += `</${name}>`
}
return doc
}
function check(doc, [tp, pos, txt], prevAST) {
let change = {fromA: pos, toA: pos, fromB: pos, toB: pos}, newDoc
if (tp == "insert") {
newDoc = doc.slice(0, pos) + txt + doc.slice(pos)
change.toA += txt.length
} else if (tp == "del") {
newDoc = doc.slice(0, pos) + doc.slice(pos + 1)
change.toB++
} else {
newDoc = doc.slice(0, pos) + txt + doc.slice(pos + 1)
change.toA += txt.length
change.toB++
}
let fragments = TreeFragment.applyChanges(TreeFragment.addTree(prevAST || parser.parse(doc)), [change], 2)
let ast = parser.parse(newDoc, fragments)
let orig = parser.parse(newDoc)
if (ast.toString() != orig.toString()) {
throw new Error(`Mismatch:\n ${ast}\nvs\n ${orig}\ndocument: ${
JSON.stringify(doc)}\naction: ${JSON.stringify([tp, pos, ch])}`)
}
return [newDoc, ast]
}
// Call this to just run random tests until a failing one is found.
// Not directly called in the tests because there's a bunch of
// circumstances in which uninteresting deviations in error recovery
// will create differing parses, so results have to be manually
// inspected.
function generate() {
for (let count = 0, size = 2;; size = Math.min(40, size + 1)) {
let doc = randomDoc(size), prev = null
for (let i = 0; i < 2; i++) {
console.log("Attempt", ++count)
let action = [["del", "insert", "replace"][r(3)], r(doc.length - 1), "<>/piabc "[r(9)]]
;([doc, prev] = check(doc, action, prev))
}
}
}
describe("Incremental parsing", () => {
it("doesn't get confused by reused opening tags", () => {
check("<code><code>mgnbni</code></code>", ["del", 29])
})
it("can handle a renamed opening tag after a self-closing", () => {
check("<p>one two three four five six seven<p>eight", ["replace", 37, "a"])
})
it("is okay with nameless elements", () => {
check("<body><code><img></code><>body>", ["replace", 14, ">"])
check("abcde<>fghij<", ["replace", 12, ">"])
})
it("doesn't get confused by an invalid close tag receiving a matching open tag", () => {
check("<div><p>foo</body>", ["insert", 0, "<body>"])
})
})

56
frontend/node_modules/@lezer/html/test/vue.txt generated vendored Normal file
View File

@ -0,0 +1,56 @@
# Parses Vue builtin directives
<span v-text="msg"></span>
==>
Document(
Element(
OpenTag(StartTag, TagName, Attribute(AttributeName, Is, AttributeValue), EndTag),
CloseTag(StartCloseTag, TagName, EndTag)))
# Parses Vue :is shorthand syntax
<Component :is="view"></Component>
==>
Document(
Element(
OpenTag(StartTag, TagName, Attribute(AttributeName, Is, AttributeValue),EndTag),
CloseTag(StartCloseTag, TagName, EndTag)))
# Parses Vue @click shorthand syntax
<button @click="handler()">Click me</button>
==>
Document(
Element(
OpenTag(StartTag, TagName, Attribute(AttributeName, Is, AttributeValue), EndTag),
Text,
CloseTag(StartCloseTag, TagName, EndTag)))
# Parses Vue @submit.prevent shorthand syntax
<form @submit.prevent="onSubmit"></form>
==>
Document(
Element(
OpenTag(StartTag, TagName, Attribute(AttributeName, Is, AttributeValue), EndTag),
CloseTag(StartCloseTag, TagName, EndTag)))
# Parses Vue Dynamic Arguments
<a v-bind:[attributeName]="url">Link</a>
==>
Document(
Element(
OpenTag(StartTag, TagName, Attribute(AttributeName, Is, AttributeValue), EndTag),
Text,
CloseTag(StartCloseTag, TagName, EndTag)))