FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

fix-next(css): className to preserve root views classes by vchimev · Pull Request #7725 · NativeScript/NativeScript · GitHub

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

Filter by extension

Filter by extension .ts  (13) All 1 file type selected
Viewed files
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Unified
Split
Hide whitespace
Diff view
Unified
Split
Hide whitespace
120 changes: 110 additions & 10 deletions tests/app/ui/styling/root-views-css-classes-tests.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
} from "tns-core-modules/ui/core/view/view-common";
import { DeviceType } from "tns-core-modules/ui/enums/enums";

const CLASS_NAME = "class-name";
const ROOT_CSS_CLASS = "ns-root";
const MODAL_CSS_CLASS = "ns-modal";
const ANDROID_PLATFORM_CSS_CLASS = "ns-android";
Expand All @@ -32,18 +33,41 @@ 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;
function _test_root_view_root_css_class(shouldSetClassName: boolean) {
const rootView = getRootView();
if (shouldSetClassName) {
rootView.className = CLASS_NAME;
}

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

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

export function test_root_view_platform_css_class() {
const rootViewCssClasses = getRootView().cssClasses;
export function test_root_view_root_css_class() {
_test_root_view_root_css_class(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),
Expand All @@ -63,10 +87,30 @@ export function test_root_view_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`
);
}
}

export function test_root_view_device_type_css_class() {
const rootViewCssClasses = getRootView().cssClasses;
export function test_root_view_platform_css_class() {
_test_root_view_platform_css_class(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) {
Expand All @@ -88,10 +132,30 @@ export function test_root_view_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`
);
}
}

export function test_root_view_orientation_css_class() {
const rootViewCssClasses = getRootView().cssClasses;
export function test_root_view_device_type_css_class() {
_test_root_view_device_type_css_class(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) {
Expand Down Expand Up @@ -140,9 +204,24 @@ export function test_root_view_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`
);
}
}

export function test_modal_root_view_modal_css_class() {
export function test_root_view_orientation_css_class() {
_test_root_view_orientation_css_class(false);
}

export function test_root_view_class_name_preserve_orientation_css_class() {
_test_root_view_orientation_css_class(true);
}

function _test_modal_root_view_modal_css_class(shouldSetClassName: boolean) {
let modalClosed = false;

const modalCloseCallback = function () {
Expand All @@ -153,7 +232,20 @@ export function test_modal_root_view_modal_css_class() {
const page = <Page>args.object;
page.off(View.shownModallyEvent, modalPageShownModallyEventHandler);

TKUnit.assertTrue(_rootModalViews[0].cssClasses.has(MODAL_CSS_CLASS));
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`);
}

args.closeCallback();
};

Expand Down Expand Up @@ -186,3 +278,11 @@ export function test_modal_root_view_modal_css_class() {
helper.navigate(hostPageFactory);
TKUnit.waitUntilReady(() => modalClosed);
}

export function test_modal_root_view_modal_css_class() {
_test_modal_root_view_modal_css_class(false);
}

