@ouestfrance/sipa-bms-ui 8.44.0 → 8.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/form/bms-input-code.linters.d.ts +0 -14
- package/dist/sipa-bms-ui.es.js +16 -3
- package/dist/sipa-bms-ui.es.js.map +1 -1
- package/dist/sipa-bms-ui.umd.js +16 -3
- package/dist/sipa-bms-ui.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/form/bms-input-code.linters.spec.ts +14 -3
- package/src/components/form/bms-input-code.linters.ts +23 -3
package/package.json
CHANGED
|
@@ -32,11 +32,22 @@ describe('htmlDiagnostics', () => {
|
|
|
32
32
|
expect(diags[0].severity).toBe('error');
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
it("positionne le diagnostic
|
|
35
|
+
it("positionne le diagnostic à proximité de l'erreur", () => {
|
|
36
|
+
// <div><p>Hello</div> — l'erreur est sur le </div> qui ferme mal le <p>
|
|
36
37
|
const code = '<div><p>Hello</div>';
|
|
37
38
|
const diags = htmlDiagnostics(code);
|
|
38
|
-
expect(diags[0].from).
|
|
39
|
-
expect(diags[0].to).
|
|
39
|
+
expect(diags[0].from).toBeGreaterThanOrEqual(0);
|
|
40
|
+
expect(diags[0].to).toBeGreaterThan(diags[0].from);
|
|
41
|
+
// le diagnostic doit pointer dans le contenu, pas sur l'intégralité
|
|
42
|
+
expect(diags[0].to).toBeLessThanOrEqual(code.length);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('positionne le diagnostic sur la ligne correcte pour une erreur multi-lignes', () => {
|
|
46
|
+
const code = '<div>\n <p>Hello\n</div>';
|
|
47
|
+
const diags = htmlDiagnostics(code);
|
|
48
|
+
expect(diags).toHaveLength(1);
|
|
49
|
+
// l'erreur est après le début du document
|
|
50
|
+
expect(diags[0].from).toBeGreaterThanOrEqual(0);
|
|
40
51
|
});
|
|
41
52
|
});
|
|
42
53
|
|
|
@@ -16,16 +16,36 @@ import type { Extension } from '@codemirror/state';
|
|
|
16
16
|
* Limitation : le parser XML est plus strict que le parser HTML du navigateur.
|
|
17
17
|
* Les balises void HTML5 non fermées (`<br>`, `<img>`) sont considérées invalides.
|
|
18
18
|
*/
|
|
19
|
+
const ROOT_TAG = '<root>';
|
|
20
|
+
|
|
21
|
+
const htmlErrorOffset = (errorText: string, code: string): number => {
|
|
22
|
+
const match = errorText.match(/error on line (\d+) at column (\d+)/i);
|
|
23
|
+
if (!match) return 0;
|
|
24
|
+
|
|
25
|
+
const line = parseInt(match[1]);
|
|
26
|
+
// La colonne de la ligne 1 inclut le préfixe <root> — on le retire
|
|
27
|
+
const col = parseInt(match[2]) - (line === 1 ? ROOT_TAG.length : 0);
|
|
28
|
+
|
|
29
|
+
const lines = code.split('\n');
|
|
30
|
+
let offset = 0;
|
|
31
|
+
for (let i = 0; i < line - 1 && i < lines.length; i++) {
|
|
32
|
+
offset += lines[i].length + 1;
|
|
33
|
+
}
|
|
34
|
+
return Math.min(Math.max(0, offset + col - 1), code.length);
|
|
35
|
+
};
|
|
36
|
+
|
|
19
37
|
export const htmlDiagnostics = (code: string): Diagnostic[] => {
|
|
20
38
|
if (!code.trim()) return [];
|
|
21
39
|
const parser = new DOMParser();
|
|
22
|
-
const doc = parser.parseFromString(
|
|
40
|
+
const doc = parser.parseFromString(`${ROOT_TAG}${code}</root>`, 'text/xml');
|
|
23
41
|
const parserError = doc.querySelector('parsererror');
|
|
24
42
|
if (!parserError) return [];
|
|
43
|
+
|
|
44
|
+
const from = htmlErrorOffset(parserError.textContent ?? '', code);
|
|
25
45
|
return [
|
|
26
46
|
{
|
|
27
|
-
from
|
|
28
|
-
to: code.length,
|
|
47
|
+
from,
|
|
48
|
+
to: Math.min(from + 1, code.length),
|
|
29
49
|
severity: 'error',
|
|
30
50
|
message: 'HTML invalide : balise mal formée ou non fermée',
|
|
31
51
|
},
|