diff --git a/nativescript-core/application/application-common.ts b/nativescript-core/application/application-common.ts index 4d376f34d..287aa6161 100644 --- a/nativescript-core/application/application-common.ts +++ b/nativescript-core/application/application-common.ts @@ -19,7 +19,7 @@ import { level as profilingLevel, } from "../profiling"; import * as bindableResources from "../ui/core/bindable/bindable-resources"; -import { CLASS_PREFIX, pushToRootViewCssClasses, removeFromRootViewCssClasses } from "../css/system-classes"; +import { CLASS_PREFIX, pushToSystemCssClasses, removeSystemCssClass } from "../css/system-classes"; import { DeviceOrientation, SystemAppearance } from "../ui/enums/enums"; export { Observable }; @@ -129,13 +129,13 @@ export function loadAppCss(): void { } } -function applyCssClass(rootView: View, cssClass: string) { - pushToRootViewCssClasses(cssClass); +function addCssClass(rootView: View, cssClass: string) { + pushToSystemCssClasses(cssClass); rootView.cssClasses.add(cssClass); } function removeCssClass(rootView: View, cssClass: string) { - removeFromRootViewCssClasses(cssClass); + removeSystemCssClass(cssClass); rootView.cssClasses.delete(cssClass); } @@ -147,18 +147,27 @@ function increaseStyleScopeApplicationCssSelectorVersion(rootView: View) { } } +function applyCssClass(rootView: View, cssClasses: string[], newCssClass: string) { + if (!rootView.cssClasses.has(newCssClass)) { + cssClasses.forEach(cssClass => removeCssClass(rootView, cssClass)); + addCssClass(rootView, newCssClass); + increaseStyleScopeApplicationCssSelectorVersion(rootView); + rootView._onCssStateChange(); + } +} + export function orientationChanged(rootView: View, newOrientation: "portrait" | "landscape" | "unknown"): void { if (!rootView) { return; } const newOrientationCssClass = `${CLASS_PREFIX}${newOrientation}`; - if (!rootView.cssClasses.has(newOrientationCssClass)) { - ORIENTATION_CSS_CLASSES.forEach(cssClass => removeCssClass(rootView, cssClass)); - applyCssClass(rootView, newOrientationCssClass); - increaseStyleScopeApplicationCssSelectorVersion(rootView); - rootView._onCssStateChange(); - } + applyCssClass(rootView, ORIENTATION_CSS_CLASSES, newOrientationCssClass); + + const rootModalViews = >rootView._getRootModalViews(); + rootModalViews.forEach(rootModalView => { + applyCssClass(rootModalView, ORIENTATION_CSS_CLASSES, newOrientationCssClass); + }); } export function systemAppearanceChanged(rootView: View, newSystemAppearance: "dark" | "light"): void { @@ -167,12 +176,12 @@ export function systemAppearanceChanged(rootView: View, newSystemAppearance: "da } const newSystemAppearanceCssClass = `${CLASS_PREFIX}${newSystemAppearance}`; - if (!rootView.cssClasses.has(newSystemAppearanceCssClass)) { - SYSTEM_APPEARANCE_CSS_CLASSES.forEach(cssClass => removeCssClass(rootView, cssClass)); - applyCssClass(rootView, newSystemAppearanceCssClass); - increaseStyleScopeApplicationCssSelectorVersion(rootView); - rootView._onCssStateChange(); - } + applyCssClass(rootView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass); + + const rootModalViews = >rootView._getRootModalViews(); + rootModalViews.forEach(rootModalView => { + applyCssClass(rootModalView, SYSTEM_APPEARANCE_CSS_CLASSES, newSystemAppearanceCssClass); + }); } global.__onUncaughtError = function (error: NativeScriptError) { diff --git a/nativescript-core/application/application.ios.ts b/nativescript-core/application/application.ios.ts index 33374a556..349513ddf 100644 --- a/nativescript-core/application/application.ios.ts +++ b/nativescript-core/application/application.ios.ts @@ -24,8 +24,9 @@ export * from "./application-common"; import { Builder } from "../ui/builder"; import { CLASS_PREFIX, - getRootViewCssClasses, - pushToRootViewCssClasses + getSystemCssClasses, + pushToSystemCssClasses, + ROOT_VIEW_CSS_CLASS } from "../css/system-classes"; import { ios as iosViewHelper } from "../ui/core/view/view-helper"; import { device } from "../platform/platform"; @@ -304,7 +305,7 @@ export class iOSApplication implements iOSApplicationDefinition { const haveController = this._window.rootViewController !== null; this._window.rootViewController = controller; - setRootViewSystemAppearanceCssClass(rootView); + setRootViewsSystemAppearanceCssClass(rootView); if (!haveController) { this._window.makeKeyAndVisible(); @@ -353,7 +354,7 @@ function createRootView(v?: View) { } } - setRootViewCssClasses(rootView); + setRootViewsCssClasses(rootView); return rootView; } @@ -395,7 +396,7 @@ export function run(entry?: string | NavigationEntry) { // Mind root view CSS classes in future work // on embedding NativeScript applications - setRootViewSystemAppearanceCssClass(rootView); + setRootViewsSystemAppearanceCssClass(rootView); rootView.on(iosViewHelper.traitCollectionColorAppearanceChangedEvent, () => { const userInterfaceStyle = controller.traitCollection.userInterfaceStyle; const newSystemAppearance = getSystemAppearanceValue(userInterfaceStyle); @@ -473,20 +474,22 @@ function setViewControllerView(view: View): void { } } -function setRootViewCssClasses(rootView: View): void { +function setRootViewsCssClasses(rootView: View): void { const deviceType = device.deviceType.toLowerCase(); - pushToRootViewCssClasses(`${CLASS_PREFIX}${IOS_PLATFORM}`); - pushToRootViewCssClasses(`${CLASS_PREFIX}${deviceType}`); - pushToRootViewCssClasses(`${CLASS_PREFIX}${iosApp.orientation}`); - const rootViewCssClasses = getRootViewCssClasses(); + pushToSystemCssClasses(`${CLASS_PREFIX}${IOS_PLATFORM}`); + pushToSystemCssClasses(`${CLASS_PREFIX}${deviceType}`); + pushToSystemCssClasses(`${CLASS_PREFIX}${iosApp.orientation}`); + + rootView.cssClasses.add(ROOT_VIEW_CSS_CLASS); + const rootViewCssClasses = getSystemCssClasses(); rootViewCssClasses.forEach(c => rootView.cssClasses.add(c)); } -function setRootViewSystemAppearanceCssClass(rootView: View): void { +function setRootViewsSystemAppearanceCssClass(rootView: View): void { if (majorVersion >= 13) { const systemAppearanceCssClass = `${CLASS_PREFIX}${iosApp.systemAppearance}`; - pushToRootViewCssClasses(systemAppearanceCssClass); + pushToSystemCssClasses(systemAppearanceCssClass); rootView.cssClasses.add(systemAppearanceCssClass); } } diff --git a/nativescript-core/css/system-classes.d.ts b/nativescript-core/css/system-classes.d.ts index cbef8e46d..43edcfee9 100644 --- a/nativescript-core/css/system-classes.d.ts +++ b/nativescript-core/css/system-classes.d.ts @@ -1,30 +1,66 @@ /** * @module "system-classes" + * This is an internal module. */ /** */ /** - * String value "ns-" used for CSS system class prefix. - */ +* String value "ns-" used for CSS system class prefix. +*/ export const CLASS_PREFIX: string; /** * Gets CSS system class for modal root view. */ -export function getModalRootViewCssClass(): string; +export const MODAL_ROOT_VIEW_CSS_CLASS; /** * Gets CSS system classes for root view. */ +export const ROOT_VIEW_CSS_CLASS; + +/** + * Gets a list of the current system classes. + * Intended for internal use only + */ +export function getSystemCssClasses(): string[]; + +/** + * Pushes to the list of the current system classes. + * Intended for internal use only + */ +export function pushToSystemCssClasses(value: string): number; + +/** + * Removes value from the list of current system classes + * Intended for internal use only + * @param value + */ +export function removeSystemCssClass(value: string): string; + +/** + * Same as MODAL_ROOT_VIEW_CSS_CLASS + */ +export function getModalRootViewCssClass(): string; + +/** + * Gets CSS system classes for root view. Same as ROOT_VIEW_CSS_CLASS + _getCssClasses + * Intended for internal use only + * @deprecated Use ROOT_VIEW_CSS_CLASS or getCssClasses() instead + */ export function getRootViewCssClasses(): string[]; /** * Appends new CSS class to the system classes and returns the new length of the array. + * Intended for internal use only + * @deprecated Use pushToCssClasses() instead * @param value New CSS system class. */ export function pushToRootViewCssClasses(value: string): number; /** * Removes CSS class from the system classes and returns it. + * Intended for internal use only + * @deprecated Use removeCssClass() instead * @param value */ -export function removeFromRootViewCssClasses(value: string): string; +export function removeFromRootViewCssClasses(value: string): string; \ No newline at end of file diff --git a/nativescript-core/css/system-classes.ts b/nativescript-core/css/system-classes.ts index 6e2f7e80c..a51ca0a85 100644 --- a/nativescript-core/css/system-classes.ts +++ b/nativescript-core/css/system-classes.ts @@ -1,32 +1,44 @@ const MODAL = "modal"; const ROOT = "root"; +const cssClasses = []; export const CLASS_PREFIX = "ns-"; +export const MODAL_ROOT_VIEW_CSS_CLASS = `${CLASS_PREFIX}${MODAL}`; +export const ROOT_VIEW_CSS_CLASS = `${CLASS_PREFIX}${ROOT}`; -const modalRootViewCssClass = `${CLASS_PREFIX}${MODAL}`; -const rootViewCssClasses = [`${CLASS_PREFIX}${ROOT}`]; - -export function getModalRootViewCssClass(): string { - return modalRootViewCssClass; +export function getSystemCssClasses(): string[] { + return cssClasses; } -export function getRootViewCssClasses(): string[] { - return rootViewCssClasses; +export function pushToSystemCssClasses(value: string): number { + cssClasses.push(value); + + return cssClasses.length; } -export function pushToRootViewCssClasses(value: string): number { - rootViewCssClasses.push(value); - - return rootViewCssClasses.length; -} - -export function removeFromRootViewCssClasses(value: string): string { - const index = rootViewCssClasses.indexOf(value); +export function removeSystemCssClass(value: string): string { + const index = cssClasses.indexOf(value); let removedElement; if (index > -1) { - removedElement = rootViewCssClasses.splice(index, 1); + removedElement = cssClasses.splice(index, 1); } return removedElement; } + +export function getModalRootViewCssClass(): string { + return MODAL_ROOT_VIEW_CSS_CLASS; +} + +export function getRootViewCssClasses(): string[] { + return [ROOT_VIEW_CSS_CLASS, ...cssClasses]; +} + +export function pushToRootViewCssClasses(value: string): number { + return pushToSystemCssClasses(value) + 1; // because of ROOT_VIEW_CSS_CLASS +} + +export function removeFromRootViewCssClasses(value: string): string { + return removeSystemCssClass(value); +} \ No newline at end of file diff --git a/nativescript-core/ui/core/view-base/view-base.ts b/nativescript-core/ui/core/view-base/view-base.ts index 8e3e730be..092eec6fc 100644 --- a/nativescript-core/ui/core/view-base/view-base.ts +++ b/nativescript-core/ui/core/view-base/view-base.ts @@ -7,7 +7,7 @@ import { Page } from "../../page"; // Types. import { Property, CssProperty, CssAnimationProperty, InheritedProperty, Style, clearInheritedProperties, propagateInheritableProperties, propagateInheritableCssProperties, initNativeView } from "../properties"; -import { getModalRootViewCssClass, getRootViewCssClasses } from "../../../css/system-classes"; +import { getSystemCssClasses, MODAL_ROOT_VIEW_CSS_CLASS, ROOT_VIEW_CSS_CLASS } from "../../../css/system-classes"; import { Source } from "../../../utils/debug"; import { Binding, BindingOptions, Observable, WrappedValue, PropertyChangeData, traceEnabled, traceWrite, traceCategories } from "../bindable"; import { isIOS, isAndroid } from "../../../platform"; @@ -1045,21 +1045,21 @@ export const classNameProperty = new Property({ name: "className", valueChanged(view: ViewBase, oldValue: string, newValue: string) { const cssClasses = view.cssClasses; + const rootViewsCssClasses = getSystemCssClasses(); - const modalViewCssClass = getModalRootViewCssClass(); - const rootViewCssClasses = getRootViewCssClasses(); - - const shouldAddModalRootViewCssClass = cssClasses.has(modalViewCssClass); - const shouldAddRootViewCssClasses = cssClasses.has(rootViewCssClasses[0]); + const shouldAddModalRootViewCssClasses = cssClasses.has(MODAL_ROOT_VIEW_CSS_CLASS); + const shouldAddRootViewCssClasses = cssClasses.has(ROOT_VIEW_CSS_CLASS); cssClasses.clear(); - if (shouldAddModalRootViewCssClass) { - cssClasses.add(modalViewCssClass); + if (shouldAddModalRootViewCssClasses) { + cssClasses.add(MODAL_ROOT_VIEW_CSS_CLASS); } else if (shouldAddRootViewCssClasses) { - rootViewCssClasses.forEach(c => cssClasses.add(c)); + cssClasses.add(ROOT_VIEW_CSS_CLASS); } + rootViewsCssClasses.forEach(c => cssClasses.add(c)); + if (typeof newValue === "string" && newValue !== "") { newValue.split(" ").forEach(c => cssClasses.add(c)); } diff --git a/nativescript-core/ui/core/view/view-common.ts b/nativescript-core/ui/core/view/view-common.ts index ae4373866..e304a3aac 100644 --- a/nativescript-core/ui/core/view/view-common.ts +++ b/nativescript-core/ui/core/view/view-common.ts @@ -20,7 +20,7 @@ import { fromString as gestureFromString } from "../../gestures"; -import { getModalRootViewCssClass } from "../../../css/system-classes"; +import { getSystemCssClasses, MODAL_ROOT_VIEW_CSS_CLASS } from "../../../css/system-classes"; import { Builder } from "../../builder"; import { sanitizeModuleName } from "../../builder/module-name-sanitizer"; import { StyleScope } from "../../styling/style-scope"; @@ -372,8 +372,9 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { protected _showNativeModalView(parent: ViewCommon, options: ShowModalOptions) { _rootModalViews.push(this); - const modalRootViewCssClass = getModalRootViewCssClass(); - this.cssClasses.add(modalRootViewCssClass); + this.cssClasses.add(MODAL_ROOT_VIEW_CSS_CLASS); + const modalRootViewCssClasses = getSystemCssClasses(); + modalRootViewCssClasses.forEach(c => this.cssClasses.add(c)); parent._modal = this; this._modalParent = parent; diff --git a/nativescript-core/ui/frame/frame.android.ts b/nativescript-core/ui/frame/frame.android.ts index 8a6946ad3..e78eddb63 100644 --- a/nativescript-core/ui/frame/frame.android.ts +++ b/nativescript-core/ui/frame/frame.android.ts @@ -21,7 +21,12 @@ import { // TODO: Remove this and get it from global to decouple builder for angular import { Builder } from "../builder"; -import { CLASS_PREFIX, getRootViewCssClasses, pushToRootViewCssClasses } from "../../css/system-classes"; +import { + CLASS_PREFIX, + getSystemCssClasses, + pushToSystemCssClasses, + ROOT_VIEW_CSS_CLASS +} from "../../css/system-classes"; import { device } from "../../platform/platform"; import { profile } from "../../profiling"; @@ -1311,12 +1316,14 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks { activityRootViewsMap.set(rootView._domId, new WeakRef(rootView)); const deviceType = device.deviceType.toLowerCase(); - pushToRootViewCssClasses(`${CLASS_PREFIX}${ANDROID_PLATFORM}`); - pushToRootViewCssClasses(`${CLASS_PREFIX}${deviceType}`); - pushToRootViewCssClasses(`${CLASS_PREFIX}${application.android.orientation}`); - pushToRootViewCssClasses(`${CLASS_PREFIX}${application.android.systemAppearance}`); - const rootViewCssClasses = getRootViewCssClasses(); + pushToSystemCssClasses(`${CLASS_PREFIX}${ANDROID_PLATFORM}`); + pushToSystemCssClasses(`${CLASS_PREFIX}${deviceType}`); + pushToSystemCssClasses(`${CLASS_PREFIX}${application.android.orientation}`); + pushToSystemCssClasses(`${CLASS_PREFIX}${application.android.systemAppearance}`); + + this._rootView.cssClasses.add(ROOT_VIEW_CSS_CLASS); + const rootViewCssClasses = getSystemCssClasses(); rootViewCssClasses.forEach(c => this._rootView.cssClasses.add(c)); } diff --git a/tests/app/ui/styling/root-views-css-classes-tests.ts b/tests/app/ui/styling/root-views-css-classes-tests.ts index b7987b892..26f4fff88 100644 --- a/tests/app/ui/styling/root-views-css-classes-tests.ts +++ b/tests/app/ui/styling/root-views-css-classes-tests.ts @@ -35,254 +35,178 @@ const UNKNOWN_ORIENTATION_CSS_CLASS = "ns-unknown"; const DARK_SYSTEM_APPEARANCE_CSS_CLASS = "ns-dark"; const LIGHT_SYSTEM_APPEARANCE_CSS_CLASS = "ns-light"; -function _test_root_view_root_css_class(shouldSetClassName: boolean) { - const rootView = getRootView(); +function _test_root_css_class(view: View, isModal: boolean, shouldSetClassName: boolean) { + if (shouldSetClassName) { + view.className = CLASS_NAME; + } + + const cssClass = isModal ? MODAL_CSS_CLASS : ROOT_CSS_CLASS; + const viewCssClasses = view.cssClasses; + TKUnit.assertTrue(viewCssClasses.has(cssClass), `${cssClass} CSS class is missing`); + + if (shouldSetClassName) { + TKUnit.assertTrue(viewCssClasses.has(CLASS_NAME), `${CLASS_NAME} CSS class is missing`); + } +} + +function _test_platform_css_class(rootView: View, shouldSetClassName: boolean) { if (shouldSetClassName) { rootView.className = CLASS_NAME; } - const rootViewCssClasses = rootView.cssClasses; - TKUnit.assertTrue(rootViewCssClasses.has( - ROOT_CSS_CLASS), - `${ROOT_CSS_CLASS} CSS class is missing` - ); + const cssClasses = rootView.cssClasses; + if (isAndroid) { + TKUnit.assertTrue(cssClasses.has(ANDROID_PLATFORM_CSS_CLASS), `${ANDROID_PLATFORM_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(IOS_PLATFORM_CSS_CLASS), `${IOS_PLATFORM_CSS_CLASS} CSS class is present`); + } + else { + TKUnit.assertTrue(cssClasses.has(IOS_PLATFORM_CSS_CLASS), `${IOS_PLATFORM_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(ANDROID_PLATFORM_CSS_CLASS), `${ANDROID_PLATFORM_CSS_CLASS} CSS class is present`); + } if (shouldSetClassName) { - TKUnit.assertTrue(rootViewCssClasses.has( - CLASS_NAME), - `${CLASS_NAME} CSS class is missing` - ); + TKUnit.assertTrue(cssClasses.has(CLASS_NAME), `${CLASS_NAME} CSS class is missing`); } } +function _test_device_type_css_class(rootView: View, shouldSetClassName: boolean) { + if (shouldSetClassName) { + rootView.className = CLASS_NAME; + } + + const cssClasses = rootView.cssClasses; + const deviceType = device.deviceType; + if (deviceType === DeviceType.Phone) { + TKUnit.assertTrue(cssClasses.has(PHONE_DEVICE_TYPE_CSS_CLASS), `${PHONE_DEVICE_TYPE_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(TABLET_DEVICE_TYPE_CSS_CLASS), `${TABLET_DEVICE_TYPE_CSS_CLASS} CSS class is present`); + } + else { + TKUnit.assertTrue(cssClasses.has(TABLET_DEVICE_TYPE_CSS_CLASS), `${TABLET_DEVICE_TYPE_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(PHONE_DEVICE_TYPE_CSS_CLASS), `${PHONE_DEVICE_TYPE_CSS_CLASS} CSS class is present`); + } + + if (shouldSetClassName) { + TKUnit.assertTrue(cssClasses.has(CLASS_NAME), `${CLASS_NAME} CSS class is missing`); + } +} + +function _test_orientation_css_class(rootView: View, shouldSetClassName: boolean) { + if (shouldSetClassName) { + rootView.className = CLASS_NAME; + } + + const cssClasses = rootView.cssClasses; + let appOrientation; + if (isAndroid) { + appOrientation = android.orientation; + } + else { + appOrientation = ios.orientation; + } + if (appOrientation === "portrait") { + TKUnit.assertTrue(cssClasses.has(PORTRAIT_ORIENTATION_CSS_CLASS), `${PORTRAIT_ORIENTATION_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(LANDSCAPE_ORIENTATION_CSS_CLASS), `${LANDSCAPE_ORIENTATION_CSS_CLASS} CSS class is present`); + TKUnit.assertFalse(cssClasses.has(UNKNOWN_ORIENTATION_CSS_CLASS), `${UNKNOWN_ORIENTATION_CSS_CLASS} CSS class is present`); + } + else if (appOrientation === "landscape") { + TKUnit.assertTrue(cssClasses.has(LANDSCAPE_ORIENTATION_CSS_CLASS), `${LANDSCAPE_ORIENTATION_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(PORTRAIT_ORIENTATION_CSS_CLASS), `${PORTRAIT_ORIENTATION_CSS_CLASS} CSS class is present`); + TKUnit.assertFalse(cssClasses.has(UNKNOWN_ORIENTATION_CSS_CLASS), `${UNKNOWN_ORIENTATION_CSS_CLASS} CSS class is present`); + } + else if (appOrientation === "landscape") { + TKUnit.assertTrue(cssClasses.has(UNKNOWN_ORIENTATION_CSS_CLASS), `${UNKNOWN_ORIENTATION_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(LANDSCAPE_ORIENTATION_CSS_CLASS), `${LANDSCAPE_ORIENTATION_CSS_CLASS} CSS class is present`); + TKUnit.assertFalse(cssClasses.has(PORTRAIT_ORIENTATION_CSS_CLASS), `${PORTRAIT_ORIENTATION_CSS_CLASS} CSS class is present`); + } + + if (shouldSetClassName) { + TKUnit.assertTrue(cssClasses.has(CLASS_NAME), `${CLASS_NAME} CSS class is missing`); + } +} + +function _test_system_appearance_css_class(rootView: View, shouldSetClassName: boolean) { + if (shouldSetClassName) { + rootView.className = CLASS_NAME; + } + + const cssClasses = rootView.cssClasses; + let systemAppearance; + if (isAndroid) { + systemAppearance = android.systemAppearance; + } + else { + systemAppearance = ios.systemAppearance; + } + if (isIOS && iosUtils.MajorVersion <= 12) { + TKUnit.assertFalse(cssClasses.has(DARK_SYSTEM_APPEARANCE_CSS_CLASS), `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`); + TKUnit.assertFalse(cssClasses.has(LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`); + } + else if (systemAppearance === "dark") { + TKUnit.assertTrue(cssClasses.has(DARK_SYSTEM_APPEARANCE_CSS_CLASS), `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`); + } + else if (systemAppearance === "light") { + TKUnit.assertTrue(cssClasses.has(LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is missing`); + TKUnit.assertFalse(cssClasses.has(DARK_SYSTEM_APPEARANCE_CSS_CLASS), `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present`); + } + + if (shouldSetClassName) { + TKUnit.assertTrue(cssClasses.has(CLASS_NAME), `${CLASS_NAME} CSS class is missing`); + } +} + +// Application root view export function test_root_view_root_css_class() { - _test_root_view_root_css_class(false); + const rootView = getRootView(); + _test_root_css_class(rootView, false, false); } export function test_root_view_class_name_preserve_root_css_class() { - _test_root_view_root_css_class(true); -} - -function _test_root_view_platform_css_class(shouldSetClassName: boolean) { const rootView = getRootView(); - if (shouldSetClassName) { - rootView.className = CLASS_NAME; - } - - const rootViewCssClasses = rootView.cssClasses; - if (isAndroid) { - TKUnit.assertTrue(rootViewCssClasses.has( - ANDROID_PLATFORM_CSS_CLASS), - `${ANDROID_PLATFORM_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - IOS_PLATFORM_CSS_CLASS), - `${IOS_PLATFORM_CSS_CLASS} CSS class is present` - ); - } else { - TKUnit.assertTrue(rootViewCssClasses.has( - IOS_PLATFORM_CSS_CLASS), - `${IOS_PLATFORM_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - ANDROID_PLATFORM_CSS_CLASS), - `${ANDROID_PLATFORM_CSS_CLASS} CSS class is present` - ); - } - - if (shouldSetClassName) { - TKUnit.assertTrue(rootViewCssClasses.has( - CLASS_NAME), - `${CLASS_NAME} CSS class is missing` - ); - } + _test_root_css_class(rootView, false, true); } export function test_root_view_platform_css_class() { - _test_root_view_platform_css_class(false); + const rootView = getRootView(); + _test_platform_css_class(rootView, false); } export function test_root_view_class_name_preserve_platform_css_class() { - _test_root_view_platform_css_class(true); -} - -function _test_root_view_device_type_css_class(shouldSetClassName: boolean) { const rootView = getRootView(); - if (shouldSetClassName) { - rootView.className = CLASS_NAME; - } - - const rootViewCssClasses = rootView.cssClasses; - const deviceType = device.deviceType; - - if (deviceType === DeviceType.Phone) { - TKUnit.assertTrue(rootViewCssClasses.has( - PHONE_DEVICE_TYPE_CSS_CLASS), - `${PHONE_DEVICE_TYPE_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - TABLET_DEVICE_TYPE_CSS_CLASS), - `${TABLET_DEVICE_TYPE_CSS_CLASS} CSS class is present` - ); - } else { - TKUnit.assertTrue(rootViewCssClasses.has( - TABLET_DEVICE_TYPE_CSS_CLASS), - `${TABLET_DEVICE_TYPE_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - PHONE_DEVICE_TYPE_CSS_CLASS), - `${PHONE_DEVICE_TYPE_CSS_CLASS} CSS class is present` - ); - } - - if (shouldSetClassName) { - TKUnit.assertTrue(rootViewCssClasses.has( - CLASS_NAME), - `${CLASS_NAME} CSS class is missing` - ); - } + _test_platform_css_class(rootView, true); } export function test_root_view_device_type_css_class() { - _test_root_view_device_type_css_class(false); + const rootView = getRootView(); + _test_device_type_css_class(rootView, false); } export function test_root_view_class_name_preserve_device_type_css_class() { - _test_root_view_device_type_css_class(true); -} - -function _test_root_view_orientation_css_class(shouldSetClassName: boolean) { const rootView = getRootView(); - if (shouldSetClassName) { - rootView.className = CLASS_NAME; - } - - const rootViewCssClasses = rootView.cssClasses; - let appOrientation; - - if (isAndroid) { - appOrientation = android.orientation; - } else { - appOrientation = ios.orientation; - } - - if (appOrientation === "portrait") { - TKUnit.assertTrue(rootViewCssClasses.has( - PORTRAIT_ORIENTATION_CSS_CLASS), - `${PORTRAIT_ORIENTATION_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - LANDSCAPE_ORIENTATION_CSS_CLASS), - `${LANDSCAPE_ORIENTATION_CSS_CLASS} CSS class is present` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - UNKNOWN_ORIENTATION_CSS_CLASS), - `${UNKNOWN_ORIENTATION_CSS_CLASS} CSS class is present` - ); - } else if (appOrientation === "landscape") { - TKUnit.assertTrue(rootViewCssClasses.has( - LANDSCAPE_ORIENTATION_CSS_CLASS), - `${LANDSCAPE_ORIENTATION_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - PORTRAIT_ORIENTATION_CSS_CLASS), - `${PORTRAIT_ORIENTATION_CSS_CLASS} CSS class is present` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - UNKNOWN_ORIENTATION_CSS_CLASS), - `${UNKNOWN_ORIENTATION_CSS_CLASS} CSS class is present` - ); - } else if (appOrientation === "landscape") { - TKUnit.assertTrue(rootViewCssClasses.has( - UNKNOWN_ORIENTATION_CSS_CLASS), - `${UNKNOWN_ORIENTATION_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - LANDSCAPE_ORIENTATION_CSS_CLASS), - `${LANDSCAPE_ORIENTATION_CSS_CLASS} CSS class is present` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - PORTRAIT_ORIENTATION_CSS_CLASS), - `${PORTRAIT_ORIENTATION_CSS_CLASS} CSS class is present` - ); - } - - if (shouldSetClassName) { - TKUnit.assertTrue(rootViewCssClasses.has( - CLASS_NAME), - `${CLASS_NAME} CSS class is missing` - ); - } + _test_device_type_css_class(rootView, true); } export function test_root_view_orientation_css_class() { - _test_root_view_orientation_css_class(false); + const rootView = getRootView(); + _test_orientation_css_class(rootView, false); } export function test_root_view_class_name_preserve_orientation_css_class() { - _test_root_view_orientation_css_class(true); -} - -function _test_root_view_system_appearance_css_class(shouldSetClassName: boolean) { const rootView = getRootView(); - if (shouldSetClassName) { - rootView.className = CLASS_NAME; - } - - const rootViewCssClasses = rootView.cssClasses; - let systemAppearance; - - if (isAndroid) { - systemAppearance = android.systemAppearance; - } else { - systemAppearance = ios.systemAppearance; - } - - if (isIOS && iosUtils.MajorVersion <= 12) { - TKUnit.assertFalse(rootViewCssClasses.has( - DARK_SYSTEM_APPEARANCE_CSS_CLASS), - `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), - `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present` - ); - } else if (systemAppearance === "dark") { - TKUnit.assertTrue(rootViewCssClasses.has( - DARK_SYSTEM_APPEARANCE_CSS_CLASS), - `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), - `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present` - ); - } else if (systemAppearance === "light") { - TKUnit.assertTrue(rootViewCssClasses.has( - LIGHT_SYSTEM_APPEARANCE_CSS_CLASS), - `${LIGHT_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is missing` - ); - TKUnit.assertFalse(rootViewCssClasses.has( - DARK_SYSTEM_APPEARANCE_CSS_CLASS), - `${DARK_SYSTEM_APPEARANCE_CSS_CLASS} CSS class is present` - ); - } - - if (shouldSetClassName) { - TKUnit.assertTrue(rootViewCssClasses.has( - CLASS_NAME), - `${CLASS_NAME} CSS class is missing` - ); - } + _test_orientation_css_class(rootView, true); } export function test_root_view_system_appearance_css_class() { - _test_root_view_system_appearance_css_class(false); + const rootView = getRootView(); + _test_system_appearance_css_class(rootView, false); } export function test_root_view_class_name_preserve_system_appearance_css_class() { - _test_root_view_system_appearance_css_class(true); + const rootView = getRootView(); + _test_system_appearance_css_class(rootView, true); } +// Modal root view function _test_modal_root_view_modal_css_class(shouldSetClassName: boolean) { let modalClosed = false; @@ -294,20 +218,8 @@ function _test_modal_root_view_modal_css_class(shouldSetClassName: boolean) { const page = args.object; page.off(View.shownModallyEvent, modalPageShownModallyEventHandler); - const rootModalView = _rootModalViews[0]; - if (shouldSetClassName) { - rootModalView.className = CLASS_NAME; - } - - const rootModalViewCssClasses = rootModalView.cssClasses; - TKUnit.assertTrue(rootModalViewCssClasses.has(MODAL_CSS_CLASS), - `${MODAL_CSS_CLASS} CSS class is missing`); - - if (shouldSetClassName) { - TKUnit.assertTrue(rootModalViewCssClasses.has(CLASS_NAME), - `${CLASS_NAME} CSS class is missing`); - } - + const rootModalView = _rootModalViews[0]; + _test_root_css_class(rootModalView, true, shouldSetClassName); args.closeCallback(); }; @@ -348,3 +260,219 @@ export function test_modal_root_view_modal_css_class() { export function test_modal_root_view_class_name_preserve_modal_css_class() { _test_modal_root_view_modal_css_class(true); } + +function _test_root_modal_view_platform_css_class(shouldSetClassName: boolean) { + let modalClosed = false; + + const modalCloseCallback = function () { + modalClosed = true; + }; + + const modalPageShownModallyEventHandler = function (args: ShownModallyData) { + const page = args.object; + page.off(View.shownModallyEvent, modalPageShownModallyEventHandler); + + const rootModalView = _rootModalViews[0]; + _test_platform_css_class(rootModalView, shouldSetClassName); + args.closeCallback(); + }; + + const hostNavigatedToEventHandler = function (args) { + const page = args.object; + page.off(Page.navigatedToEvent, hostNavigatedToEventHandler); + + const modalPage = new Page(); + modalPage.on(View.shownModallyEvent, modalPageShownModallyEventHandler); + const button =