chore(): sync with main

This commit is contained in:
Liam DeBeasi
2023-03-24 14:37:39 -04:00
79 changed files with 653 additions and 65 deletions

View File

@ -4,6 +4,7 @@ import { Watch, Component, Element, Event, Host, Method, Prop, h } from '@stenci
import { config } from '../../global/config';
import { getIonMode } from '../../global/ionic-global';
import type { AnimationBuilder, FrameworkDelegate, OverlayInterface } from '../../interface';
import { ENABLE_HTML_CONTENT_DEFAULT } from '../../utils/config';
import { raf } from '../../utils/helpers';
import {
BACKDROP,
@ -41,6 +42,7 @@ import { mdLeaveAnimation } from './animations/md.leave';
export class Loading implements ComponentInterface, OverlayInterface {
private readonly delegateController = createDelegateController(this);
private readonly triggerController = createTriggerController();
private customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
private durationTimeout?: ReturnType<typeof setTimeout>;
private currentTransition?: Promise<any>;
@ -75,6 +77,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;
@ -296,6 +303,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);
@ -335,9 +355,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);
});
});