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

feat(HMR): style view at runtime · NativeScript/NativeScript@f490652 · GitHub

Commit f490652

Browse files
committed
feat(HMR): style view at runtime
test: module root view comopnent test: update livesync tests refactor: _onLivesync function
1 parent d28ba02 commit f490652

11 files changed

Lines changed: 152 additions & 50 deletions

File tree

‎tests/app/app/main-page.css‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
Button
2+
/*
3+
TODO: uncomment and investigate a livesync test failure
4+
, Label */
5+
{
6+
color: green;
7+
}

‎tests/app/livesync/livesync-tests.ts‎

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const mainPageCssFileName = "./app/main-page.css";
1515
const mainPageHtmlFileName = "./app/main-page.html";
1616
const mainPageXmlFileName = "./app/main-page.xml";
1717

18+
const black = new Color("black");
1819
const green = new Color("green");
1920

2021
const mainPageTemplate = `
@@ -56,7 +57,7 @@ export function test_onLiveSync_ModuleContext_Script_AppTs() {
5657
}
5758

5859
export function test_onLiveSync_ModuleContext_Style_MainPageCss() {
59-
_test_onLiveSync_ModuleContext({ type: "style", path: mainPageCssFileName });
60+
_test_onLiveSync_ModuleContext_TypeStyle({ type: "style", path: mainPageCssFileName });
6061
}
6162

6263
export function test_onLiveSync_ModuleContext_Markup_MainPageHtml() {
@@ -110,4 +111,29 @@ function _test_onLiveSync_ModuleContext(context: { type, path }) {
110111
const topmostFrame = frame.topmost();
111112
TKUnit.waitUntilReady(() => topmostFrame.currentPage && topmostFrame.currentPage.isLoaded && !topmostFrame.canGoBack());
112113
TKUnit.assertTrue(topmostFrame.currentPage.getViewById("label").isLoaded);
114+
}
115+
116+
function _test_onLiveSync_ModuleContext_TypeStyle(context: { type, path }) {
117+
const pageBeforeNavigation = helper.getCurrentPage();
118+
119+
const page = <Page>parse(pageTemplate);
120+
helper.navigateWithHistory(() => page);
121+
122+
const pageBeforeLiveSync = helper.getCurrentPage();
123+
pageBeforeLiveSync._rootOfModule = "main-page";
124+
global.__onLiveSync({ type: context.type, path: context.path });
125+
126+
const pageAfterLiveSync = helper.getCurrentPage();
127+
TKUnit.waitUntilReady(() => pageAfterLiveSync.getViewById("button").style.color.toString() === green.toString());
128+
129+
TKUnit.assertTrue(pageAfterLiveSync.frame.canGoBack(), "Local styles NOT applied - livesync navigation executed!");
130+
TKUnit.assertEqual(pageAfterLiveSync, pageBeforeLiveSync, "Pages are different - livesync navigation executed!");
131+
TKUnit.assertTrue(pageAfterLiveSync._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version NOT applied!");
132+
133+
helper.goBack();
134+
135+
const pageAfterNavigationBack = helper.getCurrentPage();
136+
TKUnit.assertEqual(pageAfterNavigationBack.getViewById("label").style.color, black, "App styles applied on back navigation!");
137+
TKUnit.assertEqual(pageBeforeNavigation, pageAfterNavigationBack, "Pages are different - livesync navigation executed!");
138+
TKUnit.assertTrue(pageAfterNavigationBack._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version is NOT applied!");
113139
}

‎tests/app/testRunner.ts‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,15 @@ allTests["VISUAL-STATE"] = visualStateTests;
168168
import * as valueSourceTests from "./ui/styling/value-source-tests";
169169
allTests["VALUE-SOURCE"] = valueSourceTests;
170170

171-
import * as buttonTests from "./ui/button/button-tests";
172-
allTests["BUTTON"] = buttonTests;
173-
174171
import * as borderTests from "./ui/border/border-tests";
175172
allTests["BORDER"] = borderTests;
176173

174+
import * as builderTests from "./ui/builder/builder-tests";
175+
allTests["BUILDER"] = builderTests;
176+
177+
import * as buttonTests from "./ui/button/button-tests";
178+
allTests["BUTTON"] = buttonTests;
179+
177180
import * as labelTests from "./ui/label/label-tests";
178181
allTests["LABEL"] = labelTests;
179182

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { path } from "tns-core-modules/file-system";
2+
import { loadPage } from "tns-core-modules/ui/builder";
3+
import { assertEqual, assertNull } from "../../TKUnit";
4+
5+
const COMPONENT_MODULE = "component-module";
6+
const LABEL = "label";
7+
8+
function getViewComponent() {
9+
const moduleNamePath = path.join(__dirname, COMPONENT_MODULE);
10+
const fileName = path.join(__dirname, `${COMPONENT_MODULE}.xml`);
11+
const view = loadPage(moduleNamePath, fileName);
12+
return view;
13+
}
14+
15+
export function test_view_is_module_root_component() {
16+
const view = getViewComponent();
17+
const actualModule = view._rootOfModule;
18+
assertEqual(actualModule, COMPONENT_MODULE, `View<${view}> is NOT root component of module <${COMPONENT_MODULE}>.`);
19+
}
20+
21+
export function test_view_is_NOT_module_root_component() {
22+
const view = getViewComponent();
23+
const nestedView = view.getViewById(`${LABEL}`);
24+
const undefinedModule = nestedView._rootOfModule;
25+
assertNull(undefinedModule, `View<${nestedView}> should NOT be a root component of a module.`);
26+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<StackLayout>
2+
<Label id="label"></Label>
3+
</StackLayout>

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ export function load(pathOrOptions: string | LoadOptions, context?: any): View {
5959

6060
export function loadPage(moduleNamePath: string, fileName: string, context?: any): View {
6161
const componentModule = loadInternal(fileName, context, moduleNamePath);
62-
return componentModule && componentModule.component;
62+
const componentView = componentModule && componentModule.component;
63+
setRootOfModule(componentView, moduleNamePath);
64+
return componentView;
6365
}
6466

6567
const loadModule = profile("loadModule", (moduleNamePath: string, entry: ViewEntry): ModuleExports => {
@@ -96,7 +98,7 @@ export const createViewFromEntry = profile("createViewFromEntry", (entry: ViewEn
9698
} else if (entry.moduleName) {
9799
// Current app full path.
98100
const currentAppPath = knownFolders.currentApp().path;
99-
101+
100102
// Full path of the module = current app full path + module name.
101103
const moduleNamePath = path.join(currentAppPath, entry.moduleName);
102104
const moduleExports = loadModule(moduleNamePath, entry);
@@ -108,7 +110,7 @@ export const createViewFromEntry = profile("createViewFromEntry", (entry: ViewEn
108110
return viewFromBuilder(moduleNamePath, moduleExports);
109111
}
110112
}
111-
113+
112114
throw new Error("Failed to load page XML file for module: " + entry.moduleName);
113115
});
114116

@@ -128,14 +130,20 @@ interface ModuleExports {
128130
const moduleCreateView = profile("module.createView", (moduleNamePath: string, moduleExports: ModuleExports): View => {
129131
const view = moduleExports.createPage();
130132
const cssFileName = resolveFileName(moduleNamePath, "css");
131-
133+
132134
// If there is no cssFile only appCss will be applied at loaded.
133135
if (cssFileName) {
134136
view.addCssFile(cssFileName);
135137
}
136138
return view;
137139
});
138140

141+
function setRootOfModule(componentView: View, moduleNamePath: string): void {
142+
const lastIndexOfSeparator = moduleNamePath.lastIndexOf(path.separator);
143+
const moduleName = moduleNamePath.substring(lastIndexOfSeparator + 1);
144+
componentView._rootOfModule = moduleName;
145+
}
146+
139147
function loadInternal(fileName: string, context?: any, moduleNamePath?: string): ComponentModule {
140148
let componentModule: ComponentModule;
141149

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,12 @@ export abstract class ViewBase extends Observable {
108108
flexWrapBefore: FlexWrapBefore;
109109
alignSelf: AlignSelf;
110110

111+
/**
112+
* @private
113+
* Module name when the view is a module root. Otherwise, it is undefined.
114+
*/
115+
_rootOfModule?: string;
116+
111117
//@private
112118
/**
113119
* @private

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,8 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
244244
public _defaultPaddingLeft: number;
245245
public _isPaddingRelative: boolean;
246246

247+
public _rootOfModule: string;
248+
247249
constructor() {
248250
super();
249251
this._domId = viewIdCounter++;
@@ -651,7 +653,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
651653
}
652654

653655
public resetNativeView(): void {
654-
//
656+
//
655657
}
656658

657659
private resetNativeViewInternal(): void {
@@ -688,7 +690,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
688690

689691
this._context = context;
690692

691-
// This will account for nativeView that is created in createNativeView, recycled
693+
// This will account for nativeView that is created in createNativeView, recycled
692694
// or for backward compatability - set before _setupUI in iOS contructor.
693695
let nativeView = this.nativeViewProtected;
694696

‎tns-core-modules/ui/core/view/view-common.ts‎

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
ViewBase, Property, booleanConverter, EventData, layout,
99
getEventOrGestureName, traceEnabled, traceWrite, traceCategories,
1010
InheritedProperty,
11-
ShowModalOptions
11+
ShowModalOptions,
12+
eachDescendant
1213
} from "../view-base";
1314

1415
import { HorizontalAlignment, VerticalAlignment, Visibility, Length, PercentLength } from "../../styling/style-properties";
@@ -136,6 +137,36 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
136137
}
137138
}
138139

140+
public _onLivesync(context?: ModuleContext): boolean {
141+
_rootModalViews.forEach(v => v.closeModal());
142+
_rootModalViews.length = 0;
143+
144+
// Currently, we pass `context` only for style modules
145+
if (context && context.path) {
146+
return this.changeLocalStyles(context.path);
147+
}
148+
149+
return false;
150+
}
151+
152+
private changeLocalStyles(contextPath: string): boolean {
153+
if (!this.changeStyles(this, contextPath)) {
154+
eachDescendant(this, (child: ViewBase) => {
155+
this.changeStyles(child, contextPath);
156+
return true;
157+
});
158+
}
159+
return true;
160+
}
161+
162+
private changeStyles(view: ViewBase, contextPath: string): boolean {
163+
if (view._rootOfModule && contextPath.includes(view._rootOfModule)) {
164+
(<this>view).changeCssFile(contextPath);
165+
return true;
166+
}
167+
return false;
168+
}
169+
139170
_setupAsRootView(context: any): void {
140171
super._setupAsRootView(context);
141172
if (!this._styleScope) {
@@ -210,12 +241,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition {
210241
}
211242
}
212243

213-
_onLivesync(): boolean {
214-
_rootModalViews.forEach(v => v.closeModal());
215-
_rootModalViews.length = 0;
216-
return false;
217-
}
218-
219244
public onBackPressed(): boolean {
220245
return false;
221246
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -720,6 +720,12 @@ export abstract class View extends ViewBase {
720720
* __Obsolete:__ There is a new property system that does not rely on _setValue.
721721
*/
722722
_setValue(property: any, value: any): never;
723+
724+
/**
725+
* @private
726+
* Module name in case the view is a root. Otherwise, it is undefined.
727+
*/
728+
_rootOfModule?: string;
723729
}
724730

725731
/**

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL