Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions tests/app/test-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,9 @@ if (platform.isIOS && ios.MajorVersion > 10) {
allTests["SAFEAREA-WEBVIEW"] = webViewSafeAreaTests;
}

import * as rootViewsCssClassesTests from "./ui/styling/root-views-css-classes-tests";
allTests["ROOT-VIEWS-CSS-CLASSES"] = rootViewsCssClassesTests;

import * as stylePropertiesTests from "./ui/styling/style-properties-tests";
allTests["STYLE-PROPERTIES"] = stylePropertiesTests;

Expand Down
48 changes: 0 additions & 48 deletions tests/app/ui/page/page-tests-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -505,11 +505,6 @@ function _test_WhenInnerViewCallsCloseModal(closeModalGetter: (ShownModallyData)
helper.navigate(masterPageFactory);

TKUnit.waitUntilReady(() => modalClosedWithResult);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}
}

export function test_WhenViewBaseCallsShowModal_WithArguments_ShouldOpenModal() {
Expand Down Expand Up @@ -572,11 +567,6 @@ export function test_WhenViewBaseCallsShowModal_WithArguments_ShouldOpenModal()
helper.navigate(masterPageFactory);

TKUnit.waitUntilReady(() => modalClosed);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}
}

export function test_WhenViewBaseCallsShowModal_WithShowModalOptionsArguments_ShouldOpenModal() {
Expand Down Expand Up @@ -794,11 +784,6 @@ export function test_WhenRootTabViewShownModallyItCanCloseModal() {
helper.navigate(masterPageFactory);

TKUnit.waitUntilReady(() => modalClosed);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}
}

export function test_WhenPageIsNavigatedToItCanShowAnotherPageAsModal() {
Expand Down Expand Up @@ -885,11 +870,6 @@ export function test_WhenPageIsNavigatedToItCanShowAnotherPageAsModal() {
TKUnit.assertEqual(modalUnloaded, 1, "modalUnloaded");

masterPage.off(Page.navigatedToEvent, navigatedToEventHandler);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}
}

export function test_WhenModalPageShownHostPageNavigationEventsShouldNotBeRaised() {
Expand Down Expand Up @@ -967,11 +947,6 @@ export function test_WhenModalPageShownHostPageNavigationEventsShouldNotBeRaised

TKUnit.waitUntilReady(() => ready);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}

// only raised by the initial navigation to the master page
TKUnit.assertTrue(hostNavigatingToCount === 1);
TKUnit.assertTrue(hostNavigatedToCount === 1);
Expand Down Expand Up @@ -1058,11 +1033,6 @@ export function test_WhenModalPageShownModalNavigationToEventsShouldBeRaised() {

TKUnit.waitUntilReady(() => ready && !modalFrame.isLoaded);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}

// only raised by the initial show modal navigation
TKUnit.assertTrue(modalNavigatingToCount === 1);
TKUnit.assertTrue(modalNavigatedToCount === 1);
Expand Down Expand Up @@ -1138,12 +1108,6 @@ export function test_WhenModalFrameShownModalEventsRaisedOnRootModalFrame() {
helper.navigate(masterPageFactory);

TKUnit.waitUntilReady(() => ready && !modalFrame.isLoaded);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}

TKUnit.assertTrue(showingModallyCount === 1);
TKUnit.assertTrue(shownModallyCount === 1);
}
Expand Down Expand Up @@ -1206,12 +1170,6 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalPage() {
helper.navigate(masterPageFactory);

TKUnit.waitUntilReady(() => ready);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}

TKUnit.assertTrue(showingModallyCount === 1);
TKUnit.assertTrue(shownModallyCount === 1);
}
Expand Down Expand Up @@ -1279,12 +1237,6 @@ export function test_WhenModalPageShownShowModalEventsRaisedOnRootModalTabView()
TKUnit.assertEqual(_stack().length, 2, "Host and modal tab frame should be instantiated at this point!");

TKUnit.waitUntilReady(() => ready);

if (isIOS) {
// Remove this line when we have a good way to detect actual modal close on ios
TKUnit.waitUntilReady(() => !(<UIViewController>topmost().currentPage.viewController).presentedViewController);
}

TKUnit.assertEqual(_stack().length, 1, "Single host frame should be instantiated at this point!");

TKUnit.assertTrue(showingModallyCount === 1);
Expand Down
188 changes: 188 additions & 0 deletions tests/app/ui/styling/root-views-css-classes-tests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import * as helper from "../../ui-helper";
import * as TKUnit from "../../tk-unit";

import {
android,
getRootView,
ios
} from "tns-core-modules/application";
import {
isAndroid,
device
} from "tns-core-modules/platform";
import { Button } from "tns-core-modules/ui/button/button";
import { Page } from "tns-core-modules/ui/page";
import {
ShownModallyData,
ShowModalOptions,
View
} from "tns-core-modules/ui/frame";
import {
_rootModalViews
} from "tns-core-modules/ui/core/view/view-common";
import { DeviceType } from "tns-core-modules/ui/enums/enums";

