mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
feat(config): add option to disable custom html functionality (#26956)
This commit is contained in:
@ -5,6 +5,7 @@ import { arrowDown, caretBackSharp } from 'ionicons/icons';
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import type { SpinnerTypes } from '../../interface';
|
||||
import { ENABLE_HTML_CONTENT_DEFAULT } from '../../utils/config';
|
||||
import { isPlatform } from '../../utils/platform';
|
||||
import type { IonicSafeString } from '../../utils/sanitization';
|
||||
import { sanitizeDOMString } from '../../utils/sanitization';
|
||||
@ -14,6 +15,8 @@ import { SPINNERS } from '../spinner/spinner-configs';
|
||||
tag: 'ion-refresher-content',
|
||||
})
|
||||
export class RefresherContent implements ComponentInterface {
|
||||
private customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
|
||||
|
||||
@Element() el!: HTMLIonRefresherContentElement;
|
||||
|
||||
/**
|
||||
@ -31,6 +34,11 @@ export class RefresherContent implements ComponentInterface {
|
||||
* `<Ionic>`
|
||||
*
|
||||
* For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||
*
|
||||
* 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() pullingText?: string | IonicSafeString;
|
||||
|
||||
@ -47,6 +55,11 @@ export class RefresherContent implements ComponentInterface {
|
||||
* `<Ionic>`
|
||||
*
|
||||
* For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||
*
|
||||
* 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() refreshingText?: string | IonicSafeString;
|
||||
|
||||
@ -68,6 +81,24 @@ export class RefresherContent implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
private renderPullingText() {
|
||||
const { customHTMLEnabled, pullingText } = this;
|
||||
if (customHTMLEnabled) {
|
||||
return <div class="refresher-pulling-text" innerHTML={sanitizeDOMString(pullingText)}></div>;
|
||||
}
|
||||
|
||||
return <div class="refresher-pulling-text">{pullingText}</div>;
|
||||
}
|
||||
|
||||
private renderRefreshingText() {
|
||||
const { customHTMLEnabled, refreshingText } = this;
|
||||
if (customHTMLEnabled) {
|
||||
return <div class="refresher-refreshing-text" innerHTML={sanitizeDOMString(refreshingText)}></div>;
|
||||
}
|
||||
|
||||
return <div class="refresher-refreshing-text">{refreshingText}</div>;
|
||||
}
|
||||
|
||||
render() {
|
||||
const pullingIcon = this.pullingIcon;
|
||||
const hasSpinner = pullingIcon != null && (SPINNERS[pullingIcon] as any) !== undefined;
|
||||
@ -93,9 +124,7 @@ export class RefresherContent implements ComponentInterface {
|
||||
<ion-icon icon={this.pullingIcon} lazy={false}></ion-icon>
|
||||
</div>
|
||||
)}
|
||||
{this.pullingText !== undefined && (
|
||||
<div class="refresher-pulling-text" innerHTML={sanitizeDOMString(this.pullingText)}></div>
|
||||
)}
|
||||
{this.pullingText !== undefined && this.renderPullingText()}
|
||||
</div>
|
||||
<div class="refresher-refreshing">
|
||||
{this.refreshingSpinner && (
|
||||
@ -103,9 +132,7 @@ export class RefresherContent implements ComponentInterface {
|
||||
<ion-spinner name={this.refreshingSpinner}></ion-spinner>
|
||||
</div>
|
||||
)}
|
||||
{this.refreshingText !== undefined && (
|
||||
<div class="refresher-refreshing-text" innerHTML={sanitizeDOMString(this.refreshingText)}></div>
|
||||
)}
|
||||
{this.refreshingText !== undefined && this.renderRefreshingText()}
|
||||
</div>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@ -0,0 +1,52 @@
|
||||
import { newSpecPage } from '@stencil/core/testing';
|
||||
import { RefresherContent } from '../refresher-content';
|
||||
import { config } from '../../../global/config';
|
||||
|
||||
describe('refresher-content: custom html', () => {
|
||||
it('should allow for custom html by default', async () => {
|
||||
const page = await newSpecPage({
|
||||
components: [RefresherContent],
|
||||
html: `<ion-refresher-content pulling-text="<button class='custom-pulling-html'>Custom Pulling Text</button>" refreshing-text="<button class='custom-refreshing-html'>Custom Refreshing Text</button>"></ion-refresher-content>`,
|
||||
});
|
||||
|
||||
const pullingContent = page.body.querySelector('.refresher-pulling-text');
|
||||
expect(pullingContent.textContent).toContain('Custom Pulling Text');
|
||||
expect(pullingContent.querySelector('button.custom-pulling-html')).not.toBe(null);
|
||||
|
||||
const refreshingContent = page.body.querySelector('.refresher-refreshing-text');
|
||||
expect(refreshingContent.textContent).toContain('Custom Refreshing Text');
|
||||
expect(refreshingContent.querySelector('button.custom-refreshing-html')).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should allow for custom html', async () => {
|
||||
config.reset({ innerHTMLTemplatesEnabled: true });
|
||||
const page = await newSpecPage({
|
||||
components: [RefresherContent],
|
||||
html: `<ion-refresher-content pulling-text="<button class='custom-pulling-html'>Custom Pulling Text</button>" refreshing-text="<button class='custom-refreshing-html'>Custom Refreshing Text</button>"></ion-refresher-content>`,
|
||||
});
|
||||
|
||||
const pullingContent = page.body.querySelector('.refresher-pulling-text');
|
||||
expect(pullingContent.textContent).toContain('Custom Pulling Text');
|
||||
expect(pullingContent.querySelector('button.custom-pulling-html')).not.toBe(null);
|
||||
|
||||
const refreshingContent = page.body.querySelector('.refresher-refreshing-text');
|
||||
expect(refreshingContent.textContent).toContain('Custom Refreshing Text');
|
||||
expect(refreshingContent.querySelector('button.custom-refreshing-html')).not.toBe(null);
|
||||
});
|
||||
|
||||
it('should not allow for custom html', async () => {
|
||||
config.reset({ innerHTMLTemplatesEnabled: false });
|
||||
const page = await newSpecPage({
|
||||
components: [RefresherContent],
|
||||
html: `<ion-refresher-content pulling-text="<button class='custom-pulling-html'>Custom Pulling Text</button>" refreshing-text="<button class='custom-html'>Custom Refreshing Text</button>"></ion-refresher-content>`,
|
||||
});
|
||||
|
||||
const pullingContent = page.body.querySelector('.refresher-pulling-text');
|
||||
expect(pullingContent.textContent).toContain('Custom Pulling Text');
|
||||
expect(pullingContent.querySelector('button.custom-pulling-html')).toBe(null);
|
||||
|
||||
const refreshingContent = page.body.querySelector('.refresher-refreshing-text');
|
||||
expect(refreshingContent.textContent).toContain('Custom Refreshing Text');
|
||||
expect(refreshingContent.querySelector('button.custom-refreshing-html')).toBe(null);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user