Skip to content

Commit 297c54e

Browse files
marclavalkara
authored andcommitted
fix(ivy): support env where requestAnimationFrame is not available (angular#26779)
PR Close angular#26779
1 parent dc2464e commit 297c54e

File tree

9 files changed

+60
-21
lines changed

9 files changed

+60
-21
lines changed

packages/core/src/render3/component.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ import {CLEAN_PROMISE, createLViewData, createNodeAtIndex, createTView, getOrCre
2121
import {ComponentDef, ComponentType} from './interfaces/definition';
2222
import {TElementNode, TNodeFlags, TNodeType} from './interfaces/node';
2323
import {PlayerHandler} from './interfaces/player';
24-
import {RElement, RNode, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
24+
import {RElement, Renderer3, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
2525
import {CONTEXT, HEADER_OFFSET, HOST, HOST_NODE, INJECTOR, LViewData, LViewFlags, RootContext, RootContextFlags, TVIEW} from './interfaces/view';
2626
import {publishDefaultGlobalUtils} from './publish_global_util';
2727
import {enterView, leaveView, resetComponentState} from './state';
28-
import {getRootView, readElementValue, readPatchedLViewData, stringify} from './util';
28+
import {defaultScheduler, getRootView, readElementValue, readPatchedLViewData, stringify} from './util';
2929

3030

3131
/** Options that control how the component should be bootstrapped. */
@@ -117,8 +117,7 @@ export function renderComponent<T>(
117117
const hostRNode = locateHostElement(rendererFactory, opts.host || componentTag);
118118
const rootFlags = componentDef.onPush ? LViewFlags.Dirty | LViewFlags.IsRoot :
119119
LViewFlags.CheckAlways | LViewFlags.IsRoot;
120-
const rootContext = createRootContext(
121-
opts.scheduler || requestAnimationFrame.bind(window), opts.playerHandler || null);
120+
const rootContext = createRootContext(opts.scheduler, opts.playerHandler);
122121

123122
const renderer = rendererFactory.createRenderer(hostRNode, componentDef);
124123
const rootView: LViewData = createLViewData(
@@ -132,7 +131,7 @@ export function renderComponent<T>(
132131
const componentView =
133132
createRootComponentView(hostRNode, componentDef, rootView, renderer, sanitizer);
134133
component = createRootComponent(
135-
hostRNode, componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
134+
componentView, componentDef, rootView, rootContext, opts.hostFeatures || null);
136135

137136
refreshDescendantViews(rootView, null);
138137
} finally {
@@ -184,8 +183,8 @@ export function createRootComponentView(
184183
* renderComponent() and ViewContainerRef.createComponent().
185184
*/
186185
export function createRootComponent<T>(
187-
hostRNode: RNode | null, componentView: LViewData, componentDef: ComponentDef<T>,
188-
rootView: LViewData, rootContext: RootContext, hostFeatures: HostFeature[] | null): any {
186+
componentView: LViewData, componentDef: ComponentDef<T>, rootView: LViewData,
187+
rootContext: RootContext, hostFeatures: HostFeature[] | null): any {
189188
const tView = rootView[TVIEW];
190189
// Create directive instance with factory() and store at next index in viewData
191190
const component = instantiateRootComponent(tView, rootView, componentDef);
@@ -201,10 +200,10 @@ export function createRootComponent<T>(
201200

202201

203202
export function createRootContext(
204-
scheduler: (workFn: () => void) => void, playerHandler?: PlayerHandler|null): RootContext {
203+
scheduler?: (workFn: () => void) => void, playerHandler?: PlayerHandler|null): RootContext {
205204
return {
206205
components: [],
207-
scheduler: scheduler,
206+
scheduler: scheduler || defaultScheduler,
208207
clean: CLEAN_PROMISE,
209208
playerHandler: playerHandler || null,
210209
flags: RootContextFlags.Empty

packages/core/src/render3/component_ref.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {TElementNode, TNode, TNodeType, TViewNode} from './interfaces/node';
2626
import {RElement, RendererFactory3, domRendererFactory3} from './interfaces/renderer';
2727
import {FLAGS, HEADER_OFFSET, INJECTOR, LViewData, LViewFlags, RootContext, TVIEW} from './interfaces/view';
2828
import {enterView, leaveView} from './state';
29-
import {getTNode} from './util';
29+
import {defaultScheduler, getTNode} from './util';
3030
import {createElementRef} from './view_engine_compatibility';
3131
import {RootViewRef, ViewRef} from './view_ref';
3232

@@ -62,10 +62,7 @@ export const ROOT_CONTEXT = new InjectionToken<RootContext>(
6262
*/
6363
export const SCHEDULER = new InjectionToken<((fn: () => void) => void)>('SCHEDULER_TOKEN', {
6464
providedIn: 'root',
65-
factory: () => {
66-
const useRaf = typeof requestAnimationFrame !== 'undefined' && typeof window !== 'undefined';
67-
return useRaf ? requestAnimationFrame.bind(window) : setTimeout;
68-
},
65+
factory: () => defaultScheduler,
6966
});
7067

7168
/**
@@ -118,9 +115,8 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
118115

119116
const rootFlags = this.componentDef.onPush ? LViewFlags.Dirty | LViewFlags.IsRoot :
120117
LViewFlags.CheckAlways | LViewFlags.IsRoot;
121-
const rootContext: RootContext = ngModule && !isInternalRootView ?
122-
ngModule.injector.get(ROOT_CONTEXT) :
123-
createRootContext(requestAnimationFrame.bind(window));
118+
const rootContext: RootContext =
119+
ngModule && !isInternalRootView ? ngModule.injector.get(ROOT_CONTEXT) : createRootContext();
124120

125121
const renderer = rendererFactory.createRenderer(hostRNode, this.componentDef);
126122
// Create the root view. Uses empty TView and ContentTemplate.
@@ -174,8 +170,7 @@ export class ComponentFactory<T> extends viewEngine_ComponentFactory<T> {
174170
// executed here?
175171
// Angular 5 reference: https://stackblitz.com/edit/lifecycle-hooks-vcref
176172
component = createRootComponent(
177-
hostRNode, componentView, this.componentDef, rootView, rootContext,
178-
[LifecycleHooksFeature]);
173+
componentView, this.componentDef, rootView, rootContext, [LifecycleHooksFeature]);
179174

180175
refreshDescendantViews(rootView, RenderFlags.Create);
181176
} finally {

packages/core/src/render3/instructions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ export function renderEmbeddedTemplate<T>(
358358
let oldView: LViewData;
359359
if (viewToRender[FLAGS] & LViewFlags.IsRoot) {
360360
// This is a root view inside the view tree
361-
tickRootContext(viewToRender[CONTEXT] as RootContext);
361+
tickRootContext(getRootContext(viewToRender));
362362
} else {
363363
try {
364364
setIsParent(true);

packages/core/src/render3/util.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
*/
88

99
import {devModeEqual} from '../change_detection/change_detection_util';
10+
import {global} from '../util';
1011

1112
import {assertDefined, assertLessThan} from './assert';
1213
import {ACTIVE_INDEX, LContainer} from './interfaces/container';
@@ -154,7 +155,10 @@ export function getRootView(target: LViewData | {}): LViewData {
154155
}
155156

156157
export function getRootContext(viewOrComponent: LViewData | {}): RootContext {
157-
return getRootView(viewOrComponent)[CONTEXT] as RootContext;
158+
const rootView = getRootView(viewOrComponent);
159+
ngDevMode &&
160+
assertDefined(rootView[CONTEXT], 'RootView has no context. Perhaps it is disconnected?');
161+
return rootView[CONTEXT] as RootContext;
158162
}
159163

160164
/**
@@ -241,3 +245,8 @@ export function getParentInjectorTNode(
241245
}
242246
return parentTNode;
243247
}
248+
249+
export const defaultScheduler =
250+
(typeof requestAnimationFrame !== 'undefined' && requestAnimationFrame || // browser only
251+
setTimeout // everything else
252+
).bind(global);

packages/core/test/bundling/animation_world/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,9 @@
434434
{
435435
"name": "decreaseElementDepthCount"
436436
},
437+
{
438+
"name": "defaultScheduler"
439+
},
437440
{
438441
"name": "defineComponent"
439442
},

packages/core/test/bundling/hello_world/bundle.golden_symbols.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@
119119
{
120120
"name": "ViewEncapsulation"
121121
},
122+
{
123+
"name": "__self"
124+
},
125+
{
126+
"name": "__window"
127+
},
128+
{
129+
"name": "_global"
130+
},
122131
{
123132
"name": "_renderCompCount"
124133
},
@@ -182,6 +191,9 @@
182191
{
183192
"name": "createViewQuery"
184193
},
194+
{
195+
"name": "defaultScheduler"
196+
},
185197
{
186198
"name": "defineComponent"
187199
},
@@ -305,6 +317,12 @@
305317
{
306318
"name": "getRendererFactory"
307319
},
320+
{
321+
"name": "getRootContext"
322+
},
323+
{
324+
"name": "getRootView"
325+
},
308326
{
309327
"name": "getTView"
310328
},

packages/core/test/bundling/hello_world_r2/bundle.golden_symbols.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,9 @@
680680
{
681681
"name": "defaultErrorLogger"
682682
},
683+
{
684+
"name": "defaultScheduler"
685+
},
683686
{
684687
"name": "defineComponent"
685688
},
@@ -929,6 +932,12 @@
929932
{
930933
"name": "getRendererFactory"
931934
},
935+
{
936+
"name": "getRootContext"
937+
},
938+
{
939+
"name": "getRootView"
940+
},
932941
{
933942
"name": "getSymbolIterator$1"
934943
},

packages/core/test/bundling/todo/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@
491491
{
492492
"name": "decreaseElementDepthCount"
493493
},
494+
{
495+
"name": "defaultScheduler"
496+
},
494497
{
495498
"name": "defineComponent"
496499
},

packages/core/test/bundling/todo_r2/bundle.golden_symbols.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1415,6 +1415,9 @@
14151415
{
14161416
"name": "defaultKeyValueDiffers"
14171417
},
1418+
{
1419+
"name": "defaultScheduler"
1420+
},
14181421
{
14191422
"name": "defineComponent"
14201423
},

0 commit comments

Comments
 (0)