| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,5 @@ | |||
| 1 | + <Page loaded="onLoaded"> | ||
| 2 | + <StackLayout> | ||
| 3 | + <Button id="button" text="button"></Button> | ||
| 4 | + </StackLayout> | ||
| 5 | + </Page> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + export function onLoaded() { | ||
| 2 | + console.log("Button page loaded!"); | ||
| 3 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,5 @@ | |||
| 1 | + <Page loaded="onLoaded"> | ||
| 2 | + <StackLayout> | ||
| 3 | + <Button id="button" text="button"></Button> | ||
| 4 | + </StackLayout> | ||
| 5 | + </Page> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,3 @@ | |||
| 1 | + export function onLoaded() { | ||
| 2 | + console.log("Label page loaded!"); | ||
| 3 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,5 @@ | |||
| 1 | + <Page loaded="onLoaded"> | ||
| 2 | + <StackLayout> | ||
| 3 | + <Label id="label" text="label"></Label> | ||
| 4 | + </StackLayout> | ||
| 5 | + </Page> | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,36 +1,28 @@ | |||
| 1 | - import * as app from "tns-core-modules/application/application"; | ||
| 2 | - import * as frame from "tns-core-modules/ui/frame"; | ||
| 3 | 1 | import * as helper from "../ui/helper"; | |
| 4 | 2 | import * as TKUnit from "../TKUnit"; | |
| 3 | + | ||
| 4 | + import * as app from "tns-core-modules/application/application"; | ||
| 5 | + import * as frame from "tns-core-modules/ui/frame"; | ||
| 6 | + | ||
| 5 | 7 | import { Color } from "tns-core-modules/color"; | |
| 6 | - import { parse } from "tns-core-modules/ui/builder"; | ||
| 8 | + import { isAndroid } from "tns-core-modules/platform"; | ||
| 9 | + import { createViewFromEntry } from "tns-core-modules/ui/builder"; | ||
| 7 | 10 | import { Page } from "tns-core-modules/ui/page"; | |
| 11 | + import { Frame } from "tns-core-modules/ui/frame"; | ||
| 8 | 12 | ||
| 9 | 13 | const appCssFileName = "./app/application.css"; | |
| 10 | 14 | const appNewCssFileName = "./app/app-new.css"; | |
| 11 | 15 | const appNewScssFileName = "./app/app-new.scss"; | |
| 12 | - const appJsFileName = "./app/app.js"; | ||
| 13 | - const appTsFileName = "./app/app.ts"; | ||
| 14 | - const mainPageCssFileName = "./app/main-page.css"; | ||
| 15 | - const mainPageHtmlFileName = "./app/main-page.html"; | ||
| 16 | - const mainPageXmlFileName = "./app/main-page.xml"; | ||
| 17 | - | ||
| 18 | - const black = new Color("black"); | ||
| 19 | - const green = new Color("green"); | ||
| 16 | + const buttonCssFileName = "./app/button-page.css"; | ||
| 20 | 17 | ||
| 21 | - const mainPageTemplate = ` | ||
| 22 | - <Page> | ||
| 23 | - <StackLayout> | ||
| 24 | - <Label id="label" text="label"></Label> | ||
| 25 | - </StackLayout> | ||
| 26 | - </Page>`; | ||
| 18 | + const buttonPageModuleName = "livesync/livesync-button-page"; | ||
| 19 | + const buttonHtmlPageFileName = "./livesync/livesync-button-page.html"; | ||
| 20 | + const buttonXmlPageFileName = "./livesync/livesync-button-page.xml"; | ||
| 21 | + const buttonJsPageFileName = "./livesync/livesync-button-page.js"; | ||
| 22 | + const buttonTsPageFileName = "./livesync/livesync-button-page.ts"; | ||
| 23 | + const labelPageModuleName = "livesync/livesync-label-page"; | ||
| 27 | 24 | ||
| 28 | - const pageTemplate = ` | ||
| 29 | - <Page> | ||
| 30 | - <StackLayout> | ||
| 31 | - <Button id="button" text="button"></Button> | ||
| 32 | - </StackLayout> | ||
| 33 | - </Page>`; | ||
| 25 | + const green = new Color("green"); | ||
| 34 | 26 | ||
| 35 | 27 | export function test_onLiveSync_ModuleContext_AppStyle_AppNewCss() { | |
| 36 | 28 | _test_onLiveSync_ModuleContext_AppStyle(appNewCssFileName); | |
@@ -48,29 +40,29 @@ export function test_onLiveSync_ModuleContext_ModuleUndefined() { | |||
| 48 | 40 | _test_onLiveSync_ModuleContext({ type: "script", path: undefined }); | |
| 49 | 41 | } | |
| 50 | 42 | ||
| 51 | - export function test_onLiveSync_ModuleContext_Script_AppJs() { | ||
| 52 | - _test_onLiveSync_ModuleContext({ type: "script", path: appJsFileName }); | ||
| 43 | + export function test_onLiveSync_ModuleContext_Script_JsFile() { | ||
| 44 | + _test_onLiveSync_ModuleReplace({ type: "script", path: buttonJsPageFileName }); | ||
| 53 | 45 | } | |
| 54 | 46 | ||
| 55 | - export function test_onLiveSync_ModuleContext_Script_AppTs() { | ||
| 56 | - _test_onLiveSync_ModuleContext({ type: "script", path: appTsFileName }); | ||
| 47 | + export function test_onLiveSync_ModuleContext_Script_TsFile() { | ||
| 48 | + _test_onLiveSync_ModuleReplace({ type: "script", path: buttonTsPageFileName }); | ||
| 57 | 49 | } | |
| 58 | 50 | ||
| 59 | - export function test_onLiveSync_ModuleContext_Style_MainPageCss() { | ||
| 60 | - _test_onLiveSync_ModuleContext_TypeStyle({ type: "style", path: mainPageCssFileName }); | ||
| 51 | + export function test_onLiveSync_ModuleContext_Style_CssFile() { | ||
| 52 | + _test_onLiveSync_ModuleContext_TypeStyle({ type: "style", path: buttonCssFileName }); | ||
| 61 | 53 | } | |
| 62 | 54 | ||
| 63 | - export function test_onLiveSync_ModuleContext_Markup_MainPageHtml() { | ||
| 64 | - _test_onLiveSync_ModuleContext({ type: "markup", path: mainPageHtmlFileName }); | ||
| 55 | + export function test_onLiveSync_ModuleContext_Markup_HtmlFile() { | ||
| 56 | + _test_onLiveSync_ModuleReplace({ type: "markup", path: buttonHtmlPageFileName }); | ||
| 65 | 57 | } | |
| 66 | 58 | ||
| 67 | - export function test_onLiveSync_ModuleContext_Markup_MainPageXml() { | ||
| 68 | - _test_onLiveSync_ModuleContext({ type: "markup", path: mainPageXmlFileName }); | ||
| 59 | + export function test_onLiveSync_ModuleContext_Markup_XmlFile() { | ||
| 60 | + _test_onLiveSync_ModuleReplace({ type: "markup", path: buttonXmlPageFileName }); | ||
| 69 | 61 | } | |
| 70 | 62 | ||
| 71 | - export function setUpModule() { | ||
| 72 | - const mainPage = <Page>parse(mainPageTemplate); | ||
| 73 | - helper.navigate(() => mainPage); | ||
| 63 | + export function setUp() { | ||
| 64 | + const labelPage = <Page>createViewFromEntry(({ moduleName: labelPageModuleName })); | ||
| 65 | + helper.navigate(() => labelPage); | ||
| 74 | 66 | } | |
| 75 | 67 | ||
| 76 | 68 | export function tearDown() { | |
@@ -79,32 +71,29 @@ export function tearDown() { | |||
| 79 | 71 | ||
| 80 | 72 | function _test_onLiveSync_ModuleContext_AppStyle(styleFileName: string) { | |
| 81 | 73 | const pageBeforeNavigation = helper.getCurrentPage(); | |
| 74 | + const buttonPage = <Page>createViewFromEntry(({ moduleName: buttonPageModuleName })); | ||
| 75 | + helper.navigateWithHistory(() => buttonPage); | ||
| 82 | 76 | ||
| 83 | - const page = <Page>parse(pageTemplate); | ||
| 84 | - helper.navigateWithHistory(() => page); | ||
| 85 | 77 | app.setCssFileName(styleFileName); | |
| 86 | - | ||
| 87 | 78 | const pageBeforeLiveSync = helper.getCurrentPage(); | |
| 88 | 79 | global.__onLiveSync({ type: "style", path: styleFileName }); | |
| 89 | 80 | ||
| 90 | 81 | const pageAfterLiveSync = helper.getCurrentPage(); | |
| 91 | 82 | TKUnit.waitUntilReady(() => pageAfterLiveSync.getViewById("button").style.color.toString() === green.toString()); | |
| 92 | - | ||
| 93 | - TKUnit.assertTrue(pageAfterLiveSync.frame.canGoBack(), "App styles NOT applied - livesync navigation executed!"); | ||
| 94 | - TKUnit.assertEqual(pageAfterLiveSync, pageBeforeLiveSync, "Pages are different - livesync navigation executed!"); | ||
| 95 | - TKUnit.assertTrue(pageAfterLiveSync._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version NOT applied!"); | ||
| 83 | + TKUnit.assertTrue(pageAfterLiveSync.frame.canGoBack(), "Can NOT go back!"); | ||
| 84 | + TKUnit.assertEqual(pageAfterLiveSync, pageBeforeLiveSync, "Pages are different!"); | ||
| 85 | + TKUnit.assertTrue(pageAfterLiveSync._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version is NOT applied!"); | ||
| 96 | 86 | ||
| 97 | 87 | helper.goBack(); | |
| 98 | - | ||
| 99 | 88 | const pageAfterNavigationBack = helper.getCurrentPage(); | |
| 100 | 89 | TKUnit.assertEqual(pageAfterNavigationBack.getViewById("label").style.color, green, "App styles NOT applied on back navigation!"); | |
| 101 | - TKUnit.assertEqual(pageBeforeNavigation, pageAfterNavigationBack, "Pages are different - livesync navigation executed!"); | ||
| 90 | + TKUnit.assertEqual(pageBeforeNavigation, pageAfterNavigationBack, "Pages are different"); | ||
| 102 | 91 | TKUnit.assertTrue(pageAfterNavigationBack._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version is NOT applied!"); | |
| 103 | 92 | } | |
| 104 | 93 | ||
| 105 | 94 | function _test_onLiveSync_ModuleContext(context: { type, path }) { | |
| 106 | - const page = <Page>parse(pageTemplate); | ||
| 107 | - helper.navigateWithHistory(() => page); | ||
| 95 | + const buttonPage = <Page>createViewFromEntry(({ moduleName: buttonPageModuleName })); | ||
| 96 | + helper.navigateWithHistory(() => buttonPage); | ||
| 108 | 97 | global.__onLiveSync({ type: context.type, path: context.path }); | |
| 109 | 98 | ||
| 110 | 99 | TKUnit.waitUntilReady(() => !!frame.topmost()); | |
@@ -113,27 +102,53 @@ function _test_onLiveSync_ModuleContext(context: { type, path }) { | |||
| 113 | 102 | TKUnit.assertTrue(topmostFrame.currentPage.getViewById("label").isLoaded); | |
| 114 | 103 | } | |
| 115 | 104 | ||
| 116 | - function _test_onLiveSync_ModuleContext_TypeStyle(context: { type, path }) { | ||
| 105 | + function _test_onLiveSync_ModuleReplace(context: { type, path }) { | ||
| 117 | 106 | const pageBeforeNavigation = helper.getCurrentPage(); | |
| 107 | + const buttonPage = <Page>createViewFromEntry(({ moduleName: buttonPageModuleName })); | ||
| 108 | + helper.navigateWithHistory(() => buttonPage); | ||
| 109 | + | ||
| 110 | + global.__onLiveSync({ type: context.type, path: context.path }); | ||
| 111 | + const topmostFrame = frame.topmost(); | ||
| 112 | + waitUntilLivesyncComplete(topmostFrame); | ||
| 113 | + TKUnit.assertTrue(topmostFrame.currentPage.getViewById("button").isLoaded, "Button page is NOT loaded!"); | ||
| 114 | + TKUnit.assertEqual(topmostFrame.backStack.length, 1, "Backstack is clean!"); | ||
| 115 | + TKUnit.assertTrue(topmostFrame.canGoBack(), "Can NOT go back!"); | ||
| 118 | 116 | ||
| 119 | - const page = <Page>parse(pageTemplate); | ||
| 120 | - helper.navigateWithHistory(() => page); | ||
| 117 | + helper.goBack(); | ||
| 118 | + const pageAfterBackNavigation = helper.getCurrentPage(); | ||
| 119 | + TKUnit.assertTrue(topmostFrame.currentPage.getViewById("label").isLoaded, "Label page is NOT loaded!"); | ||
| 120 | + TKUnit.assertEqual(topmostFrame.backStack.length, 0, "Backstack is NOT clean!"); | ||
| 121 | + TKUnit.assertEqual(pageBeforeNavigation, pageAfterBackNavigation, "Pages are different!"); | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + function _test_onLiveSync_ModuleContext_TypeStyle(context: { type, path }) { | ||
| 125 | + const pageBeforeNavigation = helper.getCurrentPage(); | ||
| 126 | + const buttonPage = <Page>createViewFromEntry(({ moduleName: buttonPageModuleName })); | ||
| 127 | + helper.navigateWithHistory(() => buttonPage); | ||
| 121 | 128 | ||
| 122 | 129 | const pageBeforeLiveSync = helper.getCurrentPage(); | |
| 123 | - pageBeforeLiveSync._moduleName = "main-page"; | ||
| 130 | + pageBeforeLiveSync._moduleName = "button-page"; | ||
| 131 | + | ||
| 124 | 132 | global.__onLiveSync({ type: context.type, path: context.path }); | |
| 133 | + const topmostFrame = frame.topmost(); | ||
| 134 | + waitUntilLivesyncComplete(topmostFrame); | ||
| 125 | 135 | ||
| 126 | 136 | const pageAfterLiveSync = helper.getCurrentPage(); | |
| 127 | 137 | 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!"); | ||
| 138 | + TKUnit.assertTrue(pageAfterLiveSync.frame.canGoBack(), "Can NOT go back!"); | ||
| 139 | + TKUnit.assertEqual(topmostFrame.backStack.length, 1, "Backstack is clean!"); | ||
| 140 | + TKUnit.assertTrue(pageAfterLiveSync._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version is NOT applied!"); | ||
| 132 | 141 | ||
| 133 | 142 | helper.goBack(); | |
| 134 | - | ||
| 135 | 143 | 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!"); | ||
| 144 | + TKUnit.assertEqual(pageBeforeNavigation, pageAfterNavigationBack, "Pages are different!"); | ||
| 138 | 145 | TKUnit.assertTrue(pageAfterNavigationBack._cssState.isSelectorsLatestVersionApplied(), "Latest selectors version is NOT applied!"); | |
| 139 | - } | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + function waitUntilLivesyncComplete(frame: Frame) { | ||
| 149 | + if (isAndroid) { | ||
| 150 | + TKUnit.waitUntilReady(() => frame._executingEntry === null); | ||
| 151 | + } else { | ||
| 152 | + TKUnit.waitUntilReady(() => frame.currentPage.isLoaded); | ||
| 153 | + } | ||
| 154 | + } | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -5,11 +5,11 @@ | |||
| 5 | 5 | "repository": "<fill-your-repository-here>", | |
| 6 | 6 | "nativescript": { | |
| 7 | 7 | "id": "org.nativescript.UnitTestApp", | |
| 8 | - "tns-ios": { | ||
| 9 | - "version": "5.2.0" | ||
| 10 | - }, | ||
| 11 | 8 | "tns-android": { | |
| 12 | - "version": "5.2.1" | ||
| 9 | + "version": "5.3.1" | ||
| 10 | + }, | ||
| 11 | + "tns-ios": { | ||
| 12 | + "version": "5.3.1" | ||
| 13 | 13 | } | |
| 14 | 14 | }, | |
| 15 | 15 | "dependencies": { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -83,22 +83,20 @@ export function livesync(rootView: View, context?: ModuleContext) { | |||
| 83 | 83 | events.notify(<EventData>{ eventName: "livesync", object: app }); | |
| 84 | 84 | const liveSyncCore = global.__onLiveSyncCore; | |
| 85 | 85 | let reapplyAppStyles = false; | |
| 86 | - let reapplyLocalStyles = false; | ||
| 87 | 86 | ||
| 87 | + // ModuleContext is available only for Hot Module Replacement | ||
| 88 | 88 | if (context && context.path) { | |
| 89 | - const extensions = ["css", "scss"]; | ||
| 89 | + const styleExtensions = ["css", "scss"]; | ||
| 90 | 90 | const appStylesFullFileName = getCssFileName(); | |
| 91 | 91 | const appStylesFileName = appStylesFullFileName.substring(0, appStylesFullFileName.lastIndexOf(".") + 1); | |
| 92 | - reapplyAppStyles = extensions.some(ext => context.path === appStylesFileName.concat(ext)); | ||
| 93 | - if (!reapplyAppStyles) { | ||
| 94 | - reapplyLocalStyles = extensions.some(ext => context.path.endsWith(ext)); | ||
| 95 | - } | ||
| 92 | + reapplyAppStyles = styleExtensions.some(ext => context.path === appStylesFileName.concat(ext)); | ||
| 96 | 93 | } | |
| 97 | 94 | ||
| 95 | + // Handle application styles | ||
| 98 | 96 | if (reapplyAppStyles && rootView) { | |
| 99 | 97 | rootView._onCssStateChange(); | |
| 100 | 98 | } else if (liveSyncCore) { | |
| 101 | - reapplyLocalStyles ? liveSyncCore(context) : liveSyncCore(); | ||
| 99 | + liveSyncCore(context); | ||
| 102 | 100 | } | |
| 103 | 101 | } | |
| 104 | 102 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -10,6 +10,7 @@ import { | |||
| 10 | 10 | notify, launchEvent, resumeEvent, suspendEvent, exitEvent, lowMemoryEvent, | |
| 11 | 11 | orientationChangedEvent, setApplication, livesync, displayedEvent, getCssFileName | |
| 12 | 12 | } from "./application-common"; | |
| 13 | + import { ModuleType } from "../ui/core/view/view-common"; | ||
| 13 | 14 | ||
| 14 | 15 | // First reexport so that app module is initialized. | |
| 15 | 16 | export * from "./application-common"; | |
@@ -106,6 +107,7 @@ class IOSApplication implements IOSApplicationDefinition { | |||
| 106 | 107 | get delegate(): typeof UIApplicationDelegate { | |
| 107 | 108 | return this._delegate; | |
| 108 | 109 | } | |
| 110 | + | ||
| 109 | 111 | set delegate(value: typeof UIApplicationDelegate) { | |
| 110 | 112 | if (this._delegate !== value) { | |
| 111 | 113 | this._delegate = value; | |
@@ -228,8 +230,16 @@ class IOSApplication implements IOSApplicationDefinition { | |||
| 228 | 230 | } | |
| 229 | 231 | ||
| 230 | 232 | public _onLivesync(context?: ModuleContext): void { | |
| 231 | - // If view can't handle livesync set window controller. | ||
| 232 | - if (this._rootView && !this._rootView._onLivesync(context)) { | ||
| 233 | + // Handle application root module | ||
| 234 | + const isAppRootModuleChanged = context && context.path && context.path.includes(getMainEntry().moduleName) && context.type !== ModuleType.style; | ||
| 235 | + | ||
| 236 | + // Set window content when: | ||
| 237 | + // + Application root module is changed | ||
| 238 | + // + View did not handle the change | ||
| 239 | + // Note: | ||
| 240 | + // The case when neither app root module is changed, nor livesync is handled on View, | ||
| 241 | + // then changes will not apply until navigate forward to the module. | ||
| 242 | + if (isAppRootModuleChanged || (this._rootView && !this._rootView._onLivesync(context))) { | ||
| 233 | 243 | this.setWindowContent(); | |
| 234 | 244 | } | |
| 235 | 245 | } | |
@@ -258,7 +268,6 @@ class IOSApplication implements IOSApplicationDefinition { | |||
| 258 | 268 | this._window.makeKeyAndVisible(); | |
| 259 | 269 | } | |
| 260 | 270 | } | |
| 261 | - | ||
| 262 | 271 | } | |
| 263 | 272 | ||
| 264 | 273 | const iosApp = new IOSApplication(); | |
| Back | FazBrowse Home | New Git URL |
0 commit comments