export function test_modal_root_view_class_name_preserve_modal_css_class() {
_test_modal_root_view_modal_css_class(true);
}
30 changes: 24 additions & 6 deletions tests/app/ui/styling/style-tests.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ export function test_multiple_class_selector() {
let page = helper.getClearCurrentPage();
let btnWithClasses: buttonModule.Button;

page.css = ".style1 { color: red; } .style2 { background-color: blue } ";
page.css = ".style1 { color: red; } .style2 { background-color: blue; } ";

//// Will be styled
btnWithClasses = new buttonModule.Button();
Expand All @@ -239,6 +239,24 @@ export function test_multiple_class_selector() {
helper.assertViewBackgroundColor(btnWithClasses, "#0000FF");
}

export function test_class_selector_overwriting() {
const page = helper.getClearCurrentPage();
page.css = ".first { color: red; } .second { background-color: blue; }";

const btnWithClass = new buttonModule.Button();
const stack = new stackModule.StackLayout();
page.content = stack;
stack.addChild(btnWithClass);

btnWithClass.className = "first";
helper.assertViewColor(btnWithClass, "#FF0000");
TKUnit.assert(btnWithClass.style.backgroundColor === undefined, " Background color should not have a value");

btnWithClass.className = "second";
TKUnit.assert(btnWithClass.style.color === undefined, "Color should not have a value");
helper.assertViewBackgroundColor(btnWithClass, "#0000FF");
}

export function test_id_selector() {
let page = helper.getClearCurrentPage();
page.style.color = unsetValue;
Expand Down Expand Up @@ -1497,7 +1515,7 @@ export function test_css_calc() {
TKUnit.assertEqual(stack.width as any, 125, "Stack - width === 125");

(stack as any).style = `width: calc(100% / 2)`;
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");

// This should log an error for the invalid css-calc expression, but not cause a crash
stack.className = "invalid-css-calc";
Expand Down Expand Up @@ -1568,7 +1586,7 @@ export function test_nested_css_calc() {

(stack as any).style = `width: calc(100% * calc(1 / 2)`;

TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");
}

export function test_css_variables() {
Expand Down Expand Up @@ -1678,7 +1696,7 @@ export function test_css_calc_and_variables() {

// Test setting the CSS variable via the style-attribute, this should override any value set via css-class
(stack as any).style = `${cssVarName}: 0.5`;
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");
}

export function test_css_variable_fallback() {
Expand Down Expand Up @@ -1819,10 +1837,10 @@ export function test_nested_css_calc_and_variables() {
// Test setting the CSS variable via the style-attribute, this should override any value set via css-class
stack.className = "wide";
(stack as any).style = `${cssVarName}: 0.25`;
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 0.5 }, "Stack - width === 50%");

stack.className = "nested";
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 1 }, "Stack - width === 100%");
TKUnit.assertDeepEqual(stack.width, { unit: "%", value: 1 }, "Stack - width === 100%");
}

export function test_css_variable_is_applied_to_normal_properties() {
Expand Down
19 changes: 13 additions & 6 deletions tns-core-modules/application/application-common.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
LoadAppCSSEventData,
UnhandledErrorEventData
} from "./application";

import { CLASS_PREFIX, pushToRootViewCssClasses, removeFromRootViewCssClasses } from "../css/system-classes";
import { DeviceOrientation } from "../ui/enums/enums";

export { UnhandledErrorEventData, DiscardedErrorEventData, CssChangedEventData, LoadAppCSSEventData };
Expand All @@ -54,11 +56,10 @@ 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}`
`${CLASS_PREFIX}${DeviceOrientation.portrait}`,
`${CLASS_PREFIX}${DeviceOrientation.landscape}`,
`${CLASS_PREFIX}${DeviceOrientation.unknown}`
];

let cssFile: string = "./app.css";
Expand Down Expand Up @@ -126,9 +127,15 @@ export function loadAppCss(): void {
}

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

ORIENTATION_CSS_CLASSES.forEach(c => removeCssClass(c));
pushToRootViewCssClasses(newOrientationCssClass);
rootView.cssClasses.add(newOrientationCssClass);
rootView._onCssStateChange();
}
Expand Down
5 changes: 0 additions & 5 deletions tns-core-modules/application/application.d.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,6 @@ export const lowMemoryEvent: string;
*/
export const orientationChangedEvent: string;

/**
* String value "ns-" used for CSS class prefix.
*/
export const CSS_CLASS_PREFIX: string;

/**
* Event data containing information for the application events.
*/
Expand Down
22 changes: 10 additions & 12 deletions tns-core-modules/application/application.ios.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

import {
ApplicationEventData,
CssChangedEventData,
Expand All @@ -9,28 +8,24 @@ import {
} from ".";

import {
CSS_CLASS_PREFIX, displayedEvent, exitEvent, getCssFileName, launchEvent, livesync,
lowMemoryEvent, notify, on, orientationChanged, orientationChangedEvent, resumeEvent,
setApplication, suspendEvent
displayedEvent, exitEvent, getCssFileName, launchEvent, livesync, lowMemoryEvent, notify, on,
orientationChanged, orientationChangedEvent, resumeEvent, setApplication, suspendEvent
} from "./application-common";

// First reexport so that app module is initialized.
export * from "./application-common";

// TODO: Remove this and get it from global to decouple builder for angular
import { createViewFromEntry } from "../ui/builder";
import { CLASS_PREFIX, getRootViewCssClasses, pushToRootViewCssClasses } from "../css/system-classes";
import { ios as iosView, View } from "../ui/core/view";
import { Frame, NavigationEntry } from "../ui/frame";
import { device } from "../platform/platform";
import { profile } from "../profiling";
import { ios } from "../utils/utils";

const ROOT = "root";
const IOS_PLATFORM = "ios";
const ROOT_VIEW_CSS_CLASSES = [
`${CSS_CLASS_PREFIX}${ROOT}`,
`${CSS_CLASS_PREFIX}${IOS_PLATFORM}`
];

const getVisibleViewController = ios.getVisibleViewController;

// NOTE: UIResponder with implementation of window - related to https://github.com/NativeScript/ios-runtime/issues/430
Expand Down Expand Up @@ -317,9 +312,12 @@ function createRootView(v?: View) {
}

const deviceType = device.deviceType.toLowerCase();
ROOT_VIEW_CSS_CLASSES.push(`${CSS_CLASS_PREFIX}${deviceType}`);
ROOT_VIEW_CSS_CLASSES.push(`${CSS_CLASS_PREFIX}${iosApp.orientation}`);
ROOT_VIEW_CSS_CLASSES.forEach(c => rootView.cssClasses.add(c));
pushToRootViewCssClasses(`${CLASS_PREFIX}${IOS_PLATFORM}`);
pushToRootViewCssClasses(`${CLASS_PREFIX}${deviceType}`);
pushToRootViewCssClasses(`${CLASS_PREFIX}${iosApp.orientation}`);

const rootViewCssClasses = getRootViewCssClasses();
rootViewCssClasses.forEach(c => rootView.cssClasses.add(c));

return rootView;
}
Expand Down
30 changes: 30 additions & 0 deletions tns-core-modules/css/system-classes.d.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @module "system-classes"
*/ /** */

/**
* 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;

/**
* Gets CSS system classes for root view.
*/
export function getRootViewCssClasses(): string[];

/**
* * Appends new CSS class to the system classes and returns the new length of the array.
* @param value New CSS system class.
*/
export function pushToRootViewCssClasses(value: string): number;

/**
* Removes CSS class from the system classes and returns it.
* @param value
*/
export function removeFromRootViewCssClasses(value: string): string;
Loading

Back | FazBrowse Home | New Git URL