From d52fca084cf5a9924d0f6a6c4d9ece0373b83213 Mon Sep 17 00:00:00 2001 From: Brandy Smith Date: Wed, 16 Apr 2025 12:23:16 -0400 Subject: [PATCH] fix(config): allow LogLevel to work with isolatedModules and update all warns and errors to respect logLevel (#30350) Issue number: internal --------- ## What is the current behavior? - `LogLevel` throws error `Error: Cannot access ambient const enums when 'isolatedModules' is enabled` - Several existing console warns and errors are not calling the function that respects the `logLevel` config ## What is the new behavior? - Remove `const` from the `enum` to work with `isolatedModules` - Update `console.warn`s to `printIonWarning` - Update `console.error`s to `printIonError` ## Does this introduce a breaking change? - [ ] Yes - [x] No ## Other information Dev build: `8.5.5-dev.11744729748.174bf7e0` --------- Co-authored-by: Brandy Smith <6577830+brandyscarney@users.noreply.github.com> --- .../accordion-group/accordion-group.tsx | 2 +- core/src/components/alert/alert.tsx | 5 +++-- core/src/components/app/app.tsx | 2 +- core/src/components/button/button.tsx | 6 +++--- .../button/test/form-reference/button.e2e.ts | 4 ++-- .../datetime-button/datetime-button.tsx | 8 ++++---- core/src/components/datetime/datetime.tsx | 18 +++++++++--------- .../datetime/test/basic/datetime.e2e.ts | 4 ++-- .../components/datetime/utils/comparison.ts | 2 +- core/src/components/datetime/utils/parse.ts | 4 +++- core/src/components/datetime/utils/state.ts | 2 +- core/src/components/datetime/utils/validate.ts | 11 +++++++---- .../input-password-toggle.tsx | 4 ++-- core/src/components/input/input.utils.ts | 2 +- .../components/item-sliding/item-sliding.tsx | 3 ++- core/src/components/menu/menu.tsx | 7 ++++--- core/src/components/modal/modal.tsx | 6 +++--- .../components/modal/test/basic/modal.e2e.ts | 4 +++- .../components/modal/test/sheet/modal.e2e.ts | 2 +- core/src/components/nav/nav.tsx | 6 +++--- core/src/components/picker-legacy/picker.tsx | 2 +- core/src/components/popover/popover.tsx | 2 +- core/src/components/range/range.tsx | 4 ++-- core/src/components/refresher/refresher.tsx | 3 ++- .../components/router-outlet/router-outlet.tsx | 3 ++- core/src/components/router/router.tsx | 17 +++++++++-------- core/src/components/router/utils/dom.ts | 3 ++- .../segment-button/segment-button.tsx | 11 ++++++++--- core/src/components/select/select.tsx | 9 +++++---- core/src/components/split-pane/split-pane.tsx | 5 +++-- core/src/components/tab/tab.tsx | 7 ++++--- core/src/components/tabs/tabs.tsx | 3 ++- core/src/components/toast/animations/utils.ts | 2 +- core/src/components/toast/toast.tsx | 15 +++++++++------ core/src/global/ionic-global.ts | 3 ++- core/src/utils/animation/animation.ts | 4 +++- core/src/utils/hardware-back-button.ts | 3 ++- core/src/utils/helpers.ts | 3 ++- core/src/utils/logging/index.ts | 2 +- core/src/utils/overlays.ts | 8 ++++---- core/src/utils/sanitization/index.ts | 5 +++-- 41 files changed, 124 insertions(+), 92 deletions(-) diff --git a/core/src/components/accordion-group/accordion-group.tsx b/core/src/components/accordion-group/accordion-group.tsx index b84d75b67a..ba5b110c8b 100644 --- a/core/src/components/accordion-group/accordion-group.tsx +++ b/core/src/components/accordion-group/accordion-group.tsx @@ -87,7 +87,7 @@ export class AccordionGroup implements ComponentInterface { * Custom behavior: ['a', 'b'] */ printIonWarning( - `ion-accordion-group was passed an array of values, but multiple="false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false". + `[ion-accordion-group] - An array of values was passed, but multiple is "false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false". Value Passed: [${value.map((v) => `'${v}'`).join(', ')}] `, diff --git a/core/src/components/alert/alert.tsx b/core/src/components/alert/alert.tsx index dc598fbdf0..c126d9b0d2 100644 --- a/core/src/components/alert/alert.tsx +++ b/core/src/components/alert/alert.tsx @@ -5,6 +5,7 @@ import type { Gesture } from '@utils/gesture'; import { createButtonActiveGesture } from '@utils/gesture/button-active'; import { raf } from '@utils/helpers'; import { createLockController } from '@utils/lock-controller'; +import { printIonWarning } from '@utils/logging'; import { createDelegateController, createTriggerController, @@ -318,8 +319,8 @@ export class Alert implements ComponentInterface, OverlayInterface { // checkboxes and inputs are all accepted, but they cannot be mixed. const inputTypes = new Set(inputs.map((i) => i.type)); if (inputTypes.has('checkbox') && inputTypes.has('radio')) { - console.warn( - `Alert cannot mix input types: ${Array.from(inputTypes.values()).join( + printIonWarning( + `[ion-alert] - Alert cannot mix input types: ${Array.from(inputTypes.values()).join( '/' )}. Please see alert docs for more info.` ); diff --git a/core/src/components/app/app.tsx b/core/src/components/app/app.tsx index fadfed3f04..4f4919667f 100644 --- a/core/src/components/app/app.tsx +++ b/core/src/components/app/app.tsx @@ -46,7 +46,7 @@ export class App implements ComponentInterface { */ if (shouldUseCloseWatcher()) { printIonWarning( - 'experimentalCloseWatcher was set to `true`, but hardwareBackButton was set to `false`. Both config options must be `true` for the Close Watcher API to be used.' + '[ion-app] - experimentalCloseWatcher was set to `true`, but hardwareBackButton was set to `false`. Both config options must be `true` for the Close Watcher API to be used.' ); } diff --git a/core/src/components/button/button.tsx b/core/src/components/button/button.tsx index b3dda48877..4e63b8413e 100644 --- a/core/src/components/button/button.tsx +++ b/core/src/components/button/button.tsx @@ -235,7 +235,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf * element with that id is not a form element. */ printIonWarning( - `Form with selector: "#${form}" could not be found. Verify that the id is attached to a
element.`, + `[ion-button] - Form with selector: "#${form}" could not be found. Verify that the id is attached to a element.`, this.el ); return null; @@ -246,7 +246,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf * element with that id could not be found in the DOM. */ printIonWarning( - `Form with selector: "#${form}" could not be found. Verify that the id is correct and the form is rendered in the DOM.`, + `[ion-button] - Form with selector: "#${form}" could not be found. Verify that the id is correct and the form is rendered in the DOM.`, this.el ); return null; @@ -260,7 +260,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf * as the form attribute. */ printIonWarning( - `The provided "form" element is invalid. Verify that the form is a HTMLFormElement and rendered in the DOM.`, + `[ion-button] - The provided "form" element is invalid. Verify that the form is a HTMLFormElement and rendered in the DOM.`, this.el ); return null; diff --git a/core/src/components/button/test/form-reference/button.e2e.ts b/core/src/components/button/test/form-reference/button.e2e.ts index 0686b11298..5710f52da6 100644 --- a/core/src/components/button/test/form-reference/button.e2e.ts +++ b/core/src/components/button/test/form-reference/button.e2e.ts @@ -169,7 +169,7 @@ configs({ directions: ['ltr'], modes: ['ios'] }).forEach(({ title, config }) => expect(logs.length).toBe(1); expect(logs[0]).toContain( - '[Ionic Warning]: Form with selector: "#missingForm" could not be found. Verify that the id is correct and the form is rendered in the DOM.' + '[Ionic Warning]: [ion-button] - Form with selector: "#missingForm" could not be found. Verify that the id is correct and the form is rendered in the DOM.' ); }); @@ -197,7 +197,7 @@ configs({ directions: ['ltr'], modes: ['ios'] }).forEach(({ title, config }) => expect(logs.length).toBe(1); expect(logs[0]).toContain( - '[Ionic Warning]: The provided "form" element is invalid. Verify that the form is a HTMLFormElement and rendered in the DOM.' + '[Ionic Warning]: [ion-button] - The provided "form" element is invalid. Verify that the form is a HTMLFormElement and rendered in the DOM.' ); }); }); diff --git a/core/src/components/datetime-button/datetime-button.tsx b/core/src/components/datetime-button/datetime-button.tsx index 957a2267f0..af0a77f88e 100644 --- a/core/src/components/datetime-button/datetime-button.tsx +++ b/core/src/components/datetime-button/datetime-button.tsx @@ -63,7 +63,7 @@ export class DatetimeButton implements ComponentInterface { const { datetime } = this; if (!datetime) { printIonError( - 'An ID associated with an ion-datetime instance is required for ion-datetime-button to function properly.', + '[ion-datetime-button] - An ID associated with an ion-datetime instance is required to function properly.', this.el ); return; @@ -71,7 +71,7 @@ export class DatetimeButton implements ComponentInterface { const datetimeEl = (this.datetimeEl = document.getElementById(datetime) as HTMLIonDatetimeElement | null); if (!datetimeEl) { - printIonError(`No ion-datetime instance found for ID '${datetime}'.`, this.el); + printIonError(`[ion-datetime-button] - No ion-datetime instance found for ID '${datetime}'.`, this.el); return; } @@ -81,7 +81,7 @@ export class DatetimeButton implements ComponentInterface { */ if (datetimeEl.tagName !== 'ION-DATETIME') { printIonError( - `Expected an ion-datetime instance for ID '${datetime}' but received '${datetimeEl.tagName.toLowerCase()}' instead.`, + `[ion-datetime-button] - Expected an ion-datetime instance for ID '${datetime}' but received '${datetimeEl.tagName.toLowerCase()}' instead.`, datetimeEl ); return; @@ -245,7 +245,7 @@ export class DatetimeButton implements ComponentInterface { try { headerText = titleSelectedDatesFormatter(parsedValues); } catch (e) { - printIonError('Exception in provided `titleSelectedDatesFormatter`: ', e); + printIonError('[ion-datetime-button] - Exception in provided `titleSelectedDatesFormatter`:', e); } } this.dateText = headerText; diff --git a/core/src/components/datetime/datetime.tsx b/core/src/components/datetime/datetime.tsx index fcdb8bcabe..b63590c66b 100644 --- a/core/src/components/datetime/datetime.tsx +++ b/core/src/components/datetime/datetime.tsx @@ -584,7 +584,7 @@ export class Datetime implements ComponentInterface { * Custom behavior: ['a', 'b'] */ printIonWarning( - `ion-datetime was passed an array of values, but multiple="false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false". + `[ion-datetime] - An array of values was passed, but multiple is "false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false". Value Passed: [${value.map((v) => `'${v}'`).join(', ')}] `, @@ -1389,24 +1389,24 @@ export class Datetime implements ComponentInterface { if (multiple) { if (presentation !== 'date') { - printIonWarning('Multiple date selection is only supported for presentation="date".', el); + printIonWarning('[ion-datetime] - Multiple date selection is only supported for presentation="date".', el); } if (preferWheel) { - printIonWarning('Multiple date selection is not supported with preferWheel="true".', el); + printIonWarning('[ion-datetime] - Multiple date selection is not supported with preferWheel="true".', el); } } if (highlightedDates !== undefined) { if (presentation !== 'date' && presentation !== 'date-time' && presentation !== 'time-date') { printIonWarning( - 'The highlightedDates property is only supported with the date, date-time, and time-date presentations.', + '[ion-datetime] - The highlightedDates property is only supported with the date, date-time, and time-date presentations.', el ); } if (preferWheel) { - printIonWarning('The highlightedDates property is not supported with preferWheel="true".', el); + printIonWarning('[ion-datetime] - The highlightedDates property is not supported with preferWheel="true".', el); } } @@ -1668,7 +1668,7 @@ export class Datetime implements ComponentInterface { disabled = !isDateEnabled(convertDataToISO(referenceParts)); } catch (e) { printIonError( - 'Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', + '[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e ); } @@ -1759,7 +1759,7 @@ export class Datetime implements ComponentInterface { disabled = !isDateEnabled(convertDataToISO(referenceParts)); } catch (e) { printIonError( - 'Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', + '[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e ); } @@ -2262,7 +2262,7 @@ export class Datetime implements ComponentInterface { isCalDayDisabled = !isDateEnabled(dateIsoString); } catch (e) { printIonError( - 'Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', + '[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', el, e ); @@ -2483,7 +2483,7 @@ export class Datetime implements ComponentInterface { try { headerText = titleSelectedDatesFormatter(convertDataToISO(activeParts)); } catch (e) { - printIonError('Exception in provided `titleSelectedDatesFormatter`: ', e); + printIonError('[ion-datetime] - Exception in provided `titleSelectedDatesFormatter`:', e); } } } else { diff --git a/core/src/components/datetime/test/basic/datetime.e2e.ts b/core/src/components/datetime/test/basic/datetime.e2e.ts index f96cc64bea..67812b6d02 100644 --- a/core/src/components/datetime/test/basic/datetime.e2e.ts +++ b/core/src/components/datetime/test/basic/datetime.e2e.ts @@ -687,7 +687,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { expect(logs.length).toBe(1); expect(logs[0]).toContain( - '[Ionic Warning]: Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".' + '[Ionic Warning]: [ion-datetime] - "timeZone" and "timeZoneName" are not supported in "formatOptions".' ); }); @@ -717,7 +717,7 @@ configs({ modes: ['md'], directions: ['ltr'] }).forEach(({ title, config }) => { expect(logs.length).toBe(1); expect(logs[0]).toContain( - "[Ionic Warning]: Datetime: The 'date-time' presentation requires either a date or time object (or both) in formatOptions." + "[Ionic Warning]: [ion-datetime] - The 'date-time' presentation requires either a date or time object (or both) in formatOptions." ); }); }); diff --git a/core/src/components/datetime/utils/comparison.ts b/core/src/components/datetime/utils/comparison.ts index 0507b16908..986d583922 100644 --- a/core/src/components/datetime/utils/comparison.ts +++ b/core/src/components/datetime/utils/comparison.ts @@ -48,7 +48,7 @@ export const warnIfValueOutOfBounds = ( for (const val of valueArray) { if ((min !== undefined && isBefore(val, min)) || (max !== undefined && isAfter(val, max))) { printIonWarning( - 'The value provided to ion-datetime is out of bounds.\n\n' + + '[ion-datetime] - The value provided to ion-datetime is out of bounds.\n\n' + `Min: ${JSON.stringify(min)}\n` + `Max: ${JSON.stringify(max)}\n` + `Value: ${JSON.stringify(value)}` diff --git a/core/src/components/datetime/utils/parse.ts b/core/src/components/datetime/utils/parse.ts index efda69f655..ef18892b23 100644 --- a/core/src/components/datetime/utils/parse.ts +++ b/core/src/components/datetime/utils/parse.ts @@ -105,7 +105,9 @@ export function parseDate(val: string | string[] | undefined | null): DatetimePa if (parse === null) { // wasn't able to parse the ISO datetime - printIonWarning(`Unable to parse date string: ${val}. Please provide a valid ISO 8601 datetime string.`); + printIonWarning( + `[ion-datetime] - Unable to parse date string: ${val}. Please provide a valid ISO 8601 datetime string.` + ); return undefined; } diff --git a/core/src/components/datetime/utils/state.ts b/core/src/components/datetime/utils/state.ts index f709d7289a..80abeb25f5 100644 --- a/core/src/components/datetime/utils/state.ts +++ b/core/src/components/datetime/utils/state.ts @@ -218,7 +218,7 @@ export const getHighlightStyles = ( return highlightedDates(dateIsoString); } catch (e) { printIonError( - 'Exception thrown from provided `highlightedDates` callback. Please check your function and try again.', + '[ion-datetime] - Exception thrown from provided `highlightedDates` callback. Please check your function and try again.', el, e ); diff --git a/core/src/components/datetime/utils/validate.ts b/core/src/components/datetime/utils/validate.ts index 46c3fe633b..d11ceeec72 100644 --- a/core/src/components/datetime/utils/validate.ts +++ b/core/src/components/datetime/utils/validate.ts @@ -14,7 +14,7 @@ export const warnIfTimeZoneProvided = (el: HTMLElement, formatOptions?: FormatOp formatOptions?.time?.timeZone || formatOptions?.time?.timeZoneName ) { - printIonWarning('Datetime: "timeZone" and "timeZoneName" are not supported in "formatOptions".', el); + printIonWarning('[ion-datetime] - "timeZone" and "timeZoneName" are not supported in "formatOptions".', el); } }; @@ -33,19 +33,22 @@ export const checkForPresentationFormatMismatch = ( case 'month': case 'year': if (formatOptions.date === undefined) { - printIonWarning(`Datetime: The '${presentation}' presentation requires a date object in formatOptions.`, el); + printIonWarning( + `[ion-datetime] - The '${presentation}' presentation requires a date object in formatOptions.`, + el + ); } break; case 'time': if (formatOptions.time === undefined) { - printIonWarning(`Datetime: The 'time' presentation requires a time object in formatOptions.`, el); + printIonWarning(`[ion-datetime] - The 'time' presentation requires a time object in formatOptions.`, el); } break; case 'date-time': case 'time-date': if (formatOptions.date === undefined && formatOptions.time === undefined) { printIonWarning( - `Datetime: The '${presentation}' presentation requires either a date or time object (or both) in formatOptions.`, + `[ion-datetime] - The '${presentation}' presentation requires either a date or time object (or both) in formatOptions.`, el ); } diff --git a/core/src/components/input-password-toggle/input-password-toggle.tsx b/core/src/components/input-password-toggle/input-password-toggle.tsx index a783cfc9af..44b8e0828a 100644 --- a/core/src/components/input-password-toggle/input-password-toggle.tsx +++ b/core/src/components/input-password-toggle/input-password-toggle.tsx @@ -59,7 +59,7 @@ export class InputPasswordToggle implements ComponentInterface { onTypeChange(newValue: TextFieldTypes) { if (newValue !== 'text' && newValue !== 'password') { printIonWarning( - `ion-input-password-toggle only supports inputs of type "text" or "password". Input of type "${newValue}" is not compatible.`, + `[ion-input-password-toggle] - Only inputs of type "text" or "password" are supported. Input of type "${newValue}" is not compatible.`, this.el ); @@ -74,7 +74,7 @@ export class InputPasswordToggle implements ComponentInterface { if (!inputElRef) { printIonWarning( - 'No ancestor ion-input found for ion-input-password-toggle. This component must be slotted inside of an ion-input.', + '[ion-input-password-toggle] - No ancestor ion-input found. This component must be slotted inside of an ion-input.', el ); diff --git a/core/src/components/input/input.utils.ts b/core/src/components/input/input.utils.ts index d6812be12d..1567a3b52c 100644 --- a/core/src/components/input/input.utils.ts +++ b/core/src/components/input/input.utils.ts @@ -24,7 +24,7 @@ export const getCounterText = ( try { return counterFormatter(valueLength, maxLength); } catch (e) { - printIonError('Exception in provided `counterFormatter`.', e); + printIonError('[ion-input] - Exception in provided `counterFormatter`:', e); return defaultCounterText; } }; diff --git a/core/src/components/item-sliding/item-sliding.tsx b/core/src/components/item-sliding/item-sliding.tsx index a250b5e9bf..ef9eaae327 100644 --- a/core/src/components/item-sliding/item-sliding.tsx +++ b/core/src/components/item-sliding/item-sliding.tsx @@ -2,6 +2,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; import { Component, Element, Event, Host, Method, Prop, State, Watch, h } from '@stencil/core'; import { findClosestIonContent, disableContentScrollY, resetContentScrollY } from '@utils/content'; import { isEndSide } from '@utils/helpers'; +import { printIonWarning } from '@utils/logging'; import { watchForOptions } from '@utils/watch-options'; import { getIonMode } from '../../global/ionic-global'; @@ -343,7 +344,7 @@ export class ItemSliding implements ComponentInterface { case ItemSide.None: return; default: - console.warn('invalid ItemSideFlags value', this.sides); + printIonWarning('[ion-item-sliding] - invalid ItemSideFlags value', this.sides); break; } diff --git a/core/src/components/menu/menu.tsx b/core/src/components/menu/menu.tsx index 8a70dd8fb1..0fee7bda16 100644 --- a/core/src/components/menu/menu.tsx +++ b/core/src/components/menu/menu.tsx @@ -6,6 +6,7 @@ import { GESTURE_CONTROLLER } from '@utils/gesture'; import { shouldUseCloseWatcher } from '@utils/hardware-back-button'; import type { Attributes } from '@utils/helpers'; import { inheritAriaAttributes, assert, clamp, isEndSide as isEnd } from '@utils/helpers'; +import { printIonError } from '@utils/logging'; import { menuController } from '@utils/menu-controller'; import { BACKDROP, GESTURE, getPresentedOverlay } from '@utils/overlays'; import { isPlatform } from '@utils/platform'; @@ -215,13 +216,13 @@ export class Menu implements ComponentInterface, MenuI { const content = this.contentId !== undefined ? document.getElementById(this.contentId) : null; if (content === null) { - console.error('Menu: must have a "content" element to listen for drag events on.'); + printIonError('[ion-menu] - Must have a "content" element to listen for drag events on.'); return; } if (this.el.contains(content)) { - console.error( - `Menu: "contentId" should refer to the main view's ion-content, not the ion-content inside of the ion-menu.` + printIonError( + `[ion-menu] - The "contentId" should refer to the main view's ion-content, not the ion-content inside of the ion-menu.` ); } diff --git a/core/src/components/modal/modal.tsx b/core/src/components/modal/modal.tsx index c6f15bdce8..2ec55fca02 100644 --- a/core/src/components/modal/modal.tsx +++ b/core/src/components/modal/modal.tsx @@ -427,7 +427,7 @@ export class Modal implements ComponentInterface, OverlayInterface { } if (breakpoints !== undefined && initialBreakpoint !== undefined && !breakpoints.includes(initialBreakpoint)) { - printIonWarning('Your breakpoints array must include the initialBreakpoint value.'); + printIonWarning('[ion-modal] - Your breakpoints array must include the initialBreakpoint value.'); } if (!this.htmlAttributes?.id) { @@ -847,12 +847,12 @@ export class Modal implements ComponentInterface, OverlayInterface { @Method() async setCurrentBreakpoint(breakpoint: number): Promise { if (!this.isSheetModal) { - printIonWarning('setCurrentBreakpoint is only supported on sheet modals.'); + printIonWarning('[ion-modal] - setCurrentBreakpoint is only supported on sheet modals.'); return; } if (!this.breakpoints!.includes(breakpoint)) { printIonWarning( - `Attempted to set invalid breakpoint value ${breakpoint}. Please double check that the breakpoint value is part of your defined breakpoints.` + `[ion-modal] - Attempted to set invalid breakpoint value ${breakpoint}. Please double check that the breakpoint value is part of your defined breakpoints.` ); return; } diff --git a/core/src/components/modal/test/basic/modal.e2e.ts b/core/src/components/modal/test/basic/modal.e2e.ts index f431b6fe46..325c4b3fbb 100644 --- a/core/src/components/modal/test/basic/modal.e2e.ts +++ b/core/src/components/modal/test/basic/modal.e2e.ts @@ -145,7 +145,9 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => await modal.evaluate((el: HTMLIonModalElement) => el.setCurrentBreakpoint(0.5)); expect(warnings.length).toBe(1); - expect(warnings[0]).toBe('[Ionic Warning]: setCurrentBreakpoint is only supported on sheet modals.'); + expect(warnings[0]).toBe( + '[Ionic Warning]: [ion-modal] - setCurrentBreakpoint is only supported on sheet modals.' + ); }); test('it should return undefined when getting the breakpoint on a non-sheet modal', async ({ page }) => { diff --git a/core/src/components/modal/test/sheet/modal.e2e.ts b/core/src/components/modal/test/sheet/modal.e2e.ts index 6afb4cd67e..469040602f 100644 --- a/core/src/components/modal/test/sheet/modal.e2e.ts +++ b/core/src/components/modal/test/sheet/modal.e2e.ts @@ -96,7 +96,7 @@ configs({ modes: ['ios'], directions: ['ltr'] }).forEach(({ title, config }) => test('it should warn when setting an invalid breakpoint', async () => { expect(warnings.length).toBe(1); expect(warnings[0]).toBe( - '[Ionic Warning]: Attempted to set invalid breakpoint value 0.01. Please double check that the breakpoint value is part of your defined breakpoints.' + '[Ionic Warning]: [ion-modal] - Attempted to set invalid breakpoint value 0.01. Please double check that the breakpoint value is part of your defined breakpoints.' ); }); }); diff --git a/core/src/components/nav/nav.tsx b/core/src/components/nav/nav.tsx index cc71af4f6c..3ecd39c2aa 100644 --- a/core/src/components/nav/nav.tsx +++ b/core/src/components/nav/nav.tsx @@ -97,7 +97,7 @@ export class Nav implements NavOutlet { this.setRoot(this.root, this.rootParams); } } else if (isDev) { - printIonWarning(' does not support a root attribute when using ion-router.', this.el); + printIonWarning('[ion-nav] - A root attribute is not supported when using ion-router.', this.el); } } @@ -820,8 +820,8 @@ export class Nav implements NavOutlet { const finalNumViews = this.views.length + (insertViews?.length ?? 0) - (removeCount ?? 0); assert(finalNumViews >= 0, 'final balance can not be negative'); if (finalNumViews === 0) { - console.warn( - `You can't remove all the pages in the navigation stack. nav.pop() is probably called too many times.`, + printIonWarning( + `[ion-nav] - You can't remove all the pages in the navigation stack. nav.pop() is probably called too many times.`, this, this.el ); diff --git a/core/src/components/picker-legacy/picker.tsx b/core/src/components/picker-legacy/picker.tsx index 6b26782392..fe67cf83fe 100644 --- a/core/src/components/picker-legacy/picker.tsx +++ b/core/src/components/picker-legacy/picker.tsx @@ -206,7 +206,7 @@ export class Picker implements ComponentInterface, OverlayInterface { componentDidLoad() { printIonWarning( - 'ion-picker-legacy and ion-picker-legacy-column have been deprecated in favor of new versions of the ion-picker and ion-picker-column components. These new components display inline with your page content allowing for more presentation flexibility than before.', + '[ion-picker-legacy] - ion-picker-legacy and ion-picker-legacy-column have been deprecated in favor of new versions of the ion-picker and ion-picker-column components. These new components display inline with your page content allowing for more presentation flexibility than before.', this.el ); diff --git a/core/src/components/popover/popover.tsx b/core/src/components/popover/popover.tsx index d1205ab2f6..61d525dff9 100644 --- a/core/src/components/popover/popover.tsx +++ b/core/src/components/popover/popover.tsx @@ -648,7 +648,7 @@ export class Popover implements ComponentInterface, PopoverInterface { const triggerEl = (this.triggerEl = trigger !== undefined ? document.getElementById(trigger) : null); if (!triggerEl) { printIonWarning( - `A trigger element with the ID "${trigger}" was not found in the DOM. The trigger element must be in the DOM when the "trigger" property is set on ion-popover.`, + `[ion-popover] - A trigger element with the ID "${trigger}" was not found in the DOM. The trigger element must be in the DOM when the "trigger" property is set on ion-popover.`, this.el ); return; diff --git a/core/src/components/range/range.tsx b/core/src/components/range/range.tsx index 478b2a57e2..eac3dd3ebc 100644 --- a/core/src/components/range/range.tsx +++ b/core/src/components/range/range.tsx @@ -183,13 +183,13 @@ export class Range implements ComponentInterface { if (activeBarStart !== undefined) { if (activeBarStart > this.max) { printIonWarning( - `Range: The value of activeBarStart (${activeBarStart}) is greater than the max (${this.max}). Valid values are greater than or equal to the min value and less than or equal to the max value.`, + `[ion-range] - The value of activeBarStart (${activeBarStart}) is greater than the max (${this.max}). Valid values are greater than or equal to the min value and less than or equal to the max value.`, this.el ); this.activeBarStart = this.max; } else if (activeBarStart < this.min) { printIonWarning( - `Range: The value of activeBarStart (${activeBarStart}) is less than the min (${this.min}). Valid values are greater than or equal to the min value and less than or equal to the max value.`, + `[ion-range] - The value of activeBarStart (${activeBarStart}) is less than the min (${this.min}). Valid values are greater than or equal to the min value and less than or equal to the max value.`, this.el ); this.activeBarStart = this.min; diff --git a/core/src/components/refresher/refresher.tsx b/core/src/components/refresher/refresher.tsx index 25a121a3d0..8d01687308 100644 --- a/core/src/components/refresher/refresher.tsx +++ b/core/src/components/refresher/refresher.tsx @@ -8,6 +8,7 @@ import { printIonContentErrorMsg, } from '@utils/content'; import { clamp, componentOnReady, getElementRoot, raf, transitionEndAsync } from '@utils/helpers'; +import { printIonError } from '@utils/logging'; import { ImpactStyle, hapticImpact } from '@utils/native/haptic'; import { getIonMode } from '../../global/ionic-global'; @@ -452,7 +453,7 @@ export class Refresher implements ComponentInterface { async connectedCallback() { if (this.el.getAttribute('slot') !== 'fixed') { - console.error('Make sure you use: '); + printIonError('[ion-refresher] - Make sure you use: '); return; } const contentEl = this.el.closest(ION_CONTENT_ELEMENT_SELECTOR); diff --git a/core/src/components/router-outlet/router-outlet.tsx b/core/src/components/router-outlet/router-outlet.tsx index d25234f814..5187bddb6e 100644 --- a/core/src/components/router-outlet/router-outlet.tsx +++ b/core/src/components/router-outlet/router-outlet.tsx @@ -4,6 +4,7 @@ import { getTimeGivenProgression } from '@utils/animation/cubic-bezier'; import { attachComponent, detachComponent } from '@utils/framework-delegate'; import { shallowEqualStringMap, hasLazyBuild } from '@utils/helpers'; import { createLockController } from '@utils/lock-controller'; +import { printIonError } from '@utils/logging'; import { transition } from '@utils/transition'; import { config } from '../../global/config'; @@ -146,7 +147,7 @@ export class RouterOutlet implements ComponentInterface, NavOutlet { try { changed = await this.transition(enteringEl, leavingEl, opts); } catch (e) { - console.error(e); + printIonError('[ion-router-outlet] - Exception in commit:', e); } unlock(); return changed; diff --git a/core/src/components/router/router.tsx b/core/src/components/router/router.tsx index 3f30e6f975..c68c9c4701 100644 --- a/core/src/components/router/router.tsx +++ b/core/src/components/router/router.tsx @@ -2,6 +2,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; import { Component, Element, Event, Listen, Method, Prop } from '@stencil/core'; import type { BackButtonEvent } from '@utils/hardware-back-button'; import { debounce } from '@utils/helpers'; +import { printIonError, printIonWarning } from '@utils/logging'; import type { AnimationBuilder } from '../../interface'; import type { NavigationHookResult } from '../route/route-interface'; @@ -166,15 +167,15 @@ export class Router implements ComponentInterface { @Method() async navChanged(direction: RouterDirection): Promise { if (this.busy) { - console.warn('[ion-router] router is busy, navChanged was cancelled'); + printIonWarning('[ion-router] - Router is busy, navChanged was cancelled.'); return false; } const { ids, outlet } = await readNavState(window.document.body); const routes = readRoutes(this.el); const chain = findChainForIDs(ids, routes); if (!chain) { - console.warn( - '[ion-router] no matching URL for ', + printIonWarning( + '[ion-router] - No matching URL for', ids.map((i) => i.id) ); return false; @@ -182,7 +183,7 @@ export class Router implements ComponentInterface { const segments = chainToSegments(chain); if (!segments) { - console.warn('[ion-router] router could not match path because some required param is missing'); + printIonWarning('[ion-router] - Router could not match path because some required param is missing.'); return false; } @@ -232,7 +233,7 @@ export class Router implements ComponentInterface { animation?: AnimationBuilder ): Promise { if (!segments) { - console.error('[ion-router] URL is not part of the routing set'); + printIonError('[ion-router] - URL is not part of the routing set.'); return false; } @@ -253,7 +254,7 @@ export class Router implements ComponentInterface { const routes = readRoutes(this.el); const chain = findChainForSegments(segments, routes); if (!chain) { - console.error('[ion-router] the path does not match any route'); + printIonError('[ion-router] - The path does not match any route.'); return false; } @@ -275,7 +276,7 @@ export class Router implements ComponentInterface { try { changed = await this.writeNavState(node, chain, direction, segments, redirectFrom, index, animation); } catch (e) { - console.error(e); + printIonError('[ion-router] - Exception in safeWriteNavState:', e); } unlock(); return changed; @@ -338,7 +339,7 @@ export class Router implements ComponentInterface { animation?: AnimationBuilder ): Promise { if (this.busy) { - console.warn('[ion-router] router is busy, transition was cancelled'); + printIonWarning('[ion-router] - Router is busy, transition was cancelled.'); return false; } this.busy = true; diff --git a/core/src/components/router/utils/dom.ts b/core/src/components/router/utils/dom.ts index 95bc6fec53..c10b34d084 100644 --- a/core/src/components/router/utils/dom.ts +++ b/core/src/components/router/utils/dom.ts @@ -1,4 +1,5 @@ import { componentOnReady } from '@utils/helpers'; +import { printIonError } from '@utils/logging'; import type { AnimationBuilder } from '../../../interface'; @@ -51,7 +52,7 @@ export const writeNavState = async ( } return changed; } catch (e) { - console.error(e); + printIonError('[ion-router] - Exception in writeNavState:', e); return false; } }; diff --git a/core/src/components/segment-button/segment-button.tsx b/core/src/components/segment-button/segment-button.tsx index fb940c9d99..115040298d 100644 --- a/core/src/components/segment-button/segment-button.tsx +++ b/core/src/components/segment-button/segment-button.tsx @@ -3,6 +3,7 @@ import { Component, Element, Host, Prop, Method, State, Watch, forceUpdate, h } import type { ButtonInterface } from '@utils/element-interface'; import type { Attributes } from '@utils/helpers'; import { addEventListener, removeEventListener, inheritAttributes } from '@utils/helpers'; +import { printIonError, printIonWarning } from '@utils/logging'; import { hostContext } from '@utils/theme'; import { getIonMode } from '../../global/ionic-global'; @@ -75,7 +76,9 @@ export class SegmentButton implements ComponentInterface, ButtonInterface { // Prevent buttons from being disabled when associated with segment content if (this.contentId && this.disabled) { - console.warn(`Segment Button: Segment buttons cannot be disabled when associated with an .`); + printIonWarning( + `[ion-segment-button] - Segment buttons cannot be disabled when associated with an .` + ); this.disabled = false; } } @@ -102,13 +105,15 @@ export class SegmentButton implements ComponentInterface, ButtonInterface { // If no associated Segment Content exists, log an error and return if (!segmentContent) { - console.error(`Segment Button: Unable to find Segment Content with id="${this.contentId}".`); + printIonError(`[ion-segment-button] - Unable to find Segment Content with id="${this.contentId}".`); return; } // Ensure the found element is a valid ION-SEGMENT-CONTENT if (segmentContent.tagName !== 'ION-SEGMENT-CONTENT') { - console.error(`Segment Button: Element with id="${this.contentId}" is not an element.`); + printIonError( + `[ion-segment-button] - Element with id="${this.contentId}" is not an element.` + ); return; } } diff --git a/core/src/components/select/select.tsx b/core/src/components/select/select.tsx index 0645cd5e56..df432d8af8 100644 --- a/core/src/components/select/select.tsx +++ b/core/src/components/select/select.tsx @@ -4,6 +4,7 @@ import type { NotchController } from '@utils/forms'; import { compareOptions, createNotchController, isOptionSelected } from '@utils/forms'; import { focusVisibleElement, renderHiddenInput, inheritAttributes } from '@utils/helpers'; import type { Attributes } from '@utils/helpers'; +import { printIonWarning } from '@utils/logging'; import { actionSheetController, alertController, popoverController, modalController } from '@utils/overlays'; import type { OverlaySelect } from '@utils/overlays-interface'; import { isRTL } from '@utils/rtl'; @@ -426,15 +427,15 @@ export class Select implements ComponentInterface { private createOverlay(ev?: UIEvent): Promise { let selectInterface = this.interface; if (selectInterface === 'action-sheet' && this.multiple) { - console.warn( - `Select interface cannot be "${selectInterface}" with a multi-value select. Using the "alert" interface instead.` + printIonWarning( + `[ion-select] - Interface cannot be "${selectInterface}" with a multi-value select. Using the "alert" interface instead.` ); selectInterface = 'alert'; } if (selectInterface === 'popover' && !ev) { - console.warn( - `Select interface cannot be a "${selectInterface}" without passing an event. Using the "alert" interface instead.` + printIonWarning( + `[ion-select] - Interface cannot be a "${selectInterface}" without passing an event. Using the "alert" interface instead.` ); selectInterface = 'alert'; } diff --git a/core/src/components/split-pane/split-pane.tsx b/core/src/components/split-pane/split-pane.tsx index 7cd33ba580..e2a02dab7a 100644 --- a/core/src/components/split-pane/split-pane.tsx +++ b/core/src/components/split-pane/split-pane.tsx @@ -1,5 +1,6 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core'; import { Build, Component, Element, Event, Host, Method, Prop, State, Watch, h } from '@stencil/core'; +import { printIonWarning } from '@utils/logging'; import { getIonMode } from '../../global/ionic-global'; @@ -154,7 +155,7 @@ export class SplitPane implements ComponentInterface { const isMain = contentId !== undefined && child.id === contentId; if (isMain) { if (foundMain) { - console.warn('split pane cannot have more than one main node'); + printIonWarning('[ion-split-pane] - Cannot have more than one main node.'); return; } else { setPaneClass(child, isMain); @@ -163,7 +164,7 @@ export class SplitPane implements ComponentInterface { } } if (!foundMain) { - console.warn('split pane does not have a specified main node'); + printIonWarning('[ion-split-pane] - Does not have a specified main node.'); } } diff --git a/core/src/components/tab/tab.tsx b/core/src/components/tab/tab.tsx index ce507867fd..a1f6be57a0 100644 --- a/core/src/components/tab/tab.tsx +++ b/core/src/components/tab/tab.tsx @@ -1,6 +1,7 @@ import type { ComponentInterface } from '@stencil/core'; import { Build, Component, Element, Host, Method, Prop, Watch, h } from '@stencil/core'; import { attachComponent } from '@utils/framework-delegate'; +import { printIonError } from '@utils/logging'; import type { ComponentRef, FrameworkDelegate } from '../../interface'; @@ -33,8 +34,8 @@ export class Tab implements ComponentInterface { async componentWillLoad() { if (Build.isDev) { if (this.component !== undefined && this.el.childElementCount > 0) { - console.error( - 'You can not use a lazy-loaded component in a tab and inlined content at the same time.' + + printIonError( + '[ion-tab] - You can not use a lazy-loaded component in a tab and inlined content at the same time.' + `- Remove the component attribute in: ` + ` or` + `- Remove the embedded content inside the ion-tab: ` @@ -66,7 +67,7 @@ export class Tab implements ComponentInterface { try { return attachComponent(this.delegate, this.el, this.component, ['ion-page']); } catch (e) { - console.error(e); + printIonError('[ion-tab] - Exception in prepareLazyLoaded:', e); } } return Promise.resolve(undefined); diff --git a/core/src/components/tabs/tabs.tsx b/core/src/components/tabs/tabs.tsx index 3eebb46d15..e02e1aa91b 100644 --- a/core/src/components/tabs/tabs.tsx +++ b/core/src/components/tabs/tabs.tsx @@ -1,5 +1,6 @@ import type { EventEmitter } from '@stencil/core'; import { Component, Element, Event, Host, Method, Prop, State, h } from '@stencil/core'; +import { printIonError } from '@utils/logging'; import type { NavOutlet, RouteID, RouteWrite } from '../router/utils/interface'; import type { TabButtonClickEventDetail } from '../tab-bar/tab-bar-interface'; @@ -210,7 +211,7 @@ const getTab = (tabs: HTMLIonTabElement[], tab: string | HTMLIonTabElement): HTM const tabEl = typeof tab === 'string' ? tabs.find((t) => t.tab === tab) : tab; if (!tabEl) { - console.error(`tab with id: "${tabEl}" does not exist`); + printIonError(`[ion-tabs] - Tab with id: "${tabEl}" does not exist`); } return tabEl; }; diff --git a/core/src/components/toast/animations/utils.ts b/core/src/components/toast/animations/utils.ts index d9057dda0d..278ef2313f 100644 --- a/core/src/components/toast/animations/utils.ts +++ b/core/src/components/toast/animations/utils.ts @@ -83,7 +83,7 @@ export function getAnimationPosition( function warnIfAnchorIsHidden(positionAnchor: HTMLElement, toast: HTMLElement) { if (positionAnchor.offsetParent === null) { printIonWarning( - 'The positionAnchor element for ion-toast was found in the DOM, but appears to be hidden. This may lead to unexpected positioning of the toast.', + '[ion-toast] - The positionAnchor element for ion-toast was found in the DOM, but appears to be hidden. This may lead to unexpected positioning of the toast.', toast ); } diff --git a/core/src/components/toast/toast.tsx b/core/src/components/toast/toast.tsx index d006471618..45ec9fc064 100644 --- a/core/src/components/toast/toast.tsx +++ b/core/src/components/toast/toast.tsx @@ -4,7 +4,7 @@ import { ENABLE_HTML_CONTENT_DEFAULT } from '@utils/config'; import type { Gesture } from '@utils/gesture'; import { raf } from '@utils/helpers'; import { createLockController } from '@utils/lock-controller'; -import { printIonWarning } from '@utils/logging'; +import { printIonError, printIonWarning } from '@utils/logging'; import { GESTURE, createDelegateController, @@ -498,7 +498,7 @@ export class Toast implements ComponentInterface, OverlayInterface { } if (position === 'middle' && positionAnchor !== undefined) { - printIonWarning('The positionAnchor property is ignored when using position="middle".', this.el); + printIonWarning('[ion-toast] - The positionAnchor property is ignored when using position="middle".', this.el); return undefined; } @@ -511,7 +511,10 @@ export class Toast implements ComponentInterface, OverlayInterface { */ const foundEl = document.getElementById(positionAnchor); if (foundEl === null) { - printIonWarning(`An anchor element with an ID of "${positionAnchor}" was not found in the DOM.`, el); + printIonWarning( + `[ion-toast] - An anchor element with an ID of "${positionAnchor}" was not found in the DOM.`, + el + ); return undefined; } @@ -522,7 +525,7 @@ export class Toast implements ComponentInterface, OverlayInterface { return positionAnchor; } - printIonWarning('Invalid positionAnchor value:', positionAnchor, el); + printIonWarning('[ion-toast] - Invalid positionAnchor value:', positionAnchor, el); return undefined; } @@ -549,7 +552,7 @@ export class Toast implements ComponentInterface, OverlayInterface { return false; } } catch (e) { - console.error(e); + printIonError('[ion-toast] - Exception in callButtonHandler:', e); } } return true; @@ -705,7 +708,7 @@ export class Toast implements ComponentInterface, OverlayInterface { */ if (layout === 'stacked' && startButtons.length > 0 && endButtons.length > 0) { printIonWarning( - 'This toast is using start and end buttons with the stacked toast layout. We recommend following the best practice of using either start or end buttons with the stacked toast layout.', + '[ion-toast] - This toast is using start and end buttons with the stacked toast layout. We recommend following the best practice of using either start or end buttons with the stacked toast layout.', el ); } diff --git a/core/src/global/ionic-global.ts b/core/src/global/ionic-global.ts index 86ae5878a5..901d41fada 100644 --- a/core/src/global/ionic-global.ts +++ b/core/src/global/ionic-global.ts @@ -1,4 +1,5 @@ import { getMode, setMode } from '@stencil/core'; +import { printIonWarning } from '@utils/logging'; import type { IonicConfig, Mode } from '../interface'; import { isPlatform, setupPlatforms } from '../utils/platform'; @@ -67,7 +68,7 @@ export const initialize = (userConfig: IonicConfig = {}) => { if (isAllowedIonicModeValue(elmMode)) { return elmMode; } else if (isIonicElement(elm)) { - console.warn('Invalid ionic mode: "' + elmMode + '", expected: "ios" or "md"'); + printIonWarning('Invalid ionic mode: "' + elmMode + '", expected: "ios" or "md"'); } } elm = elm.parentElement; diff --git a/core/src/utils/animation/animation.ts b/core/src/utils/animation/animation.ts index c7c57b9f87..4751e72423 100644 --- a/core/src/utils/animation/animation.ts +++ b/core/src/utils/animation/animation.ts @@ -1,3 +1,5 @@ +import { printIonError } from '@utils/logging'; + import { win } from '../browser'; import type { @@ -455,7 +457,7 @@ export const createAnimation = (animationId?: string): Animation => { elements.push((el as any)[i]); } } else { - console.error('Invalid addElement value'); + printIonError('createAnimation - Invalid addElement value.'); } } diff --git a/core/src/utils/hardware-back-button.ts b/core/src/utils/hardware-back-button.ts index dbd5d70783..2c79e3cfaa 100644 --- a/core/src/utils/hardware-back-button.ts +++ b/core/src/utils/hardware-back-button.ts @@ -1,5 +1,6 @@ import { win } from '@utils/browser'; import type { CloseWatcher } from '@utils/browser'; +import { printIonError } from '@utils/logging'; import { config } from '../global/config'; @@ -77,7 +78,7 @@ export const startHardwareBackButton = () => { } } } catch (e) { - console.error(e); + printIonError('[ion-app] - Exception in startHardwareBackButton:', e); } }; diff --git a/core/src/utils/helpers.ts b/core/src/utils/helpers.ts index e2a65407c0..e32956c35e 100644 --- a/core/src/utils/helpers.ts +++ b/core/src/utils/helpers.ts @@ -1,4 +1,5 @@ import type { EventEmitter } from '@stencil/core'; +import { printIonError } from '@utils/logging'; import type { Side } from '../components/menu/menu-interface'; @@ -287,7 +288,7 @@ export const clamp = (min: number, n: number, max: number) => { export const assert = (actual: any, reason: string) => { if (!actual) { const message = 'ASSERT: ' + reason; - console.error(message); + printIonError(message); debugger; // eslint-disable-line throw new Error(message); } diff --git a/core/src/utils/logging/index.ts b/core/src/utils/logging/index.ts index 4bf58ce629..d13d6d8d0d 100644 --- a/core/src/utils/logging/index.ts +++ b/core/src/utils/logging/index.ts @@ -1,6 +1,6 @@ import { config } from '@global/config'; -export const enum LogLevel { +export enum LogLevel { OFF = 'OFF', ERROR = 'ERROR', WARN = 'WARN', diff --git a/core/src/utils/overlays.ts b/core/src/utils/overlays.ts index 4a392ac537..9dfc0b63ed 100644 --- a/core/src/utils/overlays.ts +++ b/core/src/utils/overlays.ts @@ -2,6 +2,7 @@ import { doc } from '@utils/browser'; import { focusFirstDescendant, focusLastDescendant, focusableQueryString } from '@utils/focus-trap'; import type { BackButtonEvent } from '@utils/hardware-back-button'; import { shouldUseCloseWatcher } from '@utils/hardware-back-button'; +import { printIonError, printIonWarning } from '@utils/logging'; import { config } from '../global/config'; import { getIonMode } from '../global/ionic-global'; @@ -31,7 +32,6 @@ import { getElementRoot, removeEventListener, } from './helpers'; -import { printIonWarning } from './logging'; import { isPlatform } from './platform'; let lastOverlayIndex = 0; @@ -648,7 +648,7 @@ export const dismiss = async ( const presentedOverlays = doc !== undefined ? getPresentedOverlays(doc) : []; /** - * For accessibility, toasts lack focus traps and don’t receive + * For accessibility, toasts lack focus traps and don't receive * `aria-hidden` on the root element when presented. * * All other overlays use focus traps to keep keyboard focus @@ -723,7 +723,7 @@ export const dismiss = async ( overlay.el.lastFocus = undefined; } } catch (err) { - console.error(err); + printIonError(`[${overlay.el.tagName.toLowerCase()}] - `, err); } overlay.el.remove(); @@ -940,7 +940,7 @@ export const createTriggerController = () => { const triggerEl = trigger !== undefined ? document.getElementById(trigger) : null; if (!triggerEl) { printIonWarning( - `A trigger element with the ID "${trigger}" was not found in the DOM. The trigger element must be in the DOM when the "trigger" property is set on an overlay component.`, + `[${el.tagName.toLowerCase()}] - A trigger element with the ID "${trigger}" was not found in the DOM. The trigger element must be in the DOM when the "trigger" property is set on an overlay component.`, el ); return; diff --git a/core/src/utils/sanitization/index.ts b/core/src/utils/sanitization/index.ts index 8d8b2d7992..acab505d82 100644 --- a/core/src/utils/sanitization/index.ts +++ b/core/src/utils/sanitization/index.ts @@ -1,8 +1,9 @@ +import { printIonError } from '@utils/logging'; + /** * Does a simple sanitization of all elements * in an untrusted string */ - export const sanitizeDOMString = (untrustedString: IonicSafeString | string | undefined): string | undefined => { try { if (untrustedString instanceof IonicSafeString) { @@ -81,7 +82,7 @@ export const sanitizeDOMString = (untrustedString: IonicSafeString | string | un const getInnerDiv = fragmentDiv.querySelector('div'); return getInnerDiv !== null ? getInnerDiv.innerHTML : fragmentDiv.innerHTML; } catch (err) { - console.error(err); + printIonError('sanitizeDOMString', err); return ''; }