@@ -15,21 +15,23 @@ export class Component {
15
15
* @param {object } data параметры
16
16
* @returns {Node }
17
17
* @params
18
- * tag {string} тег html элемента (для указания в children например)
19
- * context {object} контекст для параметра 'var' и вызовов 'also'
20
- * text {string} добавить в textContent
21
- * html {string} добавить в innerHTML
22
- * attrs {object} добавить аттрибуты
23
- * props {object} добавить свойства
24
- * class {string} добавить в className
18
+ * tag {string} - тег html элемента (для указания в children например)
19
+ * svg {boolean} - создавать как SVG элемент
20
+ * context {object} - контекст для параметра 'var' и вызовов 'also'
21
+ * text {string} - добавить в textContent
22
+ * html {string} - добавить в innerHTML
23
+ * attrs {object} - добавить аттрибуты
24
+ * props {object} - добавить свойства
25
+ * class {string} - добавить в className
25
26
* also {function} - вызвать с текущим компонентом: { ... , also(el) { console.log(el); }, }
26
27
* export {array} - положить в 0 ячейку указанного массива
27
- * var {string} создаёт переменную $имя в указанном контексте
28
- * events {object} добавляет addEventListener'ы {event: handler}
28
+ * push {array} - добавить к массиву
29
+ * var {string} - создаёт переменную $имя в указанном контексте
30
+ * events {object} - добавляет addEventListener'ы {event: handler}
29
31
* parent - {Element} добавляет компонент к указанному элементу (имеет смысл только для корневого компонента)
30
- * style {string | object} объект в виде { padding: '0px', ... } или строка css стилей
31
- * children - массив DOM, Component, object, html string
32
- * child - DOM, Component, object, html string
32
+ * style {string | object} - объект в виде { padding: '0px', ... } или строка css стилей
33
+ * children/children_r - массив DOM, Component, object, html string. _r - заменить имеющиеся
34
+ * child/child_r - DOM, Component, object, html string. _r - заменить имеющиеся
33
35
* всё остальное будет добавлено как property
34
36
*/
35
37
static make ( tag , data = { } , svg = false ) {
@@ -42,36 +44,6 @@ export class Component {
42
44
return Component . make ( tag , data , true ) ;
43
45
}
44
46
45
- /**
46
- * Создать теневой компонент от указанного tag, дети подключатся к нему в shadowRoot
47
- * @param {string|Node } host html tag теневого элемента или Node
48
- * @param {object } data параметры внешнего элемента
49
- * @param {string } sheet css стили
50
- * @returns {Node } host
51
- */
52
- static makeShadow ( host , data = { } , sheet = null ) {
53
- if ( ! host || typeof data !== 'object' ) return null ;
54
-
55
- let $host = ( host instanceof Node ) ? host : document . createElement ( host ) ;
56
- $host . attachShadow ( { mode : 'open' } ) ;
57
-
58
- Component . config ( $host . shadowRoot , {
59
- context : data . context ,
60
- children : [
61
- {
62
- tag : 'style' ,
63
- textContent : sheet ?? '' ,
64
- } ,
65
- data . child ?? { } ,
66
- ...( data . children ?? [ ] ) ,
67
- ]
68
- } ) ;
69
- delete data . children ;
70
- delete data . child ;
71
- Component . config ( $host , data ) ;
72
- return $host ;
73
- }
74
-
75
47
/**
76
48
* Настроить элемент
77
49
* @param {Node } el элемент
@@ -109,15 +81,16 @@ export class Component {
109
81
case 'context' :
110
82
case 'svg' :
111
83
continue ;
112
- case 'text' : el . textContent = val ; break ;
84
+ case 'text' : el . textContent = val + '' ; break ;
113
85
case 'html' : el . innerHTML = val ; break ;
114
86
case 'class' : el . classList . add ( ...val . split ( ' ' ) ) ; break ;
115
87
case 'also' : if ( context ) val . call ( context , el ) ; break ;
116
88
case 'export' : val [ 0 ] = el ; break ;
89
+ case 'push' : val . push ( el ) ; break ;
117
90
case 'var' : if ( context ) context [ '$' + val ] = el ; break ;
118
91
case 'events' : for ( let ev in val ) if ( val [ ev ] ) el . addEventListener ( ev , val [ ev ] . bind ( context ) ) ; break ;
119
92
case 'parent' : if ( val instanceof Node || val instanceof DocumentFragment ) val . append ( el ) ; break ;
120
- case 'attrs' : for ( let attr in val ) el . setAttribute ( attr , val [ attr ] ) ; break ;
93
+ case 'attrs' : for ( let attr in val ) svg ? el . setAttributeNS ( null , attr , val [ attr ] ) : el . setAttribute ( attr , val [ attr ] ) ; break ;
121
94
case 'props' : for ( let prop in val ) el [ prop ] = val [ prop ] ; break ;
122
95
case 'child_r' : el . replaceChildren ( ) ;
123
96
case 'child' : addChild ( val ) ; break ;
@@ -150,72 +123,86 @@ export class Component {
150
123
static makeArraySVG ( arr ) {
151
124
return Component . makeArray ( arr , true ) ;
152
125
}
126
+
127
+ /**
128
+ * Создать теневой компонент от указанного tag, дети подключатся к нему в shadowRoot
129
+ * @param {string|Node } host html tag теневого элемента или Node
130
+ * @param {object } data параметры внешнего элемента
131
+ * @param {string } sheet css стили
132
+ * @returns {Node } host
133
+ */
134
+ static makeShadow ( host , data = { } , sheet = null ) {
135
+ if ( ! host || typeof data !== 'object' ) return null ;
136
+
137
+ let $host = ( host instanceof Node ) ? host : document . createElement ( host ) ;
138
+ $host . attachShadow ( { mode : 'open' } ) ;
139
+
140
+ Component . config ( $host . shadowRoot , {
141
+ context : data . context ,
142
+ children : [
143
+ {
144
+ tag : 'style' ,
145
+ textContent : sheet ?? '' ,
146
+ } ,
147
+ data . child ?? { } ,
148
+ ...( data . children ?? [ ] ) ,
149
+ ]
150
+ } ) ;
151
+ delete data . children ;
152
+ delete data . child ;
153
+ Component . config ( $host , data ) ;
154
+ return $host ;
155
+ }
153
156
}
154
157
155
158
export class Sheet {
156
159
/**
157
160
* Добавить стиль с уникальным id в head. ext - стиль можно будет удалить по id
158
- * @param {string|array } style стили в виде css строки или [ 'class', ['color: red', 'padding: 0'], ... ]
161
+ * @param {string|array } style стили в виде css строки
159
162
* @param {string|this } id уникальный id стиля. При передаче this будет именем класса
160
163
* @param {boolean } ext внешний стиль - может быть удалён по id
161
164
*/
162
165
static addStyle ( style , id , ext = false ) {
163
166
if ( ! style || ! id ) return ;
164
167
if ( typeof id === 'object' ) id = id . constructor . name ;
165
168
166
- if ( ! Sheet . #internal. has ( id ) && ! Sheet . #external. has ( id ) ) {
167
- if ( typeof style === 'object' ) {
168
- let str = '' ;
169
- let f = 0 ;
170
- for ( const v of style ) {
171
- if ( f = ! f ) {
172
- str += v ;
173
- } else {
174
- str += '{' ;
175
- for ( const rule of v ) str += rule + ';' ;
176
- str += '}' ;
177
- }
178
- }
179
- style = str ;
180
- }
181
-
169
+ if ( ! Sheet . #int. has ( id ) && ! Sheet . #ext. has ( id ) ) {
182
170
if ( ext ) {
183
171
let sheet = document . createElement ( 'style' ) ;
184
172
document . head . appendChild ( sheet ) ;
185
- sheet . sheet . insertRule ( style ) ;
186
- Sheet . #external . set ( id , sheet ) ;
173
+ sheet . textContent = style ;
174
+ Sheet . #ext . set ( id , sheet ) ;
187
175
} else {
188
- if ( ! Sheet . #sheet) {
189
- Sheet . #sheet = document . head . appendChild ( document . createElement ( 'style' ) ) . sheet ;
190
- }
191
- Sheet . #sheet. insertRule ( style ) ;
192
- Sheet . #internal. add ( id ) ;
176
+ if ( ! Sheet . #sheet) Sheet . #sheet = document . head . appendChild ( document . createElement ( 'style' ) ) ;
177
+ Sheet . #sheet. textContent += style + '\r\n' ;
178
+ Sheet . #int. add ( id ) ;
193
179
}
194
180
}
195
181
}
196
182
197
183
/**
198
184
* Удалить ext стиль по его id
199
- * @param {string } id id стиля
185
+ * @param {string } id id стиля. При передаче this будет именем класса
200
186
*/
201
187
static removeStyle ( id ) {
202
- if ( Sheet . #external. has ( id ) ) {
203
- Sheet . #external. get ( id ) . remove ( ) ;
204
- Sheet . #external. delete ( id ) ;
188
+ if ( typeof id === 'object' ) id = id . constructor . name ;
189
+ if ( Sheet . #ext. has ( id ) ) {
190
+ Sheet . #ext. get ( id ) . remove ( ) ;
191
+ Sheet . #ext. delete ( id ) ;
205
192
}
206
193
}
207
194
208
- static #sheet;
209
- static #internal = new Set ( ) ;
210
- static #external = new Map ( ) ;
195
+ static #sheet = null ;
196
+ static #int = new Set ( ) ;
197
+ static #ext = new Map ( ) ;
211
198
}
212
199
213
200
export class StyledComponent extends Component {
214
201
/**
215
202
* Создать компонент и поместить его в переменную $root
216
203
* @param {string } tag html tag элемента
217
204
* @param {object } data параметры
218
- * @param {string|array } style стили в виде css строки или [ 'class', ['color: red', 'padding: 0'], ... ]
205
+ * @param {string|array } style стили в виде css строки
219
206
* @param {string|this } id уникальный id стиля. При передаче this будет именем класса
220
207
* @param {boolean } ext внешний стиль - может быть удалён по id
221
208
*/
@@ -228,7 +215,7 @@ export class StyledComponent extends Component {
228
215
* Создать компонент
229
216
* @param {string } tag html tag элемента
230
217
* @param {object } data параметры
231
- * @param {string|array } style стили в виде css строки или [ 'class', ['color: red', 'padding: 0'], ... ]
218
+ * @param {string|array } style стили в виде css строки
232
219
* @param {string|this } id уникальный id стиля. При передаче this будет именем класса
233
220
* @param {boolean } ext внешний стиль - может быть удалён по id
234
221
*/
0 commit comments