feat(config): add option to disable custom html functionality (#26956)

This commit is contained in:
Liam DeBeasi
2023-03-22 13:59:59 -04:00
committed by GitHub
parent 6c639ff3a5
commit 3b0af7c55d
12 changed files with 351 additions and 28 deletions

View File

@ -10,6 +10,7 @@ import type {
OverlayInterface,
SpinnerTypes,
} from '../../interface';
import { ENABLE_HTML_CONTENT_DEFAULT } from '../../utils/config';
import { BACKDROP, dismiss, eventMethod, prepareOverlay, present } from '../../utils/overlays';
import type { IonicSafeString } from '../../utils/sanitization';
import { sanitizeDOMString } from '../../utils/sanitization';
@ -34,6 +35,7 @@ import { mdLeaveAnimation } from './animations/md.leave';
scoped: true,
})
export class Loading implements ComponentInterface, OverlayInterface {
private customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
private durationTimeout?: ReturnType<typeof setTimeout>;
presented = false;
@ -61,6 +63,11 @@ export class Loading implements ComponentInterface, OverlayInterface {
/**
* Optional text content to display in the loading indicator.
*
* This property accepts custom HTML as a string.
* Developers who only want to pass plain text
* can disable the custom HTML functionality
* by setting `innerHTMLTemplatesEnabled: false` in the Ionic config.
*/
@Prop() message?: string | IonicSafeString;
@ -187,6 +194,19 @@ export class Loading implements ComponentInterface, OverlayInterface {
this.dismiss(undefined, BACKDROP);
};
private renderLoadingMessage(msgId: string) {
const { customHTMLEnabled, message } = this;
if (customHTMLEnabled) {
return <div class="loading-content" id={msgId} innerHTML={sanitizeDOMString(message)}></div>;
}
return (
<div class="loading-content" id={msgId}>
{message}
</div>
);
}
render() {
const { message, spinner, htmlAttributes, overlayIndex } = this;
const mode = getIonMode(this);
@ -226,9 +246,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
</div>
)}
{message !== undefined && (
<div class="loading-content" id={msgId} innerHTML={sanitizeDOMString(message)}></div>
)}
{message !== undefined && this.renderLoadingMessage(msgId)}
</div>
<div tabindex="0"></div>

View File

@ -0,0 +1,40 @@
import { newSpecPage } from '@stencil/core/testing';
import { Loading } from '../loading';
import { config } from '../../../global/config';
describe('alert: custom html', () => {
it('should allow for custom html by default', async () => {
const page = await newSpecPage({
components: [Loading],
html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
});
const content = page.body.querySelector('.loading-content');
expect(content.textContent).toContain('Custom Text');
expect(content.querySelector('button.custom-html')).not.toBe(null);
});
it('should allow for custom html', async () => {
config.reset({ innerHTMLTemplatesEnabled: true });
const page = await newSpecPage({
components: [Loading],
html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
});
const content = page.body.querySelector('.loading-content');
expect(content.textContent).toContain('Custom Text');
expect(content.querySelector('button.custom-html')).not.toBe(null);
});
it('should not allow for custom html', async () => {
config.reset({ innerHTMLTemplatesEnabled: false });
const page = await newSpecPage({
components: [Loading],
html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
});
const content = page.body.querySelector('.loading-content');
expect(content.textContent).toContain('Custom Text');
expect(content.querySelector('button.custom-html')).toBe(null);
});
});