@@ -79,29 +79,41 @@ export default class Localized extends Component {
7979
8080 render ( ) {
8181 const { l10n, parseMarkup } = this . context ;
82- const { id, attrs, children : elem = null } = this . props ;
82+ const { id, attrs, children : child = null } = this . props ;
8383
8484 // Validate that the child element isn't an array
85- if ( Array . isArray ( elem ) ) {
85+ if ( Array . isArray ( child ) ) {
8686 throw new Error ( "<Localized/> expected to receive a single " +
8787 "React node child" ) ;
8888 }
8989
9090 if ( ! l10n ) {
9191 // Use the wrapped component as fallback.
92- return elem ;
92+ return child ;
9393 }
9494
9595 const bundle = l10n . getBundle ( id ) ;
9696
9797 if ( bundle === null ) {
9898 // Use the wrapped component as fallback.
99- return elem ;
99+ return child ;
100100 }
101101
102102 const msg = bundle . getMessage ( id ) ;
103103 const [ args , elems ] = toArguments ( this . props ) ;
104104
105+ // Check if the child inside <Localized> is a valid element -- if not, then
106+ // it's either null or a simple fallback string. No need to localize the
107+ // attributes.
108+ if ( ! isValidElement ( child ) ) {
109+ if ( msg . value ) {
110+ // Replace the fallback string with the message value;
111+ return bundle . formatPattern ( msg . value , args ) ;
112+ }
113+
114+ return child ;
115+ }
116+
105117 // The default is to forbid all message attributes. If the attrs prop exists
106118 // on the Localized instance, only set message attributes which have been
107119 // explicitly allowed by the developer.
@@ -115,34 +127,27 @@ export default class Localized extends Component {
115127 }
116128 }
117129
130+ // If the wrapped component is a known void element, explicitly dismiss the
131+ // message value and do not pass it to cloneElement in order to avoid the
132+ // "void element tags must neither have `children` nor use
133+ // `dangerouslySetInnerHTML`" error.
134+ if ( child . type in VOID_ELEMENTS ) {
135+ return cloneElement ( child , localizedProps ) ;
136+ }
137+
118138 // If the message has a null value, we're only interested in its attributes.
119139 // Do not pass the null value to cloneElement as it would nuke all children
120140 // of the wrapped component.
121141 if ( msg . value === null ) {
122- return cloneElement ( elem , localizedProps ) ;
142+ return cloneElement ( child , localizedProps ) ;
123143 }
124144
125145 const messageValue = bundle . formatPattern ( msg . value , args ) ;
126146
127- // Check if the fallback is a valid element -- if not then it's not
128- // markup (e.g. nothing or a fallback string) so just use the
129- // formatted message value
130- if ( ! isValidElement ( elem ) ) {
131- return messageValue ;
132- }
133-
134- // If the wrapped component is a known void element, explicitly dismiss the
135- // message value and do not pass it to cloneElement in order to avoid the
136- // "void element tags must neither have `children` nor use
137- // `dangerouslySetInnerHTML`" error.
138- if ( elem . type in VOID_ELEMENTS ) {
139- return cloneElement ( elem , localizedProps ) ;
140- }
141-
142147 // If the message value doesn't contain any markup nor any HTML entities,
143148 // insert it as the only child of the wrapped component.
144149 if ( ! reMarkup . test ( messageValue ) ) {
145- return cloneElement ( elem , localizedProps , messageValue ) ;
150+ return cloneElement ( child , localizedProps , messageValue ) ;
146151 }
147152
148153 // If the message contains markup, parse it and try to match the children
@@ -175,7 +180,7 @@ export default class Localized extends Component {
175180 return cloneElement ( sourceChild , null , childNode . textContent ) ;
176181 } ) ;
177182
178- return cloneElement ( elem , localizedProps , ...translatedChildren ) ;
183+ return cloneElement ( child , localizedProps , ...translatedChildren ) ;
179184 }
180185}
181186
0 commit comments