Skip to content

Commit ce12639

Browse files
committed
Fix for chained filters and optimized parse service
1 parent 3ee7a78 commit ce12639

8 files changed

Lines changed: 26 additions & 138 deletions

File tree

@types/core/parse/interface.d.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,6 @@ export interface CompiledExpressionProps {
1212
_isPure?: boolean;
1313
/** AST node decorated with metadata. */
1414
_decoratedNode: DecoratedASTNode;
15-
/**
16-
* Optional custom watch delegate function for the expression.
17-
* @param scope - The current scope.
18-
* @param listener - A listener function.
19-
* @param equalityCheck - Whether to use deep equality.
20-
* @param expression - The compiled expression or string.
21-
*/
22-
_watchDelegate?: (
23-
scope: Scope,
24-
listener: Function,
25-
expression: CompiledExpression | string | ((scope: Scope) => any),
26-
) => any;
2715
/** Expression inputs; may be an array or a function. */
2816
_inputs?: any[] | Function;
2917
/**

@types/core/parse/parse.d.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
export function constantWatchDelegate(
2-
scope: any,
3-
listener: any,
4-
parsedExpression: any,
5-
): any;
61
export class ParseProvider {
72
$get: (string | (($filter: ng.FilterService) => ng.ParseService))[];
83
}

docs/static/typedoc/assets/search.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/static/typedoc/interfaces/CompiledExpressionProps.html

Lines changed: 10 additions & 15 deletions
Large diffs are not rendered by default.

src/core/interpolate/interpolate.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
minErr,
66
stringify,
77
} from "../../shared/utils.js";
8-
import { constantWatchDelegate } from "../parse/parse.js";
98
import { $injectTokens as $t } from "../../injection-tokens.js";
109

1110
const $interpolateMinErr = minErr("$interpolate");
@@ -227,7 +226,6 @@ export class InterpolateProvider {
227226

228227
constantInterp.exp = text;
229228
constantInterp.expressions = [];
230-
constantInterp._watchDelegate = constantWatchDelegate;
231229

232230
return constantInterp;
233231
}

src/core/parse/interface.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,7 @@ export interface CompiledExpressionProps {
1313
_isPure?: boolean;
1414
/** AST node decorated with metadata. */
1515
_decoratedNode: DecoratedASTNode;
16-
/**
17-
* Optional custom watch delegate function for the expression.
18-
* @param scope - The current scope.
19-
* @param listener - A listener function.
20-
* @param equalityCheck - Whether to use deep equality.
21-
* @param expression - The compiled expression or string.
22-
*/
23-
_watchDelegate?: (
24-
scope: Scope,
25-
listener: Function,
26-
expression: CompiledExpression | string | ((scope: Scope) => any),
27-
) => any;
16+
2817
/** Expression inputs; may be an array or a function. */
2918
_inputs?: any[] | Function;
3019
/**

src/core/parse/interpreter.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ export class ASTInterpreter {
187187

188188
return context
189189
? { context: undefined, name: undefined, value }
190-
: value;
190+
: value();
191191
}
192192
: (scope, locals, assign) => {
193193
const rhs = right(

src/core/parse/parse.js

Lines changed: 13 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ export class ParseProvider {
3535
const parser = new Parser(lexer, $filter);
3636

3737
parsedExpression = parser._parse(exp);
38-
39-
cache[cacheKey] = addWatchDelegate(parsedExpression);
4038
}
4139

4240
return addInterceptor(parsedExpression, interceptorFn);
@@ -52,111 +50,36 @@ export class ParseProvider {
5250
return parsedExpression;
5351
}
5452

55-
// Extract any existing interceptors out of the parsedExpression
56-
// to ensure the original parsedExpression is always the $$intercepted
57-
// @ts-ignore
58-
if (parsedExpression._interceptor) {
59-
interceptorFn = chainInterceptors(
60-
// @ts-ignore
61-
parsedExpression._interceptor,
62-
interceptorFn,
63-
);
64-
// @ts-ignore
65-
parsedExpression = parsedExpression.$$intercepted;
66-
}
67-
68-
const useInputs = false;
69-
70-
const fn = function interceptedExpression(
71-
scope,
72-
locals,
73-
assign,
74-
inputs,
75-
) {
76-
const value =
77-
useInputs && inputs
78-
? inputs[0]
79-
: parsedExpression(scope, locals, assign);
80-
53+
/**
54+
*
55+
* @param {ng.Scope} scope
56+
* @param {Object} [locals]
57+
* @param {*} [assign]
58+
* @returns
59+
*/
60+
const fn = function interceptedExpression(scope, locals, assign) {
8161
// Do not invoke for getters
8262
if (scope?.getter) {
8363
return undefined;
8464
}
65+
const value = parsedExpression(scope, locals, assign);
66+
8567
const res = isFunction(value) ? value() : value;
8668

8769
return interceptorFn(deProxy(res));
8870
};
8971

9072
fn._interceptor = interceptorFn;
9173

92-
// @ts-ignore
9374
fn._literal = parsedExpression._literal;
94-
// @ts-ignore
75+
9576
fn.constant = parsedExpression.constant;
96-
// @ts-ignore
77+
9778
fn._decoratedNode = parsedExpression._decoratedNode;
9879

99-
return addWatchDelegate(fn);
80+
return fn;
10081
}
10182
},
10283
];
10384
}
10485
}
105-
106-
export function constantWatchDelegate(scope, listener, parsedExpression) {
107-
const unwatch = scope.$watch(() => {
108-
unwatch();
109-
110-
return parsedExpression(scope);
111-
}, listener);
112-
113-
return unwatch;
114-
}
115-
116-
/**
117-
*
118-
* @param {import('./interface.ts').CompiledExpression} parsedExpression
119-
* @returns {import('./interface.ts').CompiledExpression}
120-
*/
121-
function addWatchDelegate(parsedExpression) {
122-
if (parsedExpression.constant) {
123-
parsedExpression._watchDelegate = constantWatchDelegate;
124-
} else if (parsedExpression._inputs) {
125-
parsedExpression._watchDelegate = inputsWatchDelegate;
126-
}
127-
128-
return parsedExpression;
129-
}
130-
131-
/**
132-
* Watches input expressions and calls the parsedExpression with their current values.
133-
*
134-
* @param {ng.Scope} scope
135-
* @param {Function} listener - Callback when the expression result changes
136-
* @param {import('./interface.ts').CompiledExpression} parsedExpression
137-
* @returns {Function} Unwatch function
138-
*/
139-
function inputsWatchDelegate(scope, listener, parsedExpression) {
140-
const { _inputs: inputs } = parsedExpression;
141-
142-
const getValues = isFunction(inputs)
143-
? () => inputs(scope)
144-
: () => inputs.map((fn) => fn(scope));
145-
146-
const evaluate = () => parsedExpression(scope, undefined, getValues());
147-
148-
// Immediately call the listener with the initial value
149-
listener(evaluate());
150-
151-
// Return a reactive/unwatch function
152-
return () => {
153-
// In AngularTS, reactive triggers would handle updates,
154-
// so this is just a placeholder for unwatch cleanup, without any cleanup
155-
};
156-
}
157-
158-
function chainInterceptors(first, second) {
159-
return function chainedInterceptor(value) {
160-
return second(first(value));
161-
};
162-
}

0 commit comments

Comments
 (0)