@@ -217,49 +217,55 @@ export class AddonModDataHelperProvider {
217
217
return '' ;
218
218
}
219
219
220
- // Replace the fields found on template.
221
- fields . forEach ( ( field ) => {
222
- let replace = `[[${ field . name } ]]` ;
223
- replace = replace . replace ( / [ - [ \] / { } ( ) * + ? . \\ ^ $ | ] / g, '\\$&' ) ;
224
- let replaceRegex = new RegExp ( replace , 'gi' ) ;
225
-
226
- const valuesInsideTags = new RegExp ( '>\\[\\[' + field . name + '\\]\\]<' , 'gi' ) ;
227
-
228
- if ( template . match ( valuesInsideTags ) ?. length ) {
229
- // Replace field by a generic directive.
230
- const hasOffline = entry . hasOffline ? 'true' : 'false' ;
231
-
232
- const render = `><addon-mod-data-field-plugin [field]="fields[${ field . id } ]" mode="${ mode } " [database]="database" \
233
- [value]="entries[${ entry . id } ].contents[${ field . id } ]" [recordHasOffline]="${ hasOffline } " \
234
- (gotoEntry)="gotoEntry($event)"></addon-mod-data-field-plugin><` ;
235
-
236
- template = template
237
- . replace ( valuesInsideTags , render )
238
- . replace ( replaceRegex , entry . contents [ field . id ] . content ) ;
239
- } else {
240
- // Replace field by a generic directive.
241
- const render = `<addon-mod-data-field-plugin [field]="fields[${ field . id } ]" mode="${ mode } " [database]="database" \
242
- [value]="entries[${ entry . id } ].contents[${ field . id } ]" [recordHasOffline]="${ entry . hasOffline ? 'true' : 'false' } " \
243
- (gotoEntry)="gotoEntry($event)"></addon-mod-data-field-plugin>` ;
244
-
245
- template = template . replace ( replaceRegex , render ) ;
246
- }
220
+ const replaceAll = ( text : string , pattern : string , replacement : string ) : string => {
221
+ const escapedPattern = pattern . replace ( / [ - [ \] / { } ( ) * + ? . \\ ^ $ | ] / g, '\\$&' ) ;
222
+
223
+ return text . replace ( new RegExp ( escapedPattern , 'gi' ) , replacement ) ;
224
+ } ;
247
225
248
- // Replace the field name tag.
249
- replace = `[[${ field . name } #name]]` ;
250
- replace = replace . replace ( / [ - [ \] / { } ( ) * + ? . \\ ^ $ | ] / g, '\\$&' ) ;
251
- replaceRegex = new RegExp ( replace , 'gi' ) ;
226
+ const replaceFields = ( template : string , useRawContent : boolean ) : string => {
227
+ fields . forEach ( ( field ) => {
228
+ if ( useRawContent ) {
229
+ // Replace field with unprocessed content.
230
+ template = replaceAll ( template , `[[${ field . name } ]]` , entry . contents [ field . id ] ?. content ?? '' ) ;
231
+ } else {
232
+ // Replace field by a generic directive.
233
+ const render = `<addon-mod-data-field-plugin [field]="fields[${ field . id } ]" mode="${ mode } " \
234
+ [database]="database" [value]="entries[${ entry . id } ].contents[${ field . id } ]" \
235
+ [recordHasOffline]="${ entry . hasOffline ? 'true' : 'false' } " \
236
+ (gotoEntry)="gotoEntry($event)"></addon-mod-data-field-plugin>` ;
237
+ template = replaceAll ( template , `[[${ field . name } ]]` , render ) ;
238
+ }
252
239
253
- template = template . replace ( replaceRegex , field . name ) ;
240
+ // Replace the field name tag.
241
+ template = replaceAll ( template , `[[${ field . name } #name]]` , field . name ) ;
254
242
255
- // Replace the field description tag.
256
- replace = `[[${ field . name } #description]]` ;
257
- replace = replace . replace ( / [ - [ \] / { } ( ) * + ? . \\ ^ $ | ] / g, '\\$&' ) ;
258
- replaceRegex = new RegExp ( replace , 'gi' ) ;
243
+ // Replace the field description tag.
244
+ template = replaceAll ( template , `[[${ field . name } #description]]` , field . description ) ;
245
+ } ) ;
259
246
260
- template = template . replace ( replaceRegex , field . description ) ;
247
+ return template ;
248
+ } ;
249
+
250
+ // First, replace fields inside attributes.
251
+ // We can't use convertTextToHTMLElement because it removes elements that
252
+ // are not allowed as a child of <div>, like <li> or <tr>.
253
+ const templateElement = document . createElement ( 'template' ) ;
254
+ templateElement . innerHTML = template ;
255
+ templateElement . content . querySelectorAll ( '*' ) . forEach ( ( element ) => {
256
+ for ( const name of element . getAttributeNames ( ) ) {
257
+ const value = element . getAttribute ( name ) ?? '' ;
258
+ if ( value . match ( / \[ \[ .* \] \] / ) ) {
259
+ element . setAttribute ( name , replaceFields ( value , true ) ) ;
260
+ }
261
+ }
261
262
} ) ;
263
+ template = templateElement . innerHTML ;
264
+
265
+ // Replace fields inside elements.
266
+ template = replaceFields ( template , false ) ;
262
267
268
+ // Replace actions.
263
269
for ( const action in actions ) {
264
270
const replaceRegex = new RegExp ( `##${ action } ##` , 'gi' ) ;
265
271
// Is enabled?
0 commit comments