Move styleScope from Page to View

Fix image-source test for API 27
setupAsRootView now makes the component styleScope
set css, addCss & addCssFile makes view to be styleScopeHost which cannot be overriden later from parent
Android modals now call setupAsRootView
Small fixes on ios layouts
launch event fired in andriod too
Moved some requestLayout calls to ios files where they belongs
This commit is contained in:
Hristo Hristov
2017-12-19 16:35:15 +02:00
parent 63ab46eb2a
commit 058a216ac9
19 changed files with 185 additions and 268 deletions

View File

@@ -90,7 +90,7 @@ const fullIosPng = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c
const fullJpegImage = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQH/wAARCAAEAAQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9oADAMBAAIRAxEAPwD+Pz/h5j+1Z/z9fBr/AMRt+AH/AM7uiiiv9fV9E36KOn/HMX0f+n/NlvDT/p3/ANUv/V3vrf8AP1nueaf8LOa9P+ZjjP8Ap3/0/wD6u99b/wD/2Q==";
const expectedJpegStart = "/9j/4AAQSkZJRgAB";
const expectedPngStart = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAA";
const expectedPngStart = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAA";
export function testBase64Encode_PNG() {
const img = imageSource.fromFile(smallImagePath);

View File

@@ -78,6 +78,22 @@ function getNativeHeight(view: View): number {
return layout.toDevicePixels(bounds.size.height);
}
export function test_correct_layout_top_bottom_edges_does_not_span_not_scrollable_not_flat() {
test_correct_layout_top_bottom_edges_does_not_span_options(false, false);
}
export function test_correct_layout_top_bottom_edges_does_not_span_scrollable_not_flat() {
test_correct_layout_top_bottom_edges_does_not_span_options(true, false);
}
export function test_correct_layout_top_bottom_edges_does_not_span_not_scrollable_flat() {
test_correct_layout_top_bottom_edges_does_not_span_options(false, true);
}
export function test_correct_layout_top_bottom_edges_does_not_span_scrollable_flat() {
test_correct_layout_top_bottom_edges_does_not_span_options(true, true);
}
export function test_correct_layout_scrollable_content_false() {
const page = new Page();
topmost().viewController.navigationBar.translucent = true;
@@ -251,6 +267,8 @@ export function test_correct_layout_scrollable_content_true_top_edge_does_not_sp
const tabItem = new TabViewItem();
tabItem.title = "Item";
const lbl = new Label();
lbl.viewController = iosView.UILayoutViewController.initWithOwner(new WeakRef(lbl));
lbl.viewController.edgesForExtendedLayout = UIRectEdge.Bottom | UIRectEdge.Left | UIRectEdge.Right;
(<any>lbl).scrollableContent = true;
tabItem.view = lbl;
tabView.items = [tabItem];
@@ -284,6 +302,8 @@ export function test_correct_layout_scrollable_content_true_bottom_edge_does_not
const tabItem = new TabViewItem();
tabItem.title = "Item";
const lbl = new Label();
lbl.viewController = iosView.UILayoutViewController.initWithOwner(new WeakRef(lbl));
lbl.viewController.edgesForExtendedLayout = UIRectEdge.Top | UIRectEdge.Left | UIRectEdge.Right;
(<any>lbl).scrollableContent = true;
tabItem.view = lbl;
tabView.items = [tabItem];
@@ -292,11 +312,7 @@ export function test_correct_layout_scrollable_content_true_bottom_edge_does_not
helper.navigate(() => page);
TKUnit.assertTrue(page.isLoaded, "page NOT loaded!");
TKUnit.assertNotNull(lbl.viewController);
(<UIViewController>lbl.viewController).edgesForExtendedLayout = UIRectEdge.Top | UIRectEdge.Left | UIRectEdge.Right;
lbl.requestLayout();
(<UIView>lbl.nativeViewProtected).setNeedsLayout();
(<UIView>lbl.nativeViewProtected).layoutIfNeeded();
TKUnit.waitUntilReady(() => lbl.isLayoutValid);
const tabBarHeight = uiUtils.ios.getActualHeight(tabView.viewController.tabBar);
const screenHeight = layout.toDevicePixels(UIScreen.mainScreen.bounds.size.height);
@@ -307,58 +323,35 @@ export function test_correct_layout_scrollable_content_true_bottom_edge_does_not
TKUnit.assertEqual(contentHeight, screenHeight - tabBarHeight, "lbl.height !== screenHeight - tabBarHeight");
}
export function test_correct_layout_top_bottom_edges_does_not_span() {
function test_correct_layout_top_bottom_edges_does_not_span_options(scrollable: boolean, flat: boolean) {
const page = new Page();
page.actionBar.flat = false;
(<any>page).scrollableContent = false;
page.actionBar.title = "ActionBar";
(<UIViewController>page.viewController).edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
const tabView = new TabView();
(<UIViewController>tabView.viewController).edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
const tabItem = new TabViewItem();
tabItem.title = "Item";
const lbl = new Label();
lbl.viewController = iosView.UILayoutViewController.initWithOwner(new WeakRef(lbl));
lbl.viewController.edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
tabItem.view = lbl;
tabView.items = [tabItem];
page.content = tabView;
page.actionBar.flat = flat;
(<any>page).scrollableContent = scrollable;
(<any>lbl).scrollableContent = scrollable;
helper.navigate(() => page);
TKUnit.assertTrue(page.isLoaded, "page NOT loaded!");
(<UIViewController>lbl.viewController).edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
lbl.requestLayout();
(<UIView>lbl.nativeViewProtected).setNeedsLayout();
(<UIView>lbl.nativeViewProtected).layoutIfNeeded();
TKUnit.waitUntilReady(() => lbl.isLayoutValid);
const statusBarHeight = uiUtils.ios.getStatusBarHeight(page.viewController);
const tabBarHeight = uiUtils.ios.getActualHeight(tabView.viewController.tabBar);
const screenHeight = layout.toDevicePixels(UIScreen.mainScreen.bounds.size.height);
const navBarHeight = uiUtils.ios.getActualHeight(page.frame.ios.controller.navigationBar);
const assert = (scrollable: boolean, flat: boolean) => {
page.actionBar.flat = flat;
(<any>page).scrollableContent = scrollable;
(<any>lbl).scrollableContent = scrollable;
lbl.requestLayout();
TKUnit.waitUntilReady(() => lbl.isLayoutValid);
const pageHeight = getHeight(page);
TKUnit.assertEqual(pageHeight, screenHeight - statusBarHeight - navBarHeight, "page.height !== screenHeight - statusBarHeight - navBarHeight");
const contentHeight = getHeight(lbl);
TKUnit.assertEqual(contentHeight, screenHeight - statusBarHeight - navBarHeight - tabBarHeight, "lbl.height !== screenHeight - statusBarHeight - navBarHeight - tabBarHeight");
};
// scrollable: false, flat: false;
assert(false, false);
// scrollable: true, flat: false;
assert(true, false);
// scrollable: true, flat: true;
assert(true, true);
// scrollable: false, flat: true;
assert(false, true);
}
export function test_showing_native_viewcontroller_doesnt_throw_exception() {

View File

@@ -57,11 +57,20 @@ global.registerWebpackModules = function registerWebpackModules(context: Context
const registerName = base + registerExt;
if (registerName.startsWith("./") && registerName.endsWith(".js")) {
const jsNickName = registerName.substr(2, registerName.length - 5);
const jsNickNames = [
// This is extremely short version like "main-page" that was promoted to be used with global.registerModule("module-name", loaderFunc);
registerName.substr(2, registerName.length - 5),
// This is for supporting module names like "./main/main-page"
registerName.substr(0, registerName.length - 3),
// This is for supporting module names like "main/main-page.js"
registerName.substr(2),
];
jsNickNames.forEach(jsNickName => {
if (isSourceFile || !global.moduleExists(jsNickName)) {
global.registerModule(jsNickName, () => context(key));
}
});
}
if (isSourceFile || !global.moduleExists(registerName)) {
global.registerModule(registerName, () => context(key));

View File

@@ -47,7 +47,7 @@ export function load(pathOrOptions: string | LoadOptions, context?: any): View {
if (typeof pathOrOptions === "string") {
componentModule = loadInternal(pathOrOptions);
} else {
componentModule = loadCustomComponent(pathOrOptions.path, pathOrOptions.name, pathOrOptions.attributes, pathOrOptions.exports, pathOrOptions.page);
componentModule = loadCustomComponent(pathOrOptions.path, pathOrOptions.name, pathOrOptions.attributes, pathOrOptions.exports, pathOrOptions.page, true);
}
} else {
let path = <string>pathOrOptions;
@@ -158,7 +158,7 @@ function loadInternal(fileName: string, context?: any, moduleNamePath?: string):
return componentModule;
}
function loadCustomComponent(componentPath: string, componentName?: string, attributes?: Object, context?: Object, parentPage?: View): ComponentModule {
function loadCustomComponent(componentPath: string, componentName?: string, attributes?: Object, context?: Object, parentPage?: View, isRootComponent: boolean = true): ComponentModule {
if (!parentPage && context) {
// Read the parent page that was passed down below
// https://github.com/NativeScript/NativeScript/issues/1639
@@ -211,7 +211,7 @@ function loadCustomComponent(componentPath: string, componentName?: string, attr
}
} else {
// Custom components without XML
result = getComponentModule(componentName, componentPath, attributes, context);
result = getComponentModule(componentName, componentPath, attributes, context, undefined, isRootComponent);
}
// webpack modules require paths to be relative to /app folder.
@@ -607,7 +607,7 @@ namespace xml2ui {
private buildComponent(args: xml.ParserEvent): ComponentModule {
if (args.prefix && args.namespace) {
// Custom components
return loadCustomComponent(args.namespace, args.elementName, args.attributes, this.context, this.currentRootView);
return loadCustomComponent(args.namespace, args.elementName, args.attributes, this.context, this.currentRootView, !this.currentRootView);
} else {
// Default components
let namespace = args.namespace;
@@ -615,7 +615,7 @@ namespace xml2ui {
//Ignore the default ...tns.xsd namespace URL
namespace = undefined;
}
return getComponentModule(args.elementName, namespace, args.attributes, this.context, this.moduleNamePath);
return getComponentModule(args.elementName, namespace, args.attributes, this.context, this.moduleNamePath, !this.currentRootView);
}
}

View File

@@ -4,7 +4,7 @@
import { View } from "../../core/view";
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string): ComponentModule;
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string, isRootComponent?: boolean): ComponentModule;
export function setPropertyValue(instance: View, instanceModuleExports: Object, pageExports: Object, propertyName: string, propertyValue: any): void;
export interface ComponentModule {

View File

@@ -174,13 +174,16 @@ const applyComponentAttributes = profile("applyComponentAttributes", (instance:
}
});
export function getComponentModule(elementName: string, namespace: string, attributes: Object, moduleExports: Object, moduleNamePath?: string): ComponentModule {
export function getComponentModule(elementName: string, namespace: string, attributes: Object, moduleExports: Object, moduleNamePath?: string, isRootComponent?: boolean): ComponentModule {
// Support lower-case-dashed component declaration in the XML (https://github.com/NativeScript/NativeScript/issues/309).
elementName = elementName.split("-").map(s => { return s[0].toUpperCase() + s.substring(1) }).join("");
const { instance, instanceModule } = createComponentInstance(elementName, namespace);
moduleExports = getComponentModuleExports(instance, moduleExports, attributes);
if (isRootComponent) {
applyComponentCss(instance, moduleNamePath, attributes);
}
applyComponentAttributes(instance, instanceModule, moduleExports, attributes);
var componentModule;

View File

@@ -1,5 +1,5 @@
import { ContentView as ContentViewDefinition } from ".";
import { View, CustomLayoutView, AddChildFromBuilder, layout } from "../core/view";
import { View, CustomLayoutView, AddChildFromBuilder, layout, isIOS } from "../core/view";
export * from "../core/view";
@@ -22,7 +22,7 @@ export class ContentView extends CustomLayoutView implements ContentViewDefiniti
}
this._onContentChanged(oldView, value);
if (oldView !== value) {
if (isIOS && oldView !== value) {
this.requestLayout();
}
}

View File

@@ -338,6 +338,11 @@ export abstract class ViewBase extends Observable {
public _isPaddingRelative: boolean;
public _styleScope: any;
/**
* @private
*/
_isStyleScopeHost: boolean;
/**
* Determines the depth of suspended updates.
* When the value is 0 the current property updates are not batched nor scoped and must be immediately applied.

View File

@@ -178,6 +178,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
private _templateParent: ViewBase;
private __nativeView: any;
// private _disableNativeViewRecycling: boolean;
public domNode: dnm.DOMNode;
public recycleNativeView: "always" | "never" | "auto";
@@ -197,6 +198,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
public _styleScope: ssm.StyleScope;
public _suspendedUpdates: { [propertyName: string]: Property<ViewBase, any> | CssProperty<Style, any> | CssAnimationProperty<Style, any> };
public _suspendNativeUpdatesCount: SuspendType;
public _isStyleScopeHost: boolean;
// Dynamic properties.
left: Length;
@@ -927,6 +929,12 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
}
_inheritStyleScope(styleScope: ssm.StyleScope): void {
// If we are styleScope don't inherit parent stylescope.
// TODO: Consider adding parent scope and merge selectors.
if (this._isStyleScopeHost) {
return;
}
if (this._styleScope !== styleScope) {
this._styleScope = styleScope;
this._onCssStateChange();

View File

@@ -20,6 +20,7 @@ import {
} from "../../gestures";
import { createViewFromEntry } from "../../builder";
import { StyleScope } from "../../styling/style-scope";
export * from "../../styling/style-properties";
export * from "../view-base";
@@ -74,6 +75,52 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
public _gestureObservers = {};
get css(): string {
const scope = this._styleScope;
return scope && scope.css;
}
set css(value: string) {
this.updateStyleScope(undefined, undefined, value);
}
public addCss(cssString: string): void {
this.updateStyleScope(undefined, cssString);
}
public addCssFile(cssFileName: string) {
this.updateStyleScope(cssFileName);
}
private updateStyleScope(cssFileName?: string, cssString?: string, css?: string): void {
let scope = this._styleScope;
if (!scope) {
scope = new StyleScope();
this.setScopeProperty(scope, cssFileName, cssString, css);
this._inheritStyleScope(scope);
this._isStyleScopeHost = true;
} else {
this.setScopeProperty(scope, cssFileName, cssString, css);
this._onCssStateChange();
}
}
private setScopeProperty(scope: StyleScope, cssFileName?: string, cssString?: string, css?: string): void {
if (cssFileName !== undefined) {
scope.addCssFile(cssFileName);
} else if (cssString !== undefined) {
scope.addCss(cssString);
} else if (css !== undefined) {
scope.css = css;
}
}
_setupAsRootView(context: any): void {
super._setupAsRootView(context);
if (!this._styleScope) {
this.updateStyleScope();
}
}
observe(type: GestureTypes, callback: (args: GestureEventData) => void, thisArg?: any): void {
if (!this._gestureObservers[type]) {
this._gestureObservers[type] = [];
@@ -886,10 +933,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
public _redrawNativeBackground(value: any): void {
//
}
addCssFile(cssFileName: string): void {
// TODO: Implement
}
}
export const automationTextProperty = new Property<ViewCommon, string>({ name: "automationText" });

View File

@@ -152,7 +152,7 @@ function initializeDialogFragment() {
public onCreateView(inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle): android.view.View {
const owner = this.owner;
owner._setupUI(this.getActivity());
owner._setupAsRootView(this.getActivity());
owner._isAddedToNativeVisualTree = true;
return this.owner.nativeViewProtected;
@@ -323,7 +323,7 @@ export class View extends ViewCommon {
public requestLayout(): void {
super.requestLayout();
if (this.nativeViewProtected) {
return this.nativeViewProtected.requestLayout();
this.nativeViewProtected.requestLayout();
}
}

View File

@@ -638,6 +638,20 @@ export abstract class View extends ViewBase {
* @private
*/
_getFragmentManager(): any; /* android.app.FragmentManager */
/**
* @private
* A valid css string which will be applied for all nested UI components (based on css rules).
*/
css: string;
/**
* @private
* Adds a new values to current css.
* @param cssString - A valid css which will be added to current css.
*/
addCss(cssString: string): void;
/**
* @private
* Adds the content of the file to the current css.
@@ -649,12 +663,12 @@ export abstract class View extends ViewBase {
/**
* __Obsolete:__ There is a new property system that does not rely on _getValue.
*/
public _getValue(property: any): never;
_getValue(property: any): never;
/**
* __Obsolete:__ There is a new property system that does not rely on _setValue.
*/
public _setValue(property: any, value: any): never;
_setValue(property: any, value: any): never;
}
/**

View File

@@ -57,7 +57,7 @@ export class View extends ViewCommon {
super.requestLayout();
this._privateFlags |= PFLAG_FORCE_LAYOUT;
const parent = <View>this.parent;
const parent = this.parent;
if (parent) {
parent.requestLayout();
}
@@ -586,134 +586,45 @@ function isScrollable(controller: UIViewController, owner: View): boolean {
const majorVersion = iosUtils.MajorVersion;
interface ExtendedController extends UIViewController {
scrollable: boolean;
navBarHidden: boolean;
hasChildControllers: boolean;
// safeAreaLeft: NSLayoutConstraint;
// safeAreaTop: NSLayoutConstraint;
// safeAreaRight: NSLayoutConstraint;
// safeAreaBottom: NSLayoutConstraint;
// fullscreenTop: NSLayoutConstraint;
// fullscreenBottom: NSLayoutConstraint;
// fullscreenLeft: NSLayoutConstraint;
// fullscreenRight: NSLayoutConstraint;
// activeConstraints: NSLayoutConstraint[];
}
export namespace ios {
function constrainView(controller: ExtendedController, owner: View): void {
export function updateConstraints(controller: UIViewController, owner: View): void {
const root = controller.view;
root.autoresizesSubviews = false;
// const view = controller.view.subviews.length > 0 ? controller.view.subviews[0] : null;
// if (view) {
// view.translatesAutoresizingMaskIntoConstraints = false;
// }
if (!root.safeAreaLayoutGuide) {
const layoutGuide = (<any>root).safeAreaLayoutGuide = UILayoutGuide.alloc().init();
root.addLayoutGuide(layoutGuide);
// // view.translatesAutoresizingMaskIntoConstraints = false;
// if (majorVersion > 10) {
// const safeArea = root.safeAreaLayoutGuide;
// layoutGuide.topAnchor.constraintEqualToAnchor(safeArea.topAnchor);
// layoutGuide.bottomAnchor.constraintEqualToAnchor(safeArea.bottomAnchor);
// layoutGuide.leftAnchor.constraintEqualToAnchor(safeArea.leftAnchor);
// layoutGuide.rightAnchor.constraintEqualToAnchor(safeArea.rightAnchor);
// } else {
NSLayoutConstraint.activateConstraints(<any>[
layoutGuide.topAnchor.constraintEqualToAnchor(controller.topLayoutGuide.bottomAnchor),
layoutGuide.bottomAnchor.constraintEqualToAnchor(controller.bottomLayoutGuide.topAnchor),
layoutGuide.leadingAnchor.constraintEqualToAnchor(root.leadingAnchor),
layoutGuide.trailingAnchor.constraintEqualToAnchor(root.trailingAnchor)
]);
// }
}
}
// const view = root.subviews[0];
// if (!controller.safeAreaTop) {
// view.translatesAutoresizingMaskIntoConstraints = false;
// if (majorVersion > 10) {
// const safeArea = root.safeAreaLayoutGuide;
// controller.safeAreaTop = view.topAnchor.constraintEqualToAnchor(safeArea.topAnchor);
// controller.fullscreenTop = view.topAnchor.constraintEqualToAnchor(root.topAnchor);
// controller.safeAreaBottom = view.bottomAnchor.constraintEqualToAnchor(safeArea.bottomAnchor);
// controller.fullscreenBottom = view.bottomAnchor.constraintEqualToAnchor(root.bottomAnchor);
// controller.safeAreaLeft = view.leftAnchor.constraintEqualToAnchor(safeArea.leftAnchor);
// controller.fullscreenLeft = view.leftAnchor.constraintEqualToAnchor(root.leftAnchor);
// controller.safeAreaRight = view.rightAnchor.constraintEqualToAnchor(safeArea.rightAnchor);
// controller.fullscreenRight = view.rightAnchor.constraintEqualToAnchor(root.rightAnchor);
// } else {
// controller.safeAreaTop = view.topAnchor.constraintEqualToAnchor(controller.topLayoutGuide.bottomAnchor);
// controller.fullscreenTop = view.topAnchor.constraintEqualToAnchor(root.topAnchor);
// controller.safeAreaBottom = view.bottomAnchor.constraintEqualToAnchor(controller.bottomLayoutGuide.topAnchor);
// controller.fullscreenBottom = view.bottomAnchor.constraintEqualToAnchor(root.bottomAnchor);
// controller.safeAreaLeft = view.leadingAnchor.constraintEqualToAnchor(root.leadingAnchor);
// controller.fullscreenLeft = controller.safeAreaLeft;
// controller.safeAreaRight = view.trailingAnchor.constraintEqualToAnchor(root.trailingAnchor);
// controller.fullscreenRight = controller.safeAreaRight;
// }
// }
// // check if this works
// const fullscreenHorizontally = controller ===
// iosUtils.getter(UIApplication, UIApplication.sharedApplication).keyWindow.rootViewController
// || !!(<any>owner).wantsFullscreen;
// const navBarHidden = controller.navBarHidden;
// const scrollable = controller.scrollable;;
// const hasChildControllers = controller.hasChildControllers;
// const constraints = [
// hasChildControllers || scrollable ? controller.fullscreenBottom : controller.safeAreaBottom,
// fullscreenHorizontally ? controller.fullscreenLeft : controller.safeAreaLeft,
// fullscreenHorizontally ? controller.fullscreenRight : controller.safeAreaRight
// ];
// if (hasChildControllers) {
// // If not inner most extend to fullscreen
// constraints.push(controller.fullscreenTop);
// } else if (!scrollable) {
// // If not scrollable dock under safe area
// constraints.push(controller.safeAreaTop);
// } else if (navBarHidden) {
// // If scrollable but no navigation bar dock under safe area
// constraints.push(controller.safeAreaTop);
// } else {
// // If scrollable and navigation bar extend to fullscreen
// constraints.push(controller.fullscreenTop);
// }
// const activeConstraints = controller.activeConstraints;
// if (activeConstraints) {
// NSLayoutConstraint.deactivateConstraints(<any>activeConstraints);
// }
// NSLayoutConstraint.activateConstraints(<any>constraints);
// controller.activeConstraints = constraints;
function getStatusBarHeight(viewController?: UIViewController): number {
const app = iosUtils.getter(UIApplication, UIApplication.sharedApplication);
if (!app || app.statusBarHidden) {
return 0;
}
export function updateConstraints(controller: UIViewController, owner: View): void {
const extendedController = <ExtendedController>controller;
// const navController = controller.navigationController;
// const navBarHidden = navController ? navController.navigationBarHidden : true;
// const scrollable = isScrollable(controller, owner);
// const hasChildControllers = controller.childViewControllers.count > 0;
if (viewController && viewController.prefersStatusBarHidden) {
return 0;
}
// if (extendedController.scrollable !== scrollable
// || extendedController.navBarHidden !== navBarHidden
// || extendedController.hasChildControllers !== hasChildControllers) {
// extendedController.scrollable = scrollable;
// extendedController.navBarHidden = navBarHidden;
// extendedController.hasChildControllers = hasChildControllers;
// constrainView(extendedController, owner);
// }
constrainView(extendedController, owner);
const statusFrame = app.statusBarFrame;
return Math.min(statusFrame.size.width, statusFrame.size.height);
}
export function layoutView(controller: UIViewController, owner: View): void {
// const frame = controller.view.subviews[0].bounds;
// check if this works
const fullscreen = controller ===
iosUtils.getter(UIApplication, UIApplication.sharedApplication).keyWindow.rootViewController;
// || !!(<any>owner).wantsFullscreen;
let left: number, top: number, width: number, height: number;
@@ -739,28 +650,32 @@ export namespace ios {
const safeAreaTopLength = safeOrigin.y - fullscreenOrigin.y;
const safeAreaBottomLength = fullscreenSize.height - safeAreaSize.height - safeAreaTopLength;
if (!(controller.edgesForExtendedLayout & UIRectEdge.Top)) {
const statusBarHeight = getStatusBarHeight(controller);
const navBarHeight = controller.navigationController ? controller.navigationController.navigationBar.frame.size.height : 0;
fullscreenOrigin.y = safeOrigin.y;
fullscreenSize.height -= (statusBarHeight + navBarHeight);
}
left = safeOrigin.x;
width = safeAreaSize.width;
if (hasChildControllers) {
// If not inner most extend to fullscreen
top = fullscreenOrigin.y; // constraints.push(controller.fullscreenTop);
top = fullscreenOrigin.y;
height = fullscreenSize.height;
} else if (!scrollable) {
// If not scrollable dock under safe area
top = safeOrigin.y;
height = safeAreaSize.height;
// constraints.push(controller.safeAreaTop);
} else if (navBarHidden) {
// If scrollable but no navigation bar dock under safe area
top = safeOrigin.y; // constraints.push(controller.safeAreaTop);
// const adjusted = parentControllerAdjustedScrollViewInsets(controller);
height = safeAreaSize.height + safeAreaBottomLength;
// if ()
top = safeOrigin.y;
height = navController ? (fullscreenSize.height - top) : safeAreaSize.height;
} else {
// If scrollable and navigation bar extend to fullscreen
top = fullscreenOrigin.y; // constraints.push(controller.fullscreenTop);
height = fullscreenOrigin.y + fullscreenSize.height;
top = fullscreenOrigin.y;
height = fullscreenSize.height;
}
left = layout.toDevicePixels(left);
@@ -769,34 +684,10 @@ export namespace ios {
height = layout.toDevicePixels(height);
}
// const frame = controller.view.safeAreaLayoutGuide.layoutFrame;
// const origin = frame.origin;
// const size = frame.size;
// width = layout.toDevicePixels(fullscreenSize.width);
// height = layout.toDevicePixels(fullscreenSize.height);
// if (iosUtils.MajorVersion < 11) {
// const window = controller.view.window;
// if (window) {
// const windowSize = window.frame.size;
// const windowInPortrait = windowSize.width < windowSize.height;
// const viewInPortrait = width < height;
// if (windowInPortrait !== viewInPortrait) {
// // NOTE: This happens on iOS <11.
// // We were not visible (probably in backstack) when orientation happened.
// // request layout so we get the new dimensions.
// // There is no sync way to force a layout.
// setTimeout(() => owner.requestLayout());
// }
// }
// }
const widthSpec = layout.makeMeasureSpec(width, layout.EXACTLY);
const heightSpec = layout.makeMeasureSpec(height, layout.EXACTLY);
View.measureChild(null, owner, widthSpec, heightSpec);
// const left = layout.toDevicePixels(fullscreenOrigin.x);
// const top = layout.toDevicePixels(fullscreenOrigin.y);
View.layoutChild(null, owner, left, top, width + left, height + top);
layoutParent(owner.parent);

View File

@@ -890,10 +890,10 @@ function setActivityContent(activity: android.app.Activity, savedInstanceState:
let rootView = callbacks._rootView = (<any>app).rootView;
if (!rootView) {
const mainEntry = application.getMainEntry();
if (shouldCreateRootFrame) {
const intent = activity.getIntent();
const extras = intent.getExtras();
rootView = notifyLaunch(intent, savedInstanceState);
if (shouldCreateRootFrame) {
const extras = intent.getExtras();
let frameId = -1;
// We have extras when we call - new Frame().navigate();

View File

@@ -278,7 +278,7 @@ export class GridLayoutBase extends LayoutBase implements GridLayoutDefinition {
}
protected invalidate(): void {
this.requestLayout();
// handled natively in android and overriden in ios.
}
set rows(value: string) {

View File

@@ -41,6 +41,11 @@ export class GridLayout extends GridLayoutBase {
this.removeFromMap(child);
}
protected invalidate(): void {
super.invalidate();
this.requestLayout();
}
private getColumnIndex(view: View): number {
return Math.max(0, Math.min(GridLayout.getColumn(view), this.columnsInternal.length - 1));
}

View File

@@ -6,7 +6,6 @@ import {
import { Frame, topmost as topmostFrame } from "../frame";
import { ActionBar } from "../action-bar";
import { KeyframeAnimationInfo } from "../animation/keyframe-animation";
import { StyleScope } from "../styling/style-scope";
import { File, path, knownFolders } from "../../file-system";
import { profile } from "../../profiling";
@@ -29,23 +28,10 @@ export class PageBase extends ContentView implements PageDefinition {
public backgroundSpanUnderStatusBar: boolean;
public hasActionBar: boolean;
constructor() {
super();
this._styleScope = new StyleScope();
}
get navigationContext(): any {
return this._navigationContext;
}
get css(): string {
return this._styleScope.css;
}
set css(value: string) {
this._styleScope.css = value;
this._onCssStateChange();
}
get actionBar(): ActionBar {
if (!this._actionBar) {
this.hasActionBar = true;
@@ -95,16 +81,6 @@ export class PageBase extends ContentView implements PageDefinition {
}
}
public addCss(cssString: string): void {
this._styleScope.addCss(cssString);
this._onCssStateChange();
}
public addCssFile(cssFileName: string) {
this._styleScope.addCssFile(cssFileName);
this._onCssStateChange();
}
public getKeyframeAnimationWithName(animationName: string): KeyframeAnimationInfo {
return this._styleScope.getKeyframeAnimationWithName(animationName);
}
@@ -161,10 +137,6 @@ export class PageBase extends ContentView implements PageDefinition {
get _childrenCount(): number {
return (this.content ? 1 : 0) + (this._actionBar ? 1 : 0);
}
_inheritStyleScope(styleScope: StyleScope): void {
// The Page have its own scope.
}
}
PageBase.prototype.recycleNativeView = "never";

View File

@@ -94,23 +94,6 @@ export class Page extends ContentView {
*/
public enableSwipeBackNavigation: boolean;
/**
* A valid css string which will be applied for all nested UI components (based on css rules).
*/
public css: string;
/**
* Adds a new values to current css.
* @param cssString - A valid css which will be added to current css.
*/
public addCss(cssString: string): void;
/**
* Adds the content of the file to the current css.
* @param cssFileName - A valid file name (from the application root) which contains a valid css.
*/
public addCssFile(cssFileName: string): void;
/**
* Returns a CSS keyframe animation with the specified name, if it exists.
*/

View File

@@ -141,24 +141,15 @@ function updateItemIconPosition(tabBarItem: UITabBarItem): void {
export class TabViewItem extends TabViewItemBase {
private __controller: UIViewController;
private _setNeedsLayoutOnSuperview: boolean;
public setViewController(controller: UIViewController, nativeView: UIView) {
this.__controller = controller;
this.setNativeView(nativeView);
this._setNeedsLayoutOnSuperview = controller.view !== nativeView;
}
public requestLayout(): void {
super.requestLayout();
if (this._setNeedsLayoutOnSuperview) {
this.nativeViewProtected.superview.setNeedsLayout();
}
}
public disposeNativeView() {
this.__controller = undefined;
this.setNativeView(undefined);
this._setNeedsLayoutOnSuperview = false;
}
public _update() {