mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-09 16:16:41 +08:00
fix(many): innerHTML is disabled by default (#27029)
BREAKING CHANGE: The `innerHTMLTemplatesEnabled` Ionic Config now defaults to `false`. Developers can set this option to `true` if they would like to continue to use custom HTML features in `ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, and `ion-toast`.
This commit is contained in:
@ -35,6 +35,7 @@ This is a comprehensive list of the breaking changes introduced in the major ver
|
|||||||
- [Textarea](#version-7x-textarea)
|
- [Textarea](#version-7x-textarea)
|
||||||
- [Toggle](#version-7x-toggle)
|
- [Toggle](#version-7x-toggle)
|
||||||
- [Virtual Scroll](#version-7x-virtual-scroll)
|
- [Virtual Scroll](#version-7x-virtual-scroll)
|
||||||
|
- [Config](#version-7x-config)
|
||||||
- [Types](#version-7x-types)
|
- [Types](#version-7x-types)
|
||||||
- [Overlay Attribute Interfaces](#version-7x-overlay-attribute-interfaces)
|
- [Overlay Attribute Interfaces](#version-7x-overlay-attribute-interfaces)
|
||||||
- [JavaScript Frameworks](#version-7x-javascript-frameworks)
|
- [JavaScript Frameworks](#version-7x-javascript-frameworks)
|
||||||
@ -297,6 +298,10 @@ Developers using the component will need to migrate to a virtual scroll solution
|
|||||||
|
|
||||||
Any references to the virtual scroll types from `@ionic/core` have been removed. Please remove or replace these types: `Cell`, `VirtualNode`, `CellType`, `NodeChange`, `HeaderFn`, `ItemHeightFn`, `FooterHeightFn`, `ItemRenderFn` and `DomRenderFn`.
|
Any references to the virtual scroll types from `@ionic/core` have been removed. Please remove or replace these types: `Cell`, `VirtualNode`, `CellType`, `NodeChange`, `HeaderFn`, `ItemHeightFn`, `FooterHeightFn`, `ItemRenderFn` and `DomRenderFn`.
|
||||||
|
|
||||||
|
<h2 id="version-7x-config">Config</h2>
|
||||||
|
|
||||||
|
- `innerHTMLTemplatesEnabled` defaults to `false`. Developers who wish to use the `innerHTML` functionality inside of `ion-alert`, `ion-infinite-scroll-content`, `ion-loading`, `ion-refresher-content`, and `ion-toast` must set this config to `true` and properly sanitize their content.
|
||||||
|
|
||||||
<h2 id="version-7x-types">Types</h2>
|
<h2 id="version-7x-types">Types</h2>
|
||||||
|
|
||||||
<h4 id="version-7x-overlay-attribute-interfaces">Overlay Attribute Interfaces</h4>
|
<h4 id="version-7x-overlay-attribute-interfaces">Overlay Attribute Interfaces</h4>
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Alert } from '../alert';
|
|||||||
import { config } from '../../../global/config';
|
import { config } from '../../../global/config';
|
||||||
|
|
||||||
describe('alert: custom html', () => {
|
describe('alert: custom html', () => {
|
||||||
it('should allow for custom html by default', async () => {
|
it('should not allow for custom html by default', async () => {
|
||||||
const page = await newSpecPage({
|
const page = await newSpecPage({
|
||||||
components: [Alert],
|
components: [Alert],
|
||||||
html: `<ion-alert message="<button class='custom-html'>Custom Text</button>"></ion-alert>`,
|
html: `<ion-alert message="<button class='custom-html'>Custom Text</button>"></ion-alert>`,
|
||||||
@ -11,7 +11,7 @@ describe('alert: custom html', () => {
|
|||||||
|
|
||||||
const content = page.body.querySelector('.alert-message');
|
const content = page.body.querySelector('.alert-message');
|
||||||
expect(content.textContent).toContain('Custom Text');
|
expect(content.textContent).toContain('Custom Text');
|
||||||
expect(content.querySelector('button.custom-html')).not.toBe(null);
|
expect(content.querySelector('button.custom-html')).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow for custom html', async () => {
|
it('should allow for custom html', async () => {
|
||||||
|
|||||||
@ -58,6 +58,12 @@
|
|||||||
</ion-app>
|
</ion-app>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
window.Ionic = {
|
||||||
|
config: {
|
||||||
|
innerHTMLTemplatesEnabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
async function openAlert(opts) {
|
async function openAlert(opts) {
|
||||||
const alert = await alertController.create(opts);
|
const alert = await alertController.create(opts);
|
||||||
await alert.present();
|
await alert.present();
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { InfiniteScrollContent } from '../infinite-scroll-content';
|
|||||||
import { config } from '../../../global/config';
|
import { config } from '../../../global/config';
|
||||||
|
|
||||||
describe('infinite-scroll-content: custom html', () => {
|
describe('infinite-scroll-content: custom html', () => {
|
||||||
it('should allow for custom html by default', async () => {
|
it('should not allow for custom html by default', async () => {
|
||||||
const page = await newSpecPage({
|
const page = await newSpecPage({
|
||||||
components: [InfiniteScrollContent],
|
components: [InfiniteScrollContent],
|
||||||
html: `<ion-infinite-scroll-content loading-text="<button class='custom-html'>Custom Text</button>"></ion-infinite-scroll-content>`,
|
html: `<ion-infinite-scroll-content loading-text="<button class='custom-html'>Custom Text</button>"></ion-infinite-scroll-content>`,
|
||||||
@ -11,7 +11,7 @@ describe('infinite-scroll-content: custom html', () => {
|
|||||||
|
|
||||||
const content = page.body.querySelector('.infinite-loading-text');
|
const content = page.body.querySelector('.infinite-loading-text');
|
||||||
expect(content.textContent).toContain('Custom Text');
|
expect(content.textContent).toContain('Custom Text');
|
||||||
expect(content.querySelector('button.custom-html')).not.toBe(null);
|
expect(content.querySelector('button.custom-html')).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow for custom html', async () => {
|
it('should allow for custom html', async () => {
|
||||||
|
|||||||
@ -100,6 +100,12 @@
|
|||||||
</ion-content>
|
</ion-content>
|
||||||
</ion-app>
|
</ion-app>
|
||||||
<script>
|
<script>
|
||||||
|
window.Ionic = {
|
||||||
|
config: {
|
||||||
|
innerHTMLTemplatesEnabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
async function openLoading(opts) {
|
async function openLoading(opts) {
|
||||||
const loading = await loadingController.create(opts);
|
const loading = await loadingController.create(opts);
|
||||||
await loading.present();
|
await loading.present();
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Loading } from '../loading';
|
|||||||
import { config } from '../../../global/config';
|
import { config } from '../../../global/config';
|
||||||
|
|
||||||
describe('alert: custom html', () => {
|
describe('alert: custom html', () => {
|
||||||
it('should allow for custom html by default', async () => {
|
it('should not allow for custom html by default', async () => {
|
||||||
const page = await newSpecPage({
|
const page = await newSpecPage({
|
||||||
components: [Loading],
|
components: [Loading],
|
||||||
html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
|
html: `<ion-loading message="<button class='custom-html'>Custom Text</button>"></ion-loading>`,
|
||||||
@ -11,7 +11,7 @@ describe('alert: custom html', () => {
|
|||||||
|
|
||||||
const content = page.body.querySelector('.loading-content');
|
const content = page.body.querySelector('.loading-content');
|
||||||
expect(content.textContent).toContain('Custom Text');
|
expect(content.textContent).toContain('Custom Text');
|
||||||
expect(content.querySelector('button.custom-html')).not.toBe(null);
|
expect(content.querySelector('button.custom-html')).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow for custom html', async () => {
|
it('should allow for custom html', async () => {
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { RefresherContent } from '../refresher-content';
|
|||||||
import { config } from '../../../global/config';
|
import { config } from '../../../global/config';
|
||||||
|
|
||||||
describe('refresher-content: custom html', () => {
|
describe('refresher-content: custom html', () => {
|
||||||
it('should allow for custom html by default', async () => {
|
it('should not allow for custom html by default', async () => {
|
||||||
const page = await newSpecPage({
|
const page = await newSpecPage({
|
||||||
components: [RefresherContent],
|
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>`,
|
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>`,
|
||||||
@ -11,11 +11,11 @@ describe('refresher-content: custom html', () => {
|
|||||||
|
|
||||||
const pullingContent = page.body.querySelector('.refresher-pulling-text');
|
const pullingContent = page.body.querySelector('.refresher-pulling-text');
|
||||||
expect(pullingContent.textContent).toContain('Custom Pulling Text');
|
expect(pullingContent.textContent).toContain('Custom Pulling Text');
|
||||||
expect(pullingContent.querySelector('button.custom-pulling-html')).not.toBe(null);
|
expect(pullingContent.querySelector('button.custom-pulling-html')).toBe(null);
|
||||||
|
|
||||||
const refreshingContent = page.body.querySelector('.refresher-refreshing-text');
|
const refreshingContent = page.body.querySelector('.refresher-refreshing-text');
|
||||||
expect(refreshingContent.textContent).toContain('Custom Refreshing Text');
|
expect(refreshingContent.textContent).toContain('Custom Refreshing Text');
|
||||||
expect(refreshingContent.querySelector('button.custom-refreshing-html')).not.toBe(null);
|
expect(refreshingContent.querySelector('button.custom-refreshing-html')).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow for custom html', async () => {
|
it('should allow for custom html', async () => {
|
||||||
|
|||||||
@ -195,6 +195,12 @@
|
|||||||
</ion-content>
|
</ion-content>
|
||||||
</ion-app>
|
</ion-app>
|
||||||
<script>
|
<script>
|
||||||
|
window.Ionic = {
|
||||||
|
config: {
|
||||||
|
innerHTMLTemplatesEnabled: true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
window.addEventListener('ionToastDidDismiss', function (e) {
|
window.addEventListener('ionToastDidDismiss', function (e) {
|
||||||
console.log('didDismiss', e);
|
console.log('didDismiss', e);
|
||||||
});
|
});
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Toast } from '../toast';
|
|||||||
import { config } from '../../../global/config';
|
import { config } from '../../../global/config';
|
||||||
|
|
||||||
describe('alert: custom html', () => {
|
describe('alert: custom html', () => {
|
||||||
it('should allow for custom html by default', async () => {
|
it('should not allow for custom html by default', async () => {
|
||||||
const page = await newSpecPage({
|
const page = await newSpecPage({
|
||||||
components: [Toast],
|
components: [Toast],
|
||||||
html: `<ion-toast message="<button class='custom-html'>Custom Text</button>"></ion-toast>`,
|
html: `<ion-toast message="<button class='custom-html'>Custom Text</button>"></ion-toast>`,
|
||||||
@ -12,7 +12,7 @@ describe('alert: custom html', () => {
|
|||||||
const toast = page.body.querySelector('ion-toast');
|
const toast = page.body.querySelector('ion-toast');
|
||||||
const content = toast.shadowRoot.querySelector('.toast-message');
|
const content = toast.shadowRoot.querySelector('.toast-message');
|
||||||
expect(content.textContent).toContain('Custom Text');
|
expect(content.textContent).toContain('Custom Text');
|
||||||
expect(content.querySelector('button.custom-html')).not.toBe(null);
|
expect(content.querySelector('button.custom-html')).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow for custom html', async () => {
|
it('should allow for custom html', async () => {
|
||||||
|
|||||||
@ -249,4 +249,4 @@ export const getMode = (): Mode => {
|
|||||||
return 'md';
|
return 'md';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const ENABLE_HTML_CONTENT_DEFAULT = true;
|
export const ENABLE_HTML_CONTENT_DEFAULT = false;
|
||||||
|
|||||||
Reference in New Issue
Block a user