const ROOT_CSS_CLASS = "ns-root";
const MODAL_CSS_CLASS = "ns-modal";
const ANDROID_PLATFORM_CSS_CLASS = "ns-android";
const IOS_PLATFORM_CSS_CLASS = "ns-ios";
const PHONE_DEVICE_TYPE_CSS_CLASS = "ns-phone";
const TABLET_DEVICE_TYPE_CSS_CLASS = "ns-tablet";
const PORTRAIT_ORIENTATION_CSS_CLASS = "ns-portrait";
const LANDSCAPE_ORIENTATION_CSS_CLASS = "ns-landscape";
const UNKNOWN_ORIENTATION_CSS_CLASS = "ns-unknown";

export function test_root_view_root_css_class() {
const rootViewCssClasses = getRootView().cssClasses;

TKUnit.assertTrue(rootViewCssClasses.has(
ROOT_CSS_CLASS),
`${ROOT_CSS_CLASS} CSS class is missing`
);
}

export function test_root_view_platform_css_class() {
const rootViewCssClasses = getRootView().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`
);
}
}

export function test_root_view_device_type_css_class() {
const rootViewCssClasses = getRootView().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`
);
}
}

export function test_root_view_orientation_css_class() {
const rootViewCssClasses = getRootView().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`
);
}
}

export function test_modal_root_view_modal_css_class() {
let modalClosed = false;

const modalCloseCallback = function () {
modalClosed = true;
};

const modalPageShownModallyEventHandler = function (args: ShownModallyData) {
const page = <Page>args.object;
page.off(View.shownModallyEvent, modalPageShownModallyEventHandler);

TKUnit.assertTrue(_rootModalViews[0].cssClasses.has(MODAL_CSS_CLASS));
args.closeCallback();
};

const hostNavigatedToEventHandler = function (args) {
const page = <Page>args.object;
page.off(Page.navigatedToEvent, hostNavigatedToEventHandler);

const modalPage = new Page();
modalPage.on(View.shownModallyEvent, modalPageShownModallyEventHandler);
const button = <Button>page.content;
const options: ShowModalOptions = {
context: {},
closeCallback: modalCloseCallback,
fullscreen: false,
animated: false
};
button.showModal(modalPage, options);
};

const hostPageFactory = function (): Page {
const hostPage = new Page();
hostPage.on(Page.navigatedToEvent, hostNavigatedToEventHandler);

const button = new Button();
hostPage.content = button;

return hostPage;
};

helper.navigate(hostPageFactory);
TKUnit.waitUntilReady(() => modalClosed);
}
19 changes: 18 additions & 1 deletion tns-core-modules/application/application-common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
LoadAppCSSEventData,
UnhandledErrorEventData
} from "./application";
import { DeviceOrientation } from "../ui/enums/enums";

export { UnhandledErrorEventData, DiscardedErrorEventData, CssChangedEventData, LoadAppCSSEventData };

Expand All @@ -53,6 +54,13 @@ export const uncaughtErrorEvent = "uncaughtError";
export const discardedErrorEvent = "discardedError";
export const orientationChangedEvent = "orientationChanged";

export const CSS_CLASS_PREFIX = "ns-";
const ORIENTATION_CSS_CLASSES = [
`${CSS_CLASS_PREFIX}${DeviceOrientation.portrait}`,
`${CSS_CLASS_PREFIX}${DeviceOrientation.landscape}`,
`${CSS_CLASS_PREFIX}${DeviceOrientation.unknown}`
];

let cssFile: string = "./app.css";

let resources: any = {};
Expand Down Expand Up @@ -92,7 +100,7 @@ export function livesync(rootView: View, context?: ModuleContext) {
}

// Handle application styles
if (reapplyAppStyles && rootView) {
if (rootView && reapplyAppStyles) {
rootView._onCssStateChange();
} else if (liveSyncCore) {
liveSyncCore(context);
Expand All @@ -117,6 +125,15 @@ export function loadAppCss(): void {
}
}

export function orientationChanged(rootView: View, newOrientation: "portrait" | "landscape" | "unknown"): void {
const newOrientationCssClass = `${CSS_CLASS_PREFIX}${newOrientation}`;
if (!rootView.cssClasses.has(newOrientationCssClass)) {
ORIENTATION_CSS_CLASSES.forEach(c => rootView.cssClasses.delete(c));
rootView.cssClasses.add(newOrientationCssClass);
rootView._onCssStateChange();
}
}

global.__onUncaughtError = function (error: NativeScriptError) {
events.notify(<UnhandledErrorEventData>{ eventName: uncaughtErrorEvent, object: app, android: error, ios: error, error: error });
};
Expand Down
Loading