|
1 | 1 | import kebbab from 'lodash.kebabcase' |
2 | 2 | import isEmpty from 'lodash.isempty' |
3 | | -import {IJsonToHtmlElementTags, IJsonToHtmlOptions, IJsonToHtmlTextTags} from './types' |
| 3 | +import {IJsonToHtmlElementTags, IJsonToHtmlOptions, IJsonToHtmlTextTags, IJsonToHtmlAllowedEmptyAttributes} from './types' |
4 | 4 | import isPlainObject from 'lodash.isplainobject' |
5 | 5 | import {replaceHtmlEntities, forbiddenAttrChars } from './utils' |
6 | 6 |
|
@@ -213,11 +213,28 @@ const TEXT_WRAPPERS: IJsonToHtmlTextTags = { |
213 | 213 | return `<span data-type='inlineCode'>${child}</span>` |
214 | 214 | }, |
215 | 215 | } |
| 216 | +const ALLOWED_EMPTY_ATTRIBUTES: IJsonToHtmlAllowedEmptyAttributes = { |
| 217 | + img: ['alt'], |
| 218 | + reference: ['alt'] |
| 219 | +} |
| 220 | + |
216 | 221 | export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string => { |
217 | 222 | //TODO: optimize assign once per function call |
218 | 223 | if(options?.customTextWrapper && !isEmpty(options.customTextWrapper)){ |
219 | 224 | Object.assign(TEXT_WRAPPERS,options.customTextWrapper) |
220 | 225 | } |
| 226 | + if (options?.allowedEmptyAttributes && !isEmpty(options.allowedEmptyAttributes)) { |
| 227 | + Object.keys(options.allowedEmptyAttributes).forEach(key => { |
| 228 | + if (key === 'img' || key === 'reference') { |
| 229 | + ALLOWED_EMPTY_ATTRIBUTES[key] = [ |
| 230 | + 'alt', |
| 231 | + ...(options.allowedEmptyAttributes?.[key] || []) |
| 232 | + ]; |
| 233 | + } else { |
| 234 | + ALLOWED_EMPTY_ATTRIBUTES[key] = options.allowedEmptyAttributes?.[key] ?? []; |
| 235 | + } |
| 236 | + }); |
| 237 | + } |
221 | 238 | if (jsonValue.hasOwnProperty('text')) { |
222 | 239 | let text = jsonValue['text'].replace(/</g, '<').replace(/>/g, '>') |
223 | 240 | if (jsonValue['break']) { |
@@ -510,12 +527,20 @@ export const toRedactor = (jsonValue: any,options?:IJsonToHtmlOptions) : string |
510 | 527 | if (forbiddenAttrChars.some(char => item[0].includes(char))) { |
511 | 528 | return; |
512 | 529 | } |
513 | | - if((jsonValue['type'] === 'img' || (jsonValue['type'] === 'reference') && jsonValue.attrs['display-type'] === 'display' ) && item[0] === 'alt'){ |
514 | | - attrs += `${item[0]}="${replaceHtmlEntities(item[1])}" ` |
515 | | - return; |
516 | | - } |
| 530 | + if (ALLOWED_EMPTY_ATTRIBUTES.hasOwnProperty(jsonValue['type'])) { |
| 531 | + if (ALLOWED_EMPTY_ATTRIBUTES[jsonValue['type']].includes(item[0])) { |
| 532 | + // Check for 'display-type' attribute for reference type, as refernce is used for entries and assets |
| 533 | + if (jsonValue['type'] === 'reference' && jsonValue.attrs['display-type'] === 'display') { |
| 534 | + attrs += `${item[0]}="${replaceHtmlEntities(item[1])}" `; |
| 535 | + return; |
| 536 | + } |
| 537 | + attrs += `${item[0]}="${replaceHtmlEntities(item[1])}" `; |
| 538 | + return; |
| 539 | + } |
| 540 | + } |
517 | 541 | return item[1] ? (item[1] !== '' ? (attrs += `${item[0]}="${replaceHtmlEntities(item[1])}" `) : '') : '' |
518 | 542 | }) |
| 543 | + |
519 | 544 | attrs = (attrs.trim() ? ' ' : '') + attrs.trim() |
520 | 545 | } |
521 | 546 | if (jsonValue['type'] === 'table') { |
|
0 commit comments