mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 11:17:19 +08:00
20
core/src/components.d.ts
vendored
20
core/src/components.d.ts
vendored
@ -285,7 +285,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'leaveAnimation'?: AnimationBuilder;
|
'leaveAnimation'?: AnimationBuilder;
|
||||||
/**
|
/**
|
||||||
* The main message to be displayed in the alert.
|
* The main message to be displayed in the alert. `message` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'message'?: string;
|
'message'?: string;
|
||||||
/**
|
/**
|
||||||
@ -352,7 +352,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'leaveAnimation'?: AnimationBuilder;
|
'leaveAnimation'?: AnimationBuilder;
|
||||||
/**
|
/**
|
||||||
* The main message to be displayed in the alert.
|
* The main message to be displayed in the alert. `message` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'message'?: string;
|
'message'?: string;
|
||||||
/**
|
/**
|
||||||
@ -1566,7 +1566,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'loadingSpinner'?: SpinnerTypes | null;
|
'loadingSpinner'?: SpinnerTypes | null;
|
||||||
/**
|
/**
|
||||||
* Optional text to display while loading.
|
* Optional text to display while loading. `loadingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'loadingText'?: string;
|
'loadingText'?: string;
|
||||||
}
|
}
|
||||||
@ -1576,7 +1576,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'loadingSpinner'?: SpinnerTypes | null;
|
'loadingSpinner'?: SpinnerTypes | null;
|
||||||
/**
|
/**
|
||||||
* Optional text to display while loading.
|
* Optional text to display while loading. `loadingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'loadingText'?: string;
|
'loadingText'?: string;
|
||||||
}
|
}
|
||||||
@ -3418,7 +3418,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'pullingIcon'?: string | null;
|
'pullingIcon'?: string | null;
|
||||||
/**
|
/**
|
||||||
* The text you want to display when you begin to pull down
|
* The text you want to display when you begin to pull down. `pullingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'pullingText'?: string;
|
'pullingText'?: string;
|
||||||
/**
|
/**
|
||||||
@ -3426,7 +3426,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'refreshingSpinner'?: SpinnerTypes | null;
|
'refreshingSpinner'?: SpinnerTypes | null;
|
||||||
/**
|
/**
|
||||||
* The text you want to display when performing a refresh
|
* The text you want to display when performing a refresh. `refreshingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'refreshingText'?: string;
|
'refreshingText'?: string;
|
||||||
}
|
}
|
||||||
@ -3436,7 +3436,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'pullingIcon'?: string | null;
|
'pullingIcon'?: string | null;
|
||||||
/**
|
/**
|
||||||
* The text you want to display when you begin to pull down
|
* The text you want to display when you begin to pull down. `pullingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'pullingText'?: string;
|
'pullingText'?: string;
|
||||||
/**
|
/**
|
||||||
@ -3444,7 +3444,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'refreshingSpinner'?: SpinnerTypes | null;
|
'refreshingSpinner'?: SpinnerTypes | null;
|
||||||
/**
|
/**
|
||||||
* The text you want to display when performing a refresh
|
* The text you want to display when performing a refresh. `refreshingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'refreshingText'?: string;
|
'refreshingText'?: string;
|
||||||
}
|
}
|
||||||
@ -3732,7 +3732,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'mode': Mode;
|
'mode': Mode;
|
||||||
/**
|
/**
|
||||||
* Set the input's placeholder.
|
* Set the input's placeholder. `placeholder` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'placeholder': string;
|
'placeholder': string;
|
||||||
/**
|
/**
|
||||||
@ -3826,7 +3826,7 @@ export namespace Components {
|
|||||||
*/
|
*/
|
||||||
'onIonInput'?: (event: CustomEvent<KeyboardEvent>) => void;
|
'onIonInput'?: (event: CustomEvent<KeyboardEvent>) => void;
|
||||||
/**
|
/**
|
||||||
* Set the input's placeholder.
|
* Set the input's placeholder. `placeholder` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
'placeholder'?: string;
|
'placeholder'?: string;
|
||||||
/**
|
/**
|
||||||
|
@ -2,6 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Listen, Me
|
|||||||
|
|
||||||
import { AlertButton, AlertInput, Animation, AnimationBuilder, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
|
import { AlertButton, AlertInput, Animation, AnimationBuilder, Config, CssClassMap, Mode, OverlayEventDetail, OverlayInterface } from '../../interface';
|
||||||
import { BACKDROP, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
import { BACKDROP, dismiss, eventMethod, isCancel, present } from '../../utils/overlays';
|
||||||
|
import { sanitizeDOMString } from '../../utils/sanitization';
|
||||||
import { getClassMap } from '../../utils/theme';
|
import { getClassMap } from '../../utils/theme';
|
||||||
|
|
||||||
import { iosEnterAnimation } from './animations/ios.enter';
|
import { iosEnterAnimation } from './animations/ios.enter';
|
||||||
@ -72,6 +73,12 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The main message to be displayed in the alert.
|
* The main message to be displayed in the alert.
|
||||||
|
* `message` can accept either plaintext or HTML as a string.
|
||||||
|
* To display characters normally reserved for HTML, they
|
||||||
|
* must be escaped. For example `<Ionic>` would become
|
||||||
|
* `<Ionic>`
|
||||||
|
*
|
||||||
|
* For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
@Prop() message?: string;
|
@Prop() message?: string;
|
||||||
|
|
||||||
@ -444,7 +451,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
|||||||
{this.subHeader && <h2 id={subHdrId} class="alert-sub-title">{this.subHeader}</h2>}
|
{this.subHeader && <h2 id={subHdrId} class="alert-sub-title">{this.subHeader}</h2>}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id={msgId} class="alert-message" innerHTML={this.message}></div>
|
<div id={msgId} class="alert-message" innerHTML={sanitizeDOMString(this.message)}></div>
|
||||||
|
|
||||||
{this.renderAlertInputs(labelledById)}
|
{this.renderAlertInputs(labelledById)}
|
||||||
{this.renderAlertButtons()}
|
{this.renderAlertButtons()}
|
||||||
|
@ -1054,21 +1054,21 @@ export default {
|
|||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
| Property | Attribute | Description | Type | Default |
|
| Property | Attribute | Description | Type | Default |
|
||||||
| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- |
|
| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- | ----------- |
|
||||||
| `animated` | `animated` | If `true`, the alert will animate. | `boolean` | `true` |
|
| `animated` | `animated` | If `true`, the alert will animate. | `boolean` | `true` |
|
||||||
| `backdropDismiss` | `backdrop-dismiss` | If `true`, the alert will be dismissed when the backdrop is clicked. | `boolean` | `true` |
|
| `backdropDismiss` | `backdrop-dismiss` | If `true`, the alert will be dismissed when the backdrop is clicked. | `boolean` | `true` |
|
||||||
| `buttons` | -- | Array of buttons to be added to the alert. | `(string \| AlertButton)[]` | `[]` |
|
| `buttons` | -- | Array of buttons to be added to the alert. | `(string \| AlertButton)[]` | `[]` |
|
||||||
| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` |
|
| `cssClass` | `css-class` | Additional classes to apply for custom CSS. If multiple classes are provided they should be separated by spaces. | `string \| string[] \| undefined` | `undefined` |
|
||||||
| `enterAnimation` | -- | Animation to use when the alert is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
|
| `enterAnimation` | -- | Animation to use when the alert is presented. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
|
||||||
| `header` | `header` | The main title in the heading of the alert. | `string \| undefined` | `undefined` |
|
| `header` | `header` | The main title in the heading of the alert. | `string \| undefined` | `undefined` |
|
||||||
| `inputs` | -- | Array of input to show in the alert. | `AlertInput[]` | `[]` |
|
| `inputs` | -- | Array of input to show in the alert. | `AlertInput[]` | `[]` |
|
||||||
| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` |
|
| `keyboardClose` | `keyboard-close` | If `true`, the keyboard will be automatically dismissed when the overlay is presented. | `boolean` | `true` |
|
||||||
| `leaveAnimation` | -- | Animation to use when the alert is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
|
| `leaveAnimation` | -- | Animation to use when the alert is dismissed. | `((Animation: Animation, baseEl: any, opts?: any) => Promise<Animation>) \| undefined` | `undefined` |
|
||||||
| `message` | `message` | The main message to be displayed in the alert. | `string \| undefined` | `undefined` |
|
| `message` | `message` | The main message to be displayed in the alert. `message` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string \| undefined` | `undefined` |
|
||||||
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
|
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
|
||||||
| `subHeader` | `sub-header` | The subtitle in the heading of the alert. Displayed under the title. | `string \| undefined` | `undefined` |
|
| `subHeader` | `sub-header` | The subtitle in the heading of the alert. Displayed under the title. | `string \| undefined` | `undefined` |
|
||||||
| `translucent` | `translucent` | If `true`, the alert will be translucent. | `boolean` | `false` |
|
| `translucent` | `translucent` | If `true`, the alert will be translucent. | `boolean` | `false` |
|
||||||
|
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, ComponentInterface, Prop } from '@stencil/core';
|
import { Component, ComponentInterface, Prop } from '@stencil/core';
|
||||||
|
|
||||||
import { Config, Mode, SpinnerTypes } from '../../interface';
|
import { Config, Mode, SpinnerTypes } from '../../interface';
|
||||||
|
import { sanitizeDOMString } from '../../utils/sanitization';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-infinite-scroll-content',
|
tag: 'ion-infinite-scroll-content',
|
||||||
@ -22,6 +23,12 @@ export class InfiniteScrollContent implements ComponentInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional text to display while loading.
|
* Optional text to display while loading.
|
||||||
|
* `loadingText` can accept either plaintext or HTML as a string.
|
||||||
|
* To display characters normally reserved for HTML, they
|
||||||
|
* must be escaped. For example `<Ionic>` would become
|
||||||
|
* `<Ionic>`
|
||||||
|
*
|
||||||
|
* For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
@Prop() loadingText?: string;
|
@Prop() loadingText?: string;
|
||||||
|
|
||||||
@ -54,7 +61,7 @@ export class InfiniteScrollContent implements ComponentInterface {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{this.loadingText && (
|
{this.loadingText && (
|
||||||
<div class="infinite-loading-text" innerHTML={this.loadingText} />
|
<div class="infinite-loading-text" innerHTML={sanitizeDOMString(this.loadingText)} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -76,10 +76,10 @@ export default Example
|
|||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
| Property | Attribute | Description | Type | Default |
|
| Property | Attribute | Description | Type | Default |
|
||||||
| ---------------- | ----------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
|
| ---------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
|
||||||
| `loadingSpinner` | `loading-spinner` | An animated SVG spinner that shows while loading. | `"bubbles" \| "circles" \| "crescent" \| "dots" \| "lines" \| "lines-small" \| null \| undefined` | `undefined` |
|
| `loadingSpinner` | `loading-spinner` | An animated SVG spinner that shows while loading. | `"bubbles" \| "circles" \| "crescent" \| "dots" \| "lines" \| "lines-small" \| null \| undefined` | `undefined` |
|
||||||
| `loadingText` | `loading-text` | Optional text to display while loading. | `string \| undefined` | `undefined` |
|
| `loadingText` | `loading-text` | Optional text to display while loading. `loadingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string \| undefined` | `undefined` |
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
@ -9,12 +9,12 @@ The refresher content contains the text, icon and spinner to display during a pu
|
|||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
| Property | Attribute | Description | Type | Default |
|
| Property | Attribute | Description | Type | Default |
|
||||||
| ------------------- | -------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
|
| ------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------- |
|
||||||
| `pullingIcon` | `pulling-icon` | A static icon to display when you begin to pull down | `null \| string \| undefined` | `undefined` |
|
| `pullingIcon` | `pulling-icon` | A static icon to display when you begin to pull down | `null \| string \| undefined` | `undefined` |
|
||||||
| `pullingText` | `pulling-text` | The text you want to display when you begin to pull down | `string \| undefined` | `undefined` |
|
| `pullingText` | `pulling-text` | The text you want to display when you begin to pull down. `pullingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string \| undefined` | `undefined` |
|
||||||
| `refreshingSpinner` | `refreshing-spinner` | An animated SVG spinner that shows when refreshing begins | `"bubbles" \| "circles" \| "crescent" \| "dots" \| "lines" \| "lines-small" \| null \| undefined` | `undefined` |
|
| `refreshingSpinner` | `refreshing-spinner` | An animated SVG spinner that shows when refreshing begins | `"bubbles" \| "circles" \| "crescent" \| "dots" \| "lines" \| "lines-small" \| null \| undefined` | `undefined` |
|
||||||
| `refreshingText` | `refreshing-text` | The text you want to display when performing a refresh | `string \| undefined` | `undefined` |
|
| `refreshingText` | `refreshing-text` | The text you want to display when performing a refresh. `refreshingText` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string \| undefined` | `undefined` |
|
||||||
|
|
||||||
|
|
||||||
----------------------------------------------
|
----------------------------------------------
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, ComponentInterface, Prop } from '@stencil/core';
|
import { Component, ComponentInterface, Prop } from '@stencil/core';
|
||||||
|
|
||||||
import { Config, Mode, SpinnerTypes } from '../../interface';
|
import { Config, Mode, SpinnerTypes } from '../../interface';
|
||||||
|
import { sanitizeDOMString } from '../../utils/sanitization';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
tag: 'ion-refresher-content'
|
tag: 'ion-refresher-content'
|
||||||
@ -17,7 +18,13 @@ export class RefresherContent implements ComponentInterface {
|
|||||||
@Prop({ mutable: true }) pullingIcon?: string | null;
|
@Prop({ mutable: true }) pullingIcon?: string | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text you want to display when you begin to pull down
|
* The text you want to display when you begin to pull down.
|
||||||
|
* `pullingText` can accept either plaintext or HTML as a string.
|
||||||
|
* To display characters normally reserved for HTML, they
|
||||||
|
* must be escaped. For example `<Ionic>` would become
|
||||||
|
* `<Ionic>`
|
||||||
|
*
|
||||||
|
* For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
@Prop() pullingText?: string;
|
@Prop() pullingText?: string;
|
||||||
|
|
||||||
@ -27,7 +34,13 @@ export class RefresherContent implements ComponentInterface {
|
|||||||
@Prop({ mutable: true }) refreshingSpinner?: SpinnerTypes | null;
|
@Prop({ mutable: true }) refreshingSpinner?: SpinnerTypes | null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The text you want to display when performing a refresh
|
* The text you want to display when performing a refresh.
|
||||||
|
* `refreshingText` can accept either plaintext or HTML as a string.
|
||||||
|
* To display characters normally reserved for HTML, they
|
||||||
|
* must be escaped. For example `<Ionic>` would become
|
||||||
|
* `<Ionic>`
|
||||||
|
*
|
||||||
|
* For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
@Prop() refreshingText?: string;
|
@Prop() refreshingText?: string;
|
||||||
|
|
||||||
@ -60,7 +73,7 @@ export class RefresherContent implements ComponentInterface {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{this.pullingText &&
|
{this.pullingText &&
|
||||||
<div class="refresher-pulling-text" innerHTML={this.pullingText}></div>
|
<div class="refresher-pulling-text" innerHTML={sanitizeDOMString(this.pullingText)}></div>
|
||||||
}
|
}
|
||||||
</div>,
|
</div>,
|
||||||
<div class="refresher-refreshing">
|
<div class="refresher-refreshing">
|
||||||
@ -70,7 +83,7 @@ export class RefresherContent implements ComponentInterface {
|
|||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
{this.refreshingText &&
|
{this.refreshingText &&
|
||||||
<div class="refresher-refreshing-text" innerHTML={this.refreshingText}></div>
|
<div class="refresher-refreshing-text" innerHTML={sanitizeDOMString(this.refreshingText)}></div>
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
];
|
];
|
||||||
|
@ -174,24 +174,24 @@ export default Example;
|
|||||||
|
|
||||||
## Properties
|
## Properties
|
||||||
|
|
||||||
| Property | Attribute | Description | Type | Default |
|
| Property | Attribute | Description | Type | Default |
|
||||||
| ------------------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ----------------- |
|
| ------------------ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | ----------------- |
|
||||||
| `animated` | `animated` | If `true`, enable searchbar animation. | `boolean` | `false` |
|
| `animated` | `animated` | If `true`, enable searchbar animation. | `boolean` | `false` |
|
||||||
| `autocomplete` | `autocomplete` | Set the input's autocomplete property. | `"off" \| "on"` | `'off'` |
|
| `autocomplete` | `autocomplete` | Set the input's autocomplete property. | `"off" \| "on"` | `'off'` |
|
||||||
| `autocorrect` | `autocorrect` | Set the input's autocorrect property. | `"off" \| "on"` | `'off'` |
|
| `autocorrect` | `autocorrect` | Set the input's autocorrect property. | `"off" \| "on"` | `'off'` |
|
||||||
| `cancelButtonIcon` | `cancel-button-icon` | Set the cancel button icon. Only applies to `md` mode. | `string` | `'md-arrow-back'` |
|
| `cancelButtonIcon` | `cancel-button-icon` | Set the cancel button icon. Only applies to `md` mode. | `string` | `'md-arrow-back'` |
|
||||||
| `cancelButtonText` | `cancel-button-text` | Set the the cancel button text. Only applies to `ios` mode. | `string` | `'Cancel'` |
|
| `cancelButtonText` | `cancel-button-text` | Set the the cancel button text. Only applies to `ios` mode. | `string` | `'Cancel'` |
|
||||||
| `clearIcon` | `clear-icon` | Set the clear icon. Defaults to `"close-circle"` for `ios` and `"close"` for `md`. | `string \| undefined` | `undefined` |
|
| `clearIcon` | `clear-icon` | Set the clear icon. Defaults to `"close-circle"` for `ios` and `"close"` for `md`. | `string \| undefined` | `undefined` |
|
||||||
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
|
| `color` | `color` | The color to use from your application's color palette. Default options are: `"primary"`, `"secondary"`, `"tertiary"`, `"success"`, `"warning"`, `"danger"`, `"light"`, `"medium"`, and `"dark"`. For more information on colors, see [theming](/docs/theming/basics). | `string \| undefined` | `undefined` |
|
||||||
| `debounce` | `debounce` | Set the amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke. | `number` | `250` |
|
| `debounce` | `debounce` | Set the amount of time, in milliseconds, to wait to trigger the `ionChange` event after each keystroke. | `number` | `250` |
|
||||||
| `disabled` | `disabled` | If `true`, the user cannot interact with the input. | `boolean` | `false` |
|
| `disabled` | `disabled` | If `true`, the user cannot interact with the input. | `boolean` | `false` |
|
||||||
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
|
| `mode` | `mode` | The mode determines which platform styles to use. | `"ios" \| "md"` | `undefined` |
|
||||||
| `placeholder` | `placeholder` | Set the input's placeholder. | `string` | `'Search'` |
|
| `placeholder` | `placeholder` | Set the input's placeholder. `placeholder` can accept either plaintext or HTML as a string. To display characters normally reserved for HTML, they must be escaped. For example `<Ionic>` would become `<Ionic>` For more information: [Security Documentation](https://ionicframework.com/docs/faq/security) | `string` | `'Search'` |
|
||||||
| `searchIcon` | `search-icon` | The icon to use as the search icon. | `string` | `'search'` |
|
| `searchIcon` | `search-icon` | The icon to use as the search icon. | `string` | `'search'` |
|
||||||
| `showCancelButton` | `show-cancel-button` | If `true`, show the cancel button. | `boolean` | `false` |
|
| `showCancelButton` | `show-cancel-button` | If `true`, show the cancel button. | `boolean` | `false` |
|
||||||
| `spellcheck` | `spellcheck` | If `true`, enable spellcheck on the input. | `boolean` | `false` |
|
| `spellcheck` | `spellcheck` | If `true`, enable spellcheck on the input. | `boolean` | `false` |
|
||||||
| `type` | `type` | Set the type of the input. | `"email" \| "number" \| "password" \| "search" \| "tel" \| "text" \| "url"` | `'search'` |
|
| `type` | `type` | Set the type of the input. | `"email" \| "number" \| "password" \| "search" \| "tel" \| "text" \| "url"` | `'search'` |
|
||||||
| `value` | `value` | the value of the searchbar. | `null \| string \| undefined` | `''` |
|
| `value` | `value` | the value of the searchbar. | `null \| string \| undefined` | `''` |
|
||||||
|
|
||||||
|
|
||||||
## Events
|
## Events
|
||||||
|
@ -2,6 +2,7 @@ import { Component, ComponentInterface, Element, Event, EventEmitter, Method, Pr
|
|||||||
|
|
||||||
import { Color, Config, Mode, SearchbarChangeEventDetail } from '../../interface';
|
import { Color, Config, Mode, SearchbarChangeEventDetail } from '../../interface';
|
||||||
import { debounceEvent } from '../../utils/helpers';
|
import { debounceEvent } from '../../utils/helpers';
|
||||||
|
import { sanitizeDOMString } from '../../utils/sanitization';
|
||||||
import { createColorClasses } from '../../utils/theme';
|
import { createColorClasses } from '../../utils/theme';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@ -85,6 +86,12 @@ export class Searchbar implements ComponentInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the input's placeholder.
|
* Set the input's placeholder.
|
||||||
|
* `placeholder` can accept either plaintext or HTML as a string.
|
||||||
|
* To display characters normally reserved for HTML, they
|
||||||
|
* must be escaped. For example `<Ionic>` would become
|
||||||
|
* `<Ionic>`
|
||||||
|
*
|
||||||
|
* For more information: [Security Documentation](https://ionicframework.com/docs/faq/security)
|
||||||
*/
|
*/
|
||||||
@Prop() placeholder = 'Search';
|
@Prop() placeholder = 'Search';
|
||||||
|
|
||||||
@ -293,7 +300,7 @@ export class Searchbar implements ComponentInterface {
|
|||||||
// Create a dummy span to get the placeholder width
|
// Create a dummy span to get the placeholder width
|
||||||
const doc = this.doc;
|
const doc = this.doc;
|
||||||
const tempSpan = doc.createElement('span');
|
const tempSpan = doc.createElement('span');
|
||||||
tempSpan.innerHTML = this.placeholder;
|
tempSpan.innerHTML = sanitizeDOMString(this.placeholder) || '';
|
||||||
doc.body.appendChild(tempSpan);
|
doc.body.appendChild(tempSpan);
|
||||||
|
|
||||||
// Get the width of the span then remove it
|
// Get the width of the span then remove it
|
||||||
|
126
core/src/utils/sanitization/index.ts
Normal file
126
core/src/utils/sanitization/index.ts
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
/**
|
||||||
|
* Does a simple sanitization of all elements
|
||||||
|
* in an untrusted string
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const sanitizeDOMString = (untrustedString: string | undefined): string | undefined => {
|
||||||
|
try {
|
||||||
|
if (typeof untrustedString !== 'string' || untrustedString === '') { return untrustedString; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a document fragment
|
||||||
|
* separate from the main DOM,
|
||||||
|
* create a div to do our work in
|
||||||
|
*/
|
||||||
|
const documentFragment = document.createDocumentFragment();
|
||||||
|
const workingDiv = document.createElement('div');
|
||||||
|
documentFragment.appendChild(workingDiv);
|
||||||
|
workingDiv.innerHTML = untrustedString;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove any elements
|
||||||
|
* that are blocked
|
||||||
|
*/
|
||||||
|
blockedTags.forEach(blockedTag => {
|
||||||
|
|
||||||
|
const getElementsToRemove = documentFragment.querySelectorAll(blockedTag);
|
||||||
|
for (let elementIndex = getElementsToRemove.length - 1; elementIndex >= 0; elementIndex--) {
|
||||||
|
const element = getElementsToRemove[elementIndex];
|
||||||
|
if (element.parentNode) {
|
||||||
|
element.parentNode.removeChild(element);
|
||||||
|
} else {
|
||||||
|
documentFragment.removeChild(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We still need to sanitize
|
||||||
|
* the children of this element
|
||||||
|
* as they are left behind
|
||||||
|
*/
|
||||||
|
const childElements = getElementChildren(element);
|
||||||
|
|
||||||
|
/* tslint:disable-next-line */
|
||||||
|
for (let childIndex = 0; childIndex < childElements.length; childIndex++) {
|
||||||
|
sanitizeElement(childElements[childIndex]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Go through remaining elements and remove
|
||||||
|
* non-allowed attribs
|
||||||
|
*/
|
||||||
|
|
||||||
|
// IE does not support .children on document fragments, only .childNodes
|
||||||
|
const documentFragmentChildren = getElementChildren(documentFragment);
|
||||||
|
|
||||||
|
/* tslint:disable-next-line */
|
||||||
|
for (let childIndex = 0; childIndex < documentFragmentChildren.length; childIndex++) {
|
||||||
|
sanitizeElement(documentFragmentChildren[childIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append document fragment to div
|
||||||
|
const fragmentDiv = document.createElement('div');
|
||||||
|
fragmentDiv.appendChild(documentFragment);
|
||||||
|
|
||||||
|
// First child is always the div we did our work in
|
||||||
|
const getInnerDiv = fragmentDiv.querySelector('div');
|
||||||
|
return (getInnerDiv !== null) ? getInnerDiv.innerHTML : fragmentDiv.innerHTML;
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clean up current element based on allowed attributes
|
||||||
|
* and then recursively dig down into any child elements to
|
||||||
|
* clean those up as well
|
||||||
|
*/
|
||||||
|
const sanitizeElement = (element: any) => {
|
||||||
|
// IE uses childNodes, so ignore nodes that are not elements
|
||||||
|
if (element.nodeType && element.nodeType !== 1) { return; }
|
||||||
|
|
||||||
|
for (let i = element.attributes.length - 1; i >= 0; i--) {
|
||||||
|
const attribute = element.attributes[i];
|
||||||
|
const attributeName = attribute.name;
|
||||||
|
|
||||||
|
// remove non-allowed attribs
|
||||||
|
if (!allowedAttributes.includes(attributeName.toLowerCase())) {
|
||||||
|
element.removeAttribute(attributeName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// clean up any allowed attribs
|
||||||
|
// that attempt to do any JS funny-business
|
||||||
|
const attributeValue = attribute.value;
|
||||||
|
|
||||||
|
/* tslint:disable-next-line */
|
||||||
|
if (attributeValue != null && attributeValue.toLowerCase().includes('javascript:')) {
|
||||||
|
element.removeAttribute(attributeName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitize any nested children
|
||||||
|
*/
|
||||||
|
const childElements = getElementChildren(element);
|
||||||
|
|
||||||
|
/* tslint:disable-next-line */
|
||||||
|
for (let i = 0; i < childElements.length; i++) {
|
||||||
|
sanitizeElement(childElements[i]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IE doesn't always support .children
|
||||||
|
* so we revert to .childNodes instead
|
||||||
|
*/
|
||||||
|
const getElementChildren = (element: any) => {
|
||||||
|
return (element.children != null) ? element.children : element.childNodes;
|
||||||
|
};
|
||||||
|
|
||||||
|
const allowedAttributes = ['class', 'id', 'href', 'src'];
|
||||||
|
const blockedTags = ['script', 'style', 'iframe', 'meta', 'link', 'object', 'embed'];
|
26
core/src/utils/sanitization/test/e2e.ts
Normal file
26
core/src/utils/sanitization/test/e2e.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { newE2EPage } from '@stencil/core/testing';
|
||||||
|
|
||||||
|
test('sanitization:', async done => {
|
||||||
|
|
||||||
|
const page = await newE2EPage({
|
||||||
|
url: '/src/utils/sanitization/test?ionic:_testing=true'
|
||||||
|
});
|
||||||
|
|
||||||
|
page.on('pageerror', (err: any) => {
|
||||||
|
if (err.message.includes('sanitizeFailed')) {
|
||||||
|
done.fail(new Error('Failed to properly sanitize'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await page.click('#testA');
|
||||||
|
await page.click('#testB');
|
||||||
|
await page.click('#testC');
|
||||||
|
await page.click('#testD');
|
||||||
|
await page.click('#testE');
|
||||||
|
await page.click('#testF');
|
||||||
|
await page.click('#testG');
|
||||||
|
await page.click('#testH');
|
||||||
|
|
||||||
|
done();
|
||||||
|
|
||||||
|
});
|
113
core/src/utils/sanitization/test/index.html
Normal file
113
core/src/utils/sanitization/test/index.html
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html dir="ltr">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Sanitization</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<link href="../../../../css/ionic.bundle.css" rel="stylesheet">
|
||||||
|
<link href="../../../../scripts/testing/styles.css" rel="stylesheet">
|
||||||
|
<script src="../../../../scripts/testing/scripts.js"></script>
|
||||||
|
<script src="../../../../dist/ionic.js"></script>
|
||||||
|
<script type="module">
|
||||||
|
import { sanitizeDOMString } from '../../../../dist/collection/utils/sanitization/index.js';
|
||||||
|
window.sanitizeDOMString = sanitizeDOMString;
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
So the goal with these tests is to ensure
|
||||||
|
that an `alert` call is never executed
|
||||||
|
in the browser. If it is, then our sanitization
|
||||||
|
function has failed to properly sanitize
|
||||||
|
an input
|
||||||
|
-->
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<ion-app>
|
||||||
|
|
||||||
|
<ion-header>
|
||||||
|
<ion-toolbar>
|
||||||
|
<ion-title>Sanitization</ion-title>
|
||||||
|
</ion-toolbar>
|
||||||
|
</ion-header>
|
||||||
|
|
||||||
|
<ion-content id="content" padding>
|
||||||
|
<div class="results">Results will appear here</div>
|
||||||
|
|
||||||
|
<ion-button onclick="testA()" id="testA">Test A</ion-button>
|
||||||
|
<ion-button onclick="testB()" id="testB">Test B</ion-button>
|
||||||
|
<ion-button onclick="testC()" id="testC">Test C</ion-button>
|
||||||
|
<ion-button onclick="testD()" id="testD">Test D</ion-button>
|
||||||
|
<ion-button onclick="testE()" id="testE">Test E</ion-button>
|
||||||
|
<ion-button onclick="testF()" id="testF">Test F</ion-button>
|
||||||
|
<ion-button onclick="testG()" id="testG">Test G</ion-button>
|
||||||
|
<ion-button onclick="testH()" id="testH">Test H</ion-button>
|
||||||
|
</ion-content>
|
||||||
|
|
||||||
|
</ion-app>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const results = document.querySelector('.results');
|
||||||
|
|
||||||
|
window.alert = () => {
|
||||||
|
throw new Error('sanitizeFailed');
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTest(inputString) {
|
||||||
|
console.log(`Sanitizing ${inputString}`);
|
||||||
|
const sanitizedResult = sanitizeDOMString(inputString);
|
||||||
|
|
||||||
|
results.innerHTML = sanitizedResult;
|
||||||
|
console.log(`Result ${sanitizedResult}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
function testA() {
|
||||||
|
runTest('<img src="x" onerror="alert(document.cookie);">');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testB() {
|
||||||
|
runTest('<button id="myButton" name="myButton" onclick="alert(document.cookie);">harmless button</button>');
|
||||||
|
|
||||||
|
const buttom = results.querySelector('button');
|
||||||
|
buttom.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testC() {
|
||||||
|
runTest('<a href="javascript:alert(document.cookie)">harmless link</a>');
|
||||||
|
|
||||||
|
const link = results.querySelector('a');
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testD() {
|
||||||
|
runTest('<a class="link" href="Javascript:alert(document.cookie)">harmless link</a>');
|
||||||
|
|
||||||
|
const link = results.querySelector('a');
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testE() {
|
||||||
|
runTest('<iframe src="javascript:alert(document.cookie)"></iframe>');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testF() {
|
||||||
|
runTest('<div><button><a href="javascript:alert(document.cookie)">click me</a></button></div>');
|
||||||
|
|
||||||
|
const link = results.querySelector('a');
|
||||||
|
link.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
function testG() {
|
||||||
|
runTest('<object><img src="x" onerror="alert(document.cookie);"></object>');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testH() {
|
||||||
|
runTest('<ion-item><ion-label>Hello!</ion-label><ion-button onclick="alert(document.cookie);">Click me</ion-button>');
|
||||||
|
|
||||||
|
const button = results.querySelector('ion-button');
|
||||||
|
button.click();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
Reference in New Issue
Block a user