File tree Expand file tree Collapse file tree 7 files changed +57
-20
lines changed
Expand file tree Collapse file tree 7 files changed +57
-20
lines changed Original file line number Diff line number Diff line change 1+ ---
2+ " lingo.dev " : patch
3+ ---
4+
5+ prevent HTML tag duplication in Android bucket
Original file line number Diff line number Diff line change 9595 <item >@drawable/icon2</item >
9696 </array >
9797
98+ <string name =" terms_of_use_raw" ><u >Terms of Use</u ></string >
99+
98100 <!-- Resource IDs - will not be translated (copied as-is to target locales) -->
99101 <item type =" id" name =" button_ok" />
100102
103+ <string name =" view_your_options" ><u >View your options</u ></string >
104+
101105</resources >
Original file line number Diff line number Diff line change 2323
2424 <string name =" html_snippet" >< b> Negrita< /b> </string >
2525
26- <string name =" apostrophe_example" >¡No olvides!</string >
26+ <string name =" apostrophe_example" >¡No lo olvides!</string >
2727
2828 <string name =" cdata_example" ><![CDATA[ Los usuarios solo pueden ver tu comentario después de registrarse. <u>Más información.</u>]]> </string >
2929
4949 <item >@drawable/icon2</item >
5050 </array >
5151
52+ <string name =" terms_of_use_raw" >< u> Términos de uso< /u> </string >
53+
5254 <item type =" id" name =" button_ok" ></item >
5355
56+ <string name =" view_your_options" >< u> Ver tus opciones< /u> </string >
57+
5458</resources >
Original file line number Diff line number Diff line change @@ -4,13 +4,14 @@ checksums:
44 app_name: 7dc70110429d46e3685f385bd2cc941c
55 welcome_message: 0468579ef2fbc83c9d520c2f2f1c5059
66 button_text: 1d5f030c4ec9c869e647ae060518b948
7- html_snippet: f060191b1af70b3848106a4df91f43cd
8- apostrophe_example: 997099339b144b06266f8da411de8d93
9- cdata_example: ba876d1379f854628eaebf67ea330ccc
107 color_names/0: bace0083b78cdb188523bc4abc7b55c6
118 color_names/1: 482ff383a4258357ba404f283682471d
12- color_names/2: a5cf034b2d370a976119335cd99f4217
13- mixed_items/0: 9278f79dfb062c6c04f6395108907816
14- mixed_items/1: 9823a57cbe6e6e84c1d025ce24a1eec4
9+ color_names/2: a3f56a5c28ea75888356c2280aadc0e7
1510 notification_count/one: fe0aceb70f334c52a87937c36898a1d0
1611 notification_count/other: 13acfd95b16962ebe1f67dcd343513e1
12+ html_snippet: f060191b1af70b3848106a4df91f43cd
13+ apostrophe_example: 997099339b144b06266f8da411de8d93
14+ cdata_example: b88d55f92c4a90f64016e497051e997d
15+ mixed_items/0: 31c5d470a2fe8e1ae88e964fc673aee3
16+ mixed_items/1: 9823a57cbe6e6e84c1d025ce24a1eec4
17+ terms_of_use_raw: e3048f75742e66473369a83c10ea95c3
Original file line number Diff line number Diff line change @@ -422,6 +422,8 @@ checksums:
422422 cdata_example: b88d55f92c4a90f64016e497051e997d
423423 mixed_items/0: 31c5d470a2fe8e1ae88e964fc673aee3
424424 mixed_items/1: 9823a57cbe6e6e84c1d025ce24a1eec4
425+ terms_of_use_raw: e3048f75742e66473369a83c10ea95c3
426+ view_your_options: 416ed59ca3254f9da0d565c7c75f9033
425427 df547e152136431bbc29e26ae0eeabb4:
426428 title: 0468579ef2fbc83c9d520c2f2f1c5059
427429 description: 49f8864eb0e53903f04532bf33e1e4fa
Original file line number Diff line number Diff line change @@ -94,6 +94,34 @@ describe("android loader", () => {
9494 } ) ;
9595 } ) ;
9696
97+ it ( "should correctly handle HTML markup in strings during push without duplication" , async ( ) => {
98+ const input = `
99+ <resources>
100+ <string name="terms_of_use"><u>Terms of Use</u></string>
101+ <string name="welcome">Welcome to <b>Android</b>!</string>
102+ </resources>
103+ ` . trim ( ) ;
104+
105+ const androidLoader = createAndroidLoader ( ) . setDefaultLocale ( "en" ) ;
106+
107+ // Pull first to initialize loader state
108+ await androidLoader . pull ( "en" , input ) ;
109+
110+ // Push translated content with HTML
111+ const pushed = await androidLoader . push ( "es" , {
112+ terms_of_use : "<u>Términos de uso</u>" ,
113+ welcome : "Bienvenido a <b>Android</b>!" ,
114+ } ) ;
115+
116+ // Verify no duplication - should only contain escaped HTML, not both escaped and unescaped
117+ expect ( pushed ) . toContain ( "<u>Términos de uso</u>" ) ;
118+ expect ( pushed ) . not . toContain ( "<u>Términos de uso</u><u>" ) ;
119+ expect ( pushed ) . not . toContain ( "<u>Terms of Use</u><u>Términos de uso</u>" ) ;
120+
121+ expect ( pushed ) . toContain ( "<b>Android</b>" ) ;
122+ expect ( pushed ) . not . toContain ( "<b>Android</b><b>" ) ;
123+ } ) ;
124+
97125 it ( "should correctly handle format strings" , async ( ) => {
98126 const input = `
99127 <resources>
Original file line number Diff line number Diff line change @@ -641,19 +641,12 @@ function setTextualNodeContent(
641641 : escapeAndroidString ( value ) ;
642642 node . _ = escapedValue ;
643643
644- node . $$ = node . $$ ?? [ ] ;
645- let textNode = node . $$ . find (
646- ( child : any ) =>
647- child [ "#name" ] === "__text__" || child [ "#name" ] === "__cdata" ,
648- ) ;
649-
650- if ( ! textNode ) {
651- textNode = { } ;
652- node . $$ . push ( textNode ) ;
653- }
654-
655- textNode [ "#name" ] = useCdata ? "__cdata" : "__text__" ;
656- textNode . _ = escapedValue ;
644+ // Replace entire children array to avoid duplicating inline HTML elements
645+ // When inline HTML exists (e.g., <b>text</b>), xml2js creates element nodes
646+ // in node.$$ that would otherwise be serialized alongside the escaped text
647+ node . $$ = [
648+ { "#name" : useCdata ? "__cdata" : "__text__" , _ : escapedValue }
649+ ] ;
657650}
658651
659652function buildResourceNameMap (
You can’t perform that action at this time.
0 commit comments