PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / 2.5.2
Kubio AI Page Builder v2.5.2
2.8.5 2.8.4 2.8.3 2.8.2 2.8.1 trunk 1.0.0 1.0.1 1.1.0 1.2.0 1.2.1 1.2.2 1.2.3 1.3.0 1.3.1 1.3.2 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.7.0 1.7.1 1.7.2 1.7.3 1.8.0 1.8.1 1.8.2 1.9.0 2.0.0 2.1.1 2.1.2 2.1.3 2.2.0 2.2.3 2.2.4 2.2.5 2.3.0 2.3.1 2.3.3 2.3.4 2.4.0 2.4.1 2.4.2 2.4.3 2.4.5 2.5.0 2.5.1 2.5.2 2.5.3 2.6.0 2.6.1 2.6.2 2.6.3 2.6.5 2.6.6 2.6.7 2.7.0 2.7.1 2.7.2 2.7.3 2.8.0
kubio / lib / src / Core / StyleManager / StyleRender.php
kubio / lib / src / Core / StyleManager Last commit date
Generics 1 year ago Props 1 year ago BlockStyleRender.php 1 year ago DynamicStyles.php 1 year ago GlobalStyleRender.php 1 year ago MainAttribute.php 4 years ago ParserUtils.php 1 year ago StyleManager.php 2 years ago StyleParser.php 1 year ago StyleRender.php 1 year ago Utils.php 1 year ago
StyleRender.php
832 lines
1 <?php
2
3 namespace Kubio\Core\StyleManager;
4
5 use Kubio\Config;
6 use Kubio\Core\LodashBasic;
7 use Kubio\Core\Utils as CoreUtils;
8
9 use function _\concat;
10 use function _\uniq;
11 use function array_merge;
12 use function count;
13 use function is_array;
14 use function is_string;
15 use function str_contains;
16 use function str_replace;
17 #[\AllowDynamicProperties]
18 class ElementStyleStateRender {
19
20 private $name;
21 private $style;
22
23 public function __construct( $name, $style ) {
24 $this->name = $name;
25 $this->style = $style;
26 }
27
28 public function toCss( $options = null ) {
29 $context = array_merge( $options, array( 'state' => $this->name ) );
30 return StyleParser::getInstance()->transform(
31 LodashBasic::omit( (array) $this->style, 'ancestor' ),
32 $context
33 );
34 }
35 }
36 #[\AllowDynamicProperties]
37 class ElementStyleMediaRender {
38
39 const DEFAULT_STATE = 'normal';
40 private $name;
41 private $style;
42 private $byState = array();
43 private $desktopMediaRender = null;
44
45 public function __construct( $mediaName, $mediaStyle, $desktopMediaRender = null ) {
46 $this->name = $mediaName;
47 $this->style = $mediaStyle;
48 $this->desktopMediaRender = $desktopMediaRender;
49
50 if ( $desktopMediaRender ) {
51 $mediaStyle = LodashBasic::mergeSkipSeqArray( array(), $desktopMediaRender->style, $mediaStyle );
52 }
53
54 $defaultStyle = LodashBasic::get(
55 $mediaStyle,
56 array( self::DEFAULT_STATE ),
57 array()
58 );
59
60 if ( $mediaStyle ) {
61 foreach ( $mediaStyle as $stateName => $stateStyle ) {
62 $mergedStyle =
63 $stateName === self::DEFAULT_STATE
64 ? $stateStyle
65 : LodashBasic::merge( array(), $defaultStyle, $stateStyle );
66 if ( is_array( $mergedStyle ) && count( $mergedStyle ) ) {
67 $this->byState[ $stateName ] = new ElementStyleStateRender(
68 $stateName,
69 $mergedStyle
70 );
71 }
72 }
73 }
74 }
75
76 public function toCss( $options = null ) {
77 $result = array();
78
79 $result[ self::DEFAULT_STATE ] = isset(
80 $this->byState[ self::DEFAULT_STATE ]
81 )
82 ? $this->byState[ self::DEFAULT_STATE ]->toCss( $options )
83 : array();
84
85 foreach ( $this->byState as $stateName => $stateStyle ) {
86 if ( $stateName !== self::DEFAULT_STATE ) {
87 $stateCss = $stateStyle->toCss( $options );
88 if ( $stateCss ) {
89 $result[ $stateName ] = LodashBasic::diff(
90 $stateCss,
91 $result[ self::DEFAULT_STATE ]
92 );
93 }
94 }
95 }
96 return $result;
97 }
98 }
99 #[\AllowDynamicProperties]
100 class ElementStyleRender {
101
102 private $byMedias = array();
103 private $name;
104
105 private function getOrderedKeys( $byMedias ) {
106 return uniq( concat( array( 'desktop' ), array_keys( $byMedias ) ) );
107 }
108
109 public function __construct( $name, $style ) {
110 $this->name = $name;
111 $byOrderedMedias = $this->getOrderedKeys( $style );
112 $desktopMediaRender = null;
113 foreach ( $byOrderedMedias as $mediaName ) {
114 $mediaStyle = $style[ $mediaName ];
115
116 $this->byMedias[ $mediaName ] = new ElementStyleMediaRender(
117 $mediaName,
118 $mediaStyle,
119 $desktopMediaRender
120 );
121
122 if ( $mediaName == 'desktop' ) {
123 $desktopMediaRender = $this->byMedias[ $mediaName ];
124 }
125 }
126 }
127
128 public function toCss( $options = null ) {
129 $result = array();
130 $byOrderedMedias = $this->getOrderedKeys( $this->byMedias );
131 foreach ( $byOrderedMedias as $mediaName ) {
132 $mediaStyle = $this->byMedias[ $mediaName ];
133 $result[ $mediaName ] = $mediaStyle->toCss( $options );
134
135 if ( $mediaName !== 'desktop' ) {
136 $result[ $mediaName ] = LodashBasic::diff( $result[ $mediaName ], $result['desktop'] );
137 }
138 }
139 return $result;
140 }
141 }
142 #[\AllowDynamicProperties]
143 class AncestorStyleRender {
144
145 private $name;
146 private $elementsByName = array();
147
148 public function __construct( $name, $style ) {
149 $this->name = $name;
150 foreach ( $style as $elementName => $elementStyle ) {
151 $this->elementsByName[ $elementName ] = new ElementStyleRender(
152 $elementName,
153 $elementStyle
154 );
155 }
156 }
157
158 public function toCss( $options ) {
159 $result = array();
160 $allowedElements = $options['allowedElements'];
161 foreach ( $allowedElements as $elementName ) {
162 $elementStyle = LodashBasic::get(
163 $this->elementsByName,
164 $elementName,
165 false
166 );
167 if ( $elementStyle ) {
168 $result[ $elementName ] = $elementStyle->toCss(
169 LodashBasic::merge(
170 $options,
171 array(
172 'styledElement' => $elementName,
173 )
174 )
175 );
176 }
177 }
178 return $result;
179 }
180 }
181 #[\AllowDynamicProperties]
182 class AncestorsStyleContext {
183
184 public $allowedElements = array();
185 public $model = array();
186 public $htmlSupport = true;
187
188 public function __construct( $model, $allowedElements, $htmlSupport = true ) {
189 $this->model = $model;
190 $this->allowedElements = $allowedElements;
191 $this->htmlSupport = $htmlSupport;
192 }
193 }
194 #[\AllowDynamicProperties]
195 class AncestorsStyleRender {
196
197 private $ancestorsByName = array();
198 private $context = array();
199
200 private function getOrderedAncestors( $ancestors ) {
201 return uniq( concat( array( 'default' ), array_keys( $ancestors ) ) );
202 }
203
204 public function __construct( $style, $context = array() ) {
205 $this->context = $context;
206 $ancestor = LodashBasic::get( $style, 'ancestor', array() );
207 $ancestors = LodashBasic::merge(
208 array( 'default' => LodashBasic::omit( $style, 'ancestor' ) ),
209 $ancestor
210 );
211 $ordered_ancestors = $this->getOrderedAncestors( $ancestors );
212
213 $defaultNormalizedStyle = array();
214 foreach ( $ordered_ancestors as $ancestorName ) {
215 $ancestorStyle = $ancestors[ $ancestorName ];
216 $normalized = Utils::normalizeStyle(
217 $ancestorStyle,
218 array(
219 'allowedElements' => $context->allowedElements,
220 )
221 );
222
223 if ( $ancestorName !== 'default' ) {
224 $normalized = LodashBasic::mergeSkipSeqArray( array(), $defaultNormalizedStyle, $normalized );
225 } else {
226 $defaultNormalizedStyle = $normalized;
227 }
228
229 $this->ancestorsByName[ $ancestorName ] = new AncestorStyleRender(
230 $ancestorName,
231 $normalized
232 );
233 }
234 }
235
236 public function toCss( $composeSelector = null, $styleType = 'shared' ) {
237 $result = array();
238
239 $ordered_ancestors = $this->getOrderedAncestors( $this->ancestorsByName );
240
241 foreach ( $ordered_ancestors as $ancestorName ) {
242 $ancestorStyle = $this->ancestorsByName[ $ancestorName ];
243 $result[ $ancestorName ] = $ancestorStyle->toCss(
244 LodashBasic::merge( (array) $this->context, array( 'styleType' => $styleType ) )
245 );
246 if ( $ancestorName !== 'default' ) {
247 $result[ $ancestorName ] = LodashBasic::diff( $result[ $ancestorName ], $result['default'] );
248 }
249 }
250
251 $mapped = array();
252 foreach ( $result as $ancestorName => $ancestorStyle ) {
253 foreach ( $ancestorStyle as $elementName => $elementStyleByMedia ) {
254 foreach ( $elementStyleByMedia as $media => $elementMediaStyle ) {
255 foreach (
256 $elementMediaStyle
257 as $elementStateName => $elementStateStyle
258 ) {
259
260 if ( $elementStateName === 'visited' ) {
261 continue;
262 }
263
264 $selectors = $composeSelector(
265 $ancestorName,
266 $elementName,
267 $elementStateName
268 );
269 $value = array();
270 LodashBasic::set(
271 $value,
272 LodashBasic::concat( array( $media ), $selectors ),
273 $elementStateStyle
274 );
275 $mapped = LodashBasic::merge( $mapped, $value );
276 }
277 }
278 }
279 }
280 return $mapped;
281 }
282 }
283 #[\AllowDynamicProperties]
284 class BasicPropsConfig {
285
286 public function __construct( $props ) {
287 foreach ( $props as $name => $value ) {
288 $this->$name = $value;
289 }
290 }
291 }
292 #[\AllowDynamicProperties]
293 class StateConfig extends BasicPropsConfig {
294
295 public $selector = false;
296 public $stateRedirectElement = false;
297 }
298 #[\AllowDynamicProperties]
299 class ElementConfig extends BasicPropsConfig {
300
301 const STATE_KEY = '{{state}}';
302 public $usePrefix = true;
303 public $useParentPrefix = false;
304 public $useWrapperPrefix = false;
305 public $ancestor = false;
306 public $selector = false;
307 public $statesConfig = array();
308 public $statesById = array();
309 public $selectorPrepend = false;
310 public $prefixWithTag = false;
311
312 public function getSelector( $state = null ) {
313 if ( $this->isSelectorPerState() ) {
314 $defaultSelector = LodashBasic::get( $this->selector, 'default' );
315 $elementSelector = LodashBasic::get(
316 $this->selector,
317 $state,
318 $defaultSelector
319 );
320 if ( $elementSelector === null ) {
321 $elementSelector = '';
322 }
323 $elementSelector = str_replace(
324 self::STATE_KEY,
325 $this->getStateConfig( $state )->selector,
326 $elementSelector
327 );
328 } else {
329 $elementSelector = $this->selector;
330 }
331 return $elementSelector;
332 }
333
334 public function isSelectorPerState() {
335 return is_array( $this->selector );
336 }
337
338 public function getStateConfig( $state ) {
339 $props = LodashBasic::merge(
340 $this->statesById[ $state ],
341 LodashBasic::get( $this->statesConfig, 'default', array() ),
342 LodashBasic::get( $this->statesConfig, $state, array() )
343 );
344 return new StateConfig( $props );
345 }
346 public function shouldPrependAncestor( $ancestor ) {
347 return $this->ancestor !== $ancestor;
348 }
349
350 public function shouldAppendStateSelector() {
351 if ( $this->isSelectorPerState() ) {
352 return false;
353 }
354 if (
355 is_string( $this->selector ) &&
356 str_contains( $this->selector, self::STATE_KEY )
357 ) {
358 return false;
359 }
360 return true;
361 }
362 }
363 #[\AllowDynamicProperties]
364 class StyleRender {
365
366 public static $prefixSelectorsByType = array(
367 'shared' => '#kubio',
368 'local' => '#kubio',
369 'dynamic' => 'body',
370 'global' => '',
371 );
372
373 public $prefixParents;
374 protected $parser;
375 protected $model = array();
376 protected $styledElementsByName = array();
377 protected $styledElementsEnum = array();
378
379 protected $statesByElement;
380 protected $statesById;
381
382 protected $allowedElements;
383 protected $htmlSupport;
384 protected $baseClass;
385
386 protected $wrapperElement;
387
388 public $useParentPrefix = false;
389
390 public $skipSharedStyleRender = false;
391
392 public function __construct( $options ) {
393 $this->parser = StyleParser::getInstance();
394 $this->statesById = Config::statesById();
395 $this->prefixParents = array();
396 $this->useParentPrefix = false;
397 $this->htmlSupport = true;
398 $this->baseClass = '';
399
400 $this->loadOptions( $options );
401
402 $this->allowedElements = LodashBasic::concat(
403 array( 'default' ),
404 array_keys( $this->styledElementsByName ),
405 array_values( $this->styledElementsEnum )
406 );
407 $this->statesByElement = $this->getStatesByElement();
408 }
409
410 public function loadOptions( $options ) {
411 foreach ( $options as $name => $value ) {
412 if ( property_exists( $this, $name ) ) {
413 $this->{$name} = $value;
414 }
415 }
416 }
417
418 public function getStatesByElement() {
419 $statesByElement = array();
420 foreach ( $this->styledElementsByName as $name => $item ) {
421 $statesByElement[ $name ] = LodashBasic::get(
422 $item,
423 array( 'supports', Config::$statesKey ),
424 array( 'normal', 'hover' )
425 );
426 }
427 return $statesByElement;
428 }
429
430 public static function normalizeData(
431 $mainAttr,
432 $styledElementsByName,
433 $styledElementsEnum
434 ) {
435 $model = array(
436 'style' => array(
437 'local' => LodashBasic::get( $mainAttr, '_style', array() ),
438 'shared' => LodashBasic::get( $mainAttr, 'style', array() ),
439 ),
440 'props' => array(
441 'local' => LodashBasic::get( $mainAttr, '_props', array() ),
442 'shared' => LodashBasic::get( $mainAttr, 'props', array() ),
443 ),
444 'id' => LodashBasic::get( $mainAttr, 'id' ),
445 'styleRef' => LodashBasic::get( $mainAttr, 'styleRef' ),
446 );
447
448 foreach ( $styledElementsEnum as $elementName ) {
449 if ( ! isset( $styledElementsByName[ $elementName ] ) ) {
450 $styledElementsByName[ $elementName ] = array();
451 }
452 }
453 return array(
454 'model' => $model,
455 'styledElementsByName' => $styledElementsByName,
456 'styledElementsEnum' => $styledElementsEnum,
457 );
458 }
459
460 public function export( $dynamicStyle = null ) {
461 $style = $this->model->style;
462 $css = array();
463
464 foreach ( $style as $styleType => $styleValue ) {
465 if (
466 $styleValue &&
467 ! ( $this->skipSharedStyleRender && $styleType == 'shared' )
468 ) {
469 $css[ $styleType ] = $this->convertStyleToCss(
470 $styleValue,
471 array(
472 'styledElementsByName' => $this->styledElementsByName,
473 'styleType' => $styleType,
474 )
475 );
476 }
477 }
478
479 if ( $dynamicStyle ) {
480 $css['dynamic'] = $this->convertStyleToCss(
481 self::normalizeDynamicStyle( $dynamicStyle ),
482 array(
483 'styledElementsByName' => $this->styledElementsByName,
484 'styleType' => 'dynamic',
485 )
486 );
487 }
488
489 return $css;
490 }
491
492 public function convertStyleToCss( $style, $settings ) {
493 $styleType = LodashBasic::get( $settings, 'styleType', 'shared' );
494 $rootPrefix = LodashBasic::get(
495 $settings,
496 'prefix',
497 self::$prefixSelectorsByType[ $styleType ]
498 );
499
500 $allowedElements = $this->getStyledElementsNames();
501
502 $ancestorsStyle = new AncestorsStyleRender(
503 $style,
504 new AncestorsStyleContext(
505 $this->model,
506 $allowedElements,
507 $this->htmlSupport
508 )
509 );
510
511 $composeSelectorWithPrefix = function (
512 $ancestor,
513 $element,
514 $state
515 ) use (
516 $rootPrefix,
517 $styleType
518 ) {
519 return $this->composeSelector(
520 $rootPrefix,
521 $styleType,
522 $ancestor,
523 $element,
524 $state
525 );
526 };
527
528 $jssByMedia = $ancestorsStyle->toCss( $composeSelectorWithPrefix, $styleType );
529
530 $cssByMedia = array();
531 foreach ( $jssByMedia as $media => $jssOnMedia ) {
532 LodashBasic::set(
533 $cssByMedia,
534 array( $media ),
535 array( self::renderJssToCss( $jssOnMedia ) )
536 );
537 }
538 return $cssByMedia;
539 }
540
541 public function getStyledElementsNames() {
542 return LodashBasic::concat( array(), array_keys( $this->styledElementsByName ) );
543 }
544
545 public function composeSelector(
546 $rootPrefix,
547 $styleType,
548 $ancestor,
549 $element,
550 $state
551 ) {
552 $elementConfig = $this->getElementData( $element );
553 $selectors = array();
554
555 if ( $elementConfig->usePrefix ) {
556 $selectors[] = $rootPrefix;
557 }
558
559 if ( $this->useParentPrefix || $elementConfig->useParentPrefix ) {
560 $selectors = array_merge( $selectors, $this->prefixParents );
561 }
562
563 $ancestorSelector =
564 $ancestor === 'default' ? '' : $this->ancestorToSelector( $ancestor );
565 $shouldPrependAncestor = $elementConfig->shouldPrependAncestor(
566 $ancestor
567 );
568 if ( $ancestorSelector && $shouldPrependAncestor ) {
569 $selectors[] = $ancestorSelector;
570 }
571
572 $isWrapperElement = $this->wrapperElement === $element;
573
574 $shouldPrefixWithWrapperSelector =
575 $this->wrapperElement &&
576 ( $elementConfig->selector || $elementConfig->useWrapperPrefix ) &&
577 $elementConfig->usePrefix &&
578 ! $isWrapperElement;
579
580 if ( $shouldPrefixWithWrapperSelector ) {
581 $selectors[] = $this->composeElementSelector(
582 $styleType,
583 $ancestor,
584 $this->wrapperElement
585 );
586 }
587
588 $stateConfig = $elementConfig->getStateConfig( $state );
589
590 if ( $stateConfig->stateRedirectElement ) {
591 $stateElementSelector = $this->composeElementSelector(
592 $styleType,
593 $ancestor,
594 $stateConfig->stateRedirectElement,
595 $state
596 );
597 $selectors[] = $stateElementSelector;
598
599 if ( $elementConfig->shouldAppendStateSelector() ) {
600 $selectors[] = '&' . $stateConfig->selector;
601 }
602 }
603
604 $mainSelector = $this->composeElementSelector(
605 $styleType,
606 $ancestor,
607 $element,
608 $state
609 );
610
611 if ( $ancestorSelector && ! $shouldPrependAncestor ) {
612 $mainSelector = $ancestorSelector . $mainSelector;
613 }
614
615 $selectors[] = $mainSelector;
616 if (
617 $elementConfig->shouldAppendStateSelector() &&
618 ! $stateConfig->stateRedirectElement &&
619 $stateConfig->selector
620 ) {
621 $selectors[] = '&' . $stateConfig->selector;
622 }
623
624 return $selectors;
625 }
626
627 public function getElementData( $elementName ) {
628 $elementConfig = isset( $this->styledElementsByName[ $elementName ] )
629 ? $this->styledElementsByName[ $elementName ]
630 : array();
631 return new ElementConfig(
632 array_merge( array( 'statesById' => $this->statesById ), $elementConfig )
633 );
634 }
635
636 /**
637 * @param $styleType
638 * @param $ancestor
639 * @param $element
640 *
641 * @return bool|string
642 */
643 public function composeElementSelector(
644 $styleType,
645 $ancestor,
646 $element,
647 $state = null
648 ) {
649 $elementConfig = $this->getElementData( $element );
650 $elementSelector = $elementConfig->getSelector( $state );
651 $isWrapperElement =
652 $this->wrapperElement && $this->wrapperElement === $element;
653
654 if (
655 $elementSelector === false ||
656 ( $isWrapperElement && $elementSelector )
657 ) {
658 $prefixWithTag =
659 $elementConfig->prefixWithTag === true
660 ? $elementConfig->props['tag']
661 : $elementConfig->prefixWithTag;
662
663 if ( isset( $elementConfig->props['htmlTag'] ) && $elementConfig->prefixWithTag === true ) {
664 $prefixWithTag = $elementConfig->props['htmlTag'];
665 }
666
667 $composedSelector = $this->componentInstanceClass(
668 $element,
669 $styleType,
670 true,
671 $elementConfig->prefixWithTag ? $prefixWithTag : false
672 );
673
674 if ( $elementSelector ) {
675 if ( $elementConfig->selectorPrepend ) {
676 $composedSelector = self::composeSelectors(
677 $elementSelector,
678 '&' . $composedSelector
679 );
680 } else {
681 $composedSelector = self::composeSelectors(
682 $composedSelector,
683 $elementSelector
684 );
685 }
686 }
687
688 $elementSelector = $composedSelector;
689 }
690
691 return $elementSelector;
692 }
693
694 public function componentInstanceClass(
695 $name,
696 $type,
697 $asSelector = false,
698 $tag = false
699 ) {
700 $id = $this->model->styleRef;
701 switch ( $type ) {
702 case 'local':
703 $id = $this->componentLocalInstanceId( $type );
704 break;
705 }
706
707 $style_prefix = apply_filters(
708 'kubio/element-style-class-prefix',
709 'style-'
710 );
711
712 $tagPrefix = $tag ? $tag : '';
713 $className = $style_prefix . $id . ( $name ? '-' . $name : '' );
714 return $asSelector ? $tagPrefix . '.' . $className : $className;
715 }
716
717 public function componentLocalInstanceId( $type ) {
718 return $type . '-' . $this->model->id;
719 }
720
721 public static function renderJssToCss( $jss, $inherited_selector = '' ) {
722 $result = '';
723 $nested = array();
724 $properties = array();
725
726 $style_join = array(
727 'new_line' => '',
728 'tab' => '',
729 );
730
731 if ( CoreUtils::isDebug() ) {
732 $style_join = array(
733 'new_line' => "\n",
734 'tab' => "\t",
735 );
736 }
737
738 foreach ( $jss as $key => $value ) {
739 if ( ! is_array( $value ) ) {
740 $properties[] = join(
741 ':',
742 array(
743 LodashBasic::kebabCase( $key ),
744 $value,
745 )
746 );
747 } else {
748 $nested[ $key ] = $value;
749 }
750 }
751
752 if ( count( $properties ) ) {
753 $result .=
754 $inherited_selector .
755 "{{$style_join['new_line']}" .
756 join( ';', $properties ) . ';' .
757 "{$style_join['new_line']}}{$style_join['new_line']}";
758 }
759
760 foreach ( $nested as $nested_selector => $value ) {
761 $new_selector = self::composeSelectors(
762 $inherited_selector,
763 $nested_selector
764 );
765 $result .= self::renderJssToCss( $value, $new_selector );
766 }
767
768 return $result;
769 }
770
771 public static function composeSelectors(
772 $inherited_selector_str,
773 $nested_selector
774 ) {
775 $selector_parts = array();
776 $selectors = explode( ',', $nested_selector );
777 $inherited_selectors = explode( ',', $inherited_selector_str );
778
779 foreach ( $inherited_selectors as $inherited_selector ) {
780 $inherited_selector = \_\trim( $inherited_selector );
781
782 foreach ( $selectors as $selector ) {
783 $selector = \_\trim( $selector );
784 $is_compounded = strpos( $selector, '&' ) !== false;
785
786 if ( $is_compounded ) {
787 $compounded_selector = str_replace( '&', trim( $inherited_selector ), $selector );
788 array_push(
789 $selector_parts,
790 $compounded_selector
791 );
792 } else {
793 array_push(
794 $selector_parts,
795 join(
796 ' ',
797 LodashBasic::compact( array( $inherited_selector, trim( $selector ) ) )
798 )
799 );
800 }
801 }
802 }
803
804 return join( ',', LodashBasic::uniq( $selector_parts ) );
805 }
806
807 public static function normalizeDynamicStyle( $dynamicStyleByElements ) {
808 $converted = array();
809 foreach ( $dynamicStyleByElements as $elementName => $styleByMedia ) {
810 $newStyle = array( 'media' => array() );
811 if ( isset( $styleByMedia['desktop'] ) ) {
812 $newStyle = $styleByMedia['desktop'];
813 }
814 foreach ( $styleByMedia as $media => $style ) {
815 if ( $media !== 'desktop' ) {
816 LodashBasic::set( $newStyle, array( 'media', $media ), $style );
817 }
818 }
819 LodashBasic::set(
820 $converted,
821 array( 'descendants', $elementName ),
822 $newStyle
823 );
824 }
825 return $converted;
826 }
827 public function ancestorToSelector( $name ) {
828 $selector = Config::value( array( 'ancestors', $name, 'selector' ) );
829 return $selector;
830 }
831 }
832