@mintjamsinc/ichigojs 0.1.73 → 0.1.75
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.
- package/README.md +99 -1
- package/dist/ichigo.cjs +369 -8
- package/dist/ichigo.cjs.map +1 -1
- package/dist/ichigo.esm.js +369 -8
- package/dist/ichigo.esm.js.map +1 -1
- package/dist/ichigo.esm.min.js +1 -1
- package/dist/ichigo.min.cjs +1 -1
- package/dist/ichigo.umd.js +369 -8
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/dist/types/ichigo/VApplication.d.ts +27 -0
- package/dist/types/ichigo/VBindings.d.ts +11 -0
- package/dist/types/ichigo/directives/StandardDirectiveName.d.ts +3 -1
- package/dist/types/ichigo/directives/VRefDirective.d.ts +94 -0
- package/dist/types/ichigo/directives/VStandardDirectiveParser.d.ts +1 -0
- package/package.json +1 -1
package/dist/ichigo.esm.js
CHANGED
|
@@ -173,6 +173,8 @@ var StandardDirectiveName;
|
|
|
173
173
|
StandardDirectiveName["V_TEXT"] = "v-text";
|
|
174
174
|
/** Focus management directive. */
|
|
175
175
|
StandardDirectiveName["V_FOCUS"] = "v-focus";
|
|
176
|
+
/** Template reference directive (Vue's `ref` / `$refs`). */
|
|
177
|
+
StandardDirectiveName["REF"] = "ref";
|
|
176
178
|
})(StandardDirectiveName || (StandardDirectiveName = {}));
|
|
177
179
|
|
|
178
180
|
// This file was generated. Do not modify manually!
|
|
@@ -8434,6 +8436,13 @@ class VBindings {
|
|
|
8434
8436
|
* Flag to suppress onChange callbacks temporarily.
|
|
8435
8437
|
*/
|
|
8436
8438
|
#suppressOnChange = false;
|
|
8439
|
+
/**
|
|
8440
|
+
* Flag forcing the next write through the `set` trap to stay in THIS scope's own
|
|
8441
|
+
* local store instead of walking up to an inherited binding of the same name.
|
|
8442
|
+
* Set only by {@link setLocal} for scope-local variables (e.g. v-for loop items),
|
|
8443
|
+
* which must shadow — never overwrite — a parent binding with the same key.
|
|
8444
|
+
*/
|
|
8445
|
+
#localWrite = false;
|
|
8437
8446
|
/**
|
|
8438
8447
|
* Per-instance path aliases. Maps local variable names to their reactive source paths.
|
|
8439
8448
|
* Scoped here instead of the global ReactiveProxy map so that v-for items each maintain
|
|
@@ -8512,8 +8521,13 @@ class VBindings {
|
|
|
8512
8521
|
setter(value);
|
|
8513
8522
|
return true;
|
|
8514
8523
|
}
|
|
8524
|
+
// For a key that is not local to this scope, an assignment normally
|
|
8525
|
+
// retargets to the nearest parent that owns it, so reassignments
|
|
8526
|
+
// (e.g. `count = count + 1` in a handler) mutate the original binding.
|
|
8527
|
+
// A scope-local write (setLocal — used for v-for loop variables) skips
|
|
8528
|
+
// this walk so the variable shadows, never clobbers, an inherited key.
|
|
8515
8529
|
let target = obj;
|
|
8516
|
-
if (!Reflect.has(target, key)) {
|
|
8530
|
+
if (!this.#localWrite && !Reflect.has(target, key)) {
|
|
8517
8531
|
for (let parent = this.#parent; parent; parent = parent.#parent) {
|
|
8518
8532
|
if (Reflect.has(parent.#local, key)) {
|
|
8519
8533
|
target = parent.#local;
|
|
@@ -8688,6 +8702,25 @@ class VBindings {
|
|
|
8688
8702
|
set(key, value) {
|
|
8689
8703
|
this.#local[key] = value;
|
|
8690
8704
|
}
|
|
8705
|
+
/**
|
|
8706
|
+
* Sets a binding value in THIS scope's own local store, without walking up to a
|
|
8707
|
+
* parent scope. Used for scope-local variables (e.g. v-for loop items) that must
|
|
8708
|
+
* shadow — never overwrite — an inherited binding of the same name. Contrast with
|
|
8709
|
+
* {@link set}, which retargets a write of an inherited key to the owning parent so
|
|
8710
|
+
* that reassignments mutate the original; a loop variable named like a root data /
|
|
8711
|
+
* method / computed key (e.g. `t`) would otherwise clobber it.
|
|
8712
|
+
* @param key The binding name.
|
|
8713
|
+
* @param value The binding value.
|
|
8714
|
+
*/
|
|
8715
|
+
setLocal(key, value) {
|
|
8716
|
+
this.#localWrite = true;
|
|
8717
|
+
try {
|
|
8718
|
+
this.#local[key] = value;
|
|
8719
|
+
}
|
|
8720
|
+
finally {
|
|
8721
|
+
this.#localWrite = false;
|
|
8722
|
+
}
|
|
8723
|
+
}
|
|
8691
8724
|
/**
|
|
8692
8725
|
* Gets a binding value.
|
|
8693
8726
|
* @param key The binding name.
|
|
@@ -10783,26 +10816,30 @@ class VForDirective {
|
|
|
10783
10816
|
* Sets item bindings for a VNode, handling nested destructuring if needed.
|
|
10784
10817
|
*/
|
|
10785
10818
|
#setItemBindings(bindings, context) {
|
|
10819
|
+
// Loop variables are scope-local: they must shadow, never overwrite, an
|
|
10820
|
+
// inherited binding of the same name (a data / method / computed key on a
|
|
10821
|
+
// parent scope). setLocal writes to this iteration's own store so a loop
|
|
10822
|
+
// variable named like e.g. the i18n helper `t` cannot clobber it.
|
|
10786
10823
|
if (this.#itemDestructure && Array.isArray(context.item)) {
|
|
10787
10824
|
// Nested destructuring: spread array items to individual bindings
|
|
10788
10825
|
// e.g., item = ['alice', 1] with itemDestructure = ['k', 'v']
|
|
10789
|
-
// bindings.
|
|
10790
|
-
// bindings.
|
|
10826
|
+
// bindings.setLocal('k', 'alice')
|
|
10827
|
+
// bindings.setLocal('v', 1)
|
|
10791
10828
|
this.#itemDestructure.forEach((name, i) => {
|
|
10792
|
-
bindings.
|
|
10829
|
+
bindings.setLocal(name, context.item[i]);
|
|
10793
10830
|
});
|
|
10794
10831
|
}
|
|
10795
10832
|
else if (this.#itemName) {
|
|
10796
10833
|
// Simple item binding
|
|
10797
|
-
bindings.
|
|
10834
|
+
bindings.setLocal(this.#itemName, context.item);
|
|
10798
10835
|
}
|
|
10799
10836
|
if (this.#indexName) {
|
|
10800
10837
|
// For objects, use objectKey if available; otherwise use numeric index
|
|
10801
|
-
bindings.
|
|
10838
|
+
bindings.setLocal(this.#indexName, context.objectKey ?? context.index);
|
|
10802
10839
|
}
|
|
10803
10840
|
if (this.#thirdName) {
|
|
10804
10841
|
// Third argument is always the numeric index
|
|
10805
|
-
bindings.
|
|
10842
|
+
bindings.setLocal(this.#thirdName, context.index);
|
|
10806
10843
|
}
|
|
10807
10844
|
}
|
|
10808
10845
|
/**
|
|
@@ -13306,6 +13343,240 @@ class VFocusDirective {
|
|
|
13306
13343
|
}
|
|
13307
13344
|
}
|
|
13308
13345
|
|
|
13346
|
+
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
|
13347
|
+
/**
|
|
13348
|
+
* Directive for registering template references (Vue's `ref` / `$refs`).
|
|
13349
|
+
*
|
|
13350
|
+
* Usage:
|
|
13351
|
+
* <input ref="search"> Static name. $refs.search === the element.
|
|
13352
|
+
* <my-card ref="card"></my-card> On a component: $refs.card === the host element.
|
|
13353
|
+
* <li v-for="i in items" ref="rows"> Inside v-for: $refs.rows === array of elements.
|
|
13354
|
+
* <input :ref="dynamicName"> Dynamic name from an expression (evaluated at mount).
|
|
13355
|
+
* <input :ref="el => collect(el)"> Function ref: called with the element on mount,
|
|
13356
|
+
* and with null on unmount (great for v-for / dynamic).
|
|
13357
|
+
*
|
|
13358
|
+
* Behavior notes:
|
|
13359
|
+
* - The reference is registered during the mount phase (before any `@mounted` hook fires) and
|
|
13360
|
+
* removed during the unmount phase, mirroring Vue's lifecycle for `$refs`.
|
|
13361
|
+
* - `$refs` is intentionally NON-reactive: registering or clearing a ref never schedules a render
|
|
13362
|
+
* and must not be used to drive reactive template output (this matches Vue).
|
|
13363
|
+
* - When the same `ref` name appears inside a `v-for` (i.e. one of the element's ancestors is a
|
|
13364
|
+
* `v-for` template), the entries are collected into an array, in registration order. Reused
|
|
13365
|
+
* v-for rows are not re-registered, so the array order is not guaranteed to match DOM order after
|
|
13366
|
+
* reordering — the same caveat Vue documents.
|
|
13367
|
+
* - Cleanup is identity-safe: a ref slot (or array entry) is only cleared when it still points at
|
|
13368
|
+
* THIS element, so a freshly mounted element that reused the name is never clobbered by the
|
|
13369
|
+
* teardown of the element it replaced.
|
|
13370
|
+
*
|
|
13371
|
+
* The directive is purely lifecycle-driven: it has no DOM updater and never templatizes the node.
|
|
13372
|
+
*/
|
|
13373
|
+
class VRefDirective {
|
|
13374
|
+
/**
|
|
13375
|
+
* The virtual node to which this directive is applied.
|
|
13376
|
+
*/
|
|
13377
|
+
#vNode;
|
|
13378
|
+
/**
|
|
13379
|
+
* The static ref name parsed from `ref="name"`. Undefined for the dynamic `:ref` form.
|
|
13380
|
+
*/
|
|
13381
|
+
#staticName;
|
|
13382
|
+
/**
|
|
13383
|
+
* Expression evaluator for the dynamic `:ref` / `v-bind:ref` form. Undefined for static refs.
|
|
13384
|
+
*/
|
|
13385
|
+
#evaluator;
|
|
13386
|
+
/**
|
|
13387
|
+
* The name under which this element was actually registered, retained so unmount removes the
|
|
13388
|
+
* exact same slot it created (the dynamic name is evaluated once at mount and may differ from
|
|
13389
|
+
* the source expression). Undefined when nothing was registered (function ref, or empty value).
|
|
13390
|
+
*/
|
|
13391
|
+
#registeredName;
|
|
13392
|
+
/**
|
|
13393
|
+
* The function supplied by a function ref (`:ref="el => ..."`), retained so it can be invoked
|
|
13394
|
+
* with null on unmount. Undefined unless a function ref was used.
|
|
13395
|
+
*/
|
|
13396
|
+
#functionRef;
|
|
13397
|
+
/**
|
|
13398
|
+
* Whether this ref is registered in array mode (collected because it lives inside a v-for).
|
|
13399
|
+
* Resolved lazily at mount time via {@link #isInsideForLoop}.
|
|
13400
|
+
*/
|
|
13401
|
+
#asArray = false;
|
|
13402
|
+
/**
|
|
13403
|
+
* @param context The context for parsing the directive.
|
|
13404
|
+
*/
|
|
13405
|
+
constructor(context) {
|
|
13406
|
+
this.#vNode = context.vNode;
|
|
13407
|
+
const attrName = context.attribute.name;
|
|
13408
|
+
const isDynamic = attrName !== StandardDirectiveName.REF; // ":ref" or "v-bind:ref"
|
|
13409
|
+
if (isDynamic) {
|
|
13410
|
+
// Dynamic / function ref: the value is an expression.
|
|
13411
|
+
const expression = context.attribute.value;
|
|
13412
|
+
if (expression && context.vNode.bindings) {
|
|
13413
|
+
this.#evaluator = ExpressionEvaluator.create(expression, context.vNode.bindings, context.vNode.vApplication.functionDependencies);
|
|
13414
|
+
}
|
|
13415
|
+
}
|
|
13416
|
+
else {
|
|
13417
|
+
// Static ref: the value is the literal name.
|
|
13418
|
+
const name = context.attribute.value.trim();
|
|
13419
|
+
this.#staticName = name.length > 0 ? name : undefined;
|
|
13420
|
+
}
|
|
13421
|
+
// Remove the directive attribute from the element so it does not linger in the DOM.
|
|
13422
|
+
this.#vNode.node.removeAttribute(attrName);
|
|
13423
|
+
}
|
|
13424
|
+
/**
|
|
13425
|
+
* @inheritdoc
|
|
13426
|
+
*/
|
|
13427
|
+
get name() {
|
|
13428
|
+
return StandardDirectiveName.REF;
|
|
13429
|
+
}
|
|
13430
|
+
/**
|
|
13431
|
+
* @inheritdoc
|
|
13432
|
+
*/
|
|
13433
|
+
get vNode() {
|
|
13434
|
+
return this.#vNode;
|
|
13435
|
+
}
|
|
13436
|
+
/**
|
|
13437
|
+
* @inheritdoc
|
|
13438
|
+
*/
|
|
13439
|
+
get needsAnchor() {
|
|
13440
|
+
return false;
|
|
13441
|
+
}
|
|
13442
|
+
/**
|
|
13443
|
+
* @inheritdoc
|
|
13444
|
+
*/
|
|
13445
|
+
get bindingsPreparer() {
|
|
13446
|
+
return undefined;
|
|
13447
|
+
}
|
|
13448
|
+
/**
|
|
13449
|
+
* @inheritdoc
|
|
13450
|
+
*/
|
|
13451
|
+
get domUpdater() {
|
|
13452
|
+
// Refs are resolved once at mount; they are deliberately not reactive (see class docs).
|
|
13453
|
+
return undefined;
|
|
13454
|
+
}
|
|
13455
|
+
/**
|
|
13456
|
+
* @inheritdoc
|
|
13457
|
+
*/
|
|
13458
|
+
get templatize() {
|
|
13459
|
+
return false;
|
|
13460
|
+
}
|
|
13461
|
+
/**
|
|
13462
|
+
* @inheritdoc
|
|
13463
|
+
*/
|
|
13464
|
+
get dependentIdentifiers() {
|
|
13465
|
+
// This directive never drives reactive updates, so it contributes no dependencies.
|
|
13466
|
+
return [];
|
|
13467
|
+
}
|
|
13468
|
+
/**
|
|
13469
|
+
* @inheritdoc
|
|
13470
|
+
*/
|
|
13471
|
+
get onMount() {
|
|
13472
|
+
// Register during the mount phase so the reference is available before any `@mounted`
|
|
13473
|
+
// hook runs (those fire a frame later via requestAnimationFrame).
|
|
13474
|
+
return () => this.#register();
|
|
13475
|
+
}
|
|
13476
|
+
/**
|
|
13477
|
+
* @inheritdoc
|
|
13478
|
+
*/
|
|
13479
|
+
get onMounted() {
|
|
13480
|
+
return undefined;
|
|
13481
|
+
}
|
|
13482
|
+
/**
|
|
13483
|
+
* @inheritdoc
|
|
13484
|
+
*/
|
|
13485
|
+
get onUpdate() {
|
|
13486
|
+
return undefined;
|
|
13487
|
+
}
|
|
13488
|
+
/**
|
|
13489
|
+
* @inheritdoc
|
|
13490
|
+
*/
|
|
13491
|
+
get onUpdated() {
|
|
13492
|
+
return undefined;
|
|
13493
|
+
}
|
|
13494
|
+
/**
|
|
13495
|
+
* @inheritdoc
|
|
13496
|
+
*/
|
|
13497
|
+
get onUnmount() {
|
|
13498
|
+
return undefined;
|
|
13499
|
+
}
|
|
13500
|
+
/**
|
|
13501
|
+
* @inheritdoc
|
|
13502
|
+
*/
|
|
13503
|
+
get onUnmounted() {
|
|
13504
|
+
// Clear during the unmount phase. The element reference is still valid here.
|
|
13505
|
+
return () => this.#unregister();
|
|
13506
|
+
}
|
|
13507
|
+
/**
|
|
13508
|
+
* @inheritdoc
|
|
13509
|
+
*/
|
|
13510
|
+
destroy() {
|
|
13511
|
+
// No additional cleanup beyond onUnmounted; kept for interface completeness.
|
|
13512
|
+
}
|
|
13513
|
+
/**
|
|
13514
|
+
* Registers this element under its resolved ref name (or invokes its function ref).
|
|
13515
|
+
*/
|
|
13516
|
+
#register() {
|
|
13517
|
+
const element = this.#vNode.node;
|
|
13518
|
+
if (this.#evaluator) {
|
|
13519
|
+
// Dynamic / function ref.
|
|
13520
|
+
let value;
|
|
13521
|
+
try {
|
|
13522
|
+
value = this.#evaluator.evaluate();
|
|
13523
|
+
}
|
|
13524
|
+
catch {
|
|
13525
|
+
// Evaluation errors are already logged by ExpressionEvaluator; nothing to register.
|
|
13526
|
+
return;
|
|
13527
|
+
}
|
|
13528
|
+
if (typeof value === 'function') {
|
|
13529
|
+
this.#functionRef = value;
|
|
13530
|
+
this.#functionRef(element);
|
|
13531
|
+
return;
|
|
13532
|
+
}
|
|
13533
|
+
if (value === null || value === undefined || value === '') {
|
|
13534
|
+
return; // Nothing to register under an empty dynamic name.
|
|
13535
|
+
}
|
|
13536
|
+
this.#registeredName = String(value);
|
|
13537
|
+
}
|
|
13538
|
+
else if (this.#staticName) {
|
|
13539
|
+
this.#registeredName = this.#staticName;
|
|
13540
|
+
}
|
|
13541
|
+
if (!this.#registeredName) {
|
|
13542
|
+
return;
|
|
13543
|
+
}
|
|
13544
|
+
this.#asArray = this.#isInsideForLoop();
|
|
13545
|
+
this.#vNode.vApplication.registerRef(this.#registeredName, element, this.#asArray);
|
|
13546
|
+
}
|
|
13547
|
+
/**
|
|
13548
|
+
* Removes this element's reference (or invokes its function ref with null).
|
|
13549
|
+
*/
|
|
13550
|
+
#unregister() {
|
|
13551
|
+
if (this.#functionRef) {
|
|
13552
|
+
this.#functionRef(null);
|
|
13553
|
+
this.#functionRef = undefined;
|
|
13554
|
+
return;
|
|
13555
|
+
}
|
|
13556
|
+
if (this.#registeredName) {
|
|
13557
|
+
this.#vNode.vApplication.unregisterRef(this.#registeredName, this.#vNode.node);
|
|
13558
|
+
this.#registeredName = undefined;
|
|
13559
|
+
}
|
|
13560
|
+
}
|
|
13561
|
+
/**
|
|
13562
|
+
* Determines whether this element is rendered inside a `v-for` by walking up the VNode tree.
|
|
13563
|
+
* A `v-for` multiplies its template into N rows, so a static ref name on (or within) a row is
|
|
13564
|
+
* shared by N elements and must be collected into an array — matching Vue's documented
|
|
13565
|
+
* "ref inside v-for yields an array" behavior. The walk inspects ancestors only: the directive
|
|
13566
|
+
* lives on a cloned row (or a descendant of one), and the clone's parent chain leads back to the
|
|
13567
|
+
* `v-for` template node, which still carries the `v-for` directive.
|
|
13568
|
+
*/
|
|
13569
|
+
#isInsideForLoop() {
|
|
13570
|
+
for (let ancestor = this.#vNode.parentVNode; ancestor; ancestor = ancestor.parentVNode) {
|
|
13571
|
+
const hasFor = ancestor.directiveManager?.directives?.some(d => d.name === StandardDirectiveName.V_FOR);
|
|
13572
|
+
if (hasFor) {
|
|
13573
|
+
return true;
|
|
13574
|
+
}
|
|
13575
|
+
}
|
|
13576
|
+
return false;
|
|
13577
|
+
}
|
|
13578
|
+
}
|
|
13579
|
+
|
|
13309
13580
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
|
13310
13581
|
/**
|
|
13311
13582
|
* The directive parser for standard directives.
|
|
@@ -13350,15 +13621,33 @@ class VStandardDirectiveParser {
|
|
|
13350
13621
|
context.attribute.name === StandardDirectiveName.V_TEXT ||
|
|
13351
13622
|
// v-focus, v-focus.<modifier>
|
|
13352
13623
|
context.attribute.name === StandardDirectiveName.V_FOCUS ||
|
|
13353
|
-
context.attribute.name.startsWith(StandardDirectiveName.V_FOCUS + ".")
|
|
13624
|
+
context.attribute.name.startsWith(StandardDirectiveName.V_FOCUS + ".") ||
|
|
13625
|
+
// ref, :ref, v-bind:ref
|
|
13626
|
+
this.#isRefAttribute(context.attribute.name)) {
|
|
13354
13627
|
return true;
|
|
13355
13628
|
}
|
|
13356
13629
|
return false;
|
|
13357
13630
|
}
|
|
13631
|
+
/**
|
|
13632
|
+
* Determines whether the attribute is a template reference (`ref`, `:ref`, or `v-bind:ref`).
|
|
13633
|
+
* The dynamic forms also match the generic v-bind shorthand, so {@link parse} dispatches them
|
|
13634
|
+
* to VRefDirective explicitly before the v-bind branch is reached.
|
|
13635
|
+
*/
|
|
13636
|
+
#isRefAttribute(name) {
|
|
13637
|
+
return name === StandardDirectiveName.REF ||
|
|
13638
|
+
name === ":" + StandardDirectiveName.REF ||
|
|
13639
|
+
name === StandardDirectiveName.V_BIND + ":" + StandardDirectiveName.REF;
|
|
13640
|
+
}
|
|
13358
13641
|
/**
|
|
13359
13642
|
* @inheritdoc
|
|
13360
13643
|
*/
|
|
13361
13644
|
parse(context) {
|
|
13645
|
+
// ref, :ref, v-bind:ref
|
|
13646
|
+
// Checked before the v-bind branch below, since ":ref" / "v-bind:ref" also match the
|
|
13647
|
+
// generic v-bind shorthand but must be handled as template references, not attribute binds.
|
|
13648
|
+
if (this.#isRefAttribute(context.attribute.name)) {
|
|
13649
|
+
return new VRefDirective(context);
|
|
13650
|
+
}
|
|
13362
13651
|
if (context.attribute.name === StandardDirectiveName.V_IF) {
|
|
13363
13652
|
return new VIfDirective(context);
|
|
13364
13653
|
}
|
|
@@ -13795,6 +14084,17 @@ class VApplication {
|
|
|
13795
14084
|
* The watcher manager for this application.
|
|
13796
14085
|
*/
|
|
13797
14086
|
#watcher;
|
|
14087
|
+
/**
|
|
14088
|
+
* Template references registered by the `ref` directive, exposed to data(), methods, and
|
|
14089
|
+
* expressions as `$refs` (Vue's `$refs`). Each entry is either a single Element or, for a
|
|
14090
|
+
* `ref` used inside `v-for`, an array of Elements.
|
|
14091
|
+
*
|
|
14092
|
+
* This object is intentionally marked raw (non-reactive): mutating it when an element mounts or
|
|
14093
|
+
* unmounts must never schedule a render, and it must not be used to drive reactive template
|
|
14094
|
+
* output — matching Vue's semantics for `$refs`. It is held as a direct field (in addition to
|
|
14095
|
+
* being injected as the `$refs` binding) so registration is a plain property write.
|
|
14096
|
+
*/
|
|
14097
|
+
#refs = {};
|
|
13798
14098
|
/**
|
|
13799
14099
|
* Flag to indicate if an update is already scheduled.
|
|
13800
14100
|
*/
|
|
@@ -13895,6 +14195,13 @@ class VApplication {
|
|
|
13895
14195
|
get functionDependencies() {
|
|
13896
14196
|
return this.#functionDependencies;
|
|
13897
14197
|
}
|
|
14198
|
+
/**
|
|
14199
|
+
* Gets the template references registered via the `ref` directive (Vue's `$refs`). The same
|
|
14200
|
+
* object is exposed to data(), methods, and expressions as `$refs`. Non-reactive by design.
|
|
14201
|
+
*/
|
|
14202
|
+
get refs() {
|
|
14203
|
+
return this.#refs;
|
|
14204
|
+
}
|
|
13898
14205
|
/**
|
|
13899
14206
|
* Mounts the application.
|
|
13900
14207
|
* @param target The CSS selector string or HTMLElement to mount the application to.
|
|
@@ -14023,6 +14330,56 @@ class VApplication {
|
|
|
14023
14330
|
}
|
|
14024
14331
|
return identifiers;
|
|
14025
14332
|
}
|
|
14333
|
+
/**
|
|
14334
|
+
* Registers a template reference under the given name. Called by the `ref` directive during the
|
|
14335
|
+
* mount phase. When {@param asArray} is true (the element lives inside a `v-for`), references
|
|
14336
|
+
* accumulate into an array in registration order; otherwise the name holds a single element.
|
|
14337
|
+
*
|
|
14338
|
+
* Mutates the raw (non-reactive) `$refs` object directly, so this never schedules a render.
|
|
14339
|
+
*
|
|
14340
|
+
* @param name The ref name.
|
|
14341
|
+
* @param element The element (or component host element) to register.
|
|
14342
|
+
* @param asArray Whether to collect into an array (refs used inside a v-for).
|
|
14343
|
+
*/
|
|
14344
|
+
registerRef(name, element, asArray) {
|
|
14345
|
+
if (asArray) {
|
|
14346
|
+
const current = this.#refs[name];
|
|
14347
|
+
if (Array.isArray(current)) {
|
|
14348
|
+
if (!current.includes(element)) {
|
|
14349
|
+
current.push(element);
|
|
14350
|
+
}
|
|
14351
|
+
}
|
|
14352
|
+
else {
|
|
14353
|
+
this.#refs[name] = [element];
|
|
14354
|
+
}
|
|
14355
|
+
return;
|
|
14356
|
+
}
|
|
14357
|
+
this.#refs[name] = element;
|
|
14358
|
+
}
|
|
14359
|
+
/**
|
|
14360
|
+
* Removes a template reference registered under the given name. Called by the `ref` directive
|
|
14361
|
+
* during the unmount phase. The removal is identity-safe: an entry is only cleared when it still
|
|
14362
|
+
* points at {@param element}, so a newly mounted element that reused the name is never clobbered
|
|
14363
|
+
* by the teardown of the element it replaced.
|
|
14364
|
+
*
|
|
14365
|
+
* @param name The ref name.
|
|
14366
|
+
* @param element The element whose registration should be removed.
|
|
14367
|
+
*/
|
|
14368
|
+
unregisterRef(name, element) {
|
|
14369
|
+
const current = this.#refs[name];
|
|
14370
|
+
if (Array.isArray(current)) {
|
|
14371
|
+
const index = current.indexOf(element);
|
|
14372
|
+
if (index !== -1) {
|
|
14373
|
+
current.splice(index, 1);
|
|
14374
|
+
}
|
|
14375
|
+
if (current.length === 0) {
|
|
14376
|
+
delete this.#refs[name];
|
|
14377
|
+
}
|
|
14378
|
+
}
|
|
14379
|
+
else if (current === element) {
|
|
14380
|
+
delete this.#refs[name];
|
|
14381
|
+
}
|
|
14382
|
+
}
|
|
14026
14383
|
/**
|
|
14027
14384
|
* Initializes bindings from data, computed properties, and methods.
|
|
14028
14385
|
* @returns The initialized bindings object.
|
|
@@ -14043,6 +14400,10 @@ class VApplication {
|
|
|
14043
14400
|
this.#bindings.set('$nextTick', (callback) => this.#nextTick(callback));
|
|
14044
14401
|
this.#bindings.set('$markRaw', (obj) => ReactiveProxy.markRaw(obj));
|
|
14045
14402
|
this.#bindings.set('$emit', (name, detail, options) => this.#emit(name, detail, options));
|
|
14403
|
+
// Inject the (non-reactive) $refs container. Marking it raw prevents VBindings from wrapping
|
|
14404
|
+
// it in a reactive proxy, so populating it from the ref directive never schedules a render.
|
|
14405
|
+
ReactiveProxy.markRaw(this.#refs);
|
|
14406
|
+
this.#bindings.set('$refs', this.#refs);
|
|
14046
14407
|
// Add methods
|
|
14047
14408
|
if (this.#options.methods) {
|
|
14048
14409
|
for (const [key, method] of Object.entries(this.#options.methods)) {
|