| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 451026f commit 3c2c1d9
10 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + Button { | ||
| 2 | + color: green; | ||
| 3 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,6 +15,7 @@ const mainPageCssFileName = "./app/main-page.css"; | |||
| 15 | 15 | const mainPageHtmlFileName = "./app/main-page.html"; | |
| 16 | 16 | const mainPageXmlFileName = "./app/main-page.xml"; | |
| 17 | 17 | ||
| 18 | + const black = new Color("black"); | ||
| 18 | 19 | const green = new Color("green"); | |
| 19 | 20 | ||
| 20 | 21 | const mainPageTemplate = ` | |
@@ -56,7 +57,7 @@ export function test_onLiveSync_ModuleContext_Script_AppTs() { | |||
| 56 | 57 | } | |
| 57 | 58 | ||
| 58 | 59 | export function test_onLiveSync_ModuleContext_Style_MainPageCss() { | |
| 59 | - _test_onLiveSync_ModuleContext({ type: "style", path: mainPageCssFileName }); | ||
| 60 | + _test_onLiveSync_ModuleContext_TypeStyle({ type: "style", path: mainPageCssFileName }); | ||
| 60 | 61 | } | |
| 61 | 62 | ||
| 62 | 63 | export function test_onLiveSync_ModuleContext_Markup_MainPageHtml() { | |
@@ -110,4 +111,29 @@ function _test_onLiveSync_ModuleContext(context: { type, path }) { | |||
| 110 | 111 | const topmostFrame = frame.topmost(); | |
| 111 | 112 | TKUnit.waitUntilReady(() => topmostFrame.currentPage && topmostFrame.currentPage.isLoaded && !topmostFrame.canGoBack()); | |
| 112 | 113 | 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._moduleName = "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!"); | ||
| 113 | 139 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -168,12 +168,15 @@ allTests["VISUAL-STATE"] = visualStateTests; | |||
| 168 | 168 | import * as valueSourceTests from "./ui/styling/value-source-tests"; | |
| 169 | 169 | allTests["VALUE-SOURCE"] = valueSourceTests; | |
| 170 | 170 | ||
| 171 | - import * as buttonTests from "./ui/button/button-tests"; | ||
| 172 | - allTests["BUTTON"] = buttonTests; | ||
| 173 | - | ||
| 174 | 171 | import * as borderTests from "./ui/border/border-tests"; | |
| 175 | 172 | allTests["BORDER"] = borderTests; | |
| 176 | 173 | ||
| 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 | + | ||
| 177 | 180 | import * as labelTests from "./ui/label/label-tests"; | |
| 178 | 181 | allTests["LABEL"] = labelTests; | |
| 179 | 182 | ||
| Original file line number | Diff line number | Diff 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._moduleName; | ||
| 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._moduleName; | ||
| 25 | + assertNull(undefinedModule, `View<${nestedView}> should NOT be a root component of a module.`); | ||
| 26 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + <StackLayout> | ||
| 2 | + <Label id="label"></Label> | ||
| 3 | + </StackLayout> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -59,7 +59,9 @@ export function load(pathOrOptions: string | LoadOptions, context?: any): View { | |||
| 59 | 59 | ||
| 60 | 60 | export function loadPage(moduleNamePath: string, fileName: string, context?: any): View { | |
| 61 | 61 | const componentModule = loadInternal(fileName, context, moduleNamePath); | |
| 62 | - return componentModule && componentModule.component; | ||
| 62 | + const componentView = componentModule && componentModule.component; | ||
| 63 | + markAsModuleRoot(componentView, moduleNamePath); | ||
| 64 | + return componentView; | ||
| 63 | 65 | } | |
| 64 | 66 | ||
| 65 | 67 | const loadModule = profile("loadModule", (moduleNamePath: string, entry: ViewEntry): ModuleExports => { | |
@@ -96,7 +98,7 @@ export const createViewFromEntry = profile("createViewFromEntry", (entry: ViewEn | |||
| 96 | 98 | } else if (entry.moduleName) { | |
| 97 | 99 | // Current app full path. | |
| 98 | 100 | const currentAppPath = knownFolders.currentApp().path; | |
| 99 | - | ||
| 101 | + | ||
| 100 | 102 | // Full path of the module = current app full path + module name. | |
| 101 | 103 | const moduleNamePath = path.join(currentAppPath, entry.moduleName); | |
| 102 | 104 | const moduleExports = loadModule(moduleNamePath, entry); | |
@@ -108,7 +110,7 @@ export const createViewFromEntry = profile("createViewFromEntry", (entry: ViewEn | |||
| 108 | 110 | return viewFromBuilder(moduleNamePath, moduleExports); | |
| 109 | 111 | } | |
| 110 | 112 | } | |
| 111 | - | ||
| 113 | + | ||
| 112 | 114 | throw new Error("Failed to load page XML file for module: " + entry.moduleName); | |
| 113 | 115 | }); | |
| 114 | 116 | ||
@@ -128,14 +130,20 @@ interface ModuleExports { | |||
| 128 | 130 | const moduleCreateView = profile("module.createView", (moduleNamePath: string, moduleExports: ModuleExports): View => { | |
| 129 | 131 | const view = moduleExports.createPage(); | |
| 130 | 132 | const cssFileName = resolveFileName(moduleNamePath, "css"); | |
| 131 | - | ||
| 133 | + | ||
| 132 | 134 | // If there is no cssFile only appCss will be applied at loaded. | |
| 133 | 135 | if (cssFileName) { | |
| 134 | 136 | view.addCssFile(cssFileName); | |
| 135 | 137 | } | |
| 136 | 138 | return view; | |
| 137 | 139 | }); | |
| 138 | 140 | ||
| 141 | + function markAsModuleRoot(componentView: View, moduleNamePath: string): void { | ||
| 142 | + const lastIndexOfSeparator = moduleNamePath.lastIndexOf(path.separator); | ||
| 143 | + const moduleName = moduleNamePath.substring(lastIndexOfSeparator + 1); | ||
| 144 | + componentView._moduleName = moduleName; | ||
| 145 | + } | ||
| 146 | + | ||
| 139 | 147 | function loadInternal(fileName: string, context?: any, moduleNamePath?: string): ComponentModule { | |
| 140 | 148 | let componentModule: ComponentModule; | |
| 141 | 149 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -108,6 +108,12 @@ export abstract class ViewBase extends Observable { | |||
| 108 | 108 | flexWrapBefore: FlexWrapBefore; | |
| 109 | 109 | alignSelf: AlignSelf; | |
| 110 | 110 | ||
| 111 | + /** | ||
| 112 | + * @private | ||
| 113 | + * Module name when the view is a module root. Otherwise, it is undefined. | ||
| 114 | + */ | ||
| 115 | + _moduleName?: string; | ||
| 116 | + | ||
| 111 | 117 | //@private | |
| 112 | 118 | /** | |
| 113 | 119 | * @private | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -244,6 +244,8 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition | |||
| 244 | 244 | public _defaultPaddingLeft: number; | |
| 245 | 245 | public _isPaddingRelative: boolean; | |
| 246 | 246 | ||
| 247 | + public _moduleName: string; | ||
| 248 | + | ||
| 247 | 249 | constructor() { | |
| 248 | 250 | super(); | |
| 249 | 251 | this._domId = viewIdCounter++; | |
@@ -651,7 +653,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition | |||
| 651 | 653 | } | |
| 652 | 654 | ||
| 653 | 655 | public resetNativeView(): void { | |
| 654 | - // | ||
| 656 | + // | ||
| 655 | 657 | } | |
| 656 | 658 | ||
| 657 | 659 | private resetNativeViewInternal(): void { | |
@@ -688,7 +690,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition | |||
| 688 | 690 | ||
| 689 | 691 | this._context = context; | |
| 690 | 692 | ||
| 691 | - // This will account for nativeView that is created in createNativeView, recycled | ||
| 693 | + // This will account for nativeView that is created in createNativeView, recycled | ||
| 692 | 694 | // or for backward compatability - set before _setupUI in iOS contructor. | |
| 693 | 695 | let nativeView = this.nativeViewProtected; | |
| 694 | 696 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,7 +5,7 @@ import { | |||
| 5 | 5 | } from "."; | |
| 6 | 6 | ||
| 7 | 7 | import { | |
| 8 | - ViewBase, Property, booleanConverter, EventData, layout, | ||
| 8 | + ViewBase, Property, booleanConverter, eachDescendant, EventData, layout, | ||
| 9 | 9 | getEventOrGestureName, traceEnabled, traceWrite, traceCategories, | |
| 10 | 10 | InheritedProperty, | |
| 11 | 11 | ShowModalOptions | |
@@ -136,6 +136,37 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { | |||
| 136 | 136 | } | |
| 137 | 137 | } | |
| 138 | 138 | ||
| 139 | + public _onLivesync(context?: ModuleContext): boolean { | ||
| 140 | + _rootModalViews.forEach(v => v.closeModal()); | ||
| 141 | + _rootModalViews.length = 0; | ||
| 142 | + | ||
| 143 | + // Currently, we pass `context` only for style modules | ||
| 144 | + if (context && context.path) { | ||
| 145 | + return this.changeLocalStyles(context.path); | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + return false; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + private changeLocalStyles(contextPath: string): boolean { | ||
| 152 | + if (!this.changeStyles(this, contextPath)) { | ||
| 153 | + eachDescendant(this, (child: ViewBase) => { | ||
| 154 | + this.changeStyles(child, contextPath); | ||
| 155 | + return true; | ||
| 156 | + }); | ||
| 157 | + } | ||
| 158 | + // Do not execute frame navigation for a change in styles | ||
| 159 | + return true; | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + private changeStyles(view: ViewBase, contextPath: string): boolean { | ||
| 163 | + if (view._moduleName && contextPath.includes(view._moduleName)) { | ||
| 164 | + (<this>view).changeCssFile(contextPath); | ||
| 165 | + return true; | ||
| 166 | + } | ||
| 167 | + return false; | ||
| 168 | + } | ||
| 169 | + | ||
| 139 | 170 | _setupAsRootView(context: any): void { | |
| 140 | 171 | super._setupAsRootView(context); | |
| 141 | 172 | if (!this._styleScope) { | |
@@ -210,12 +241,6 @@ export abstract class ViewCommon extends ViewBase implements ViewDefinition { | |||
| 210 | 241 | } | |
| 211 | 242 | } | |
| 212 | 243 | ||
| 213 | - _onLivesync(): boolean { | ||
| 214 | - _rootModalViews.forEach(v => v.closeModal()); | ||
| 215 | - _rootModalViews.length = 0; | ||
| 216 | - return false; | ||
| 217 | - } | ||
| 218 | - | ||
| 219 | 244 | public onBackPressed(): boolean { | |
| 220 | 245 | return false; | |
| 221 | 246 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -564,44 +564,34 @@ export class FrameBase extends CustomLayoutView implements FrameDefinition { | |||
| 564 | 564 | } | |
| 565 | 565 | ||
| 566 | 566 | public _onLivesync(context?: ModuleContext): boolean { | |
| 567 | - super._onLivesync(); | ||
| 568 | - | ||
| 569 | - if (!this._currentEntry || !this._currentEntry.entry) { | ||
| 570 | - return false; | ||
| 571 | - } | ||
| 572 | - | ||
| 573 | - const currentEntry = this._currentEntry.entry; | ||
| 574 | - if (context && context.path) { | ||
| 575 | - // Use topmost instead of this to cover nested frames scenario | ||
| 576 | - const topmostFrame = topmost(); | ||
| 577 | - const moduleName = topmostFrame.currentEntry.moduleName; | ||
| 578 | - const reapplyStyles = context.path.includes(moduleName); | ||
| 579 | - if (reapplyStyles && moduleName) { | ||
| 580 | - topmostFrame.currentPage.changeCssFile(context.path); | ||
| 581 | - return true; | ||
| 567 | + // Execute a navigation if not handled on `View` level | ||
| 568 | + if (!super._onLivesync(context)) { | ||
| 569 | + if (!this._currentEntry || !this._currentEntry.entry) { | ||
| 570 | + return false; | ||
| 582 | 571 | } | |
| 583 | - } | ||
| 584 | 572 | ||
| 585 | - const newEntry: NavigationEntry = { | ||
| 586 | - animated: false, | ||
| 587 | - clearHistory: true, | ||
| 588 | - context: currentEntry.context, | ||
| 589 | - create: currentEntry.create, | ||
| 590 | - moduleName: currentEntry.moduleName, | ||
| 591 | - backstackVisible: currentEntry.backstackVisible | ||
| 592 | - } | ||
| 573 | + const currentEntry = this._currentEntry.entry; | ||
| 574 | + const newEntry: NavigationEntry = { | ||
| 575 | + animated: false, | ||
| 576 | + clearHistory: true, | ||
| 577 | + context: currentEntry.context, | ||
| 578 | + create: currentEntry.create, | ||
| 579 | + moduleName: currentEntry.moduleName, | ||
| 580 | + backstackVisible: currentEntry.backstackVisible | ||
| 581 | + } | ||
| 593 | 582 | ||
| 594 | - // If create returns the same page instance we can't recreate it. | ||
| 595 | - // Instead of navigation set activity content. | ||
| 596 | - // This could happen if current page was set in XML as a Page instance. | ||
| 597 | - if (newEntry.create) { | ||
| 598 | - const page = newEntry.create(); | ||
| 599 | - if (page === this.currentPage) { | ||
| 600 | - return false; | ||
| 583 | + // If create returns the same page instance we can't recreate it. | ||
| 584 | + // Instead of navigation set activity content. | ||
| 585 | + // This could happen if current page was set in XML as a Page instance. | ||
| 586 | + if (newEntry.create) { | ||
| 587 | + const page = newEntry.create(); | ||
| 588 | + if (page === this.currentPage) { | ||
| 589 | + return false; | ||
| 590 | + } | ||
| 601 | 591 | } | |
| 602 | - } | ||
| 603 | 592 | ||
| 604 | - this.navigate(newEntry); | ||
| 593 | + this.navigate(newEntry); | ||
| 594 | + } | ||
| 605 | 595 | return true; | |
| 606 | 596 | } | |
| 607 | 597 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments