@mintjamsinc/ichigojs 0.1.83 → 0.1.85
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/dist/ichigo.cjs +133 -6
- package/dist/ichigo.cjs.map +1 -1
- package/dist/ichigo.esm.js +133 -6
- 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 +133 -6
- package/dist/ichigo.umd.js.map +1 -1
- package/dist/ichigo.umd.min.js +1 -1
- package/package.json +1 -1
package/dist/ichigo.cjs
CHANGED
|
@@ -7787,13 +7787,20 @@
|
|
|
7787
7787
|
}
|
|
7788
7788
|
/**
|
|
7789
7789
|
* Updates a regular attribute.
|
|
7790
|
+
* An attribute that already holds the value is left alone: setting `src` on
|
|
7791
|
+
* an <iframe>, even to the same URL, loads its page again.
|
|
7790
7792
|
*/
|
|
7791
7793
|
#updateAttribute(element, name, value) {
|
|
7792
7794
|
if (value == null || value === false) {
|
|
7793
|
-
element.
|
|
7795
|
+
if (element.hasAttribute(name)) {
|
|
7796
|
+
element.removeAttribute(name);
|
|
7797
|
+
}
|
|
7794
7798
|
}
|
|
7795
7799
|
else {
|
|
7796
|
-
|
|
7800
|
+
const text = String(value);
|
|
7801
|
+
if (element.getAttribute(name) !== text) {
|
|
7802
|
+
element.setAttribute(name, text);
|
|
7803
|
+
}
|
|
7797
7804
|
}
|
|
7798
7805
|
}
|
|
7799
7806
|
}
|
|
@@ -11319,6 +11326,25 @@
|
|
|
11319
11326
|
* Previous iterations to detect changes
|
|
11320
11327
|
*/
|
|
11321
11328
|
#previousIterations = [];
|
|
11329
|
+
/**
|
|
11330
|
+
* The source array watched for writes made directly to it, and the function
|
|
11331
|
+
* that stops watching it.
|
|
11332
|
+
*
|
|
11333
|
+
* A write such as `items[1] = x` is reported as a change of "items[1]", which
|
|
11334
|
+
* does not match this directive's dependency on "items", and the row's loop
|
|
11335
|
+
* variable holds the value it was rendered with. The directive therefore
|
|
11336
|
+
* watches the array itself and refreshes the rows that were written.
|
|
11337
|
+
*/
|
|
11338
|
+
#watchedSource;
|
|
11339
|
+
#unwatchSource;
|
|
11340
|
+
/**
|
|
11341
|
+
* Positions written since the last refresh, and whether a write (such as one
|
|
11342
|
+
* to `length`) needs the whole list rendered again.
|
|
11343
|
+
*/
|
|
11344
|
+
#writtenIndexes = new Set();
|
|
11345
|
+
#writtenWhole = false;
|
|
11346
|
+
#refreshScheduled = false;
|
|
11347
|
+
#destroyed = false;
|
|
11322
11348
|
/**
|
|
11323
11349
|
* @param context The context for parsing the directive.
|
|
11324
11350
|
*/
|
|
@@ -11435,6 +11461,10 @@
|
|
|
11435
11461
|
* @inheritdoc
|
|
11436
11462
|
*/
|
|
11437
11463
|
destroy() {
|
|
11464
|
+
this.#destroyed = true;
|
|
11465
|
+
this.#unwatchSource?.();
|
|
11466
|
+
this.#unwatchSource = undefined;
|
|
11467
|
+
this.#watchedSource = undefined;
|
|
11438
11468
|
// Clean up all rendered items
|
|
11439
11469
|
// First destroy all VNodes (calls @unmount hooks), then remove from DOM
|
|
11440
11470
|
for (const { vNode } of this.#renderedItems) {
|
|
@@ -11466,6 +11496,10 @@
|
|
|
11466
11496
|
}
|
|
11467
11497
|
// Evaluate the source expression to get the data
|
|
11468
11498
|
const sourceData = this.#sourceEvaluator.evaluate();
|
|
11499
|
+
// Every row is rendered from the source below, including those written in place
|
|
11500
|
+
this.#watchSource(sourceData);
|
|
11501
|
+
this.#writtenIndexes.clear();
|
|
11502
|
+
this.#writtenWhole = false;
|
|
11469
11503
|
// Get iterations from the source data
|
|
11470
11504
|
let iterations = this.#getIterations(sourceData);
|
|
11471
11505
|
// If we don't have a key evaluator yet, try to create it
|
|
@@ -11859,6 +11893,89 @@
|
|
|
11859
11893
|
}
|
|
11860
11894
|
vNode.update();
|
|
11861
11895
|
}
|
|
11896
|
+
/**
|
|
11897
|
+
* Watches the source for writes made directly to its elements. Only a
|
|
11898
|
+
* reactive array can be written that way; anything else is not watched.
|
|
11899
|
+
*/
|
|
11900
|
+
#watchSource(source) {
|
|
11901
|
+
if (source === this.#watchedSource) {
|
|
11902
|
+
return;
|
|
11903
|
+
}
|
|
11904
|
+
this.#unwatchSource?.();
|
|
11905
|
+
this.#unwatchSource = undefined;
|
|
11906
|
+
this.#watchedSource = source;
|
|
11907
|
+
const path = Array.isArray(source) ? ReactiveProxy.getPath(source) : undefined;
|
|
11908
|
+
if (!path) {
|
|
11909
|
+
return;
|
|
11910
|
+
}
|
|
11911
|
+
this.#unwatchSource = ReactiveProxy.subscribe(source, (changedPath) => {
|
|
11912
|
+
this.#onSourceWritten(path, changedPath);
|
|
11913
|
+
});
|
|
11914
|
+
}
|
|
11915
|
+
/**
|
|
11916
|
+
* Notes a write made directly to the source array. A change below an
|
|
11917
|
+
* element (e.g. "items[1].name") is followed by the row's own bindings, and
|
|
11918
|
+
* a change of the whole array (e.g. by splice) by the usual dependency on it.
|
|
11919
|
+
*/
|
|
11920
|
+
#onSourceWritten(path, changedPath) {
|
|
11921
|
+
if (!changedPath || !changedPath.startsWith(path + '[') || !changedPath.endsWith(']')) {
|
|
11922
|
+
return;
|
|
11923
|
+
}
|
|
11924
|
+
const property = changedPath.substring(path.length + 1, changedPath.length - 1);
|
|
11925
|
+
if (property.includes(']')) {
|
|
11926
|
+
return;
|
|
11927
|
+
}
|
|
11928
|
+
if (/^\d+$/.test(property)) {
|
|
11929
|
+
this.#writtenIndexes.add(Number(property));
|
|
11930
|
+
}
|
|
11931
|
+
else {
|
|
11932
|
+
// e.g. `items.length = 0`
|
|
11933
|
+
this.#writtenWhole = true;
|
|
11934
|
+
}
|
|
11935
|
+
// Writes made together are refreshed together, after the application's update
|
|
11936
|
+
if (!this.#refreshScheduled) {
|
|
11937
|
+
this.#refreshScheduled = true;
|
|
11938
|
+
queueMicrotask(() => {
|
|
11939
|
+
this.#refreshScheduled = false;
|
|
11940
|
+
this.#refreshWritten();
|
|
11941
|
+
});
|
|
11942
|
+
}
|
|
11943
|
+
}
|
|
11944
|
+
/**
|
|
11945
|
+
* Shows the elements written since the last refresh. A row whose position or
|
|
11946
|
+
* key no longer holds is not patched; the whole list is rendered again.
|
|
11947
|
+
*/
|
|
11948
|
+
#refreshWritten() {
|
|
11949
|
+
if (this.#destroyed || (!this.#writtenWhole && this.#writtenIndexes.size === 0)) {
|
|
11950
|
+
return;
|
|
11951
|
+
}
|
|
11952
|
+
const indexes = [...this.#writtenIndexes];
|
|
11953
|
+
const whole = this.#writtenWhole;
|
|
11954
|
+
this.#writtenIndexes.clear();
|
|
11955
|
+
this.#writtenWhole = false;
|
|
11956
|
+
const source = this.#sourceEvaluator?.evaluate();
|
|
11957
|
+
if (whole || source !== this.#watchedSource || !Array.isArray(source) || source.length !== this.#renderedItems.length) {
|
|
11958
|
+
this.#render();
|
|
11959
|
+
return;
|
|
11960
|
+
}
|
|
11961
|
+
for (const index of indexes) {
|
|
11962
|
+
const rendered = this.#renderedItems[index];
|
|
11963
|
+
let context = { key: index, item: source[index], index };
|
|
11964
|
+
if (this.#evaluateKey && (this.#itemName || this.#itemDestructure)) {
|
|
11965
|
+
const itemBindings = new VBindings({
|
|
11966
|
+
parent: this.#vNode.bindings
|
|
11967
|
+
});
|
|
11968
|
+
this.#setItemBindings(itemBindings, context);
|
|
11969
|
+
context = { ...context, key: this.#evaluateKey(itemBindings) };
|
|
11970
|
+
}
|
|
11971
|
+
if (!rendered || context.key !== rendered.key) {
|
|
11972
|
+
this.#render();
|
|
11973
|
+
return;
|
|
11974
|
+
}
|
|
11975
|
+
this.#updateItemBindings(rendered.vNode, context);
|
|
11976
|
+
this.#previousIterations[index] = context;
|
|
11977
|
+
}
|
|
11978
|
+
}
|
|
11862
11979
|
/**
|
|
11863
11980
|
* Get iterations from various data types
|
|
11864
11981
|
* Supports: Arrays, Objects, Sets, Maps, Iterables, Numbers, Strings
|
|
@@ -11868,7 +11985,8 @@
|
|
|
11868
11985
|
return [];
|
|
11869
11986
|
// Array
|
|
11870
11987
|
if (Array.isArray(data)) {
|
|
11871
|
-
|
|
11988
|
+
// Array.from rather than map: a hole (e.g. after `items[5] = x` past the end) is a row of undefined
|
|
11989
|
+
return Array.from(data, (item, index) => ({
|
|
11872
11990
|
item,
|
|
11873
11991
|
index,
|
|
11874
11992
|
key: index
|
|
@@ -11949,6 +12067,11 @@
|
|
|
11949
12067
|
* The expression evaluator for this directive.
|
|
11950
12068
|
*/
|
|
11951
12069
|
#evaluator;
|
|
12070
|
+
/**
|
|
12071
|
+
* The HTML last set on the element. The same HTML is not set again: that
|
|
12072
|
+
* would replace the elements inside, and load their frames and images again.
|
|
12073
|
+
*/
|
|
12074
|
+
#html;
|
|
11952
12075
|
/**
|
|
11953
12076
|
* @param context The context for parsing the directive.
|
|
11954
12077
|
*/
|
|
@@ -11999,10 +12122,14 @@
|
|
|
11999
12122
|
get dependentIdentifiers() {
|
|
12000
12123
|
return identifiers;
|
|
12001
12124
|
},
|
|
12002
|
-
applyToDOM() {
|
|
12125
|
+
applyToDOM: () => {
|
|
12003
12126
|
const element = vNode.node;
|
|
12004
|
-
const htmlContent = evaluator.evaluate();
|
|
12005
|
-
|
|
12127
|
+
const htmlContent = evaluator.evaluate() ?? '';
|
|
12128
|
+
if (htmlContent === this.#html) {
|
|
12129
|
+
return;
|
|
12130
|
+
}
|
|
12131
|
+
this.#html = htmlContent;
|
|
12132
|
+
element.innerHTML = htmlContent;
|
|
12006
12133
|
}
|
|
12007
12134
|
};
|
|
12008
12135
|
return updater;
|