feat(planning): grille hebdomadaire complète avec API et filtres
- Connexion API via proxy Angular (résolution CORS, base path /api) - Import CSS ng-zorro global pour les modales et composants - Filtres Camion/Show câblés sur l'affichage de la grille - Camions affichés via TrucksService (linkés au show du même créneau) - Panneau de détails : spectacles + camions du jour sélectionné - Modale de création de spectacle stylisée avec fond et centrage - Positionnement précis des events à la minute dans leur créneau - Auto-scroll vers l'heure courante au chargement - Ligne "maintenant" sur la colonne du jour actuel - Régénération des services OpenAPI (nouveaux noms de types) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+20
-41
@@ -1,17 +1,5 @@
|
||||
'use strict'
|
||||
|
||||
// Escapes sequences that could break out of an HTML <style> context.
|
||||
// Uses CSS unicode escaping (\3c = '<') which is valid CSS and parsed
|
||||
// correctly by all compliant CSS consumers.
|
||||
const STYLE_TAG = /(<)(\/?style\b)/gi
|
||||
const COMMENT_OPEN = /(<)(!--)/g
|
||||
|
||||
function escapeHTMLInCSS(str) {
|
||||
if (typeof str !== 'string') return str
|
||||
if (!str.includes('<')) return str
|
||||
return str.replace(STYLE_TAG, '\\3c $2').replace(COMMENT_OPEN, '\\3c $2')
|
||||
}
|
||||
|
||||
const DEFAULT_RAW = {
|
||||
after: '\n',
|
||||
beforeClose: '\n',
|
||||
@@ -37,12 +25,11 @@ class Stringifier {
|
||||
}
|
||||
|
||||
atrule(node, semicolon) {
|
||||
let raws = node.raws
|
||||
let name = '@' + node.name
|
||||
let params = node.params ? this.rawValue(node, 'params') : ''
|
||||
|
||||
if (typeof raws.afterName !== 'undefined') {
|
||||
name += raws.afterName
|
||||
if (typeof node.raws.afterName !== 'undefined') {
|
||||
name += node.raws.afterName
|
||||
} else if (params) {
|
||||
name += ' '
|
||||
}
|
||||
@@ -50,8 +37,8 @@ class Stringifier {
|
||||
if (node.nodes) {
|
||||
this.block(node, name + params)
|
||||
} else {
|
||||
let end = (raws.between || '') + (semicolon ? ';' : '')
|
||||
this.builder(escapeHTMLInCSS(name + params + end), node)
|
||||
let end = (node.raws.between || '') + (semicolon ? ';' : '')
|
||||
this.builder(name + params + end, node)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +73,7 @@ class Stringifier {
|
||||
|
||||
block(node, start) {
|
||||
let between = this.raw(node, 'between', 'beforeOpen')
|
||||
this.builder(escapeHTMLInCSS(start + between) + '{', node, 'start')
|
||||
this.builder(start + between + '{', node, 'start')
|
||||
|
||||
let after
|
||||
if (node.nodes && node.nodes.length) {
|
||||
@@ -96,24 +83,22 @@ class Stringifier {
|
||||
after = this.raw(node, 'after', 'emptyBody')
|
||||
}
|
||||
|
||||
if (after) this.builder(escapeHTMLInCSS(after))
|
||||
if (after) this.builder(after)
|
||||
this.builder('}', node, 'end')
|
||||
}
|
||||
|
||||
body(node) {
|
||||
let nodes = node.nodes
|
||||
let last = nodes.length - 1
|
||||
let last = node.nodes.length - 1
|
||||
while (last > 0) {
|
||||
if (nodes[last].type !== 'comment') break
|
||||
if (node.nodes[last].type !== 'comment') break
|
||||
last -= 1
|
||||
}
|
||||
|
||||
let semicolon = this.raw(node, 'semicolon')
|
||||
let isDocument = node.type === 'document'
|
||||
for (let i = 0; i < nodes.length; i++) {
|
||||
let child = nodes[i]
|
||||
for (let i = 0; i < node.nodes.length; i++) {
|
||||
let child = node.nodes[i]
|
||||
let before = this.raw(child, 'before')
|
||||
if (before) this.builder(isDocument ? before : escapeHTMLInCSS(before))
|
||||
if (before) this.builder(before)
|
||||
this.stringify(child, last !== i || semicolon)
|
||||
}
|
||||
}
|
||||
@@ -121,21 +106,19 @@ class Stringifier {
|
||||
comment(node) {
|
||||
let left = this.raw(node, 'left', 'commentLeft')
|
||||
let right = this.raw(node, 'right', 'commentRight')
|
||||
this.builder(escapeHTMLInCSS('/*' + left + node.text + right + '*/'), node)
|
||||
this.builder('/*' + left + node.text + right + '*/', node)
|
||||
}
|
||||
|
||||
decl(node, semicolon) {
|
||||
let raws = node.raws
|
||||
let between = this.raw(node, 'between', 'colon')
|
||||
|
||||
let string = node.prop + between + this.rawValue(node, 'value')
|
||||
|
||||
if (node.important) {
|
||||
string += raws.important || ' !important'
|
||||
string += node.raws.important || ' !important'
|
||||
}
|
||||
|
||||
if (semicolon) string += ';'
|
||||
this.builder(escapeHTMLInCSS(string), node)
|
||||
this.builder(string, node)
|
||||
}
|
||||
|
||||
document(node) {
|
||||
@@ -171,9 +154,9 @@ class Stringifier {
|
||||
|
||||
// Detect style by other nodes
|
||||
let root = node.root()
|
||||
let cache = root.rawCache || (root.rawCache = {})
|
||||
if (typeof cache[detect] !== 'undefined') {
|
||||
return cache[detect]
|
||||
if (!root.rawCache) root.rawCache = {}
|
||||
if (typeof root.rawCache[detect] !== 'undefined') {
|
||||
return root.rawCache[detect]
|
||||
}
|
||||
|
||||
if (detect === 'before' || detect === 'after') {
|
||||
@@ -192,7 +175,7 @@ class Stringifier {
|
||||
|
||||
if (typeof value === 'undefined') value = DEFAULT_RAW[detect]
|
||||
|
||||
cache[detect] = value
|
||||
root.rawCache[detect] = value
|
||||
return value
|
||||
}
|
||||
|
||||
@@ -341,17 +324,13 @@ class Stringifier {
|
||||
|
||||
root(node) {
|
||||
this.body(node)
|
||||
if (node.raws.after) {
|
||||
let after = node.raws.after
|
||||
let isDocument = node.parent && node.parent.type === 'document'
|
||||
this.builder(isDocument ? after : escapeHTMLInCSS(after))
|
||||
}
|
||||
if (node.raws.after) this.builder(node.raws.after)
|
||||
}
|
||||
|
||||
rule(node) {
|
||||
this.block(node, this.rawValue(node, 'selector'))
|
||||
if (node.raws.ownSemicolon) {
|
||||
this.builder(escapeHTMLInCSS(node.raws.ownSemicolon), node, 'end')
|
||||
this.builder(node.raws.ownSemicolon, node, 'end')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user