@@ -41,7 +41,34 @@ import {
4141/**
4242 * Internal dependencies
4343 */
44- import { Fragment , RawHTML } from './' ;
44+ import {
45+ Fragment ,
46+ StrictMode ,
47+ } from './react' ;
48+ import RawHTML from './raw-html' ;
49+
50+ /**
51+ * Boolean reflecting whether the current environment supports Symbol.
52+ *
53+ * @link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol
54+ *
55+ * @type {boolean }
56+ */
57+ const HAS_SYMBOL = typeof Symbol === 'function' && Symbol . for ;
58+
59+ /**
60+ * Internal React symbol representing Provider type.
61+ *
62+ * @type {Symbol }
63+ */
64+ const REACT_PROVIDER_TYPE = HAS_SYMBOL ? Symbol . for ( 'react.provider' ) : 0xeacd ;
65+
66+ /**
67+ * Internal React symbol representing context (Consumer) type.
68+ *
69+ * @type {Symbol }
70+ */
71+ const REACT_CONTEXT_TYPE = HAS_SYMBOL ? Symbol . for ( 'react.context' ) : 0xeace ;
4572
4673/**
4774 * Valid attribute types.
@@ -430,18 +457,19 @@ function getNormalStylePropertyValue( property, value ) {
430457/**
431458 * Serializes a React element to string.
432459 *
433- * @param {WPElement } element Element to serialize.
434- * @param {?Object } context Context object.
460+ * @param {WPElement } element Element to serialize.
461+ * @param {?Object } context Context object.
462+ * @param {?Object } legacyContext Legacy context object.
435463 *
436464 * @return {string } Serialized element.
437465 */
438- export function renderElement ( element , context = { } ) {
466+ export function renderElement ( element , context , legacyContext = { } ) {
439467 if ( null === element || undefined === element || false === element ) {
440468 return '' ;
441469 }
442470
443471 if ( Array . isArray ( element ) ) {
444- return renderChildren ( element , context ) ;
472+ return renderChildren ( element , context , legacyContext ) ;
445473 }
446474
447475 switch ( typeof element ) {
@@ -452,11 +480,12 @@ export function renderElement( element, context = {} ) {
452480 return element . toString ( ) ;
453481 }
454482
455- const { type : tagName , props } = element ;
483+ const { type, props } = element ;
456484
457- switch ( tagName ) {
485+ switch ( type ) {
486+ case StrictMode :
458487 case Fragment :
459- return renderChildren ( props . children , context ) ;
488+ return renderChildren ( props . children , context , legacyContext ) ;
460489
461490 case RawHTML :
462491 const { children, ...wrapperProps } = props ;
@@ -467,20 +496,28 @@ export function renderElement( element, context = {} ) {
467496 ...wrapperProps ,
468497 dangerouslySetInnerHTML : { __html : children } ,
469498 } ,
470- context
499+ context ,
500+ legacyContext
471501 ) ;
472502 }
473503
474- switch ( typeof tagName ) {
504+ switch ( typeof type ) {
475505 case 'string' :
476- return renderNativeComponent ( tagName , props , context ) ;
506+ return renderNativeComponent ( type , props , context , legacyContext ) ;
477507
478508 case 'function' :
479- if ( tagName . prototype && typeof tagName . prototype . render === 'function' ) {
480- return renderComponent ( tagName , props , context ) ;
509+ if ( type . prototype && typeof type . prototype . render === 'function' ) {
510+ return renderComponent ( type , props , context , legacyContext ) ;
481511 }
482512
483- return renderElement ( tagName ( props , context ) , context ) ;
513+ return renderElement ( type ( props , legacyContext ) , context , legacyContext ) ;
514+ }
515+ switch ( type && type . $$typeof ) {
516+ case REACT_PROVIDER_TYPE :
517+ return renderChildren ( props . children , props . value , legacyContext ) ;
518+
519+ case REACT_CONTEXT_TYPE :
520+ return renderElement ( props . children ( context || type . _currentValue ) , context , legacyContext ) ;
484521 }
485522
486523 return '' ;
@@ -489,27 +526,28 @@ export function renderElement( element, context = {} ) {
489526/**
490527 * Serializes a native component type to string.
491528 *
492- * @param {?string } type Native component type to serialize, or null if
493- * rendering as fragment of children content.
494- * @param {Object } props Props object.
495- * @param {?Object } context Context object.
529+ * @param {?string } type Native component type to serialize, or null if
530+ * rendering as fragment of children content.
531+ * @param {Object } props Props object.
532+ * @param {?Object } context Context object.
533+ * @param {?Object } legacyContext Legacy context object.
496534 *
497535 * @return {string } Serialized element.
498536 */
499- export function renderNativeComponent ( type , props , context = { } ) {
537+ export function renderNativeComponent ( type , props , context , legacyContext = { } ) {
500538 let content = '' ;
501539 if ( type === 'textarea' && props . hasOwnProperty ( 'value' ) ) {
502540 // Textarea children can be assigned as value prop. If it is, render in
503541 // place of children. Ensure to omit so it is not assigned as attribute
504542 // as well.
505- content = renderChildren ( props . value , context ) ;
543+ content = renderChildren ( props . value , context , legacyContext ) ;
506544 props = omit ( props , 'value' ) ;
507545 } else if ( props . dangerouslySetInnerHTML &&
508546 typeof props . dangerouslySetInnerHTML . __html === 'string' ) {
509547 // Dangerous content is left unescaped.
510548 content = props . dangerouslySetInnerHTML . __html ;
511549 } else if ( typeof props . children !== 'undefined' ) {
512- content = renderChildren ( props . children , context ) ;
550+ content = renderChildren ( props . children , context , legacyContext ) ;
513551 }
514552
515553 if ( ! type ) {
@@ -528,41 +566,43 @@ export function renderNativeComponent( type, props, context = {} ) {
528566/**
529567 * Serializes a non-native component type to string.
530568 *
531- * @param {Function } Component Component type to serialize.
532- * @param {Object } props Props object.
533- * @param {?Object } context Context object.
569+ * @param {Function } Component Component type to serialize.
570+ * @param {Object } props Props object.
571+ * @param {?Object } context Context object.
572+ * @param {?Object } legacyContext Legacy context object.
534573 *
535574 * @return {string } Serialized element
536575 */
537- export function renderComponent ( Component , props , context = { } ) {
538- const instance = new Component ( props , context ) ;
576+ export function renderComponent ( Component , props , context , legacyContext = { } ) {
577+ const instance = new Component ( props , legacyContext ) ;
539578
540579 if ( typeof instance . getChildContext === 'function' ) {
541- Object . assign ( context , instance . getChildContext ( ) ) ;
580+ Object . assign ( legacyContext , instance . getChildContext ( ) ) ;
542581 }
543582
544- const html = renderElement ( instance . render ( ) , context ) ;
583+ const html = renderElement ( instance . render ( ) , context , legacyContext ) ;
545584
546585 return html ;
547586}
548587
549588/**
550589 * Serializes an array of children to string.
551590 *
552- * @param {Array } children Children to serialize.
553- * @param {?Object } context Context object.
591+ * @param {Array } children Children to serialize.
592+ * @param {?Object } context Context object.
593+ * @param {?Object } legacyContext Legacy context object.
554594 *
555595 * @return {string } Serialized children.
556596 */
557- function renderChildren ( children , context = { } ) {
597+ function renderChildren ( children , context , legacyContext = { } ) {
558598 let result = '' ;
559599
560600 children = castArray ( children ) ;
561601
562602 for ( let i = 0 ; i < children . length ; i ++ ) {
563603 const child = children [ i ] ;
564604
565- result += renderElement ( child , context ) ;
605+ result += renderElement ( child , context , legacyContext ) ;
566606 }
567607
568608 return result ;
0 commit comments