Skip to content

Commit 058a216

Browse files
Hristo HristovHristo Hristov
authored andcommitted
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
1 parent 63ab46e commit 058a216

File tree

19 files changed

+186
-269
lines changed

19 files changed

+186
-269
lines changed

tests/app/image-source/image-source-tests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const fullIosPng = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAAAXNSR0IArs4c
9090

9191
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==";
9292
const expectedJpegStart = "/9j/4AAQSkZJRgAB";
93-
const expectedPngStart = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAAA";
93+
const expectedPngStart = "iVBORw0KGgoAAAANSUhEUgAAAAQAAAAECAIAAAAmkwkpAAA";
9494

9595
export function testBase64Encode_PNG() {
9696
const img = imageSource.fromFile(smallImagePath);

tests/app/ui/page/page-tests.ios.ts

Lines changed: 31 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,22 @@ function getNativeHeight(view: View): number {
7878
return layout.toDevicePixels(bounds.size.height);
7979
}
8080

81+
export function test_correct_layout_top_bottom_edges_does_not_span_not_scrollable_not_flat() {
82+
test_correct_layout_top_bottom_edges_does_not_span_options(false, false);
83+
}
84+
85+
export function test_correct_layout_top_bottom_edges_does_not_span_scrollable_not_flat() {
86+
test_correct_layout_top_bottom_edges_does_not_span_options(true, false);
87+
}
88+
89+
export function test_correct_layout_top_bottom_edges_does_not_span_not_scrollable_flat() {
90+
test_correct_layout_top_bottom_edges_does_not_span_options(false, true);
91+
}
92+
93+
export function test_correct_layout_top_bottom_edges_does_not_span_scrollable_flat() {
94+
test_correct_layout_top_bottom_edges_does_not_span_options(true, true);
95+
}
96+
8197
export function test_correct_layout_scrollable_content_false() {
8298
const page = new Page();
8399
topmost().viewController.navigationBar.translucent = true;
@@ -251,6 +267,8 @@ export function test_correct_layout_scrollable_content_true_top_edge_does_not_sp
251267
const tabItem = new TabViewItem();
252268
tabItem.title = "Item";
253269
const lbl = new Label();
270+
lbl.viewController = iosView.UILayoutViewController.initWithOwner(new WeakRef(lbl));
271+
lbl.viewController.edgesForExtendedLayout = UIRectEdge.Bottom | UIRectEdge.Left | UIRectEdge.Right;
254272
(<any>lbl).scrollableContent = true;
255273
tabItem.view = lbl;
256274
tabView.items = [tabItem];
@@ -284,6 +302,8 @@ export function test_correct_layout_scrollable_content_true_bottom_edge_does_not
284302
const tabItem = new TabViewItem();
285303
tabItem.title = "Item";
286304
const lbl = new Label();
305+
lbl.viewController = iosView.UILayoutViewController.initWithOwner(new WeakRef(lbl));
306+
lbl.viewController.edgesForExtendedLayout = UIRectEdge.Top | UIRectEdge.Left | UIRectEdge.Right;
287307
(<any>lbl).scrollableContent = true;
288308
tabItem.view = lbl;
289309
tabView.items = [tabItem];
@@ -292,11 +312,7 @@ export function test_correct_layout_scrollable_content_true_bottom_edge_does_not
292312
helper.navigate(() => page);
293313
TKUnit.assertTrue(page.isLoaded, "page NOT loaded!");
294314
TKUnit.assertNotNull(lbl.viewController);
295-
(<UIViewController>lbl.viewController).edgesForExtendedLayout = UIRectEdge.Top | UIRectEdge.Left | UIRectEdge.Right;
296-
lbl.requestLayout();
297-
(<UIView>lbl.nativeViewProtected).setNeedsLayout();
298-
(<UIView>lbl.nativeViewProtected).layoutIfNeeded();
299-
TKUnit.waitUntilReady(() => lbl.isLayoutValid);
315+
300316
const tabBarHeight = uiUtils.ios.getActualHeight(tabView.viewController.tabBar);
301317
const screenHeight = layout.toDevicePixels(UIScreen.mainScreen.bounds.size.height);
302318

@@ -307,58 +323,35 @@ export function test_correct_layout_scrollable_content_true_bottom_edge_does_not
307323
TKUnit.assertEqual(contentHeight, screenHeight - tabBarHeight, "lbl.height !== screenHeight - tabBarHeight");
308324
}
309325

310-
export function test_correct_layout_top_bottom_edges_does_not_span() {
326+
function test_correct_layout_top_bottom_edges_does_not_span_options(scrollable: boolean, flat: boolean) {
311327
const page = new Page();
312-
page.actionBar.flat = false;
313-
(<any>page).scrollableContent = false;
314328
page.actionBar.title = "ActionBar";
315-
(<UIViewController>page.viewController).edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
316329

317330
const tabView = new TabView();
318-
(<UIViewController>tabView.viewController).edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
319331
const tabItem = new TabViewItem();
320332
tabItem.title = "Item";
321333
const lbl = new Label();
334+
lbl.viewController = iosView.UILayoutViewController.initWithOwner(new WeakRef(lbl));
335+
lbl.viewController.edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
322336
tabItem.view = lbl;
323337
tabView.items = [tabItem];
324338

325339
page.content = tabView;
340+
341+
page.actionBar.flat = flat;
342+
(<any>page).scrollableContent = scrollable;
343+
(<any>lbl).scrollableContent = scrollable;
344+
326345
helper.navigate(() => page);
327346
TKUnit.assertTrue(page.isLoaded, "page NOT loaded!");
328347

329-
(<UIViewController>lbl.viewController).edgesForExtendedLayout = UIRectEdge.Left | UIRectEdge.Right;
330-
lbl.requestLayout();
331-
(<UIView>lbl.nativeViewProtected).setNeedsLayout();
332-
(<UIView>lbl.nativeViewProtected).layoutIfNeeded();
333-
TKUnit.waitUntilReady(() => lbl.isLayoutValid);
334-
335348
const statusBarHeight = uiUtils.ios.getStatusBarHeight(page.viewController);
336349
const tabBarHeight = uiUtils.ios.getActualHeight(tabView.viewController.tabBar);
337350
const screenHeight = layout.toDevicePixels(UIScreen.mainScreen.bounds.size.height);
338351
const navBarHeight = uiUtils.ios.getActualHeight(page.frame.ios.controller.navigationBar);
339352

340-
const assert = (scrollable: boolean, flat: boolean) => {
341-
page.actionBar.flat = flat;
342-
(<any>page).scrollableContent = scrollable;
343-
(<any>lbl).scrollableContent = scrollable;
344-
345-
lbl.requestLayout();
346-
TKUnit.waitUntilReady(() => lbl.isLayoutValid);
347-
348-
const pageHeight = getHeight(page);
349-
TKUnit.assertEqual(pageHeight, screenHeight - statusBarHeight - navBarHeight, "page.height !== screenHeight - statusBarHeight - navBarHeight");
350-
const contentHeight = getHeight(lbl);
351-
TKUnit.assertEqual(contentHeight, screenHeight - statusBarHeight - navBarHeight - tabBarHeight, "lbl.height !== screenHeight - statusBarHeight - navBarHeight - tabBarHeight");
352-
};
353-
354-
// scrollable: false, flat: false;
355-
assert(false, false);
356-
// scrollable: true, flat: false;
357-
assert(true, false);
358-
// scrollable: true, flat: true;
359-
assert(true, true);
360-
// scrollable: false, flat: true;
361-
assert(false, true);
353+
const contentHeight = getHeight(lbl);
354+
TKUnit.assertEqual(contentHeight, screenHeight - statusBarHeight - navBarHeight - tabBarHeight, "lbl.height !== screenHeight - statusBarHeight - navBarHeight - tabBarHeight");
362355
}
363356

364357
export function test_showing_native_viewcontroller_doesnt_throw_exception() {

tns-core-modules/globals/globals.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const modules: Map<string, ModuleLoader> = new Map<string, ModuleLoader>();
3030

3131
(<any>global).moduleResolvers = [global.require];
3232

33-
global.registerModule = function(name: string, loader: ModuleLoader): void {
33+
global.registerModule = function (name: string, loader: ModuleLoader): void {
3434
modules.set(name, loader);
3535
}
3636

@@ -57,23 +57,32 @@ global.registerWebpackModules = function registerWebpackModules(context: Context
5757

5858
const registerName = base + registerExt;
5959
if (registerName.startsWith("./") && registerName.endsWith(".js")) {
60-
const jsNickName = registerName.substr(2, registerName.length - 5);
61-
// This is extremely short version like "main-page" that was promoted to be used with global.registerModule("module-name", loaderFunc);
62-
if (isSourceFile || !global.moduleExists(jsNickName)) {
63-
global.registerModule(jsNickName, () => context(key));
64-
}
60+
const jsNickNames = [
61+
// This is extremely short version like "main-page" that was promoted to be used with global.registerModule("module-name", loaderFunc);
62+
registerName.substr(2, registerName.length - 5),
63+
// This is for supporting module names like "./main/main-page"
64+
registerName.substr(0, registerName.length - 3),
65+
// This is for supporting module names like "main/main-page.js"
66+
registerName.substr(2),
67+
];
68+
69+
jsNickNames.forEach(jsNickName => {
70+
if (isSourceFile || !global.moduleExists(jsNickName)) {
71+
global.registerModule(jsNickName, () => context(key));
72+
}
73+
});
6574
}
6675
if (isSourceFile || !global.moduleExists(registerName)) {
6776
global.registerModule(registerName, () => context(key));
6877
}
6978
});
7079
}
7180

72-
global.moduleExists = function(name: string): boolean {
81+
global.moduleExists = function (name: string): boolean {
7382
return modules.has(name);
7483
}
7584

76-
global.loadModule = function(name: string): any {
85+
global.loadModule = function (name: string): any {
7786
const loader = modules.get(name);
7887
if (loader) {
7988
return loader();
@@ -110,7 +119,7 @@ global.registerModule("fetch", () => require("fetch"));
110119
return new Promise((resolve, reject) => {
111120
try {
112121
resolve(global.require(path));
113-
} catch(e) {
122+
} catch (e) {
114123
reject(e);
115124
}
116125
});

tns-core-modules/ui/builder/builder.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export function load(pathOrOptions: string | LoadOptions, context?: any): View {
4747
if (typeof pathOrOptions === "string") {
4848
componentModule = loadInternal(pathOrOptions);
4949
} else {
50-
componentModule = loadCustomComponent(pathOrOptions.path, pathOrOptions.name, pathOrOptions.attributes, pathOrOptions.exports, pathOrOptions.page);
50+
componentModule = loadCustomComponent(pathOrOptions.path, pathOrOptions.name, pathOrOptions.attributes, pathOrOptions.exports, pathOrOptions.page, true);
5151
}
5252
} else {
5353
let path = <string>pathOrOptions;
@@ -158,7 +158,7 @@ function loadInternal(fileName: string, context?: any, moduleNamePath?: string):
158158
return componentModule;
159159
}
160160

161-
function loadCustomComponent(componentPath: string, componentName?: string, attributes?: Object, context?: Object, parentPage?: View): ComponentModule {
161+
function loadCustomComponent(componentPath: string, componentName?: string, attributes?: Object, context?: Object, parentPage?: View, isRootComponent: boolean = true): ComponentModule {
162162
if (!parentPage && context) {
163163
// Read the parent page that was passed down below
164164
// https://github.com/NativeScript/NativeScript/issues/1639
@@ -211,7 +211,7 @@ function loadCustomComponent(componentPath: string, componentName?: string, attr
211211
}
212212
} else {
213213
// Custom components without XML
214-
result = getComponentModule(componentName, componentPath, attributes, context);
214+
result = getComponentModule(componentName, componentPath, attributes, context, undefined, isRootComponent);
215215
}
216216

217217
// webpack modules require paths to be relative to /app folder.
@@ -607,15 +607,15 @@ namespace xml2ui {
607607
private buildComponent(args: xml.ParserEvent): ComponentModule {
608608
if (args.prefix && args.namespace) {
609609
// Custom components
610-
return loadCustomComponent(args.namespace, args.elementName, args.attributes, this.context, this.currentRootView);
610+
return loadCustomComponent(args.namespace, args.elementName, args.attributes, this.context, this.currentRootView, !this.currentRootView);
611611
} else {
612612
// Default components
613613
let namespace = args.namespace;
614614
if (defaultNameSpaceMatcher.test(namespace || '')) {
615615
//Ignore the default ...tns.xsd namespace URL
616616
namespace = undefined;
617617
}
618-
return getComponentModule(args.elementName, namespace, args.attributes, this.context, this.moduleNamePath);
618+
return getComponentModule(args.elementName, namespace, args.attributes, this.context, this.moduleNamePath, !this.currentRootView);
619619
}
620620
}
621621

tns-core-modules/ui/builder/component-builder/component-builder.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import { View } from "../../core/view";
66

7-
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string): ComponentModule;
7+
export function getComponentModule(elementName: string, namespace: string, attributes: Object, exports: Object, moduleNamePath?: string, isRootComponent?: boolean): ComponentModule;
88
export function setPropertyValue(instance: View, instanceModuleExports: Object, pageExports: Object, propertyName: string, propertyValue: any): void;
99

1010
export interface ComponentModule {

tns-core-modules/ui/builder/component-builder/component-builder.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,16 @@ const applyComponentAttributes = profile("applyComponentAttributes", (instance:
174174
}
175175
});
176176

177-
export function getComponentModule(elementName: string, namespace: string, attributes: Object, moduleExports: Object, moduleNamePath?: string): ComponentModule {
177+
export function getComponentModule(elementName: string, namespace: string, attributes: Object, moduleExports: Object, moduleNamePath?: string, isRootComponent?: boolean): ComponentModule {
178178
// Support lower-case-dashed component declaration in the XML (https://github.com/NativeScript/NativeScript/issues/309).
179179
elementName = elementName.split("-").map(s => { return s[0].toUpperCase() + s.substring(1) }).join("");
180180

181181
const { instance, instanceModule } = createComponentInstance(elementName, namespace);
182182
moduleExports = getComponentModuleExports(instance, moduleExports, attributes);
183-
applyComponentCss(instance, moduleNamePath, attributes);
183+
if (isRootComponent) {
184+
applyComponentCss(instance, moduleNamePath, attributes);
185+
}
186+
184187
applyComponentAttributes(instance, instanceModule, moduleExports, attributes);
185188

186189
var componentModule;

tns-core-modules/ui/content-view/content-view.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ContentView as ContentViewDefinition } from ".";
2-
import { View, CustomLayoutView, AddChildFromBuilder, layout } from "../core/view";
2+
import { View, CustomLayoutView, AddChildFromBuilder, layout, isIOS } from "../core/view";
33

44
export * from "../core/view";
55

@@ -22,7 +22,7 @@ export class ContentView extends CustomLayoutView implements ContentViewDefiniti
2222
}
2323

2424
this._onContentChanged(oldView, value);
25-
if (oldView !== value) {
25+
if (isIOS && oldView !== value) {
2626
this.requestLayout();
2727
}
2828
}

tns-core-modules/ui/core/view-base/view-base.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,11 @@ export abstract class ViewBase extends Observable {
337337
*/
338338
public _isPaddingRelative: boolean;
339339
public _styleScope: any;
340+
341+
/**
342+
* @private
343+
*/
344+
_isStyleScopeHost: boolean;
340345

341346
/**
342347
* Determines the depth of suspended updates.

tns-core-modules/ui/core/view-base/view-base.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
178178
private _templateParent: ViewBase;
179179
private __nativeView: any;
180180
// private _disableNativeViewRecycling: boolean;
181+
181182
public domNode: dnm.DOMNode;
182183

183184
public recycleNativeView: "always" | "never" | "auto";
@@ -197,6 +198,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
197198
public _styleScope: ssm.StyleScope;
198199
public _suspendedUpdates: { [propertyName: string]: Property<ViewBase, any> | CssProperty<Style, any> | CssAnimationProperty<Style, any> };
199200
public _suspendNativeUpdatesCount: SuspendType;
201+
public _isStyleScopeHost: boolean;
200202

201203
// Dynamic properties.
202204
left: Length;
@@ -927,6 +929,12 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
927929
}
928930

929931
_inheritStyleScope(styleScope: ssm.StyleScope): void {
932+
// If we are styleScope don't inherit parent stylescope.
933+
// TODO: Consider adding parent scope and merge selectors.
934+
if (this._isStyleScopeHost) {
935+
return;
936+
}
937+
930938
if (this._styleScope !== styleScope) {
931939
this._styleScope = styleScope;
932940
this._onCssStateChange();

0 commit comments

Comments
 (0)