PluginProbe ʕ •ᴥ•ʔ
Kubio AI Page Builder / 1.6.4
Kubio AI Page Builder v1.6.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 4 years ago Props 3 years ago BlockStyleRender.php 4 years ago DynamicStyles.php 3 years ago GlobalStyleRender.php 4 years ago MainAttribute.php 4 years ago ParserUtils.php 4 years ago StyleManager.php 4 years ago StyleParser.php 4 years ago StyleRender.php 3 years ago Utils.php 4 years ago
StyleRender.php
817 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
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
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
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
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
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
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 $selectors = $composeSelector(
260 $ancestorName,
261 $elementName,
262 $elementStateName
263 );
264 $value = array();
265 LodashBasic::set(
266 $value,
267 LodashBasic::concat( array( $media ), $selectors ),
268 $elementStateStyle
269 );
270 $mapped = LodashBasic::merge( $mapped, $value );
271 }
272 }
273 }
274 }
275 return $mapped;
276 }
277 }
278
279 class BasicPropsConfig {
280
281 public function __construct( $props ) {
282 foreach ( $props as $name => $value ) {
283 $this->$name = $value;
284 }
285 }
286 }
287
288 class StateConfig extends BasicPropsConfig {
289
290 public $selector = false;
291 public $stateRedirectElement = false;
292 }
293
294 class ElementConfig extends BasicPropsConfig {
295
296 const STATE_KEY = '{{state}}';
297 public $usePrefix = true;
298 public $useParentPrefix = false;
299 public $useWrapperPrefix = false;
300 public $ancestor = false;
301 public $selector = false;
302 public $statesConfig = array();
303 public $statesById = array();
304 public $selectorPrepend = false;
305 public $prefixWithTag = false;
306
307 public function getSelector( $state = null ) {
308 if ( $this->isSelectorPerState() ) {
309 $defaultSelector = LodashBasic::get( $this->selector, 'default' );
310 $elementSelector = LodashBasic::get(
311 $this->selector,
312 $state,
313 $defaultSelector
314 );
315 $elementSelector = str_replace(
316 self::STATE_KEY,
317 $this->getStateConfig( $state )->selector,
318 $elementSelector
319 );
320 } else {
321 $elementSelector = $this->selector;
322 }
323 return $elementSelector;
324 }
325
326 public function isSelectorPerState() {
327 return is_array( $this->selector );
328 }
329
330 public function getStateConfig( $state ) {
331 $props = LodashBasic::merge(
332 $this->statesById[ $state ],
333 LodashBasic::get( $this->statesConfig, 'default', array() ),
334 LodashBasic::get( $this->statesConfig, $state, array() )
335 );
336 return new StateConfig( $props );
337 }
338 public function shouldPrependAncestor( $ancestor ) {
339 return $this->ancestor !== $ancestor;
340 }
341
342 public function shouldAppendStateSelector() {
343 if ( $this->isSelectorPerState() ) {
344 return false;
345 }
346 if (
347 is_string( $this->selector ) &&
348 str_contains( $this->selector, self::STATE_KEY )
349 ) {
350 return false;
351 }
352 return true;
353 }
354 }
355
356 class StyleRender {
357
358 public static $prefixSelectorsByType = array(
359 'shared' => '#kubio',
360 'local' => '#kubio',
361 'dynamic' => 'body',
362 'global' => '',
363 );
364
365 public $prefixParents;
366 protected $parser;
367 protected $model = array();
368 protected $styledElementsByName = array();
369 protected $styledElementsEnum = array();
370
371 protected $statesByElement;
372 protected $statesById;
373
374 protected $allowedElements;
375 protected $htmlSupport;
376 protected $baseClass;
377
378 protected $wrapperElement;
379
380 public $useParentPrefix = false;
381
382 public $skipSharedStyleRender = false;
383
384 public function __construct( $options ) {
385 $this->parser = StyleParser::getInstance();
386 $this->statesById = Config::statesById();
387 $this->prefixParents = array();
388 $this->useParentPrefix = false;
389 $this->htmlSupport = true;
390 $this->baseClass = '';
391
392 $this->loadOptions( $options );
393
394 $this->allowedElements = LodashBasic::concat(
395 array( 'default' ),
396 array_keys( $this->styledElementsByName ),
397 array_values( $this->styledElementsEnum )
398 );
399 $this->statesByElement = $this->getStatesByElement();
400 }
401
402 public function loadOptions( $options ) {
403 foreach ( $options as $name => $value ) {
404 if ( property_exists( $this, $name ) ) {
405 $this->{$name} = $value;
406 }
407 }
408 }
409
410 public function getStatesByElement() {
411 $statesByElement = array();
412 foreach ( $this->styledElementsByName as $name => $item ) {
413 $statesByElement[ $name ] = LodashBasic::get(
414 $item,
415 array( 'supports', Config::$statesKey ),
416 array( 'normal', 'hover' )
417 );
418 }
419 return $statesByElement;
420 }
421
422 public static function normalizeData(
423 $mainAttr,
424 $styledElementsByName,
425 $styledElementsEnum
426 ) {
427 $model = array(
428 'style' => array(
429 'local' => LodashBasic::get( $mainAttr, '_style', array() ),
430 'shared' => LodashBasic::get( $mainAttr, 'style', array() ),
431 ),
432 'props' => array(
433 'local' => LodashBasic::get( $mainAttr, '_props', array() ),
434 'shared' => LodashBasic::get( $mainAttr, 'props', array() ),
435 ),
436 'id' => LodashBasic::get( $mainAttr, 'id' ),
437 'styleRef' => LodashBasic::get( $mainAttr, 'styleRef' ),
438 );
439
440 foreach ( $styledElementsEnum as $elementName ) {
441 if ( ! isset( $styledElementsByName[ $elementName ] ) ) {
442 $styledElementsByName[ $elementName ] = array();
443 }
444 }
445 return array(
446 'model' => $model,
447 'styledElementsByName' => $styledElementsByName,
448 'styledElementsEnum' => $styledElementsEnum,
449 );
450 }
451
452 public function export( $dynamicStyle = null ) {
453 $style = $this->model->style;
454 $css = array();
455
456 foreach ( $style as $styleType => $styleValue ) {
457 if (
458 $styleValue &&
459 ! ( $this->skipSharedStyleRender && $styleType == 'shared' )
460 ) {
461 $css[ $styleType ] = $this->convertStyleToCss(
462 $styleValue,
463 array(
464 'styledElementsByName' => $this->styledElementsByName,
465 'styleType' => $styleType,
466 )
467 );
468 }
469 }
470
471 if ( $dynamicStyle ) {
472 $css['dynamic'] = $this->convertStyleToCss(
473 self::normalizeDynamicStyle( $dynamicStyle ),
474 array(
475 'styledElementsByName' => $this->styledElementsByName,
476 'styleType' => 'dynamic',
477 )
478 );
479 }
480
481 return $css;
482 }
483
484 public function convertStyleToCss( $style, $settings ) {
485 $styleType = LodashBasic::get( $settings, 'styleType', 'shared' );
486 $rootPrefix = LodashBasic::get(
487 $settings,
488 'prefix',
489 self::$prefixSelectorsByType[ $styleType ]
490 );
491
492 $allowedElements = $this->getStyledElementsNames();
493
494 $ancestorsStyle = new AncestorsStyleRender(
495 $style,
496 new AncestorsStyleContext(
497 $this->model,
498 $allowedElements,
499 $this->htmlSupport
500 )
501 );
502
503 $composeSelectorWithPrefix = function (
504 $ancestor,
505 $element,
506 $state
507 ) use ( $rootPrefix, $styleType ) {
508 return $this->composeSelector(
509 $rootPrefix,
510 $styleType,
511 $ancestor,
512 $element,
513 $state
514 );
515 };
516
517 $jssByMedia = $ancestorsStyle->toCss( $composeSelectorWithPrefix, $styleType );
518
519 $cssByMedia = array();
520 foreach ( $jssByMedia as $media => $jssOnMedia ) {
521 LodashBasic::set(
522 $cssByMedia,
523 array( $media ),
524 array( self::renderJssToCss( $jssOnMedia ) )
525 );
526 }
527 return $cssByMedia;
528 }
529
530 public function getStyledElementsNames() {
531 return LodashBasic::concat( array(), array_keys( $this->styledElementsByName ) );
532 }
533
534 public function composeSelector(
535 $rootPrefix,
536 $styleType,
537 $ancestor,
538 $element,
539 $state
540 ) {
541 $elementConfig = $this->getElementData( $element );
542 $selectors = array();
543
544 if ( $elementConfig->usePrefix ) {
545 $selectors[] = $rootPrefix;
546 }
547
548 if ( $this->useParentPrefix || $elementConfig->useParentPrefix ) {
549 $selectors = array_merge( $selectors, $this->prefixParents );
550 }
551
552 $ancestorSelector =
553 $ancestor === 'default' ? '' : $this->ancestorToSelector( $ancestor );
554 $shouldPrependAncestor = $elementConfig->shouldPrependAncestor(
555 $ancestor
556 );
557 if ( $ancestorSelector && $shouldPrependAncestor ) {
558 $selectors[] = $ancestorSelector;
559 }
560
561 $isWrapperElement = $this->wrapperElement === $element;
562
563 $shouldPrefixWithWrapperSelector =
564 $this->wrapperElement &&
565 ( $elementConfig->selector || $elementConfig->useWrapperPrefix ) &&
566 $elementConfig->usePrefix &&
567 ! $isWrapperElement;
568
569 if ( $shouldPrefixWithWrapperSelector ) {
570 $selectors[] = $this->composeElementSelector(
571 $styleType,
572 $ancestor,
573 $this->wrapperElement
574 );
575 }
576
577 $stateConfig = $elementConfig->getStateConfig( $state );
578
579 if ( $stateConfig->stateRedirectElement ) {
580 $stateElementSelector = $this->composeElementSelector(
581 $styleType,
582 $ancestor,
583 $stateConfig->stateRedirectElement,
584 $state
585 );
586 $selectors[] = $stateElementSelector;
587
588 if ( $elementConfig->shouldAppendStateSelector() ) {
589 $selectors[] = '&' . $stateConfig->selector;
590 }
591 }
592
593 $mainSelector = $this->composeElementSelector(
594 $styleType,
595 $ancestor,
596 $element,
597 $state
598 );
599
600 if ( $ancestorSelector && ! $shouldPrependAncestor ) {
601 $mainSelector = $ancestorSelector . $mainSelector;
602 }
603
604 $selectors[] = $mainSelector;
605 if (
606 $elementConfig->shouldAppendStateSelector() &&
607 ! $stateConfig->stateRedirectElement &&
608 $stateConfig->selector
609 ) {
610 $selectors[] = '&' . $stateConfig->selector;
611 }
612
613 return $selectors;
614 }
615
616 public function getElementData( $elementName ) {
617 $elementConfig = isset( $this->styledElementsByName[ $elementName ] )
618 ? $this->styledElementsByName[ $elementName ]
619 : array();
620 return new ElementConfig(
621 array_merge( array( 'statesById' => $this->statesById ), $elementConfig )
622 );
623 }
624
625 /**
626 * @param $styleType
627 * @param $ancestor
628 * @param $element
629 *
630 * @return bool|string
631 */
632 public function composeElementSelector(
633 $styleType,
634 $ancestor,
635 $element,
636 $state = null
637 ) {
638 $elementConfig = $this->getElementData( $element );
639 $elementSelector = $elementConfig->getSelector( $state );
640 $isWrapperElement =
641 $this->wrapperElement && $this->wrapperElement === $element;
642
643 if (
644 $elementSelector === false ||
645 ( $isWrapperElement && $elementSelector )
646 ) {
647 $prefixWithTag =
648 $elementConfig->prefixWithTag === true
649 ? $elementConfig->props['tag']
650 : $elementConfig->prefixWithTag;
651
652 $composedSelector = $this->componentInstanceClass(
653 $element,
654 $styleType,
655 true,
656 $elementConfig->prefixWithTag ? $prefixWithTag : false
657 );
658
659 if ( $elementSelector ) {
660 if ( $elementConfig->selectorPrepend ) {
661 $composedSelector = self::composeSelectors(
662 $elementSelector,
663 '&' . $composedSelector
664 );
665 } else {
666 $composedSelector = self::composeSelectors(
667 $composedSelector,
668 $elementSelector
669 );
670 }
671 }
672
673 $elementSelector = $composedSelector;
674 }
675
676 return $elementSelector;
677 }
678
679 public function componentInstanceClass(
680 $name,
681 $type,
682 $asSelector = false,
683 $tag = false
684 ) {
685 $id = $this->model->styleRef;
686 switch ( $type ) {
687 case 'local':
688 $id = $this->componentLocalInstanceId( $type );
689 break;
690 }
691
692 $style_prefix = apply_filters(
693 'kubio/element-style-class-prefix',
694 'style-'
695 );
696
697 $tagPrefix = $tag ? $tag : '';
698 $className = $style_prefix . $id . ( $name ? '-' . $name : '' );
699 return $asSelector ? $tagPrefix . '.' . $className : $className;
700 }
701
702 public function componentLocalInstanceId( $type ) {
703 return $type . '-' . $this->model->id;
704 }
705
706 public static function renderJssToCss( $jss, $inherited_selector = '' ) {
707 $result = '';
708 $nested = array();
709 $properties = array();
710
711 $style_join = array(
712 'new_line' => '',
713 'tab' => '',
714 );
715
716 if ( CoreUtils::isDebug() ) {
717 $style_join = array(
718 'new_line' => "\n",
719 'tab' => "\t",
720 );
721 }
722
723 foreach ( $jss as $key => $value ) {
724 if ( ! is_array( $value ) ) {
725 $properties[] = join(
726 ':',
727 array(
728 LodashBasic::kebabCase( $key ),
729 $value,
730 )
731 );
732 } else {
733 $nested[ $key ] = $value;
734 }
735 }
736
737 if ( count( $properties ) ) {
738 $result .=
739 $inherited_selector .
740 "{{$style_join['new_line']}" .
741 join( ';', $properties ) . ';' .
742 "{$style_join['new_line']}}{$style_join['new_line']}";
743 }
744
745 foreach ( $nested as $nested_selector => $value ) {
746 $new_selector = self::composeSelectors(
747 $inherited_selector,
748 $nested_selector
749 );
750 $result .= self::renderJssToCss( $value, $new_selector );
751 }
752
753 return $result;
754 }
755
756 public static function composeSelectors(
757 $inherited_selector_str,
758 $nested_selector
759 ) {
760 $selector_parts = array();
761 $selectors = explode( ',', $nested_selector );
762 $inherited_selectors = explode( ',', $inherited_selector_str );
763
764 foreach ( $inherited_selectors as $inherited_selector ) {
765 $inherited_selector = \_\trim( $inherited_selector );
766
767 foreach ( $selectors as $selector ) {
768 $selector = \_\trim( $selector );
769 $is_compounded = strpos( $selector, '&' ) !== false;
770
771 if ( $is_compounded ) {
772 $compounded_selector = str_replace( '&', trim( $inherited_selector ), $selector );
773 array_push(
774 $selector_parts,
775 $compounded_selector
776 );
777 } else {
778 array_push(
779 $selector_parts,
780 join(
781 ' ',
782 LodashBasic::compact( array( $inherited_selector, trim( $selector ) ) )
783 )
784 );
785 }
786 }
787 }
788
789 return join( ',', LodashBasic::uniq( $selector_parts ) );
790 }
791
792 public static function normalizeDynamicStyle( $dynamicStyleByElements ) {
793 $converted = array();
794 foreach ( $dynamicStyleByElements as $elementName => $styleByMedia ) {
795 $newStyle = array( 'media' => array() );
796 if ( isset( $styleByMedia['desktop'] ) ) {
797 $newStyle = $styleByMedia['desktop'];
798 }
799 foreach ( $styleByMedia as $media => $style ) {
800 if ( $media !== 'desktop' ) {
801 LodashBasic::set( $newStyle, array( 'media', $media ), $style );
802 }
803 }
804 LodashBasic::set(
805 $converted,
806 array( 'descendants', $elementName ),
807 $newStyle
808 );
809 }
810 return $converted;
811 }
812 public function ancestorToSelector( $name ) {
813 $selector = Config::value( array( 'ancestors', $name, 'selector' ) );
814 return $selector;
815 }
816 }
817