diff --git a/core/src/global/ionic-global.ts b/core/src/global/ionic-global.ts index 1d48701995..5af7bc9bbf 100644 --- a/core/src/global/ionic-global.ts +++ b/core/src/global/ionic-global.ts @@ -49,14 +49,22 @@ export default () => { config.set('animated', false); } + const isIonicElement = (elm: any) => + elm.tagName && elm.tagName.startsWith('ION-'); + + const isAllowedIonicModeValue = (elmMode: string) => + ['ios', 'md'].includes(elmMode); + setMode((elm: any) => { while (elm) { const elmMode = (elm as any).mode || elm.getAttribute('mode'); - if (elmMode) { - return elmMode; + if (isAllowedIonicModeValue(elmMode)) { + return elmMode; + } else if (isIonicElement(elm)) { + console.warn('Invalid ionic mode: "' + elmMode + '", expected: "ios" or "md"'); + } } - elm = elm.parentElement; } return defaultMode; diff --git a/core/src/utils/test/modes/e2e.ts b/core/src/utils/test/modes/e2e.ts index e9ac09a979..5f5d28ba9d 100644 --- a/core/src/utils/test/modes/e2e.ts +++ b/core/src/utils/test/modes/e2e.ts @@ -58,4 +58,21 @@ test('component: modes', async () => { const el = await page.find(tag); await checkModeClasses(el, globalMode!); } + + // Fifth test: {mode} attribute on non-ionic ancestor element + // ---------------------------------------------------------------- + // non-ionic ancestor components with a mode attribute + // e.g.

+ const ancestorTags = ['p[mode]']; + const childTag = 'ion-label'; + + for (const tag of ancestorTags) { + await page.waitForSelector(tag); + const ancestor = await page.find(tag); + const mode = ancestor.getAttribute('mode'); + const expectedMode = ['ios', 'md'].includes(mode) ? mode : globalMode!; + const el = await ancestor.find(childTag); + await checkModeClasses(el, expectedMode); + } + }); diff --git a/core/src/utils/test/modes/index.html b/core/src/utils/test/modes/index.html index 5f9ac5b375..6fa41ef42d 100644 --- a/core/src/utils/test/modes/index.html +++ b/core/src/utils/test/modes/index.html @@ -105,6 +105,15 @@ +

+ +

+

+ +

+

+ +