ngx-blocks-studio 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, signal, computed, Injectable, isSignal, isWritableSignal, linkedSignal, inputBinding, twoWayBinding, outputBinding, Injector, ViewContainerRef, DestroyRef, input, effect, Directive } from '@angular/core';
|
|
2
|
+
import { inject, signal, computed, Injectable, isSignal, reflectComponentType, isWritableSignal, linkedSignal, inputBinding, twoWayBinding, outputBinding, Injector, ViewContainerRef, DestroyRef, input, effect, Directive } from '@angular/core';
|
|
3
3
|
import { Router } from '@angular/router';
|
|
4
4
|
import { HttpClient } from '@angular/common/http';
|
|
5
5
|
import { firstValueFrom } from 'rxjs';
|
|
@@ -851,10 +851,10 @@ class RouteLoader {
|
|
|
851
851
|
}
|
|
852
852
|
return guard;
|
|
853
853
|
}
|
|
854
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
855
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
854
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: RouteLoader, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
855
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: RouteLoader, providedIn: 'root' });
|
|
856
856
|
}
|
|
857
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
857
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: RouteLoader, decorators: [{
|
|
858
858
|
type: Injectable,
|
|
859
859
|
args: [{
|
|
860
860
|
providedIn: 'root',
|
|
@@ -938,10 +938,10 @@ class BlockRegistryService {
|
|
|
938
938
|
getParentScopeKey(scopeKey) {
|
|
939
939
|
return this.registry.get(scopeKey)?.parentScopeKey ?? null;
|
|
940
940
|
}
|
|
941
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
942
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
941
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockRegistryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
942
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockRegistryService, providedIn: 'root' });
|
|
943
943
|
}
|
|
944
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
944
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockRegistryService, decorators: [{
|
|
945
945
|
type: Injectable,
|
|
946
946
|
args: [{ providedIn: 'root' }]
|
|
947
947
|
}] });
|
|
@@ -1273,15 +1273,15 @@ function isTwoWayRefString(value) {
|
|
|
1273
1273
|
return TWOWAY_REF_RE.test(value.trim());
|
|
1274
1274
|
}
|
|
1275
1275
|
/**
|
|
1276
|
-
* True when a string contains two-way ref
|
|
1277
|
-
*
|
|
1276
|
+
* True when a string contains the two-way ref opener `[(` but is not a valid standalone
|
|
1277
|
+
* two-way ref (exact form `[(refPath)]`). Mixing two-way with literals or {{ }} is invalid.
|
|
1278
|
+
* Plain `)]` substrings (e.g. Tailwind `minmax(0,1fr)]`) are not treated as two-way syntax.
|
|
1278
1279
|
*/
|
|
1279
1280
|
function isInvalidTwoWayMix(value) {
|
|
1280
1281
|
if (typeof value !== 'string')
|
|
1281
1282
|
return false;
|
|
1282
1283
|
const s = value.trim();
|
|
1283
|
-
|
|
1284
|
-
return hasDelimiters && !TWOWAY_REF_RE.test(s);
|
|
1284
|
+
return s.includes('[(') && !TWOWAY_REF_RE.test(s);
|
|
1285
1285
|
}
|
|
1286
1286
|
/**
|
|
1287
1287
|
* One trim + one pass: classify string for two-way ref handling. Use instead of calling
|
|
@@ -1293,15 +1293,8 @@ function classifyTwoWayString(value) {
|
|
|
1293
1293
|
const s = value.trim();
|
|
1294
1294
|
if (TWOWAY_REF_RE.test(s))
|
|
1295
1295
|
return 'two-way';
|
|
1296
|
-
|
|
1297
|
-
const hasClose = s.includes(')]');
|
|
1298
|
-
if (!hasOpen && !hasClose)
|
|
1299
|
-
return 'none';
|
|
1300
|
-
// Only treat as invalid mix when the string looks like an attempted two-way ref
|
|
1301
|
-
// wrapper, not when it contains ")]" from normal indexing/calls inside templates.
|
|
1302
|
-
if ((hasOpen && hasClose) || s.startsWith('[(') || s.endsWith(')]')) {
|
|
1296
|
+
if (s.includes('[('))
|
|
1303
1297
|
return 'invalid-mix';
|
|
1304
|
-
}
|
|
1305
1298
|
return 'none';
|
|
1306
1299
|
}
|
|
1307
1300
|
function parseTwoWayRef(value) {
|
|
@@ -1357,7 +1350,9 @@ function resolveRefPath(refPath, ctx) {
|
|
|
1357
1350
|
instance = ctx.currentInstance;
|
|
1358
1351
|
}
|
|
1359
1352
|
else {
|
|
1360
|
-
|
|
1353
|
+
/* v8 ignore next -- registry is always set when blockId resolves (see scope guard above) */
|
|
1354
|
+
const blockRegistry = registry ?? ctx.registry;
|
|
1355
|
+
const handle = blockRegistry.get(blockId);
|
|
1361
1356
|
if (!handle) {
|
|
1362
1357
|
warnOnce(`Ref "${refPath}" could not resolve block id "${blockId}".`);
|
|
1363
1358
|
return null;
|
|
@@ -1440,11 +1435,16 @@ function getValueByPath(obj, path) {
|
|
|
1440
1435
|
*/
|
|
1441
1436
|
function refPathResolvesToSignal(refPath, ctx) {
|
|
1442
1437
|
const resolved = resolveRefPath(refPath, ctx);
|
|
1443
|
-
if (resolved == null)
|
|
1438
|
+
if (resolved == null) {
|
|
1444
1439
|
return false;
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1440
|
+
}
|
|
1441
|
+
let val;
|
|
1442
|
+
if (resolved.path.length === 0) {
|
|
1443
|
+
val = resolved.target;
|
|
1444
|
+
}
|
|
1445
|
+
else {
|
|
1446
|
+
val = resolved.target?.[resolved.path[0]];
|
|
1447
|
+
}
|
|
1448
1448
|
return val != null && isSignal(val);
|
|
1449
1449
|
}
|
|
1450
1450
|
/**
|
|
@@ -1510,8 +1510,12 @@ function setRefValue(refPath, ctx, value) {
|
|
|
1510
1510
|
if (writable) {
|
|
1511
1511
|
writable.set(value);
|
|
1512
1512
|
}
|
|
1513
|
-
else
|
|
1514
|
-
|
|
1513
|
+
else {
|
|
1514
|
+
/* v8 ignore start */
|
|
1515
|
+
if (obj != null && typeof obj === 'object') {
|
|
1516
|
+
obj[key] = value;
|
|
1517
|
+
}
|
|
1518
|
+
/* v8 ignore end */
|
|
1515
1519
|
}
|
|
1516
1520
|
}
|
|
1517
1521
|
/**
|
|
@@ -1597,12 +1601,12 @@ function parseFlowTemplate(template) {
|
|
|
1597
1601
|
let next = bodyEnd + 1;
|
|
1598
1602
|
let elseBody;
|
|
1599
1603
|
let cursor = next;
|
|
1600
|
-
while (cursor < template.length && /\s/.test(template[cursor]
|
|
1604
|
+
while (cursor < template.length && /\s/.test(template[cursor])) {
|
|
1601
1605
|
cursor++;
|
|
1602
1606
|
}
|
|
1603
1607
|
if (template.startsWith('@else', cursor)) {
|
|
1604
1608
|
let elseCursor = cursor + '@else'.length;
|
|
1605
|
-
while (elseCursor < template.length && /\s/.test(template[elseCursor]
|
|
1609
|
+
while (elseCursor < template.length && /\s/.test(template[elseCursor])) {
|
|
1606
1610
|
elseCursor++;
|
|
1607
1611
|
}
|
|
1608
1612
|
if (template[elseCursor] === '{') {
|
|
@@ -1672,7 +1676,7 @@ function parseFlowTemplate(template) {
|
|
|
1672
1676
|
i = end;
|
|
1673
1677
|
}
|
|
1674
1678
|
else {
|
|
1675
|
-
nodes.push({ type: 'text', value: rest
|
|
1679
|
+
nodes.push({ type: 'text', value: rest.charAt(0) });
|
|
1676
1680
|
i++;
|
|
1677
1681
|
}
|
|
1678
1682
|
}
|
|
@@ -1788,6 +1792,7 @@ function interpretFlow(nodes, ctx, scope = {}, options) {
|
|
|
1788
1792
|
}
|
|
1789
1793
|
continue;
|
|
1790
1794
|
}
|
|
1795
|
+
/* v8 ignore start -- exhaustive node.type chain; non-for nodes handled above */
|
|
1791
1796
|
if (node.type === 'for') {
|
|
1792
1797
|
const arr = resolveRefOrModel(node.refPath, ctx);
|
|
1793
1798
|
const list = Array.isArray(arr) ? arr : [];
|
|
@@ -1800,6 +1805,7 @@ function interpretFlow(nodes, ctx, scope = {}, options) {
|
|
|
1800
1805
|
}
|
|
1801
1806
|
continue;
|
|
1802
1807
|
}
|
|
1808
|
+
/* v8 ignore end */
|
|
1803
1809
|
}
|
|
1804
1810
|
return out;
|
|
1805
1811
|
}
|
|
@@ -2104,6 +2110,7 @@ function evalExpr(expr, ctx) {
|
|
|
2104
2110
|
if (obj == null || (typeof obj !== 'object' && typeof obj !== 'function'))
|
|
2105
2111
|
return undefined;
|
|
2106
2112
|
const key = evalExpr(expr.index, ctx);
|
|
2113
|
+
/* v8 ignore next */
|
|
2107
2114
|
if (typeof key !== 'string' && typeof key !== 'number')
|
|
2108
2115
|
return undefined;
|
|
2109
2116
|
return obj[key];
|
|
@@ -2129,13 +2136,18 @@ function evalExpr(expr, ctx) {
|
|
|
2129
2136
|
}
|
|
2130
2137
|
case 'unary': {
|
|
2131
2138
|
const v = evalExpr(expr.argument, ctx);
|
|
2132
|
-
if (expr.op === '!')
|
|
2139
|
+
if (expr.op === '!') {
|
|
2133
2140
|
return !v;
|
|
2134
|
-
|
|
2141
|
+
}
|
|
2142
|
+
if (expr.op === '+') {
|
|
2135
2143
|
return Number(v);
|
|
2136
|
-
|
|
2144
|
+
}
|
|
2145
|
+
/* v8 ignore start */
|
|
2146
|
+
if (expr.op === '-') {
|
|
2137
2147
|
return -Number(v);
|
|
2148
|
+
}
|
|
2138
2149
|
return undefined;
|
|
2150
|
+
/* v8 ignore end */
|
|
2139
2151
|
}
|
|
2140
2152
|
case 'binary': {
|
|
2141
2153
|
const left = evalExpr(expr.left, ctx);
|
|
@@ -2158,6 +2170,7 @@ function evalExpr(expr, ctx) {
|
|
|
2158
2170
|
case '!=': return left != right;
|
|
2159
2171
|
case '===': return left === right;
|
|
2160
2172
|
case '!==': return left !== right;
|
|
2173
|
+
/* v8 ignore next */
|
|
2161
2174
|
default: return undefined;
|
|
2162
2175
|
}
|
|
2163
2176
|
}
|
|
@@ -2178,9 +2191,11 @@ function evaluateSafeExpression(expression, resolverContext, payload, resolveRef
|
|
|
2178
2191
|
const MUSTACHE_MAX_SEGMENTS = 200;
|
|
2179
2192
|
function resolveReferenceValue(ref, ctx) {
|
|
2180
2193
|
const resolved = resolveRefPath(ref, ctx);
|
|
2181
|
-
if (resolved != null)
|
|
2194
|
+
if (resolved != null) {
|
|
2182
2195
|
return getRefValue(ref, ctx);
|
|
2183
|
-
|
|
2196
|
+
}
|
|
2197
|
+
const model = ctx.currentInstance?.model?.() ?? {};
|
|
2198
|
+
return getValueByPath(model, ref);
|
|
2184
2199
|
}
|
|
2185
2200
|
/**
|
|
2186
2201
|
* Safe expression evaluation (same as output `{{ }}` / `@if (...)` when used with this module).
|
|
@@ -2220,7 +2235,7 @@ function resolveMustacheInterpolatedString(value, ctx, payload) {
|
|
|
2220
2235
|
let out = '';
|
|
2221
2236
|
let lastIndex = 0;
|
|
2222
2237
|
for (const match of limited) {
|
|
2223
|
-
const start = match.index
|
|
2238
|
+
const start = match.index;
|
|
2224
2239
|
out += value.slice(lastIndex, start);
|
|
2225
2240
|
const evaluated = evaluateExpression(match[1], ctx, payload);
|
|
2226
2241
|
out += evaluated != null ? String(evaluated) : '';
|
|
@@ -2428,9 +2443,14 @@ function runThenChain(steps, index, ctx, parentDef, payload, onComplete) {
|
|
|
2428
2443
|
}
|
|
2429
2444
|
}
|
|
2430
2445
|
function runOnError(def, ctx, payload) {
|
|
2431
|
-
|
|
2432
|
-
|
|
2446
|
+
const onError = def.onError;
|
|
2447
|
+
if (onError == null) {
|
|
2448
|
+
return;
|
|
2433
2449
|
}
|
|
2450
|
+
if (!shouldRunWhen(onError.when, ctx, payload)) {
|
|
2451
|
+
return;
|
|
2452
|
+
}
|
|
2453
|
+
invokeRefMethod(ctx, onError.ref, payload, resolveStepParams(onError.params, ctx, payload));
|
|
2434
2454
|
}
|
|
2435
2455
|
function invokeRefMethod(ctx, refTemplate, payload, params) {
|
|
2436
2456
|
const resolvedCallable = resolveReferencePath(refTemplate, ctx, payload);
|
|
@@ -2458,6 +2478,147 @@ function createOutputHandler(outputValue, _outputKey, ctx) {
|
|
|
2458
2478
|
return () => { };
|
|
2459
2479
|
}
|
|
2460
2480
|
|
|
2481
|
+
/** JSON-like objects only — skip class instances, Date, Map, etc. */
|
|
2482
|
+
function isPlainObject(value) {
|
|
2483
|
+
if (value === null || typeof value !== 'object')
|
|
2484
|
+
return false;
|
|
2485
|
+
if (Array.isArray(value))
|
|
2486
|
+
return false;
|
|
2487
|
+
const proto = Object.getPrototypeOf(value);
|
|
2488
|
+
return proto === null || proto === Object.prototype;
|
|
2489
|
+
}
|
|
2490
|
+
function looksLikeBlockIdReference(value) {
|
|
2491
|
+
if (value['component'] != null)
|
|
2492
|
+
return false;
|
|
2493
|
+
const blockId = value['blockId'];
|
|
2494
|
+
if (typeof blockId === 'string' && blockId.length > 0) {
|
|
2495
|
+
return true;
|
|
2496
|
+
}
|
|
2497
|
+
const id = value['id'];
|
|
2498
|
+
if (typeof id !== 'string' || id.length === 0) {
|
|
2499
|
+
return false;
|
|
2500
|
+
}
|
|
2501
|
+
if ('blockDefinition' in value) {
|
|
2502
|
+
return true;
|
|
2503
|
+
}
|
|
2504
|
+
const keys = Object.keys(value);
|
|
2505
|
+
if (keys.length !== 1 || keys[0] !== 'id') {
|
|
2506
|
+
return false;
|
|
2507
|
+
}
|
|
2508
|
+
return !id.includes('{{') && !id.includes('[(');
|
|
2509
|
+
}
|
|
2510
|
+
/**
|
|
2511
|
+
* Child block entry in a parent input tree (`blocks`, `rows`, `columns`, etc.).
|
|
2512
|
+
* Template refs inside these objects are resolved when that block is loaded, not on the parent.
|
|
2513
|
+
*/
|
|
2514
|
+
function looksLikeBlockDescriptor(value) {
|
|
2515
|
+
if (!isPlainObject(value))
|
|
2516
|
+
return false;
|
|
2517
|
+
if (typeof value['component'] === 'string' && isPlainObject(value['inputs'])) {
|
|
2518
|
+
return true;
|
|
2519
|
+
}
|
|
2520
|
+
return looksLikeBlockIdReference(value);
|
|
2521
|
+
}
|
|
2522
|
+
/** Same as {@link looksLikeBlockDescriptor}; use in custom layout blocks if needed. */
|
|
2523
|
+
const shouldDeferInputTemplateResolution = looksLikeBlockDescriptor;
|
|
2524
|
+
function stringNeedsInputResolve(s) {
|
|
2525
|
+
if (classifyTwoWayString(s) !== 'none')
|
|
2526
|
+
return true;
|
|
2527
|
+
if (s.includes('{{') && s.includes('}}'))
|
|
2528
|
+
return true;
|
|
2529
|
+
if (looksLikeFlowTemplate(s))
|
|
2530
|
+
return true;
|
|
2531
|
+
return false;
|
|
2532
|
+
}
|
|
2533
|
+
/** True when any string leaf in the tree needs input-style resolution (mustache, flow, or `[( )]`). */
|
|
2534
|
+
function valueNeedsInputResolve(value, visited = new WeakSet()) {
|
|
2535
|
+
if (typeof value === 'string') {
|
|
2536
|
+
return stringNeedsInputResolve(value);
|
|
2537
|
+
}
|
|
2538
|
+
if (Array.isArray(value)) {
|
|
2539
|
+
return value.some((item) => valueNeedsInputResolve(item, visited));
|
|
2540
|
+
}
|
|
2541
|
+
if (value != null && typeof value === 'object') {
|
|
2542
|
+
if (!isPlainObject(value))
|
|
2543
|
+
return false;
|
|
2544
|
+
if (looksLikeBlockDescriptor(value))
|
|
2545
|
+
return false;
|
|
2546
|
+
if (visited.has(value))
|
|
2547
|
+
return false;
|
|
2548
|
+
visited.add(value);
|
|
2549
|
+
return Object.values(value).some((item) => valueNeedsInputResolve(item, visited));
|
|
2550
|
+
}
|
|
2551
|
+
return false;
|
|
2552
|
+
}
|
|
2553
|
+
/** True when any string leaf contains `{{ }}` (block model seeding). */
|
|
2554
|
+
function valueContainsMustacheInTree(value, visited = new WeakSet()) {
|
|
2555
|
+
if (typeof value === 'string') {
|
|
2556
|
+
return value.includes('{{') && value.includes('}}');
|
|
2557
|
+
}
|
|
2558
|
+
if (Array.isArray(value)) {
|
|
2559
|
+
return value.some((item) => valueContainsMustacheInTree(item, visited));
|
|
2560
|
+
}
|
|
2561
|
+
if (value != null && typeof value === 'object') {
|
|
2562
|
+
if (!isPlainObject(value))
|
|
2563
|
+
return false;
|
|
2564
|
+
if (looksLikeBlockDescriptor(value))
|
|
2565
|
+
return false;
|
|
2566
|
+
if (visited.has(value))
|
|
2567
|
+
return false;
|
|
2568
|
+
visited.add(value);
|
|
2569
|
+
return Object.values(value).some((item) => valueContainsMustacheInTree(item, visited));
|
|
2570
|
+
}
|
|
2571
|
+
return false;
|
|
2572
|
+
}
|
|
2573
|
+
function resolveStringLeaf(str, ctx, path, options) {
|
|
2574
|
+
const twoWayKind = classifyTwoWayString(str);
|
|
2575
|
+
if (twoWayKind === 'invalid-mix') {
|
|
2576
|
+
throw new Error(`Invalid value at "${path}": two-way ref "[( )]" cannot be mixed with literals or "{{ }}". ` +
|
|
2577
|
+
`Use exactly "[(refPath)]" for read-resolve or "{{ refPath }}" for read-only.`);
|
|
2578
|
+
}
|
|
2579
|
+
if (twoWayKind === 'two-way' && options.resolveTwoWayStringsAsReadonly) {
|
|
2580
|
+
const refPath = parseTwoWayRef(str);
|
|
2581
|
+
if (refPath) {
|
|
2582
|
+
return getRefValue(refPath, ctx);
|
|
2583
|
+
}
|
|
2584
|
+
}
|
|
2585
|
+
return resolveTemplateString(str, ctx, undefined, {
|
|
2586
|
+
escapeFlowRefs: options.escapeFlowRefs !== false,
|
|
2587
|
+
});
|
|
2588
|
+
}
|
|
2589
|
+
/**
|
|
2590
|
+
* Deep-resolve template strings in plain objects and arrays (new object graph each call).
|
|
2591
|
+
*/
|
|
2592
|
+
function resolveNestedTemplateValues(value, ctx, path = '', visited = new WeakSet(), options = {}) {
|
|
2593
|
+
if (typeof value === 'string') {
|
|
2594
|
+
return resolveStringLeaf(value, ctx, path || 'input', options);
|
|
2595
|
+
}
|
|
2596
|
+
if (Array.isArray(value)) {
|
|
2597
|
+
return value.map((item, index) => {
|
|
2598
|
+
const childPath = path ? `${path}[${index}]` : `[${index}]`;
|
|
2599
|
+
return resolveNestedTemplateValues(item, ctx, childPath, visited, options);
|
|
2600
|
+
});
|
|
2601
|
+
}
|
|
2602
|
+
if (value != null && typeof value === 'object') {
|
|
2603
|
+
if (!isPlainObject(value))
|
|
2604
|
+
return value;
|
|
2605
|
+
if (looksLikeBlockDescriptor(value))
|
|
2606
|
+
return value;
|
|
2607
|
+
if (visited.has(value))
|
|
2608
|
+
return value;
|
|
2609
|
+
visited.add(value);
|
|
2610
|
+
return Object.fromEntries(Object.entries(value).map(([key, item]) => {
|
|
2611
|
+
const childPath = path ? `${path}.${key}` : key;
|
|
2612
|
+
return [key, resolveNestedTemplateValues(item, ctx, childPath, visited, options)];
|
|
2613
|
+
}));
|
|
2614
|
+
}
|
|
2615
|
+
return value;
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2618
|
+
const NESTED_INPUT_RESOLVE_OPTIONS = {
|
|
2619
|
+
resolveTwoWayStringsAsReadonly: true,
|
|
2620
|
+
escapeFlowRefs: true,
|
|
2621
|
+
};
|
|
2461
2622
|
function getBlockInputsAndOutputs(componentOrDirectives) {
|
|
2462
2623
|
const inputs = new Set();
|
|
2463
2624
|
const outputs = new Set();
|
|
@@ -2472,22 +2633,50 @@ function getBlockInputsAndOutputs(componentOrDirectives) {
|
|
|
2472
2633
|
}
|
|
2473
2634
|
return { inputs, outputs, twoWay };
|
|
2474
2635
|
}
|
|
2636
|
+
function isTwoWayInput(publicName, publicOutputKeys, _inputDef, outputsRecord) {
|
|
2637
|
+
const changeOutputName = `${publicName}Change`;
|
|
2638
|
+
// model(): def.outputs is { value: 'valueChange' } (key = input name, not *Change)
|
|
2639
|
+
if (outputsRecord?.[publicName] === changeOutputName) {
|
|
2640
|
+
return true;
|
|
2641
|
+
}
|
|
2642
|
+
// @Input + @Output *Change, or signal/model inputs with a public *Change output
|
|
2643
|
+
return publicOutputKeys.has(changeOutputName);
|
|
2644
|
+
}
|
|
2475
2645
|
function getDirectiveMetadata(type) {
|
|
2476
|
-
|
|
2477
|
-
|
|
2646
|
+
const angularType = type;
|
|
2647
|
+
if (angularType.ɵcmp) {
|
|
2648
|
+
const mirror = reflectComponentType(type);
|
|
2649
|
+
if (mirror != null && mirror.inputs.length > 0) {
|
|
2650
|
+
const outputNames = new Set(mirror.outputs.map((o) => o.templateName));
|
|
2651
|
+
const twoWay = [];
|
|
2652
|
+
const inputs = [];
|
|
2653
|
+
for (const inp of mirror.inputs) {
|
|
2654
|
+
const name = inp.templateName;
|
|
2655
|
+
if (isTwoWayInput(name, outputNames, null, undefined)) {
|
|
2656
|
+
twoWay.push(name);
|
|
2657
|
+
}
|
|
2658
|
+
else {
|
|
2659
|
+
inputs.push(name);
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
const outputs = mirror.outputs.map((o) => o.templateName);
|
|
2663
|
+
return { inputs, outputs, twoWay, isComponent: true };
|
|
2664
|
+
}
|
|
2665
|
+
}
|
|
2666
|
+
// Directives have ɵdir, Components have ɵcmp (fallback when mirror is empty)
|
|
2667
|
+
const def = angularType.ɵdir || angularType.ɵcmp;
|
|
2478
2668
|
if (!def)
|
|
2479
2669
|
return null;
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
const
|
|
2484
|
-
const
|
|
2485
|
-
const twoWay = publicInputs.filter((key) => publicOutputs.includes(`${key}Change`) && def.inputs[key][1]);
|
|
2670
|
+
const inputsRecord = def.inputs || {};
|
|
2671
|
+
const outputsRecord = def.outputs || {};
|
|
2672
|
+
const publicInputs = Object.keys(inputsRecord);
|
|
2673
|
+
const publicOutputs = new Set(Object.keys(outputsRecord));
|
|
2674
|
+
const twoWay = publicInputs.filter((key) => isTwoWayInput(key, publicOutputs, inputsRecord[key], outputsRecord));
|
|
2486
2675
|
return {
|
|
2487
2676
|
inputs: publicInputs.filter((key) => !twoWay.includes(key)),
|
|
2488
|
-
outputs: publicOutputs.filter((key) => !twoWay.includes(key)),
|
|
2677
|
+
outputs: [...publicOutputs].filter((key) => !twoWay.includes(key)),
|
|
2489
2678
|
twoWay,
|
|
2490
|
-
isComponent: !!
|
|
2679
|
+
isComponent: !!angularType.ɵcmp,
|
|
2491
2680
|
};
|
|
2492
2681
|
}
|
|
2493
2682
|
function resolveBlockInputsAndOutputs(description, inputKeys, outputKeys, twoWayKeys, ctx) {
|
|
@@ -2539,13 +2728,15 @@ function resolveBlockInputsAndOutputs(description, inputKeys, outputKeys, twoWay
|
|
|
2539
2728
|
continue;
|
|
2540
2729
|
}
|
|
2541
2730
|
}
|
|
2542
|
-
if (Array.isArray(value)) {
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
}
|
|
2731
|
+
if (Array.isArray(value) || isPlainObject(value)) {
|
|
2732
|
+
if (valueNeedsInputResolve(value)) {
|
|
2733
|
+
resolvedInputs[key] = computed(() => resolveNestedTemplateValues(value, ctx, key, new WeakSet(), NESTED_INPUT_RESOLVE_OPTIONS));
|
|
2734
|
+
}
|
|
2735
|
+
else if (inputKeys.has(key)) {
|
|
2736
|
+
resolvedInputs[key] = () => value;
|
|
2737
|
+
}
|
|
2738
|
+
if (twoWayKeys.has(key))
|
|
2739
|
+
resolvedTwoWay[key] = signal(value);
|
|
2549
2740
|
continue;
|
|
2550
2741
|
}
|
|
2551
2742
|
if (inputKeys.has(key))
|
|
@@ -2564,6 +2755,10 @@ function resolveBlockInputsAndOutputs(description, inputKeys, outputKeys, twoWay
|
|
|
2564
2755
|
}
|
|
2565
2756
|
|
|
2566
2757
|
const INTERPOLATE_MAX_PLACEHOLDERS = 200;
|
|
2758
|
+
/** Builds a two-way binding when only a read getter exists for the key (used by {@link createInputBindingsWithWarnings}). */
|
|
2759
|
+
function linkedTwoWayFromInputGetter(resolvedInputs, key) {
|
|
2760
|
+
return linkedSignal(() => resolvedInputs[key]?.());
|
|
2761
|
+
}
|
|
2567
2762
|
function createInputBindingsWithWarnings(ownerName, inputKeys, twoWayKeys, outputKeys, resolvedInputs, resolvedTwoWay, resolvedOutputs) {
|
|
2568
2763
|
const inputBindingsArray = Array.from(inputKeys)
|
|
2569
2764
|
.filter((key) => {
|
|
@@ -2582,7 +2777,7 @@ function createInputBindingsWithWarnings(ownerName, inputKeys, twoWayKeys, outpu
|
|
|
2582
2777
|
})
|
|
2583
2778
|
// resolvedTwoWay is guaranteed non-null after the filter.
|
|
2584
2779
|
.map((key) => twoWayBinding(key, (resolvedTwoWay[key] ??
|
|
2585
|
-
|
|
2780
|
+
linkedTwoWayFromInputGetter(resolvedInputs, key))));
|
|
2586
2781
|
const outputBindingsArray = Array.from(outputKeys)
|
|
2587
2782
|
.filter((key) => {
|
|
2588
2783
|
if (resolvedOutputs[key] == null) {
|
|
@@ -2593,15 +2788,6 @@ function createInputBindingsWithWarnings(ownerName, inputKeys, twoWayKeys, outpu
|
|
|
2593
2788
|
.map((key) => outputBinding(key, resolvedOutputs[key]));
|
|
2594
2789
|
return [...inputBindingsArray, ...twoWayBindingsArray, ...outputBindingsArray];
|
|
2595
2790
|
}
|
|
2596
|
-
/** JSON-like objects only — skip class instances, Date, Map, etc. */
|
|
2597
|
-
function isPlainObject(value) {
|
|
2598
|
-
if (value === null || typeof value !== 'object')
|
|
2599
|
-
return false;
|
|
2600
|
-
if (Array.isArray(value))
|
|
2601
|
-
return false;
|
|
2602
|
-
const proto = Object.getPrototypeOf(value);
|
|
2603
|
-
return proto === null || proto === Object.prototype;
|
|
2604
|
-
}
|
|
2605
2791
|
class BlockLoaderService {
|
|
2606
2792
|
componentRegistry = ComponentRegistry.getInstance();
|
|
2607
2793
|
directiveRegistry = DirectiveRegistry.getInstance();
|
|
@@ -2780,9 +2966,9 @@ class BlockLoaderService {
|
|
|
2780
2966
|
}
|
|
2781
2967
|
}
|
|
2782
2968
|
else {
|
|
2783
|
-
const hasTemplates =
|
|
2969
|
+
const hasTemplates = valueContainsMustacheInTree(directiveModel);
|
|
2784
2970
|
blockInstanceModel = hasTemplates
|
|
2785
|
-
? linkedSignal(() =>
|
|
2971
|
+
? linkedSignal(() => resolveNestedTemplateValues(blockModel(), this.withModelOverrideContext(ctx, blockModel), 'model', new WeakSet(), { resolveTwoWayStringsAsReadonly: false }))
|
|
2786
2972
|
: blockModel;
|
|
2787
2973
|
}
|
|
2788
2974
|
if (blockInstanceModel != null) {
|
|
@@ -2792,43 +2978,6 @@ class BlockLoaderService {
|
|
|
2792
2978
|
blockInstance.model = blockInstanceModel;
|
|
2793
2979
|
}
|
|
2794
2980
|
}
|
|
2795
|
-
valueContainsTemplate(value, visited = new WeakSet()) {
|
|
2796
|
-
if (typeof value === 'string') {
|
|
2797
|
-
return value.includes('{{') && value.includes('}}');
|
|
2798
|
-
}
|
|
2799
|
-
if (Array.isArray(value)) {
|
|
2800
|
-
return value.some((item) => this.valueContainsTemplate(item, visited));
|
|
2801
|
-
}
|
|
2802
|
-
if (value != null && typeof value === 'object') {
|
|
2803
|
-
if (!isPlainObject(value))
|
|
2804
|
-
return false;
|
|
2805
|
-
if (visited.has(value))
|
|
2806
|
-
return false;
|
|
2807
|
-
visited.add(value);
|
|
2808
|
-
return Object.values(value).some((item) => this.valueContainsTemplate(item, visited));
|
|
2809
|
-
}
|
|
2810
|
-
return false;
|
|
2811
|
-
}
|
|
2812
|
-
resolveNestedModelTemplates(value, ctx, visited = new WeakSet()) {
|
|
2813
|
-
if (typeof value === 'string') {
|
|
2814
|
-
return resolveTemplateString(value, ctx);
|
|
2815
|
-
}
|
|
2816
|
-
if (Array.isArray(value)) {
|
|
2817
|
-
return value.map((item) => this.resolveNestedModelTemplates(item, ctx, visited));
|
|
2818
|
-
}
|
|
2819
|
-
if (value != null && typeof value === 'object') {
|
|
2820
|
-
if (!isPlainObject(value))
|
|
2821
|
-
return value;
|
|
2822
|
-
if (visited.has(value))
|
|
2823
|
-
return value;
|
|
2824
|
-
visited.add(value);
|
|
2825
|
-
return Object.fromEntries(Object.entries(value).map(([key, item]) => [
|
|
2826
|
-
key,
|
|
2827
|
-
this.resolveNestedModelTemplates(item, ctx, visited),
|
|
2828
|
-
]));
|
|
2829
|
-
}
|
|
2830
|
-
return value;
|
|
2831
|
-
}
|
|
2832
2981
|
withModelOverrideContext(ctx, model) {
|
|
2833
2982
|
if (ctx.currentInstance == null)
|
|
2834
2983
|
return ctx;
|
|
@@ -2840,10 +2989,10 @@ class BlockLoaderService {
|
|
|
2840
2989
|
},
|
|
2841
2990
|
};
|
|
2842
2991
|
}
|
|
2843
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.
|
|
2844
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.
|
|
2992
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockLoaderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
2993
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockLoaderService, providedIn: 'root' });
|
|
2845
2994
|
}
|
|
2846
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.
|
|
2995
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockLoaderService, decorators: [{
|
|
2847
2996
|
type: Injectable,
|
|
2848
2997
|
args: [{ providedIn: 'root' }]
|
|
2849
2998
|
}] });
|
|
@@ -2867,10 +3016,117 @@ function safeJsonKey(value) {
|
|
|
2867
3016
|
return String(value);
|
|
2868
3017
|
}
|
|
2869
3018
|
}
|
|
3019
|
+
|
|
3020
|
+
function createInitialBlockDirectiveLoadState() {
|
|
3021
|
+
return {
|
|
3022
|
+
loadResult: null,
|
|
3023
|
+
lastRegistry: null,
|
|
3024
|
+
lastId: null,
|
|
3025
|
+
loadedComponent: null,
|
|
3026
|
+
loadedServicesKey: null,
|
|
3027
|
+
loadedReloadKey: null,
|
|
3028
|
+
loadedDescKey: null,
|
|
3029
|
+
loadGeneration: 0,
|
|
3030
|
+
effectRunId: 0,
|
|
3031
|
+
lastDescRef: null,
|
|
3032
|
+
lastParsedData: null,
|
|
3033
|
+
};
|
|
3034
|
+
}
|
|
3035
|
+
function clearBlockDirective(state, viewContainerRef) {
|
|
3036
|
+
state.loadGeneration++;
|
|
3037
|
+
state.lastDescRef = null;
|
|
3038
|
+
state.lastParsedData = null;
|
|
3039
|
+
if (state.lastId != null) {
|
|
3040
|
+
state.lastRegistry?.unregister(state.lastId);
|
|
3041
|
+
state.lastId = null;
|
|
3042
|
+
}
|
|
3043
|
+
if (state.loadResult) {
|
|
3044
|
+
viewContainerRef.clear();
|
|
3045
|
+
state.loadResult = null;
|
|
3046
|
+
state.loadedComponent = null;
|
|
3047
|
+
state.loadedServicesKey = null;
|
|
3048
|
+
state.loadedReloadKey = null;
|
|
3049
|
+
state.loadedDescKey = null;
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
function runBlockDirectiveEffect(state, ctx, desc, inputDefs, blockRegistry, reloadKey) {
|
|
3053
|
+
const runId = ++state.effectRunId;
|
|
3054
|
+
if (desc == null) {
|
|
3055
|
+
state.lastDescRef = null;
|
|
3056
|
+
state.lastParsedData = null;
|
|
3057
|
+
clearBlockDirective(state, ctx.viewContainerRef);
|
|
3058
|
+
return;
|
|
3059
|
+
}
|
|
3060
|
+
const runAfterResolved = (resolved) => {
|
|
3061
|
+
if (runId !== state.effectRunId) {
|
|
3062
|
+
return;
|
|
3063
|
+
}
|
|
3064
|
+
let data;
|
|
3065
|
+
if (resolved === state.lastDescRef && state.lastParsedData != null) {
|
|
3066
|
+
data = state.lastParsedData;
|
|
3067
|
+
}
|
|
3068
|
+
else {
|
|
3069
|
+
const parsed = safeParseBlockDescription(resolved);
|
|
3070
|
+
if (!parsed.success) {
|
|
3071
|
+
return;
|
|
3072
|
+
}
|
|
3073
|
+
state.lastDescRef = resolved;
|
|
3074
|
+
state.lastParsedData = parsed.data;
|
|
3075
|
+
data = parsed.data;
|
|
3076
|
+
}
|
|
3077
|
+
const servicesKey = getServicesKey(data.services);
|
|
3078
|
+
const descKey = safeJsonKey(resolved);
|
|
3079
|
+
const effectiveReloadKey = reloadKey ?? descKey;
|
|
3080
|
+
const mustReload = state.loadResult == null ||
|
|
3081
|
+
state.loadedComponent !== data.component ||
|
|
3082
|
+
state.loadedServicesKey !== servicesKey ||
|
|
3083
|
+
state.loadedReloadKey !== effectiveReloadKey ||
|
|
3084
|
+
state.loadedDescKey !== descKey;
|
|
3085
|
+
if (!mustReload) {
|
|
3086
|
+
return;
|
|
3087
|
+
}
|
|
3088
|
+
clearBlockDirective(state, ctx.viewContainerRef);
|
|
3089
|
+
const registry = blockRegistry ?? undefined;
|
|
3090
|
+
state.lastRegistry = registry ?? null;
|
|
3091
|
+
state.lastId = data.id ?? null;
|
|
3092
|
+
const generation = ++state.loadGeneration;
|
|
3093
|
+
ctx
|
|
3094
|
+
.loadBlock(resolved, registry, inputDefs ?? undefined)
|
|
3095
|
+
.then((result) => {
|
|
3096
|
+
if (generation !== state.loadGeneration)
|
|
3097
|
+
return;
|
|
3098
|
+
state.loadResult = result;
|
|
3099
|
+
state.loadedComponent = data.component;
|
|
3100
|
+
state.loadedServicesKey = servicesKey;
|
|
3101
|
+
state.loadedReloadKey = effectiveReloadKey;
|
|
3102
|
+
state.loadedDescKey = descKey;
|
|
3103
|
+
})
|
|
3104
|
+
.catch((err) => {
|
|
3105
|
+
if (generation !== state.loadGeneration)
|
|
3106
|
+
return;
|
|
3107
|
+
console.error('Block load failed:', err);
|
|
3108
|
+
});
|
|
3109
|
+
};
|
|
3110
|
+
if (isBlockReference(desc)) {
|
|
3111
|
+
void resolveBlockReference(desc, inputDefs ?? undefined)
|
|
3112
|
+
.then((resolved) => {
|
|
3113
|
+
runAfterResolved(resolved);
|
|
3114
|
+
})
|
|
3115
|
+
.catch((err) => {
|
|
3116
|
+
if (runId !== state.effectRunId)
|
|
3117
|
+
return;
|
|
3118
|
+
console.error('Block reference resolution failed:', err);
|
|
3119
|
+
});
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
runAfterResolved(desc);
|
|
3123
|
+
}
|
|
3124
|
+
|
|
2870
3125
|
class BlockDirective {
|
|
2871
3126
|
viewContainerRef = inject(ViewContainerRef);
|
|
2872
3127
|
loader = inject(BlockLoaderService);
|
|
2873
3128
|
destroyRef = inject(DestroyRef);
|
|
3129
|
+
loadState = createInitialBlockDirectiveLoadState();
|
|
2874
3130
|
/** Full description, or { id } / { blockId, blockDefinition? } to reuse/override from blockDefinitions. */
|
|
2875
3131
|
description = input(null, /* @ts-ignore */
|
|
2876
3132
|
...(ngDevMode ? [{ debugName: "description" }] : /* istanbul ignore next */ []));
|
|
@@ -2889,124 +3145,25 @@ class BlockDirective {
|
|
|
2889
3145
|
*/
|
|
2890
3146
|
reloadKey = input(null, /* @ts-ignore */
|
|
2891
3147
|
...(ngDevMode ? [{ debugName: "reloadKey" }] : /* istanbul ignore next */ []));
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
loadedDescKey = null;
|
|
2899
|
-
loadGeneration = 0;
|
|
2900
|
-
/** Invalidates in-flight block-reference resolution when the effect re-runs. */
|
|
2901
|
-
effectRunId = 0;
|
|
2902
|
-
/** Avoid re-parsing when the same description reference is passed (e.g. stable signal). */
|
|
2903
|
-
lastDescRef = null;
|
|
2904
|
-
lastParsedData = null;
|
|
3148
|
+
loadBlock(resolved, registry, blockDefinitions) {
|
|
3149
|
+
return this.loader.load(resolved, this.viewContainerRef, this.model, {
|
|
3150
|
+
registry,
|
|
3151
|
+
blockDefinitions,
|
|
3152
|
+
});
|
|
3153
|
+
}
|
|
2905
3154
|
constructor() {
|
|
2906
3155
|
effect(() => {
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
if (desc == null) {
|
|
2912
|
-
this.lastDescRef = null;
|
|
2913
|
-
this.lastParsedData = null;
|
|
2914
|
-
this.clear();
|
|
2915
|
-
return;
|
|
2916
|
-
}
|
|
2917
|
-
const runAfterResolved = (resolved) => {
|
|
2918
|
-
if (runId !== this.effectRunId) {
|
|
2919
|
-
return;
|
|
2920
|
-
}
|
|
2921
|
-
let data;
|
|
2922
|
-
if (resolved === this.lastDescRef && this.lastParsedData != null) {
|
|
2923
|
-
data = this.lastParsedData;
|
|
2924
|
-
}
|
|
2925
|
-
else {
|
|
2926
|
-
const parsed = safeParseBlockDescription(resolved);
|
|
2927
|
-
if (!parsed.success) {
|
|
2928
|
-
return;
|
|
2929
|
-
}
|
|
2930
|
-
this.lastDescRef = resolved;
|
|
2931
|
-
this.lastParsedData = parsed.data;
|
|
2932
|
-
data = parsed.data;
|
|
2933
|
-
}
|
|
2934
|
-
const servicesKey = getServicesKey(data.services);
|
|
2935
|
-
const descKey = safeJsonKey(resolved);
|
|
2936
|
-
const effectiveReloadKey = reloadKey ?? descKey;
|
|
2937
|
-
// Only clear when the logical description changed (component or services). Avoids
|
|
2938
|
-
// clear+reload when the parent passes a new reference with the same content (e.g. BlockFor).
|
|
2939
|
-
const mustReload = this.loadResult == null ||
|
|
2940
|
-
this.loadedComponent !== data.component ||
|
|
2941
|
-
this.loadedServicesKey !== servicesKey ||
|
|
2942
|
-
this.loadedReloadKey !== effectiveReloadKey ||
|
|
2943
|
-
this.loadedDescKey !== descKey;
|
|
2944
|
-
if (!mustReload) {
|
|
2945
|
-
// Description is logically unchanged (same component + services); no work needed.
|
|
2946
|
-
return;
|
|
2947
|
-
}
|
|
2948
|
-
this.clear();
|
|
2949
|
-
const registry = this.blockRegistry() ?? undefined;
|
|
2950
|
-
this.lastRegistry = registry ?? null;
|
|
2951
|
-
this.lastId = data.id ?? null;
|
|
2952
|
-
const generation = ++this.loadGeneration;
|
|
2953
|
-
this.loader
|
|
2954
|
-
.load(resolved, this.viewContainerRef, this.model, {
|
|
2955
|
-
registry,
|
|
2956
|
-
blockDefinitions: inputDefs ?? undefined,
|
|
2957
|
-
})
|
|
2958
|
-
.then((result) => {
|
|
2959
|
-
if (generation !== this.loadGeneration)
|
|
2960
|
-
return;
|
|
2961
|
-
this.loadResult = result;
|
|
2962
|
-
this.loadedComponent = data.component;
|
|
2963
|
-
this.loadedServicesKey = servicesKey;
|
|
2964
|
-
this.loadedReloadKey = effectiveReloadKey;
|
|
2965
|
-
this.loadedDescKey = descKey;
|
|
2966
|
-
})
|
|
2967
|
-
.catch((err) => {
|
|
2968
|
-
if (generation !== this.loadGeneration)
|
|
2969
|
-
return;
|
|
2970
|
-
console.error('Block load failed:', err);
|
|
2971
|
-
});
|
|
2972
|
-
};
|
|
2973
|
-
if (isBlockReference(desc)) {
|
|
2974
|
-
void resolveBlockReference(desc, inputDefs ?? undefined)
|
|
2975
|
-
.then((resolved) => {
|
|
2976
|
-
runAfterResolved(resolved);
|
|
2977
|
-
})
|
|
2978
|
-
.catch((err) => {
|
|
2979
|
-
if (runId !== this.effectRunId)
|
|
2980
|
-
return;
|
|
2981
|
-
console.error('Block reference resolution failed:', err);
|
|
2982
|
-
});
|
|
2983
|
-
return;
|
|
2984
|
-
}
|
|
2985
|
-
runAfterResolved(desc);
|
|
3156
|
+
runBlockDirectiveEffect(this.loadState, {
|
|
3157
|
+
viewContainerRef: this.viewContainerRef,
|
|
3158
|
+
loadBlock: this.loadBlock.bind(this),
|
|
3159
|
+
}, this.description(), this.blockDefinitions(), this.blockRegistry(), this.reloadKey());
|
|
2986
3160
|
});
|
|
2987
|
-
this.destroyRef.onDestroy(() => this.
|
|
3161
|
+
this.destroyRef.onDestroy(() => clearBlockDirective(this.loadState, this.viewContainerRef));
|
|
2988
3162
|
}
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
if (this.lastId != null) {
|
|
2994
|
-
this.lastRegistry?.unregister(this.lastId);
|
|
2995
|
-
this.lastId = null;
|
|
2996
|
-
}
|
|
2997
|
-
if (this.loadResult) {
|
|
2998
|
-
this.viewContainerRef.clear();
|
|
2999
|
-
this.loadResult = null;
|
|
3000
|
-
this.loadedComponent = null;
|
|
3001
|
-
this.loadedServicesKey = null;
|
|
3002
|
-
this.loadedReloadKey = null;
|
|
3003
|
-
this.loadedDescKey = null;
|
|
3004
|
-
}
|
|
3005
|
-
}
|
|
3006
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: BlockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3007
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.7", type: BlockDirective, isStandalone: true, selector: "[block]", inputs: { description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, blockRegistry: { classPropertyName: "blockRegistry", publicName: "blockRegistry", isSignal: true, isRequired: false, transformFunction: null }, blockDefinitions: { classPropertyName: "blockDefinitions", publicName: "blockDefinitions", isSignal: true, isRequired: false, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, reloadKey: { classPropertyName: "reloadKey", publicName: "reloadKey", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
3008
|
-
}
|
|
3009
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImport: i0, type: BlockDirective, decorators: [{
|
|
3163
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
3164
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.2.3", type: BlockDirective, isStandalone: true, selector: "[block]", inputs: { description: { classPropertyName: "description", publicName: "description", isSignal: true, isRequired: false, transformFunction: null }, blockRegistry: { classPropertyName: "blockRegistry", publicName: "blockRegistry", isSignal: true, isRequired: false, transformFunction: null }, blockDefinitions: { classPropertyName: "blockDefinitions", publicName: "blockDefinitions", isSignal: true, isRequired: false, transformFunction: null }, model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, reloadKey: { classPropertyName: "reloadKey", publicName: "reloadKey", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
|
|
3165
|
+
}
|
|
3166
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.2.3", ngImport: i0, type: BlockDirective, decorators: [{
|
|
3010
3167
|
type: Directive,
|
|
3011
3168
|
args: [{
|
|
3012
3169
|
selector: '[block]',
|
|
@@ -3022,5 +3179,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.7", ngImpor
|
|
|
3022
3179
|
* Generated bundle index. Do not edit.
|
|
3023
3180
|
*/
|
|
3024
3181
|
|
|
3025
|
-
export { BlockDefinitionsRegistry, BlockDirective, BlockLoaderService, BlockRegistryImpl, BlockRegistryService, ChainedBlockRegistry, ComponentRegistry, DirectiveRegistry, GuardRegistry, INTERPOLATE_MAX_PLACEHOLDERS, RegistryMetadataStore, RouteLoader, ServiceRegistry, buildComputedForTemplate, classifyTwoWayString, collectRefPaths, createOutputHandler, deepMergeBlockDefinition, evaluateExpression, extractReadonlyRefs, getRefPathFromReadonly, getRefSignal, getRefValue, getValueByPath, interpretFlow, isBlockDefinitionLoader, isBlockReference, isInvalidTwoWayMix, isOutputCallObject, isOutputReference, isTwoWayRefString, looksLikeFlowTemplate, mustacheSegmentToString, normalizeDirectives, normalizeServices, parseFlowTemplate, parseRefPath, parseTwoWayRef, refPathResolvesToSignal, resolveBlockReference, resolveMustacheInterpolatedString, resolveRefOrModel, resolveRefPath, resolveReferenceValue, resolveTemplateString, safeParseBlockDescription, setRefValue, splitCallableRef };
|
|
3182
|
+
export { BlockDefinitionsRegistry, BlockDirective, BlockLoaderService, BlockRegistryImpl, BlockRegistryService, ChainedBlockRegistry, ComponentRegistry, DirectiveRegistry, GuardRegistry, INTERPOLATE_MAX_PLACEHOLDERS, RegistryMetadataStore, RouteLoader, ServiceRegistry, buildComputedForTemplate, classifyTwoWayString, collectRefPaths, createInputBindingsWithWarnings, createOutputHandler, deepMergeBlockDefinition, evaluateExpression, extractReadonlyRefs, getRefPathFromReadonly, getRefSignal, getRefValue, getValueByPath, interpretFlow, isBlockDefinitionLoader, isBlockReference, isInvalidTwoWayMix, isOutputCallObject, isOutputReference, isPlainObject, isTwoWayRefString, linkedTwoWayFromInputGetter, looksLikeBlockDescriptor, looksLikeFlowTemplate, mustacheSegmentToString, normalizeDirectives, normalizeServices, parseFlowTemplate, parseRefPath, parseTwoWayRef, refPathResolvesToSignal, resolveBlockReference, resolveMustacheInterpolatedString, resolveNestedTemplateValues, resolveRefOrModel, resolveRefPath, resolveReferenceValue, resolveTemplateString, safeParseBlockDescription, setRefValue, shouldDeferInputTemplateResolution, splitCallableRef, valueContainsMustacheInTree, valueNeedsInputResolve };
|
|
3026
3183
|
//# sourceMappingURL=ngx-blocks-studio.mjs.map
|