@mintjamsinc/ichigojs 0.1.6 → 0.1.8
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 +101 -8
- package/dist/ichigo.esm.js +493 -10
- package/dist/ichigo.esm.js.map +1 -1
- package/dist/ichigo.esm.min.js +1 -1
- package/dist/ichigo.esm.min.js.map +1 -1
- package/dist/ichigo.umd.js +493 -10
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/dist/ichigo.umd.min.js.map +1 -1
- package/dist/types/ichigo/directives/StandardDirectiveName.d.ts +3 -1
- package/dist/types/ichigo/directives/VBindDirective.d.ts +9 -0
- package/dist/types/ichigo/directives/VDirective.d.ts +2 -1
- package/dist/types/ichigo/directives/VDirectiveManager.d.ts +18 -0
- package/dist/types/ichigo/directives/VIntersectionDirective.d.ts +91 -0
- package/dist/types/ichigo/directives/VOnDirective.d.ts +2 -2
- package/dist/types/ichigo/directives/VResizeDirective.d.ts +84 -0
- package/package.json +1 -1
package/dist/ichigo.umd.js
CHANGED
@@ -59,6 +59,8 @@
|
|
59
59
|
StandardDirectiveName["V_ON"] = "v-on";
|
60
60
|
StandardDirectiveName["V_BIND"] = "v-bind";
|
61
61
|
StandardDirectiveName["V_MODEL"] = "v-model";
|
62
|
+
StandardDirectiveName["V_RESIZE"] = "v-resize";
|
63
|
+
StandardDirectiveName["V_INTERSECTION"] = "v-intersection";
|
62
64
|
})(StandardDirectiveName || (StandardDirectiveName = {}));
|
63
65
|
|
64
66
|
// This file was generated. Do not modify manually!
|
@@ -6873,6 +6875,19 @@
|
|
6873
6875
|
get isKey() {
|
6874
6876
|
return (this.#attributeName === 'key');
|
6875
6877
|
}
|
6878
|
+
/**
|
6879
|
+
* Indicates if this directive is binding the "options" attribute or any of its sub-properties (e.g., "options.intersection").
|
6880
|
+
* The "options" attribute is special and is used for passing options to certain directives like VIntersectionDirective.
|
6881
|
+
*/
|
6882
|
+
get isOptions() {
|
6883
|
+
return (this.#attributeName === 'options' || this.#attributeName?.startsWith('options.') === true);
|
6884
|
+
}
|
6885
|
+
/**
|
6886
|
+
* Gets the name of the attribute being bound (e.g., "src", "class", "options", "options.intersection").
|
6887
|
+
*/
|
6888
|
+
get attributeName() {
|
6889
|
+
return this.#attributeName;
|
6890
|
+
}
|
6876
6891
|
/**
|
6877
6892
|
* Gets the original expression string from the directive.
|
6878
6893
|
*/
|
@@ -6925,8 +6940,8 @@
|
|
6925
6940
|
* Renders the bound attribute by evaluating the expression and updating the DOM element.
|
6926
6941
|
*/
|
6927
6942
|
#render() {
|
6928
|
-
//
|
6929
|
-
if (this.isKey) {
|
6943
|
+
// Do nothing for special attributes
|
6944
|
+
if (this.isKey || this.isOptions) {
|
6930
6945
|
return;
|
6931
6946
|
}
|
6932
6947
|
const element = this.#vNode.node;
|
@@ -7370,16 +7385,47 @@
|
|
7370
7385
|
}
|
7371
7386
|
|
7372
7387
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
7388
|
+
/**
|
7389
|
+
* Manages directives associated with a virtual node (VNode).
|
7390
|
+
* This class is responsible for parsing, storing, and managing the lifecycle of directives.
|
7391
|
+
* It also provides access to bindings preparers and DOM updaters from the associated directives.
|
7392
|
+
*/
|
7373
7393
|
class VDirectiveManager {
|
7374
7394
|
/**
|
7375
7395
|
* The virtual node to which this directive handler is associated.
|
7376
7396
|
*/
|
7377
7397
|
#vNode;
|
7398
|
+
/**
|
7399
|
+
* The list of directives associated with the virtual node.
|
7400
|
+
* This may be undefined if there are no directives.
|
7401
|
+
*/
|
7378
7402
|
#directives;
|
7403
|
+
/**
|
7404
|
+
* The anchor comment node used for certain directives (e.g., v-if, v-for).
|
7405
|
+
* This may be undefined if no directive requires an anchor.
|
7406
|
+
*/
|
7379
7407
|
#anchorNode;
|
7408
|
+
/**
|
7409
|
+
* The list of bindings preparers from the associated directives.
|
7410
|
+
* This may be undefined if no directive provides a bindings preparer.
|
7411
|
+
*/
|
7380
7412
|
#bindingsPreparers;
|
7413
|
+
/**
|
7414
|
+
* The list of DOM updaters from the associated directives.
|
7415
|
+
* This may be undefined if no directive provides a DOM updater.
|
7416
|
+
*/
|
7381
7417
|
#domUpdaters;
|
7418
|
+
/**
|
7419
|
+
* The directive that binds the ":key" or "v-bind:key" attribute, if any.
|
7420
|
+
* This directive is special and is used for optimizing rendering of lists.
|
7421
|
+
* If no such directive exists, this is undefined.
|
7422
|
+
*/
|
7382
7423
|
#keyDirective;
|
7424
|
+
/**
|
7425
|
+
* A cache of VBindDirectives for options specific to certain directives.
|
7426
|
+
* The keys are directive names (e.g., 'options', 'options.intersection').
|
7427
|
+
*/
|
7428
|
+
#optionsDirectives = {};
|
7383
7429
|
constructor(vNode) {
|
7384
7430
|
// Directives can only be associated with element nodes
|
7385
7431
|
if (vNode.nodeType !== Node.ELEMENT_NODE) {
|
@@ -7437,6 +7483,35 @@
|
|
7437
7483
|
get keyDirective() {
|
7438
7484
|
return this.#keyDirective;
|
7439
7485
|
}
|
7486
|
+
/**
|
7487
|
+
* Gets a record of VBindDirectives for options specific to certain directives.
|
7488
|
+
* The keys are directive names (e.g., 'options', 'options.intersection').
|
7489
|
+
*/
|
7490
|
+
get optionsDirectives() {
|
7491
|
+
return this.#optionsDirectives;
|
7492
|
+
}
|
7493
|
+
/**
|
7494
|
+
* Gets the VBindDirective for options specific to the given directive name.
|
7495
|
+
* Searches in order: `:options.{directive}` -> `:options`
|
7496
|
+
*
|
7497
|
+
* @param directive The directive name (e.g., 'intersection', 'resize')
|
7498
|
+
* @returns The VBindDirective instance or undefined
|
7499
|
+
*/
|
7500
|
+
optionsDirective(directive) {
|
7501
|
+
if (!this.#directives || this.#directives.length === 0) {
|
7502
|
+
return undefined;
|
7503
|
+
}
|
7504
|
+
// Search for `:options.{directive}` or `v-bind:options.{directive}` first
|
7505
|
+
const specificAttrName = `options.${directive}`;
|
7506
|
+
if (this.#optionsDirectives[specificAttrName]) {
|
7507
|
+
return this.#optionsDirectives[specificAttrName];
|
7508
|
+
}
|
7509
|
+
// Fallback: search for `:options` or `v-bind:options`
|
7510
|
+
if (this.#optionsDirectives['options']) {
|
7511
|
+
return this.#optionsDirectives['options'];
|
7512
|
+
}
|
7513
|
+
return undefined;
|
7514
|
+
}
|
7440
7515
|
/**
|
7441
7516
|
* Cleans up any resources used by the directive handler.
|
7442
7517
|
*/
|
@@ -7496,6 +7571,10 @@
|
|
7496
7571
|
if (directive.name === StandardDirectiveName.V_BIND && directive.isKey) {
|
7497
7572
|
this.#keyDirective = directive;
|
7498
7573
|
}
|
7574
|
+
// If this is an options binding directive, cache it
|
7575
|
+
if (directive.name === StandardDirectiveName.V_BIND && directive.isOptions) {
|
7576
|
+
this.#optionsDirectives[directive.name] = directive;
|
7577
|
+
}
|
7499
7578
|
}
|
7500
7579
|
}
|
7501
7580
|
// Sort directives by priority: v-for > v-if > v-else-if > v-else > v-show > others
|
@@ -8983,6 +9062,209 @@
|
|
8983
9062
|
}
|
8984
9063
|
}
|
8985
9064
|
|
9065
|
+
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
9066
|
+
/**
|
9067
|
+
* Directive for observing element intersection with viewport or ancestor elements using IntersectionObserver.
|
9068
|
+
* The `v-intersection` directive allows you to respond to changes in an element's visibility.
|
9069
|
+
*
|
9070
|
+
* Example usage:
|
9071
|
+
* <div v-intersection="handleIntersection">Observable content</div>
|
9072
|
+
* <div v-intersection="handleIntersection" :options.intersection="{threshold: 0.5}">Observable content</div>
|
9073
|
+
*
|
9074
|
+
* The handler receives IntersectionObserverEntry array as the first argument and $ctx as the second:
|
9075
|
+
* handleIntersection(entries, $ctx) {
|
9076
|
+
* const entry = entries[0];
|
9077
|
+
* if (entry.isIntersecting) {
|
9078
|
+
* console.log('Element is visible!');
|
9079
|
+
* }
|
9080
|
+
* }
|
9081
|
+
*
|
9082
|
+
* Options can be provided via :options or :options.intersection attribute:
|
9083
|
+
* :options="{root: null, threshold: 0.5, rootMargin: '0px'}"
|
9084
|
+
* :options.intersection="{root: null, threshold: 0.5, rootMargin: '0px'}"
|
9085
|
+
*
|
9086
|
+
* This directive is useful for lazy-loading, infinite scrolling, animation triggers,
|
9087
|
+
* and other features that depend on element visibility.
|
9088
|
+
*/
|
9089
|
+
class VIntersectionDirective {
|
9090
|
+
/**
|
9091
|
+
* The virtual node to which this directive is applied.
|
9092
|
+
*/
|
9093
|
+
#vNode;
|
9094
|
+
/**
|
9095
|
+
* A list of variable and function names used in the directive's expression.
|
9096
|
+
*/
|
9097
|
+
#dependentIdentifiers;
|
9098
|
+
/**
|
9099
|
+
* The intersection handler wrapper function.
|
9100
|
+
*/
|
9101
|
+
#handlerWrapper;
|
9102
|
+
/**
|
9103
|
+
* The IntersectionObserver instance.
|
9104
|
+
*/
|
9105
|
+
#intersectionObserver;
|
9106
|
+
/**
|
9107
|
+
* @param context The context for parsing the directive.
|
9108
|
+
*/
|
9109
|
+
constructor(context) {
|
9110
|
+
this.#vNode = context.vNode;
|
9111
|
+
// Parse the expression to extract identifiers and create the handler wrapper
|
9112
|
+
const expression = context.attribute.value;
|
9113
|
+
if (expression) {
|
9114
|
+
this.#dependentIdentifiers = ExpressionUtils.extractIdentifiers(expression, context.vNode.vApplication.functionDependencies);
|
9115
|
+
this.#handlerWrapper = this.#createIntersectionHandlerWrapper(expression);
|
9116
|
+
}
|
9117
|
+
// Remove the directive attribute from the element
|
9118
|
+
this.#vNode.node.removeAttribute(context.attribute.name);
|
9119
|
+
}
|
9120
|
+
/**
|
9121
|
+
* @inheritdoc
|
9122
|
+
*/
|
9123
|
+
get name() {
|
9124
|
+
return StandardDirectiveName.V_INTERSECTION;
|
9125
|
+
}
|
9126
|
+
/**
|
9127
|
+
* @inheritdoc
|
9128
|
+
*/
|
9129
|
+
get vNode() {
|
9130
|
+
return this.#vNode;
|
9131
|
+
}
|
9132
|
+
/**
|
9133
|
+
* @inheritdoc
|
9134
|
+
*/
|
9135
|
+
get needsAnchor() {
|
9136
|
+
return false;
|
9137
|
+
}
|
9138
|
+
/**
|
9139
|
+
* @inheritdoc
|
9140
|
+
*/
|
9141
|
+
get bindingsPreparer() {
|
9142
|
+
return undefined;
|
9143
|
+
}
|
9144
|
+
/**
|
9145
|
+
* @inheritdoc
|
9146
|
+
*/
|
9147
|
+
get domUpdater() {
|
9148
|
+
return undefined;
|
9149
|
+
}
|
9150
|
+
/**
|
9151
|
+
* @inheritdoc
|
9152
|
+
*/
|
9153
|
+
get templatize() {
|
9154
|
+
return false;
|
9155
|
+
}
|
9156
|
+
/**
|
9157
|
+
* @inheritdoc
|
9158
|
+
*/
|
9159
|
+
get dependentIdentifiers() {
|
9160
|
+
return this.#dependentIdentifiers ?? [];
|
9161
|
+
}
|
9162
|
+
/**
|
9163
|
+
* @inheritdoc
|
9164
|
+
*/
|
9165
|
+
get onMount() {
|
9166
|
+
return undefined;
|
9167
|
+
}
|
9168
|
+
/**
|
9169
|
+
* @inheritdoc
|
9170
|
+
*/
|
9171
|
+
get onMounted() {
|
9172
|
+
if (!this.#handlerWrapper) {
|
9173
|
+
return undefined;
|
9174
|
+
}
|
9175
|
+
const element = this.#vNode.node;
|
9176
|
+
const handler = this.#handlerWrapper;
|
9177
|
+
return () => {
|
9178
|
+
// Get options from :options.intersection or :options directive
|
9179
|
+
let optionsDirective = this.#vNode.directiveManager?.optionsDirective('intersection');
|
9180
|
+
// Evaluate the options expression
|
9181
|
+
let options;
|
9182
|
+
if (optionsDirective && optionsDirective.expression) {
|
9183
|
+
// Evaluate the options expression
|
9184
|
+
const identifiers = optionsDirective.dependentIdentifiers;
|
9185
|
+
const values = identifiers.map(id => this.#vNode.bindings?.get(id));
|
9186
|
+
const args = identifiers.join(", ");
|
9187
|
+
const funcBody = `return (${optionsDirective.expression});`;
|
9188
|
+
const func = new Function(args, funcBody);
|
9189
|
+
options = func(...values);
|
9190
|
+
}
|
9191
|
+
// Create IntersectionObserver and start observing
|
9192
|
+
this.#intersectionObserver = new IntersectionObserver((entries) => {
|
9193
|
+
handler(entries);
|
9194
|
+
}, options);
|
9195
|
+
this.#intersectionObserver.observe(element);
|
9196
|
+
};
|
9197
|
+
}
|
9198
|
+
/**
|
9199
|
+
* @inheritdoc
|
9200
|
+
*/
|
9201
|
+
get onUpdate() {
|
9202
|
+
return undefined;
|
9203
|
+
}
|
9204
|
+
/**
|
9205
|
+
* @inheritdoc
|
9206
|
+
*/
|
9207
|
+
get onUpdated() {
|
9208
|
+
return undefined;
|
9209
|
+
}
|
9210
|
+
/**
|
9211
|
+
* @inheritdoc
|
9212
|
+
*/
|
9213
|
+
get onUnmount() {
|
9214
|
+
return undefined;
|
9215
|
+
}
|
9216
|
+
/**
|
9217
|
+
* @inheritdoc
|
9218
|
+
*/
|
9219
|
+
get onUnmounted() {
|
9220
|
+
return undefined;
|
9221
|
+
}
|
9222
|
+
/**
|
9223
|
+
* @inheritdoc
|
9224
|
+
*/
|
9225
|
+
destroy() {
|
9226
|
+
// Disconnect the IntersectionObserver when the directive is destroyed
|
9227
|
+
if (this.#intersectionObserver) {
|
9228
|
+
this.#intersectionObserver.disconnect();
|
9229
|
+
this.#intersectionObserver = undefined;
|
9230
|
+
}
|
9231
|
+
}
|
9232
|
+
/**
|
9233
|
+
* Creates a wrapper function for intersection handlers.
|
9234
|
+
* @param expression The expression string to evaluate.
|
9235
|
+
* @returns A function that handles the intersection event.
|
9236
|
+
*/
|
9237
|
+
#createIntersectionHandlerWrapper(expression) {
|
9238
|
+
const identifiers = this.#dependentIdentifiers ?? [];
|
9239
|
+
const vNode = this.#vNode;
|
9240
|
+
// Return a function that handles the intersection event with proper scope
|
9241
|
+
return (entries) => {
|
9242
|
+
const bindings = vNode.bindings;
|
9243
|
+
const $ctx = {
|
9244
|
+
element: vNode.node,
|
9245
|
+
vnode: vNode,
|
9246
|
+
userData: vNode.userData
|
9247
|
+
};
|
9248
|
+
// If the expression is just a method name, call it with bindings as 'this'
|
9249
|
+
const trimmedExpr = expression.trim();
|
9250
|
+
if (identifiers.includes(trimmedExpr) && typeof bindings?.get(trimmedExpr) === 'function') {
|
9251
|
+
const methodName = trimmedExpr;
|
9252
|
+
const originalMethod = bindings?.get(methodName);
|
9253
|
+
// Call the method with bindings as 'this' context
|
9254
|
+
// Pass entries as first argument and $ctx as second argument
|
9255
|
+
return originalMethod(entries, $ctx);
|
9256
|
+
}
|
9257
|
+
// For inline expressions, evaluate normally
|
9258
|
+
// Note: inline expressions receive entries and $ctx as parameters
|
9259
|
+
const values = identifiers.map(id => vNode.bindings?.get(id));
|
9260
|
+
const args = [...identifiers, 'entries', '$ctx'].join(", ");
|
9261
|
+
const funcBody = `return (${expression});`;
|
9262
|
+
const func = new Function(args, funcBody);
|
9263
|
+
return func.call(bindings?.raw, ...values, entries, $ctx);
|
9264
|
+
};
|
9265
|
+
}
|
9266
|
+
}
|
9267
|
+
|
8986
9268
|
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
8987
9269
|
/**
|
8988
9270
|
* Directive for two-way data binding on form input elements.
|
@@ -9308,8 +9590,8 @@
|
|
9308
9590
|
* @mounted="onMounted" - Called after the element is inserted into the DOM
|
9309
9591
|
* @update="onUpdate" - Called before the element is updated
|
9310
9592
|
* @updated="onUpdated" - Called after the element is updated
|
9311
|
-
* @unmount="onUnmount" - Called before
|
9312
|
-
* @unmounted="onUnmounted" - Called after
|
9593
|
+
* @unmount="onUnmount" - Called before VNode cleanup begins
|
9594
|
+
* @unmounted="onUnmounted" - Called after VNode cleanup is complete (element reference still available)
|
9313
9595
|
*
|
9314
9596
|
* This directive is essential for handling user interactions and lifecycle events in your application.
|
9315
9597
|
* Note that the methods referenced in the directive should be defined in the component's methods object.
|
@@ -9585,7 +9867,7 @@
|
|
9585
9867
|
};
|
9586
9868
|
}
|
9587
9869
|
/**
|
9588
|
-
* Creates a wrapper function for DOM event handlers (with event
|
9870
|
+
* Creates a wrapper function for DOM event handlers (with event and $ctx parameters).
|
9589
9871
|
* @param expression The expression string to evaluate.
|
9590
9872
|
* @returns A function that handles the event.
|
9591
9873
|
*/
|
@@ -9595,21 +9877,210 @@
|
|
9595
9877
|
// Return a function that handles the event with proper scope
|
9596
9878
|
return (event) => {
|
9597
9879
|
const bindings = vNode.bindings;
|
9880
|
+
const $ctx = {
|
9881
|
+
element: vNode.node,
|
9882
|
+
vnode: vNode,
|
9883
|
+
userData: vNode.userData
|
9884
|
+
};
|
9885
|
+
// If the expression is just a method name, call it with bindings as 'this'
|
9886
|
+
const trimmedExpr = expression.trim();
|
9887
|
+
if (identifiers.includes(trimmedExpr) && typeof bindings?.get(trimmedExpr) === 'function') {
|
9888
|
+
const methodName = trimmedExpr;
|
9889
|
+
const originalMethod = bindings?.get(methodName);
|
9890
|
+
// Call the method with bindings as 'this' context
|
9891
|
+
// Pass event as first argument and $ctx as second argument
|
9892
|
+
return originalMethod(event, $ctx);
|
9893
|
+
}
|
9894
|
+
// For inline expressions, evaluate normally
|
9895
|
+
// Note: inline expressions receive event and $ctx as parameters
|
9896
|
+
const values = identifiers.map(id => vNode.bindings?.get(id));
|
9897
|
+
const args = [...identifiers, 'event', '$ctx'].join(", ");
|
9898
|
+
const funcBody = `return (${expression});`;
|
9899
|
+
const func = new Function(args, funcBody);
|
9900
|
+
return func.call(bindings?.raw, ...values, event, $ctx);
|
9901
|
+
};
|
9902
|
+
}
|
9903
|
+
}
|
9904
|
+
|
9905
|
+
// Copyright (c) 2025 MintJams Inc. Licensed under MIT License.
|
9906
|
+
/**
|
9907
|
+
* Directive for observing element resize events using ResizeObserver.
|
9908
|
+
* The `v-resize` directive allows you to respond to changes in an element's size.
|
9909
|
+
*
|
9910
|
+
* Example usage:
|
9911
|
+
* <div v-resize="handleResize">Resizable content</div>
|
9912
|
+
*
|
9913
|
+
* The handler receives ResizeObserverEntry array as the first argument and $ctx as the second:
|
9914
|
+
* handleResize(entries, $ctx) {
|
9915
|
+
* const { width, height } = entries[0].contentRect;
|
9916
|
+
* console.log(`Size: ${width}x${height}`);
|
9917
|
+
* }
|
9918
|
+
*
|
9919
|
+
* This directive is useful for responsive layouts, charts, and other components
|
9920
|
+
* that need to adapt to size changes.
|
9921
|
+
*/
|
9922
|
+
class VResizeDirective {
|
9923
|
+
/**
|
9924
|
+
* The virtual node to which this directive is applied.
|
9925
|
+
*/
|
9926
|
+
#vNode;
|
9927
|
+
/**
|
9928
|
+
* A list of variable and function names used in the directive's expression.
|
9929
|
+
*/
|
9930
|
+
#dependentIdentifiers;
|
9931
|
+
/**
|
9932
|
+
* The resize handler wrapper function.
|
9933
|
+
*/
|
9934
|
+
#handlerWrapper;
|
9935
|
+
/**
|
9936
|
+
* The ResizeObserver instance.
|
9937
|
+
*/
|
9938
|
+
#resizeObserver;
|
9939
|
+
/**
|
9940
|
+
* @param context The context for parsing the directive.
|
9941
|
+
*/
|
9942
|
+
constructor(context) {
|
9943
|
+
this.#vNode = context.vNode;
|
9944
|
+
// Parse the expression to extract identifiers and create the handler wrapper
|
9945
|
+
const expression = context.attribute.value;
|
9946
|
+
if (expression) {
|
9947
|
+
this.#dependentIdentifiers = ExpressionUtils.extractIdentifiers(expression, context.vNode.vApplication.functionDependencies);
|
9948
|
+
this.#handlerWrapper = this.#createResizeHandlerWrapper(expression);
|
9949
|
+
}
|
9950
|
+
// Remove the directive attribute from the element
|
9951
|
+
this.#vNode.node.removeAttribute(context.attribute.name);
|
9952
|
+
}
|
9953
|
+
/**
|
9954
|
+
* @inheritdoc
|
9955
|
+
*/
|
9956
|
+
get name() {
|
9957
|
+
return StandardDirectiveName.V_RESIZE;
|
9958
|
+
}
|
9959
|
+
/**
|
9960
|
+
* @inheritdoc
|
9961
|
+
*/
|
9962
|
+
get vNode() {
|
9963
|
+
return this.#vNode;
|
9964
|
+
}
|
9965
|
+
/**
|
9966
|
+
* @inheritdoc
|
9967
|
+
*/
|
9968
|
+
get needsAnchor() {
|
9969
|
+
return false;
|
9970
|
+
}
|
9971
|
+
/**
|
9972
|
+
* @inheritdoc
|
9973
|
+
*/
|
9974
|
+
get bindingsPreparer() {
|
9975
|
+
return undefined;
|
9976
|
+
}
|
9977
|
+
/**
|
9978
|
+
* @inheritdoc
|
9979
|
+
*/
|
9980
|
+
get domUpdater() {
|
9981
|
+
return undefined;
|
9982
|
+
}
|
9983
|
+
/**
|
9984
|
+
* @inheritdoc
|
9985
|
+
*/
|
9986
|
+
get templatize() {
|
9987
|
+
return false;
|
9988
|
+
}
|
9989
|
+
/**
|
9990
|
+
* @inheritdoc
|
9991
|
+
*/
|
9992
|
+
get dependentIdentifiers() {
|
9993
|
+
return this.#dependentIdentifiers ?? [];
|
9994
|
+
}
|
9995
|
+
/**
|
9996
|
+
* @inheritdoc
|
9997
|
+
*/
|
9998
|
+
get onMount() {
|
9999
|
+
return undefined;
|
10000
|
+
}
|
10001
|
+
/**
|
10002
|
+
* @inheritdoc
|
10003
|
+
*/
|
10004
|
+
get onMounted() {
|
10005
|
+
if (!this.#handlerWrapper) {
|
10006
|
+
return undefined;
|
10007
|
+
}
|
10008
|
+
const element = this.#vNode.node;
|
10009
|
+
const handler = this.#handlerWrapper;
|
10010
|
+
return () => {
|
10011
|
+
// Create ResizeObserver and start observing
|
10012
|
+
this.#resizeObserver = new ResizeObserver((entries) => {
|
10013
|
+
handler(entries);
|
10014
|
+
});
|
10015
|
+
this.#resizeObserver.observe(element);
|
10016
|
+
};
|
10017
|
+
}
|
10018
|
+
/**
|
10019
|
+
* @inheritdoc
|
10020
|
+
*/
|
10021
|
+
get onUpdate() {
|
10022
|
+
return undefined;
|
10023
|
+
}
|
10024
|
+
/**
|
10025
|
+
* @inheritdoc
|
10026
|
+
*/
|
10027
|
+
get onUpdated() {
|
10028
|
+
return undefined;
|
10029
|
+
}
|
10030
|
+
/**
|
10031
|
+
* @inheritdoc
|
10032
|
+
*/
|
10033
|
+
get onUnmount() {
|
10034
|
+
return undefined;
|
10035
|
+
}
|
10036
|
+
/**
|
10037
|
+
* @inheritdoc
|
10038
|
+
*/
|
10039
|
+
get onUnmounted() {
|
10040
|
+
return undefined;
|
10041
|
+
}
|
10042
|
+
/**
|
10043
|
+
* @inheritdoc
|
10044
|
+
*/
|
10045
|
+
destroy() {
|
10046
|
+
// Disconnect the ResizeObserver when the directive is destroyed
|
10047
|
+
if (this.#resizeObserver) {
|
10048
|
+
this.#resizeObserver.disconnect();
|
10049
|
+
this.#resizeObserver = undefined;
|
10050
|
+
}
|
10051
|
+
}
|
10052
|
+
/**
|
10053
|
+
* Creates a wrapper function for resize handlers.
|
10054
|
+
* @param expression The expression string to evaluate.
|
10055
|
+
* @returns A function that handles the resize event.
|
10056
|
+
*/
|
10057
|
+
#createResizeHandlerWrapper(expression) {
|
10058
|
+
const identifiers = this.#dependentIdentifiers ?? [];
|
10059
|
+
const vNode = this.#vNode;
|
10060
|
+
// Return a function that handles the resize event with proper scope
|
10061
|
+
return (entries) => {
|
10062
|
+
const bindings = vNode.bindings;
|
10063
|
+
const $ctx = {
|
10064
|
+
element: vNode.node,
|
10065
|
+
vnode: vNode,
|
10066
|
+
userData: vNode.userData
|
10067
|
+
};
|
9598
10068
|
// If the expression is just a method name, call it with bindings as 'this'
|
9599
10069
|
const trimmedExpr = expression.trim();
|
9600
10070
|
if (identifiers.includes(trimmedExpr) && typeof bindings?.get(trimmedExpr) === 'function') {
|
9601
10071
|
const methodName = trimmedExpr;
|
9602
10072
|
const originalMethod = bindings?.get(methodName);
|
9603
10073
|
// Call the method with bindings as 'this' context
|
9604
|
-
//
|
9605
|
-
return originalMethod(
|
10074
|
+
// Pass entries as first argument and $ctx as second argument
|
10075
|
+
return originalMethod(entries, $ctx);
|
9606
10076
|
}
|
9607
10077
|
// For inline expressions, evaluate normally
|
10078
|
+
// Note: inline expressions receive entries and $ctx as parameters
|
9608
10079
|
const values = identifiers.map(id => vNode.bindings?.get(id));
|
9609
|
-
const args = identifiers.join(", ");
|
10080
|
+
const args = [...identifiers, 'entries', '$ctx'].join(", ");
|
9610
10081
|
const funcBody = `return (${expression});`;
|
9611
10082
|
const func = new Function(args, funcBody);
|
9612
|
-
return func.call(bindings?.raw, ...values,
|
10083
|
+
return func.call(bindings?.raw, ...values, entries, $ctx);
|
9613
10084
|
};
|
9614
10085
|
}
|
9615
10086
|
}
|
@@ -9839,7 +10310,11 @@
|
|
9839
10310
|
context.attribute.name.startsWith(":") ||
|
9840
10311
|
// v-model, v-model.<modifier>
|
9841
10312
|
context.attribute.name === StandardDirectiveName.V_MODEL ||
|
9842
|
-
context.attribute.name.startsWith(StandardDirectiveName.V_MODEL + ".")
|
10313
|
+
context.attribute.name.startsWith(StandardDirectiveName.V_MODEL + ".") ||
|
10314
|
+
// v-resize
|
10315
|
+
context.attribute.name === StandardDirectiveName.V_RESIZE ||
|
10316
|
+
// v-intersection
|
10317
|
+
context.attribute.name === StandardDirectiveName.V_INTERSECTION) {
|
9843
10318
|
return true;
|
9844
10319
|
}
|
9845
10320
|
return false;
|
@@ -9878,6 +10353,14 @@
|
|
9878
10353
|
context.attribute.name.startsWith(StandardDirectiveName.V_MODEL + ".")) {
|
9879
10354
|
return new VModelDirective(context);
|
9880
10355
|
}
|
10356
|
+
// v-resize
|
10357
|
+
if (context.attribute.name === StandardDirectiveName.V_RESIZE) {
|
10358
|
+
return new VResizeDirective(context);
|
10359
|
+
}
|
10360
|
+
// v-intersection
|
10361
|
+
if (context.attribute.name === StandardDirectiveName.V_INTERSECTION) {
|
10362
|
+
return new VIntersectionDirective(context);
|
10363
|
+
}
|
9881
10364
|
throw new Error(`The attribute "${context.attribute.name}" cannot be parsed by ${this.name}.`);
|
9882
10365
|
}
|
9883
10366
|
}
|