feat: introduce source maps for templates (#15011)
The main use case for the generated source maps is to give errors a meaningful context in terms of the original source that the user wrote. Related changes that are included in this commit: * renamed virtual folders used for jit: * ng://<module type>/module.ngfactory.js * ng://<module type>/<comp type>.ngfactory.js * ng://<module type>/<comp type>.html (for inline templates) * error logging: * all errors that happen in templates are logged from the place of the nearest element. * instead of logging error messages and stacks separately, we log the actual error. This is needed so that browsers apply source maps to the stack correctly. * error type and error is logged as one log entry. Note that long-stack-trace zone has a bug that disables source maps for stack traces, see https://github.com/angular/zone.js/issues/661. BREAKING CHANGE: - DebugNode.source no more returns the source location of a node. Closes 14013
This commit is contained in:

committed by
Chuck Jazdzewski

parent
1c1085b140
commit
cdc882bd36
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import {Injector} from '../di';
|
||||
import {RenderDebugInfo} from '../render/api';
|
||||
import {DebugContext} from '../view/index';
|
||||
|
||||
export class EventListener { constructor(public name: string, public callback: Function){}; }
|
||||
|
||||
@ -19,7 +19,7 @@ export class DebugNode {
|
||||
listeners: EventListener[];
|
||||
parent: DebugElement;
|
||||
|
||||
constructor(nativeNode: any, parent: DebugNode, private _debugInfo: RenderDebugInfo) {
|
||||
constructor(nativeNode: any, parent: DebugNode, private _debugContext: DebugContext) {
|
||||
this.nativeNode = nativeNode;
|
||||
if (parent && parent instanceof DebugElement) {
|
||||
parent.addChild(this);
|
||||
@ -29,19 +29,24 @@ export class DebugNode {
|
||||
this.listeners = [];
|
||||
}
|
||||
|
||||
get injector(): Injector { return this._debugInfo ? this._debugInfo.injector : null; }
|
||||
get injector(): Injector { return this._debugContext ? this._debugContext.injector : null; }
|
||||
|
||||
get componentInstance(): any { return this._debugInfo ? this._debugInfo.component : null; }
|
||||
get componentInstance(): any { return this._debugContext ? this._debugContext.component : null; }
|
||||
|
||||
get context(): any { return this._debugInfo ? this._debugInfo.context : null; }
|
||||
get context(): any { return this._debugContext ? this._debugContext.context : null; }
|
||||
|
||||
get references(): {[key: string]: any} {
|
||||
return this._debugInfo ? this._debugInfo.references : null;
|
||||
return this._debugContext ? this._debugContext.references : null;
|
||||
}
|
||||
|
||||
get providerTokens(): any[] { return this._debugInfo ? this._debugInfo.providerTokens : null; }
|
||||
get providerTokens(): any[] {
|
||||
return this._debugContext ? this._debugContext.providerTokens : null;
|
||||
}
|
||||
|
||||
get source(): string { return this._debugInfo ? this._debugInfo.source : null; }
|
||||
/**
|
||||
* @deprecated since v4
|
||||
*/
|
||||
get source(): string { return 'Deprecated since v4'; }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -56,8 +61,8 @@ export class DebugElement extends DebugNode {
|
||||
childNodes: DebugNode[];
|
||||
nativeElement: any;
|
||||
|
||||
constructor(nativeNode: any, parent: any, _debugInfo: RenderDebugInfo) {
|
||||
super(nativeNode, parent, _debugInfo);
|
||||
constructor(nativeNode: any, parent: any, _debugContext: DebugContext) {
|
||||
super(nativeNode, parent, _debugContext);
|
||||
this.properties = {};
|
||||
this.attributes = {};
|
||||
this.classes = {};
|
||||
|
@ -6,7 +6,8 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ERROR_ORIGINAL_ERROR, getDebugContext, getOriginalError} from './errors';
|
||||
import {ERROR_ORIGINAL_ERROR, getDebugContext, getErrorLogger, getOriginalError} from './errors';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@ -49,36 +50,23 @@ export class ErrorHandler {
|
||||
constructor(rethrowError: boolean = false) { this.rethrowError = rethrowError; }
|
||||
|
||||
handleError(error: any): void {
|
||||
this._console.error(`EXCEPTION: ${this._extractMessage(error)}`);
|
||||
const originalError = this._findOriginalError(error);
|
||||
const context = this._findContext(error);
|
||||
// Note: Browser consoles show the place from where console.error was called.
|
||||
// We can use this to give users additional information about the error.
|
||||
const errorLogger = getErrorLogger(error);
|
||||
|
||||
if (error instanceof Error) {
|
||||
const originalError = this._findOriginalError(error);
|
||||
const originalStack = this._findOriginalStack(error);
|
||||
const context = this._findContext(error);
|
||||
|
||||
if (originalError) {
|
||||
this._console.error(`ORIGINAL EXCEPTION: ${this._extractMessage(originalError)}`);
|
||||
}
|
||||
|
||||
if (originalStack) {
|
||||
this._console.error('ORIGINAL STACKTRACE:');
|
||||
this._console.error(originalStack);
|
||||
}
|
||||
|
||||
if (context) {
|
||||
this._console.error('ERROR CONTEXT:');
|
||||
this._console.error(context);
|
||||
}
|
||||
errorLogger(this._console, `ERROR`, error);
|
||||
if (originalError) {
|
||||
errorLogger(this._console, `ORIGINAL ERROR`, originalError);
|
||||
}
|
||||
if (context) {
|
||||
errorLogger(this._console, 'ERROR CONTEXT', context);
|
||||
}
|
||||
|
||||
if (this.rethrowError) throw error;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_extractMessage(error: any): string {
|
||||
return error instanceof Error ? error.message : error.toString();
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_findContext(error: any): any {
|
||||
if (error) {
|
||||
@ -98,20 +86,6 @@ export class ErrorHandler {
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
_findOriginalStack(error: Error): string {
|
||||
let e: any = error;
|
||||
let stack: string = e.stack;
|
||||
while (e instanceof Error && getOriginalError(e)) {
|
||||
e = getOriginalError(e);
|
||||
if (e instanceof Error && e.stack) {
|
||||
stack = e.stack;
|
||||
}
|
||||
}
|
||||
|
||||
return stack;
|
||||
}
|
||||
}
|
||||
|
||||
export function wrappedError(message: string, originalError: any): Error {
|
||||
|
@ -12,6 +12,7 @@ export const ERROR_TYPE = 'ngType';
|
||||
export const ERROR_COMPONENT_TYPE = 'ngComponentType';
|
||||
export const ERROR_DEBUG_CONTEXT = 'ngDebugContext';
|
||||
export const ERROR_ORIGINAL_ERROR = 'ngOriginalError';
|
||||
export const ERROR_LOGGER = 'ngErrorLogger';
|
||||
|
||||
|
||||
export function getType(error: Error): Function {
|
||||
@ -25,3 +26,12 @@ export function getDebugContext(error: Error): DebugContext {
|
||||
export function getOriginalError(error: Error): Error {
|
||||
return (error as any)[ERROR_ORIGINAL_ERROR];
|
||||
}
|
||||
|
||||
export function getErrorLogger(error: Error): (console: Console, ...values: any[]) => void {
|
||||
return (error as any)[ERROR_LOGGER] || defaultErrorLogger;
|
||||
}
|
||||
|
||||
|
||||
function defaultErrorLogger(console: Console, ...values: any[]) {
|
||||
(<any>console.error)(...values);
|
||||
}
|
@ -6,14 +6,11 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {isDevMode} from '../application_ref';
|
||||
import {Renderer2, RendererType2} from '../render/api';
|
||||
import {SecurityContext} from '../security';
|
||||
|
||||
import {BindingDef, BindingType, DebugContext, DisposableFn, ElementData, ElementHandleEventFn, NodeData, NodeDef, NodeFlags, OutputDef, OutputType, QueryValueType, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, asElementData, asProviderData} from './types';
|
||||
import {checkAndUpdateBinding, dispatchEvent, elementEventFullName, filterQueryId, getParentRenderElement, resolveViewDefinition, sliceErrorStack, splitMatchedQueriesDsl, splitNamespace} from './util';
|
||||
|
||||
const NOOP: any = () => {};
|
||||
import {NOOP, checkAndUpdateBinding, dispatchEvent, elementEventFullName, filterQueryId, getParentRenderElement, resolveViewDefinition, splitMatchedQueriesDsl, splitNamespace} from './util';
|
||||
|
||||
export function anchorDef(
|
||||
flags: NodeFlags, matchedQueriesDsl: [string | number, QueryValueType][],
|
||||
@ -24,8 +21,6 @@ export function anchorDef(
|
||||
}
|
||||
flags |= NodeFlags.TypeElement;
|
||||
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
||||
// skip the call to sliceErrorStack itself + the call to this function.
|
||||
const source = isDevMode() ? sliceErrorStack(2, 3) : '';
|
||||
const template = templateFactory ? resolveViewDefinition(templateFactory) : null;
|
||||
|
||||
return {
|
||||
@ -45,7 +40,7 @@ export function anchorDef(
|
||||
element: {
|
||||
ns: undefined,
|
||||
name: undefined,
|
||||
attrs: undefined, template, source,
|
||||
attrs: undefined, template,
|
||||
componentProvider: undefined,
|
||||
componentView: undefined,
|
||||
componentRendererType: undefined,
|
||||
@ -71,12 +66,10 @@ export function elementDef(
|
||||
string, SecurityContext
|
||||
])[],
|
||||
outputs?: ([string, string])[], handleEvent?: ElementHandleEventFn,
|
||||
componentView?: () => ViewDefinition, componentRendererType?: RendererType2): NodeDef {
|
||||
componentView?: ViewDefinitionFactory, componentRendererType?: RendererType2): NodeDef {
|
||||
if (!handleEvent) {
|
||||
handleEvent = NOOP;
|
||||
}
|
||||
// skip the call to sliceErrorStack itself + the call to this function.
|
||||
const source = isDevMode() ? sliceErrorStack(2, 3) : '';
|
||||
const {matchedQueries, references, matchedQueryIds} = splitMatchedQueriesDsl(matchedQueriesDsl);
|
||||
let ns: string;
|
||||
let name: string;
|
||||
@ -146,7 +139,6 @@ export function elementDef(
|
||||
ns,
|
||||
name,
|
||||
attrs,
|
||||
source,
|
||||
template: undefined,
|
||||
// will bet set by the view definition
|
||||
componentProvider: undefined, componentView, componentRendererType,
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ERROR_DEBUG_CONTEXT, ERROR_ORIGINAL_ERROR, getDebugContext} from '../errors';
|
||||
import {ERROR_DEBUG_CONTEXT, ERROR_LOGGER, getDebugContext} from '../errors';
|
||||
import {DebugContext, ViewState} from './types';
|
||||
|
||||
export function expressionChangedAfterItHasBeenCheckedError(
|
||||
@ -21,19 +21,27 @@ export function expressionChangedAfterItHasBeenCheckedError(
|
||||
return viewDebugError(msg, context);
|
||||
}
|
||||
|
||||
export function viewWrappedDebugError(originalError: any, context: DebugContext): Error {
|
||||
const err = viewDebugError(originalError.message, context);
|
||||
(err as any)[ERROR_ORIGINAL_ERROR] = originalError;
|
||||
export function viewWrappedDebugError(err: any, context: DebugContext): Error {
|
||||
if (!(err instanceof Error)) {
|
||||
// errors that are not Error instances don't have a stack,
|
||||
// so it is ok to wrap them into a new Error object...
|
||||
err = new Error(err.toString());
|
||||
}
|
||||
_addDebugContext(err, context);
|
||||
return err;
|
||||
}
|
||||
|
||||
export function viewDebugError(msg: string, context: DebugContext): Error {
|
||||
const err = new Error(msg);
|
||||
(err as any)[ERROR_DEBUG_CONTEXT] = context;
|
||||
err.stack = context.source;
|
||||
_addDebugContext(err, context);
|
||||
return err;
|
||||
}
|
||||
|
||||
function _addDebugContext(err: Error, context: DebugContext) {
|
||||
(err as any)[ERROR_DEBUG_CONTEXT] = context;
|
||||
(err as any)[ERROR_LOGGER] = context.logError.bind(context);
|
||||
}
|
||||
|
||||
export function isViewDebugError(err: Error): boolean {
|
||||
return !!getDebugContext(err);
|
||||
}
|
||||
|
@ -16,8 +16,8 @@ import {isViewDebugError, viewDestroyedError, viewWrappedDebugError} from './err
|
||||
import {resolveDep} from './provider';
|
||||
import {dirtyParentQueries, getQueryValue} from './query';
|
||||
import {createInjector} from './refs';
|
||||
import {ArgumentType, BindingType, CheckType, DebugContext, DepFlags, ElementData, NodeCheckFn, NodeData, NodeDef, NodeFlags, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewState, asElementData, asProviderData, asPureExpressionData} from './types';
|
||||
import {checkBinding, isComponentView, renderNode, viewParentEl} from './util';
|
||||
import {ArgumentType, BindingType, CheckType, DebugContext, DepFlags, ElementData, NodeCheckFn, NodeData, NodeDef, NodeFlags, NodeLogger, RootData, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewState, asElementData, asProviderData, asPureExpressionData} from './types';
|
||||
import {NOOP, checkBinding, isComponentView, renderNode, viewParentEl} from './util';
|
||||
import {checkAndUpdateNode, checkAndUpdateView, checkNoChangesNode, checkNoChangesView, createEmbeddedView, createRootView, destroyView} from './view';
|
||||
|
||||
let initialized = false;
|
||||
@ -357,13 +357,6 @@ class DebugContext_ implements DebugContext {
|
||||
}
|
||||
return references;
|
||||
}
|
||||
get source(): string {
|
||||
if (this.nodeDef.flags & NodeFlags.TypeText) {
|
||||
return this.nodeDef.text.source;
|
||||
} else {
|
||||
return this.elDef.element.source;
|
||||
}
|
||||
}
|
||||
get componentRenderElement() {
|
||||
const elData = findHostElement(this.elOrCompView);
|
||||
return elData ? elData.renderElement : undefined;
|
||||
@ -372,6 +365,31 @@ class DebugContext_ implements DebugContext {
|
||||
return this.nodeDef.flags & NodeFlags.TypeText ? renderNode(this.view, this.nodeDef) :
|
||||
renderNode(this.elView, this.elDef);
|
||||
}
|
||||
logError(console: Console, ...values: any[]) {
|
||||
let logViewFactory: ViewDefinitionFactory;
|
||||
let logNodeIndex: number;
|
||||
if (this.nodeDef.flags & NodeFlags.TypeText) {
|
||||
logViewFactory = this.view.def.factory;
|
||||
logNodeIndex = this.nodeDef.index;
|
||||
} else {
|
||||
logViewFactory = this.elView.def.factory;
|
||||
logNodeIndex = this.elDef.index;
|
||||
}
|
||||
let currNodeIndex = -1;
|
||||
let nodeLogger: NodeLogger = () => {
|
||||
currNodeIndex++;
|
||||
if (currNodeIndex === logNodeIndex) {
|
||||
return console.error.bind(console, ...values);
|
||||
} else {
|
||||
return NOOP;
|
||||
}
|
||||
};
|
||||
logViewFactory(nodeLogger);
|
||||
if (currNodeIndex < logNodeIndex) {
|
||||
console.error('Illegal state: the ViewDefinitionFactory did not call the logger!');
|
||||
(<any>console.error)(...values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findHostElement(view: ViewData): ElementData {
|
||||
|
@ -6,15 +6,12 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {isDevMode} from '../application_ref';
|
||||
import {looseIdentical} from '../util';
|
||||
|
||||
import {BindingDef, BindingType, DebugContext, NodeData, NodeDef, NodeFlags, RootData, Services, TextData, ViewData, ViewFlags, asElementData, asTextData} from './types';
|
||||
import {checkAndUpdateBinding, getParentRenderElement, sliceErrorStack} from './util';
|
||||
import {checkAndUpdateBinding, getParentRenderElement} from './util';
|
||||
|
||||
export function textDef(ngContentIndex: number, constants: string[]): NodeDef {
|
||||
// skip the call to sliceErrorStack itself + the call to this function.
|
||||
const source = isDevMode() ? sliceErrorStack(2, 3) : '';
|
||||
const bindings: BindingDef[] = new Array(constants.length - 1);
|
||||
for (let i = 1; i < constants.length; i++) {
|
||||
bindings[i - 1] = {
|
||||
@ -46,7 +43,7 @@ export function textDef(ngContentIndex: number, constants: string[]): NodeDef {
|
||||
outputs: [],
|
||||
element: undefined,
|
||||
provider: undefined,
|
||||
text: {prefix: constants[0], source},
|
||||
text: {prefix: constants[0]},
|
||||
query: undefined,
|
||||
ngContent: undefined
|
||||
};
|
||||
|
@ -22,6 +22,7 @@ import {Sanitizer, SecurityContext} from '../security';
|
||||
// -------------------------------------
|
||||
|
||||
export interface ViewDefinition {
|
||||
factory: ViewDefinitionFactory;
|
||||
flags: ViewFlags;
|
||||
updateDirectives: ViewUpdateFn;
|
||||
updateRenderer: ViewUpdateFn;
|
||||
@ -45,9 +46,22 @@ export interface ViewDefinition {
|
||||
nodeMatchedQueries: number;
|
||||
}
|
||||
|
||||
export type ViewDefinitionFactory = () => ViewDefinition;
|
||||
/**
|
||||
* Factory for ViewDefinitions.
|
||||
* We use a function so we can reexeute it in case an error happens and use the given logger
|
||||
* function to log the error from the definition of the node, which is shown in all browser
|
||||
* logs.
|
||||
*/
|
||||
export interface ViewDefinitionFactory { (logger: NodeLogger): ViewDefinition; }
|
||||
|
||||
export type ViewUpdateFn = (check: NodeCheckFn, view: ViewData) => void;
|
||||
/**
|
||||
* Function to call console.error at the right source location. This is an indirection
|
||||
* via another function as browser will log the location that actually called
|
||||
* `console.error`.
|
||||
*/
|
||||
export interface NodeLogger { (): () => void; }
|
||||
|
||||
export interface ViewUpdateFn { (check: NodeCheckFn, view: ViewData): void; }
|
||||
|
||||
// helper functions to create an overloaded function type.
|
||||
export interface NodeCheckFn {
|
||||
@ -57,11 +71,12 @@ export interface NodeCheckFn {
|
||||
v3?: any, v4?: any, v5?: any, v6?: any, v7?: any, v8?: any, v9?: any): any;
|
||||
}
|
||||
|
||||
export type ViewHandleEventFn =
|
||||
(view: ViewData, nodeIndex: number, eventName: string, event: any) => boolean;
|
||||
|
||||
export const enum ArgumentType {Inline, Dynamic}
|
||||
|
||||
export interface ViewHandleEventFn {
|
||||
(view: ViewData, nodeIndex: number, eventName: string, event: any): boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bitmask for ViewDefintion.flags.
|
||||
*/
|
||||
@ -221,11 +236,10 @@ export interface ElementDef {
|
||||
* that are located on this element.
|
||||
*/
|
||||
allProviders: {[tokenKey: string]: NodeDef};
|
||||
source: string;
|
||||
handleEvent: ElementHandleEventFn;
|
||||
}
|
||||
|
||||
export type ElementHandleEventFn = (view: ViewData, eventName: string, event: any) => boolean;
|
||||
export interface ElementHandleEventFn { (view: ViewData, eventName: string, event: any): boolean; }
|
||||
|
||||
export interface ProviderDef {
|
||||
token: any;
|
||||
@ -250,10 +264,7 @@ export const enum DepFlags {
|
||||
Value = 2 << 2,
|
||||
}
|
||||
|
||||
export interface TextDef {
|
||||
prefix: string;
|
||||
source: string;
|
||||
}
|
||||
export interface TextDef { prefix: string; }
|
||||
|
||||
export interface QueryDef {
|
||||
id: number;
|
||||
@ -318,7 +329,7 @@ export const enum ViewState {
|
||||
Destroyed = 1 << 3
|
||||
}
|
||||
|
||||
export type DisposableFn = () => void;
|
||||
export interface DisposableFn { (): void; }
|
||||
|
||||
/**
|
||||
* Node instance data.
|
||||
@ -428,9 +439,9 @@ export abstract class DebugContext {
|
||||
abstract get providerTokens(): any[];
|
||||
abstract get references(): {[key: string]: any};
|
||||
abstract get context(): any;
|
||||
abstract get source(): string;
|
||||
abstract get componentRenderElement(): any;
|
||||
abstract get renderNode(): any;
|
||||
abstract logError(console: Console, ...values: any[]): void;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
|
@ -6,7 +6,6 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {isDevMode} from '../application_ref';
|
||||
import {WrappedValue, devModeEqual} from '../change_detection/change_detection';
|
||||
import {SimpleChange} from '../change_detection/change_detection_util';
|
||||
import {Injector} from '../di';
|
||||
@ -18,7 +17,9 @@ import {Renderer, RendererType2} from '../render/api';
|
||||
import {looseIdentical, stringify} from '../util';
|
||||
|
||||
import {expressionChangedAfterItHasBeenCheckedError, isViewDebugError, viewDestroyedError, viewWrappedDebugError} from './errors';
|
||||
import {DebugContext, ElementData, NodeData, NodeDef, NodeFlags, QueryValueType, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewState, asElementData, asProviderData, asTextData} from './types';
|
||||
import {DebugContext, ElementData, NodeData, NodeDef, NodeFlags, NodeLogger, QueryValueType, Services, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewState, asElementData, asProviderData, asTextData} from './types';
|
||||
|
||||
export const NOOP: any = () => {};
|
||||
|
||||
const _tokenKeyCache = new Map<any, string>();
|
||||
|
||||
@ -194,29 +195,13 @@ const VIEW_DEFINITION_CACHE = new WeakMap<any, ViewDefinition>();
|
||||
export function resolveViewDefinition(factory: ViewDefinitionFactory): ViewDefinition {
|
||||
let value: ViewDefinition = VIEW_DEFINITION_CACHE.get(factory);
|
||||
if (!value) {
|
||||
value = factory();
|
||||
value = factory(() => NOOP);
|
||||
value.factory = factory;
|
||||
VIEW_DEFINITION_CACHE.set(factory, value);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
export function sliceErrorStack(start: number, end: number): string {
|
||||
let err: any;
|
||||
try {
|
||||
throw new Error();
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
const stack = err.stack || '';
|
||||
const lines = stack.split('\n');
|
||||
if (lines[0].startsWith('Error')) {
|
||||
// Chrome always adds the message to the stack as well...
|
||||
start++;
|
||||
end++;
|
||||
}
|
||||
return lines.slice(start, end).join('\n');
|
||||
}
|
||||
|
||||
export function rootRenderNodes(view: ViewData): any[] {
|
||||
const renderNodes: any[] = [];
|
||||
visitRootRenderNodes(view, RenderNodeAction.Collect, undefined, undefined, renderNodes);
|
||||
|
@ -18,9 +18,7 @@ import {checkAndUpdateQuery, createQuery, queryDef} from './query';
|
||||
import {createTemplateData, createViewContainerData} from './refs';
|
||||
import {checkAndUpdateTextDynamic, checkAndUpdateTextInline, createText} from './text';
|
||||
import {ArgumentType, CheckType, ElementData, ElementDef, NodeData, NodeDef, NodeFlags, ProviderData, ProviderDef, RootData, Services, TextDef, ViewData, ViewDefinition, ViewDefinitionFactory, ViewFlags, ViewHandleEventFn, ViewState, ViewUpdateFn, asElementData, asProviderData, asPureExpressionData, asQueryList, asTextData} from './types';
|
||||
import {checkBindingNoChanges, isComponentView, resolveViewDefinition, viewParentEl} from './util';
|
||||
|
||||
const NOOP = (): any => undefined;
|
||||
import {NOOP, checkBindingNoChanges, isComponentView, resolveViewDefinition, viewParentEl} from './util';
|
||||
|
||||
export function viewDef(
|
||||
flags: ViewFlags, nodes: NodeDef[], updateDirectives?: ViewUpdateFn,
|
||||
@ -137,6 +135,8 @@ export function viewDef(
|
||||
const handleEvent: ViewHandleEventFn = (view, nodeIndex, eventName, event) =>
|
||||
nodes[nodeIndex].element.handleEvent(view, eventName, event);
|
||||
return {
|
||||
// Will be filled later...
|
||||
factory: undefined,
|
||||
nodeFlags: viewNodeFlags,
|
||||
rootNodeFlags: viewRootNodeFlags,
|
||||
nodeMatchedQueries: viewMatchedQueries, flags,
|
||||
|
Reference in New Issue
Block a user