5htp 0.0.2
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/package.json +94 -0
- package/src/commands/build.ts +32 -0
- package/src/commands/deploy/app.ts +29 -0
- package/src/commands/deploy/web.ts +62 -0
- package/src/commands/dev.ts +100 -0
- package/src/compiler/client/identite.ts +70 -0
- package/src/compiler/client/index.ts +335 -0
- package/src/compiler/common/babel/index.ts +261 -0
- package/src/compiler/common/babel/plugins/form.ts +191 -0
- package/src/compiler/common/babel/plugins/icones-svg.ts +350 -0
- package/src/compiler/common/babel/plugins/importations.ts +337 -0
- package/src/compiler/common/babel/plugins/injection-dependances/index.ts +223 -0
- package/src/compiler/common/babel/plugins/injection-dependances/remplacerFonction.ts +226 -0
- package/src/compiler/common/babel/plugins/models.ts +241 -0
- package/src/compiler/common/babel/plugins/pages.ts +185 -0
- package/src/compiler/common/babel/plugins/queries/index.ts +166 -0
- package/src/compiler/common/files/autres.ts +37 -0
- package/src/compiler/common/files/images.ts +19 -0
- package/src/compiler/common/files/style.ts +64 -0
- package/src/compiler/common/index.ts +148 -0
- package/src/compiler/common/plugins/indexage/_utils/Stringify.ts +72 -0
- package/src/compiler/common/plugins/indexage/_utils/annotations.ts +88 -0
- package/src/compiler/common/plugins/indexage/_utils/iterateur.ts +52 -0
- package/src/compiler/common/plugins/indexage/icones-svg/index.ts +198 -0
- package/src/compiler/common/plugins/indexage/index.ts +132 -0
- package/src/compiler/common/plugins/indexage/indexeur.ts +13 -0
- package/src/compiler/common/plugins/indexage/injection-dependances/index.ts +68 -0
- package/src/compiler/index.ts +86 -0
- package/src/compiler/server/index.ts +177 -0
- package/src/index.ts +192 -0
- package/src/paths.ts +158 -0
- package/src/print.ts +12 -0
- package/src/utils/index.ts +22 -0
- package/src/utils/keyboard.ts +78 -0
- package/tsconfig.json +38 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
import { PluginObj } from '@babel/core';
|
|
6
|
+
|
|
7
|
+
import * as types from '@babel/types'
|
|
8
|
+
import generate from '@babel/generator';
|
|
9
|
+
|
|
10
|
+
/*----------------------------------
|
|
11
|
+
- WEBPACK RULE
|
|
12
|
+
----------------------------------*/
|
|
13
|
+
module.exports = {
|
|
14
|
+
test: "**/client/**/*.tsx",
|
|
15
|
+
plugins: [
|
|
16
|
+
[Plugin]
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const debug = false
|
|
21
|
+
|
|
22
|
+
/*----------------------------------
|
|
23
|
+
- PLUGIN
|
|
24
|
+
----------------------------------*/
|
|
25
|
+
function Plugin (babel) {
|
|
26
|
+
|
|
27
|
+
const t = babel.types as typeof types;
|
|
28
|
+
|
|
29
|
+
const plugin: PluginObj<{
|
|
30
|
+
fichier: string,
|
|
31
|
+
cancel: boolean
|
|
32
|
+
}> = {
|
|
33
|
+
pre(state) {
|
|
34
|
+
|
|
35
|
+
this.fichier = state.opts.filename as string;
|
|
36
|
+
|
|
37
|
+
if (!('useForm' in state.scope.bindings))
|
|
38
|
+
this.cancel = true;
|
|
39
|
+
|
|
40
|
+
},
|
|
41
|
+
visitor: {
|
|
42
|
+
JSXElement(instruction) {
|
|
43
|
+
|
|
44
|
+
if (this.cancel === true)
|
|
45
|
+
return;
|
|
46
|
+
|
|
47
|
+
const balise = instruction.node.openingElement;
|
|
48
|
+
|
|
49
|
+
/*
|
|
50
|
+
<Champs.metas.titre className="full" attrsChamp={{ className: "h1" }} />
|
|
51
|
+
*/
|
|
52
|
+
|
|
53
|
+
if (!(
|
|
54
|
+
balise.selfClosing === true
|
|
55
|
+
&&
|
|
56
|
+
balise.name.type === 'JSXMemberExpression'
|
|
57
|
+
&&
|
|
58
|
+
balise.name.property.type === 'JSXIdentifier'
|
|
59
|
+
))
|
|
60
|
+
return;
|
|
61
|
+
|
|
62
|
+
debug && console.log(`[compilation][babel][form] Original: `, generate(instruction.node).code);
|
|
63
|
+
|
|
64
|
+
// Si le premier element du memberexpression est Champ
|
|
65
|
+
let nomA: types.JSXMemberExpression | types.JSXIdentifier = balise.name;
|
|
66
|
+
while (nomA.type === 'JSXMemberExpression')
|
|
67
|
+
nomA = nomA.object;
|
|
68
|
+
if (!nomA.name.startsWith('Champs'))
|
|
69
|
+
return;
|
|
70
|
+
|
|
71
|
+
// Ne pas parcourir les élements enfant
|
|
72
|
+
// Avec .stop, babel arrête d'itérer les élements voisins à partir du 6ème - 7ème
|
|
73
|
+
//instruction.stop();
|
|
74
|
+
instruction.skip();
|
|
75
|
+
|
|
76
|
+
// Transformation de la lste des attributs en un objet
|
|
77
|
+
/*
|
|
78
|
+
className="full" attrsChamp={{ className: "h1" }}
|
|
79
|
+
|
|
80
|
+
=>
|
|
81
|
+
|
|
82
|
+
{ className: "full", attrsChamp: { className: "h1" } }
|
|
83
|
+
*/
|
|
84
|
+
let objAttributs: types.ObjectProperty[] = [];
|
|
85
|
+
for (const attribut of balise.attributes)
|
|
86
|
+
if (
|
|
87
|
+
attribut.type === 'JSXAttribute' &&
|
|
88
|
+
attribut.value !== undefined &&
|
|
89
|
+
typeof attribut.name.name === "string"
|
|
90
|
+
) {
|
|
91
|
+
|
|
92
|
+
let propValue: types.ObjectProperty["value"];
|
|
93
|
+
if (attribut.value === null) // <Champ.titre autoFocus />
|
|
94
|
+
propValue = t.booleanLiteral(true);
|
|
95
|
+
else if (attribut.value.type !== 'JSXExpressionContainer')
|
|
96
|
+
propValue = attribut.value;
|
|
97
|
+
else if (attribut.value.expression.type !== 'JSXEmptyExpression')
|
|
98
|
+
propValue = attribut.value.expression;
|
|
99
|
+
else
|
|
100
|
+
propValue = t.nullLiteral();
|
|
101
|
+
|
|
102
|
+
objAttributs.push(
|
|
103
|
+
t.objectProperty(
|
|
104
|
+
t.identifier( attribut.name.name ),
|
|
105
|
+
propValue
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Traverse chaque branche du chemin du champ, dans l'ordre inverse
|
|
111
|
+
// NOTE: on aurai pu reconstituer le chemin et créer les memberexpressions en une seule itération
|
|
112
|
+
// Mais le fait d ele faire en deux itérations rend le code plus claire et maintenable
|
|
113
|
+
let cheminComposant: string[] = []
|
|
114
|
+
let brancheA: types.JSXMemberExpression | types.JSXIdentifier = balise.name;
|
|
115
|
+
while (brancheA.type === 'JSXMemberExpression') {
|
|
116
|
+
|
|
117
|
+
const { property } = brancheA;
|
|
118
|
+
|
|
119
|
+
cheminComposant.unshift(property.name)
|
|
120
|
+
brancheA = brancheA.object;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let cheminSchema: types.MemberExpression | types.OptionalMemberExpression = t.memberExpression(
|
|
124
|
+
t.identifier('Champs'),
|
|
125
|
+
t.identifier('schema')
|
|
126
|
+
);
|
|
127
|
+
let cheminDonnees: types.MemberExpression | types.OptionalMemberExpression = t.memberExpression(
|
|
128
|
+
t.identifier('Champs'),
|
|
129
|
+
t.identifier('data')
|
|
130
|
+
);
|
|
131
|
+
const iDerniereBranche = cheminComposant.length - 1
|
|
132
|
+
for (let iBranche = iDerniereBranche; iBranche >= 0; iBranche--) {
|
|
133
|
+
|
|
134
|
+
const branche = cheminComposant[ iBranche ];
|
|
135
|
+
|
|
136
|
+
cheminSchema = t.optionalMemberExpression(
|
|
137
|
+
cheminSchema,
|
|
138
|
+
t.identifier( branche ),
|
|
139
|
+
undefined,
|
|
140
|
+
true
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
if (iBranche !== iDerniereBranche)
|
|
144
|
+
cheminDonnees = t.optionalMemberExpression(
|
|
145
|
+
cheminDonnees,
|
|
146
|
+
t.identifier(branche),
|
|
147
|
+
undefined,
|
|
148
|
+
true
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Remplacement
|
|
154
|
+
/*
|
|
155
|
+
{Champs._render( Champs.metas?.titre, Champs._data.metas?.titre, 'metas.titre', {
|
|
156
|
+
className: "full",
|
|
157
|
+
attrsChamp: { className: "h1" }
|
|
158
|
+
})}
|
|
159
|
+
*/
|
|
160
|
+
const remplacement = t.callExpression(
|
|
161
|
+
|
|
162
|
+
// Champs.render
|
|
163
|
+
t.memberExpression(
|
|
164
|
+
t.identifier('Champs'),
|
|
165
|
+
t.identifier('render')
|
|
166
|
+
),
|
|
167
|
+
[
|
|
168
|
+
// Champs.<chemin>
|
|
169
|
+
cheminSchema,
|
|
170
|
+
|
|
171
|
+
// Champs._data.<chemin>
|
|
172
|
+
cheminDonnees,
|
|
173
|
+
|
|
174
|
+
// Chemin
|
|
175
|
+
t.stringLiteral( cheminComposant.join('.') ),
|
|
176
|
+
|
|
177
|
+
// { <attrs> }
|
|
178
|
+
t.objectExpression(objAttributs)
|
|
179
|
+
]
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
debug && console.log(`[compilation][babel][form] Remplacement: `, generate(remplacement).code );
|
|
183
|
+
|
|
184
|
+
instruction.replaceWith(remplacement);
|
|
185
|
+
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
return plugin;
|
|
191
|
+
}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import * as types from '@babel/types'
|
|
7
|
+
|
|
8
|
+
import { PluginObj } from '@babel/core';
|
|
9
|
+
|
|
10
|
+
export type TIndexIcones = { [chemin: string]: { id: string, nom: string, fichier: string } };
|
|
11
|
+
|
|
12
|
+
/*----------------------------------
|
|
13
|
+
- WEBPACK RULE
|
|
14
|
+
----------------------------------*/
|
|
15
|
+
module.exports = {
|
|
16
|
+
test: /\.(tsx|jsx|ts)$/, // <i src="icon" /> et /* @icon */"icon"
|
|
17
|
+
plugins: [
|
|
18
|
+
[Plugin]
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const debug = false;
|
|
23
|
+
|
|
24
|
+
const defaultIconsPack = 'regular';
|
|
25
|
+
|
|
26
|
+
/*----------------------------------
|
|
27
|
+
- PLUGIN
|
|
28
|
+
----------------------------------*/
|
|
29
|
+
const ids: string[] = []
|
|
30
|
+
function Plugin (babel) {
|
|
31
|
+
|
|
32
|
+
const t = babel.types as typeof types;
|
|
33
|
+
|
|
34
|
+
const plugin: PluginObj<{
|
|
35
|
+
referencerIcone: (nomBrut: string) => string | null,
|
|
36
|
+
fichier: string,
|
|
37
|
+
traiter: boolean,
|
|
38
|
+
iconeTrouvee: boolean,
|
|
39
|
+
icones: TIndexIcones
|
|
40
|
+
}> = {
|
|
41
|
+
pre(state) {
|
|
42
|
+
|
|
43
|
+
this.fichier = state.opts.filename as string;
|
|
44
|
+
|
|
45
|
+
//console.log('SVG', fichier);
|
|
46
|
+
|
|
47
|
+
this.traiter = true;
|
|
48
|
+
this.iconeTrouvee = false;
|
|
49
|
+
|
|
50
|
+
this.icones = {}; // chemin => { id, nom }
|
|
51
|
+
|
|
52
|
+
this.referencerIcone = (nomBrut: string) => {
|
|
53
|
+
|
|
54
|
+
// Décomposition & dossier par défaut
|
|
55
|
+
let [dossierIcone, nomIcone] = nomBrut.split('/');
|
|
56
|
+
if (nomIcone === undefined) {
|
|
57
|
+
nomIcone = dossierIcone;
|
|
58
|
+
dossierIcone = defaultIconsPack;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Extraction des infos
|
|
62
|
+
const cheminIconeBrut = dossierIcone + '/' + nomIcone;
|
|
63
|
+
const cheminIcone = cheminIconeBrut + '.svg';
|
|
64
|
+
|
|
65
|
+
// Référencement si pas déjà fait
|
|
66
|
+
if (this.icones[ cheminIconeBrut ] === undefined) {
|
|
67
|
+
|
|
68
|
+
const id = nomBrut.replace(/\//g, '-');
|
|
69
|
+
|
|
70
|
+
this.icones[ cheminIconeBrut ] = {
|
|
71
|
+
//id: dossierIcone.substring(0, 1) + '-' + nomIcone,
|
|
72
|
+
id: id,
|
|
73
|
+
nom: nomBrut,
|
|
74
|
+
fichier: cheminIcone
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
this.iconeTrouvee = true;
|
|
80
|
+
|
|
81
|
+
debug && console.log(`[icons]`, nomBrut, '=>', this.icones[cheminIconeBrut].id);
|
|
82
|
+
|
|
83
|
+
ids.push(this.icones[cheminIconeBrut].id);
|
|
84
|
+
|
|
85
|
+
return this.icones[ cheminIconeBrut ].id;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
},
|
|
89
|
+
visitor: {
|
|
90
|
+
Program: {
|
|
91
|
+
|
|
92
|
+
enter(path) {
|
|
93
|
+
|
|
94
|
+
if (!this.traiter)
|
|
95
|
+
return;
|
|
96
|
+
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
StringLiteral(path) {
|
|
101
|
+
|
|
102
|
+
// Marquage d'une référence à une icon via un /* @icon */"<nom>"
|
|
103
|
+
if (
|
|
104
|
+
path.node.leadingComments
|
|
105
|
+
&&
|
|
106
|
+
path.node.leadingComments.length !== 0
|
|
107
|
+
&&
|
|
108
|
+
path.node.leadingComments[0].value === ' @icon '
|
|
109
|
+
) {
|
|
110
|
+
|
|
111
|
+
// Remplacement par id
|
|
112
|
+
const idIcone = this.referencerIcone(path.node.value);
|
|
113
|
+
if (idIcone === null)
|
|
114
|
+
return;
|
|
115
|
+
|
|
116
|
+
path.replaceWith(
|
|
117
|
+
t.stringLiteral(idIcone)
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
path.skip();
|
|
121
|
+
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
// { icon: "solid/<nom>" }
|
|
126
|
+
Property(path) {
|
|
127
|
+
if (
|
|
128
|
+
path.node.key.type === 'Identifier'
|
|
129
|
+
&&
|
|
130
|
+
path.node.key.name === 'icon'
|
|
131
|
+
&&
|
|
132
|
+
path.node.value?.type === 'StringLiteral'
|
|
133
|
+
) {
|
|
134
|
+
|
|
135
|
+
// Remplacement par id
|
|
136
|
+
const idIcone = this.referencerIcone(path.node.value.value);
|
|
137
|
+
if (idIcone === null)
|
|
138
|
+
return;
|
|
139
|
+
|
|
140
|
+
path.replaceWith(
|
|
141
|
+
t.objectProperty(
|
|
142
|
+
t.identifier('icon'),
|
|
143
|
+
t.stringLiteral( idIcone )
|
|
144
|
+
)
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
path.skip();
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
JSXAttribute(path) {
|
|
153
|
+
|
|
154
|
+
// icon="solid/<nom>"
|
|
155
|
+
if (
|
|
156
|
+
path.node.name.type === 'JSXIdentifier'
|
|
157
|
+
&&
|
|
158
|
+
path.node.name.name.startsWith("icon")
|
|
159
|
+
&&
|
|
160
|
+
path.node.value
|
|
161
|
+
) {
|
|
162
|
+
|
|
163
|
+
const nomAttr = path.node.name.name;
|
|
164
|
+
const valAttr = path.node.value;
|
|
165
|
+
let remplacement;
|
|
166
|
+
|
|
167
|
+
// icon="solid/<nom>"
|
|
168
|
+
if (valAttr.type === 'StringLiteral') {
|
|
169
|
+
|
|
170
|
+
const idIcone = this.referencerIcone(valAttr.value);
|
|
171
|
+
if (idIcone === null)
|
|
172
|
+
return;
|
|
173
|
+
|
|
174
|
+
remplacement = t.stringLiteral(idIcone)
|
|
175
|
+
|
|
176
|
+
// icon={condition ? "solid/<nom>" : "solid/<nom>"}
|
|
177
|
+
} else if (
|
|
178
|
+
valAttr.type === 'JSXExpressionContainer'
|
|
179
|
+
&&
|
|
180
|
+
valAttr.expression.type === 'ConditionalExpression'
|
|
181
|
+
&&
|
|
182
|
+
valAttr.expression.consequent.type === 'StringLiteral'
|
|
183
|
+
&&
|
|
184
|
+
valAttr.expression.alternate.type === 'StringLiteral'
|
|
185
|
+
) {
|
|
186
|
+
|
|
187
|
+
const idIcone1 = this.referencerIcone(valAttr.expression.consequent.value);
|
|
188
|
+
const idIcone2 = this.referencerIcone(valAttr.expression.alternate.value);
|
|
189
|
+
|
|
190
|
+
remplacement = t.jsxExpressionContainer(
|
|
191
|
+
t.conditionalExpression(
|
|
192
|
+
valAttr.expression.test,
|
|
193
|
+
idIcone1 ? t.stringLiteral(idIcone1) : valAttr.expression.consequent,
|
|
194
|
+
idIcone2 ? t.stringLiteral(idIcone2) : valAttr.expression.alternate,
|
|
195
|
+
|
|
196
|
+
)
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
} else
|
|
200
|
+
return;
|
|
201
|
+
|
|
202
|
+
path.replaceWith(
|
|
203
|
+
t.jsxAttribute(
|
|
204
|
+
t.jsxIdentifier( nomAttr ),
|
|
205
|
+
remplacement
|
|
206
|
+
)
|
|
207
|
+
);
|
|
208
|
+
|
|
209
|
+
path.skip();
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
JSXElement(path) {
|
|
215
|
+
|
|
216
|
+
// <i />
|
|
217
|
+
if (
|
|
218
|
+
this.traiter
|
|
219
|
+
&&
|
|
220
|
+
path.node
|
|
221
|
+
&&
|
|
222
|
+
path.node.openingElement
|
|
223
|
+
&&
|
|
224
|
+
path.node.openingElement.name.type === 'JSXIdentifier'
|
|
225
|
+
&&
|
|
226
|
+
path.node.openingElement.name.name === 'i'
|
|
227
|
+
) {
|
|
228
|
+
|
|
229
|
+
// Extraction des attributs src et class
|
|
230
|
+
const attrs: {[prop: string]: types.JSXAttribute["value"]} = {}
|
|
231
|
+
let nouveauxAttributs = path.node.openingElement.attributes.filter((attribut) => {
|
|
232
|
+
|
|
233
|
+
if (attribut.type === 'JSXAttribute' && attribut.name) {
|
|
234
|
+
|
|
235
|
+
if (attribut.name.name === 'src') {
|
|
236
|
+
attrs.src = attribut.value
|
|
237
|
+
return false;
|
|
238
|
+
} else if (attribut.name.name === 'class') {
|
|
239
|
+
attrs.class = attribut.value
|
|
240
|
+
return false;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
if (!attrs.src)
|
|
247
|
+
return;
|
|
248
|
+
|
|
249
|
+
// <i src="..." />
|
|
250
|
+
let classeIcone: types.StringLiteral | types.BinaryExpression | undefined = undefined;
|
|
251
|
+
|
|
252
|
+
// Chaine: On référence le nom de l'icon
|
|
253
|
+
if (attrs.src.type === 'StringLiteral') {
|
|
254
|
+
|
|
255
|
+
// <i src="spin" /> => <i class="svg-xxxxx spin" />
|
|
256
|
+
let valSrc = attrs.src.value
|
|
257
|
+
if (valSrc === 'spin') {
|
|
258
|
+
|
|
259
|
+
const idIcone = this.referencerIcone('solid/spinner-third');
|
|
260
|
+
if (idIcone === null)
|
|
261
|
+
return;
|
|
262
|
+
|
|
263
|
+
classeIcone = t.stringLiteral('svg-' + idIcone + ' spin');
|
|
264
|
+
|
|
265
|
+
// <i src="regular/user" /> => <i class="svg-xxxxxx" />
|
|
266
|
+
} else {
|
|
267
|
+
|
|
268
|
+
const idIcone = this.referencerIcone(valSrc);
|
|
269
|
+
if (idIcone === null)
|
|
270
|
+
return;
|
|
271
|
+
|
|
272
|
+
classeIcone = t.stringLiteral('svg-' + idIcone);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Autre: on renomme src en class et contatène le préfixe "svg-"
|
|
276
|
+
// <i src={icon} /> => <i class={"svg-" + icon} />
|
|
277
|
+
} else if (attrs.src.type === 'JSXExpressionContainer' && attrs.src.expression.type !== 'JSXEmptyExpression') {
|
|
278
|
+
|
|
279
|
+
classeIcone = t.binaryExpression(
|
|
280
|
+
'+',
|
|
281
|
+
t.stringLiteral('svg-'),
|
|
282
|
+
attrs.src.expression
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
} else
|
|
286
|
+
throw new Error(`Type de valeur non-géré pour l'attribut src: ${attrs.src.type}`);
|
|
287
|
+
|
|
288
|
+
const origClass = attrs.class?.type !== 'JSXExpressionContainer'
|
|
289
|
+
? attrs.class
|
|
290
|
+
: attrs.class.expression.type !== 'JSXEmptyExpression'
|
|
291
|
+
? attrs.class.expression
|
|
292
|
+
: null
|
|
293
|
+
|
|
294
|
+
path.replaceWith(
|
|
295
|
+
|
|
296
|
+
// Balise <i>
|
|
297
|
+
t.jsxElement(
|
|
298
|
+
t.jsxOpeningElement(
|
|
299
|
+
t.jsxIdentifier('i'),
|
|
300
|
+
|
|
301
|
+
// Attributs
|
|
302
|
+
[
|
|
303
|
+
...nouveauxAttributs,
|
|
304
|
+
t.jsxAttribute(
|
|
305
|
+
t.jsxIdentifier("class"),
|
|
306
|
+
|
|
307
|
+
// Attribut class
|
|
308
|
+
// concatSrc doit toujours être en premier dans les binary expressions
|
|
309
|
+
// afin que le sélecteur CSS i[class^="svg-"] soit toujours valable
|
|
310
|
+
t.jsxExpressionContainer(
|
|
311
|
+
origClass // Concaténation si attribut déjà défini
|
|
312
|
+
? t.binaryExpression(
|
|
313
|
+
'+',
|
|
314
|
+
classeIcone,
|
|
315
|
+
|
|
316
|
+
t.binaryExpression(
|
|
317
|
+
'+',
|
|
318
|
+
t.stringLiteral(' '),
|
|
319
|
+
origClass
|
|
320
|
+
)
|
|
321
|
+
)
|
|
322
|
+
: classeIcone
|
|
323
|
+
)
|
|
324
|
+
)
|
|
325
|
+
]
|
|
326
|
+
),
|
|
327
|
+
t.jsxClosingElement(
|
|
328
|
+
t.jsxIdentifier('i')
|
|
329
|
+
),
|
|
330
|
+
path.node.children,
|
|
331
|
+
path.node.selfClosing
|
|
332
|
+
)
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
},
|
|
337
|
+
post(state) {
|
|
338
|
+
|
|
339
|
+
if (!this.traiter || !this.iconeTrouvee)
|
|
340
|
+
return;
|
|
341
|
+
|
|
342
|
+
//console.log('@@@@@@ TEST ICONE', this.icones['/home/gaetan/www/Professionnel/Node/framework/kernel/client/assets/img/icones/fa/free/brands/youtube.svg']);
|
|
343
|
+
|
|
344
|
+
state.metadata['icones-svg'] = this.icones;
|
|
345
|
+
|
|
346
|
+
}
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
return plugin;
|
|
350
|
+
}
|