mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-11-05 13:26:48 +08:00
refactor(HMR): apply changes in application styles at runtime
This commit is contained in:
@@ -32,7 +32,14 @@ export function hasLaunched(): boolean {
|
|||||||
|
|
||||||
export { Observable };
|
export { Observable };
|
||||||
|
|
||||||
import { UnhandledErrorEventData, iOSApplication, AndroidApplication, CssChangedEventData, LoadAppCSSEventData } from ".";
|
import {
|
||||||
|
AndroidApplication,
|
||||||
|
CssChangedEventData,
|
||||||
|
getRootView,
|
||||||
|
iOSApplication,
|
||||||
|
LoadAppCSSEventData,
|
||||||
|
UnhandledErrorEventData
|
||||||
|
} from "./application";
|
||||||
|
|
||||||
export { UnhandledErrorEventData, CssChangedEventData, LoadAppCSSEventData };
|
export { UnhandledErrorEventData, CssChangedEventData, LoadAppCSSEventData };
|
||||||
|
|
||||||
@@ -73,8 +80,19 @@ export function setApplication(instance: iOSApplication | AndroidApplication): v
|
|||||||
export function livesync(context?: HmrContext) {
|
export function livesync(context?: HmrContext) {
|
||||||
events.notify(<EventData>{ eventName: "livesync", object: app });
|
events.notify(<EventData>{ eventName: "livesync", object: app });
|
||||||
const liveSyncCore = global.__onLiveSyncCore;
|
const liveSyncCore = global.__onLiveSyncCore;
|
||||||
if (liveSyncCore) {
|
let reapplyAppCss = false
|
||||||
liveSyncCore(context);
|
|
||||||
|
if (context) {
|
||||||
|
const fullFileName = getCssFileName();
|
||||||
|
const fileName = fullFileName.substring(0, fullFileName.lastIndexOf(".") + 1);
|
||||||
|
const extensions = ["css", "scss"];
|
||||||
|
reapplyAppCss = extensions.some(ext => context.module === fileName.concat(ext));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reapplyAppCss) {
|
||||||
|
getRootView()._onCssStateChange();
|
||||||
|
} else if (liveSyncCore) {
|
||||||
|
liveSyncCore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ export * from "./application-common";
|
|||||||
import { createViewFromEntry } from "../ui/builder";
|
import { createViewFromEntry } from "../ui/builder";
|
||||||
import { ios as iosView, View } from "../ui/core/view";
|
import { ios as iosView, View } from "../ui/core/view";
|
||||||
import { Frame, NavigationEntry } from "../ui/frame";
|
import { Frame, NavigationEntry } from "../ui/frame";
|
||||||
import { loadCss } from "../ui/styling/style-scope";
|
|
||||||
import * as utils from "../utils/utils";
|
import * as utils from "../utils/utils";
|
||||||
import { profile, level as profilingLevel, Level } from "../profiling";
|
import { profile, level as profilingLevel, Level } from "../profiling";
|
||||||
|
|
||||||
@@ -162,7 +161,7 @@ class IOSApplication implements IOSApplicationDefinition {
|
|||||||
this.setWindowContent(args.root);
|
this.setWindowContent(args.root);
|
||||||
} else {
|
} else {
|
||||||
this._window = UIApplication.sharedApplication.delegate.window;
|
this._window = UIApplication.sharedApplication.delegate.window;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@profile
|
@profile
|
||||||
@@ -226,21 +225,10 @@ class IOSApplication implements IOSApplicationDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public _onLivesync(context?: HmrContext): void {
|
public _onLivesync(): void {
|
||||||
let executeLivesync = true;
|
// If view can't handle livesync set window controller.
|
||||||
// HMR has context, livesync does not
|
if (!this._rootView._onLivesync()) {
|
||||||
if (context) {
|
this.setWindowContent();
|
||||||
if (context.module === getCssFileName()) {
|
|
||||||
loadCss(context.module);
|
|
||||||
this._rootView._onCssStateChange();
|
|
||||||
executeLivesync = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (executeLivesync) {
|
|
||||||
// If view can't handle livesync set window controller.
|
|
||||||
if (!this._rootView._onLivesync()) {
|
|
||||||
this.setWindowContent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,8 +264,8 @@ exports.ios = iosApp;
|
|||||||
setApplication(iosApp);
|
setApplication(iosApp);
|
||||||
|
|
||||||
// attach on global, so it can be overwritten in NativeScript Angular
|
// attach on global, so it can be overwritten in NativeScript Angular
|
||||||
(<any>global).__onLiveSyncCore = function __onLiveSyncCore(context?: HmrContext) {
|
(<any>global).__onLiveSyncCore = function () {
|
||||||
iosApp._onLivesync(context);
|
iosApp._onLivesync();
|
||||||
}
|
}
|
||||||
|
|
||||||
let mainEntry: NavigationEntry;
|
let mainEntry: NavigationEntry;
|
||||||
@@ -391,4 +379,4 @@ global.__onLiveSync = function __onLiveSync(context?: HmrContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
livesync(context);
|
livesync(context);
|
||||||
}
|
}
|
||||||
2
tns-core-modules/module.d.ts
vendored
2
tns-core-modules/module.d.ts
vendored
@@ -52,7 +52,7 @@ declare namespace NodeJS {
|
|||||||
__inspector?: any;
|
__inspector?: any;
|
||||||
__extends: any;
|
__extends: any;
|
||||||
__onLiveSync: (context?: { type: string, module: string }) => void;
|
__onLiveSync: (context?: { type: string, module: string }) => void;
|
||||||
__onLiveSyncCore: (context?: { type: string, module: string }) => void;
|
__onLiveSyncCore: () => void;
|
||||||
__onUncaughtError: (error: NativeScriptError) => void;
|
__onUncaughtError: (error: NativeScriptError) => void;
|
||||||
TNS_WEBPACK?: boolean;
|
TNS_WEBPACK?: boolean;
|
||||||
__requireOverride?: (name: string, dir: string) => any;
|
__requireOverride?: (name: string, dir: string) => any;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ import {
|
|||||||
_updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, AnimationType
|
_updateTransitions, _reverseTransitions, _clearEntry, _clearFragment, AnimationType
|
||||||
} from "./fragment.transitions";
|
} from "./fragment.transitions";
|
||||||
|
|
||||||
import { loadCss } from "../styling/style-scope";
|
|
||||||
import { profile } from "../../profiling";
|
import { profile } from "../../profiling";
|
||||||
|
|
||||||
// TODO: Remove this and get it from global to decouple builder for angular
|
// TODO: Remove this and get it from global to decouple builder for angular
|
||||||
@@ -83,24 +82,13 @@ function getAttachListener(): android.view.View.OnAttachStateChangeListener {
|
|||||||
return attachStateChangeListener;
|
return attachStateChangeListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reloadPage(context?: HmrContext): void {
|
export function reloadPage(): void {
|
||||||
const activity = application.android.foregroundActivity;
|
const activity = application.android.foregroundActivity;
|
||||||
const callbacks: AndroidActivityCallbacks = activity[CALLBACKS];
|
const callbacks: AndroidActivityCallbacks = activity[CALLBACKS];
|
||||||
const rootView: View = callbacks.getRootView();
|
const rootView: View = callbacks.getRootView();
|
||||||
|
|
||||||
let executeLivesync = true;
|
if (!rootView || !rootView._onLivesync()) {
|
||||||
// HMR has context, livesync does not
|
callbacks.resetActivityContent(activity);
|
||||||
if (context) {
|
|
||||||
if (context.module === application.getCssFileName()) {
|
|
||||||
loadCss(context.module);
|
|
||||||
rootView._onCssStateChange();
|
|
||||||
executeLivesync = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (executeLivesync) {
|
|
||||||
if (!rootView || !rootView._onLivesync()) {
|
|
||||||
callbacks.resetActivityContent(activity);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,19 +469,19 @@ export class Frame extends FrameBase {
|
|||||||
switch (this.actionBarVisibility) {
|
switch (this.actionBarVisibility) {
|
||||||
case "never":
|
case "never":
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case "always":
|
case "always":
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (page.actionBarHidden !== undefined) {
|
if (page.actionBarHidden !== undefined) {
|
||||||
return !page.actionBarHidden;
|
return !page.actionBarHidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this._android && this._android.showActionBar !== undefined) {
|
if (this._android && this._android.showActionBar !== undefined) {
|
||||||
return this._android.showActionBar;
|
return this._android.showActionBar;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -858,14 +846,14 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
|||||||
// parent while its supposed parent believes it properly removed its children; in order to "force" the child to
|
// parent while its supposed parent believes it properly removed its children; in order to "force" the child to
|
||||||
// lose its parent we temporarily add it to the parent, and then remove it (addViewInLayout doesn't trigger layout pass)
|
// lose its parent we temporarily add it to the parent, and then remove it (addViewInLayout doesn't trigger layout pass)
|
||||||
const nativeView = page.nativeViewProtected;
|
const nativeView = page.nativeViewProtected;
|
||||||
if (nativeView != null) {
|
if (nativeView != null) {
|
||||||
const parentView = nativeView.getParent();
|
const parentView = nativeView.getParent();
|
||||||
if (parentView instanceof android.view.ViewGroup) {
|
if (parentView instanceof android.view.ViewGroup) {
|
||||||
if (parentView.getChildCount() === 0) {
|
if (parentView.getChildCount() === 0) {
|
||||||
parentView.addViewInLayout(nativeView, -1, new org.nativescript.widgets.CommonLayoutParams());
|
parentView.addViewInLayout(nativeView, -1, new org.nativescript.widgets.CommonLayoutParams());
|
||||||
}
|
}
|
||||||
|
|
||||||
parentView.removeView(nativeView);
|
parentView.removeView(nativeView);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1210,4 +1198,4 @@ export function setActivityCallbacks(activity: android.support.v7.app.AppCompatA
|
|||||||
|
|
||||||
export function setFragmentCallbacks(fragment: android.support.v4.app.Fragment): void {
|
export function setFragmentCallbacks(fragment: android.support.v4.app.Fragment): void {
|
||||||
fragment[CALLBACKS] = new FragmentCallbacksImplementation();
|
fragment[CALLBACKS] = new FragmentCallbacksImplementation();
|
||||||
}
|
}
|
||||||
@@ -103,8 +103,11 @@ export class PageBase extends ContentView implements PageDefinition {
|
|||||||
public onNavigatingTo(context: any, isBackNavigation: boolean, bindingContext?: any) {
|
public onNavigatingTo(context: any, isBackNavigation: boolean, bindingContext?: any) {
|
||||||
this._navigationContext = context;
|
this._navigationContext = context;
|
||||||
|
|
||||||
if (!this._cssState.isSelectorsLatestVersionApplied()) {
|
if (isBackNavigation && this._styleScope) {
|
||||||
this._onCssStateChange();
|
this._styleScope.ensureSelectors();
|
||||||
|
if (!this._cssState.isSelectorsLatestVersionApplied()) {
|
||||||
|
this._onCssStateChange();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//https://github.com/NativeScript/NativeScript/issues/731
|
//https://github.com/NativeScript/NativeScript/issues/731
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ function onLiveSync(args: applicationCommon.CssChangedEventData): void {
|
|||||||
loadCss(applicationCommon.getCssFileName());
|
loadCss(applicationCommon.getCssFileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
export const loadCss = profile(`"style-scope".loadCss`, (cssFile: string) => {
|
const loadCss = profile(`"style-scope".loadCss`, (cssFile: string) => {
|
||||||
if (!cssFile) {
|
if (!cssFile) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -369,12 +369,7 @@ export class CssState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public isSelectorsLatestVersionApplied(): boolean {
|
public isSelectorsLatestVersionApplied(): boolean {
|
||||||
if (this._appliedSelectorsVersion && this.view._styleScope) {
|
return this.view._styleScope._getSelectorsVersion() === this._appliedSelectorsVersion;
|
||||||
this.view._styleScope.ensureSelectors();
|
|
||||||
return this.view._styleScope._getSelectorsVersion() === this._appliedSelectorsVersion;
|
|
||||||
} else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public onLoaded(): void {
|
public onLoaded(): void {
|
||||||
|
|||||||
@@ -26,4 +26,4 @@
|
|||||||
"tns-core-modules/*": ["tns-core-modules/*"]
|
"tns-core-modules/*": ["tns-core-modules/*"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user