maquette 4.1.2 → 4.1.4
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/cache.d.ts +3 -3
- package/dist/cache.js +3 -3
- package/dist/cache.js.map +1 -1
- package/dist/dom.d.ts +28 -28
- package/dist/dom.js +28 -28
- package/dist/dom.js.map +1 -1
- package/dist/h.d.ts +2 -2
- package/dist/h.js.map +1 -1
- package/dist/index.d.ts +9 -4
- package/dist/index.js +9 -4
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +75 -75
- package/dist/interfaces.js.map +1 -1
- package/dist/mapping.d.ts +1 -1
- package/dist/mapping.js +1 -1
- package/dist/mapping.js.map +1 -1
- package/dist/maquette.cjs.js +142 -144
- package/dist/maquette.umd.js +142 -144
- package/dist/maquette.umd.min.js +1 -1
- package/dist/projection.js +28 -23
- package/dist/projection.js.map +1 -1
- package/dist/projector.d.ts +8 -8
- package/dist/projector.js +3 -10
- package/dist/projector.js.map +1 -1
- package/package.json +30 -63
- package/polyfills/maquette-polyfills.js +0 -531
package/dist/maquette.cjs.js
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Creates a {@link CalculationCache} object, useful for caching {@link VNode} trees.
|
|
5
|
+
* In practice, caching of {@link VNode} trees is not needed, because achieving 60 frames per second is almost never a problem.
|
|
6
|
+
* For more information, see {@link CalculationCache}.
|
|
7
|
+
*
|
|
8
|
+
* @param <Result> The type of the value that is cached.
|
|
9
|
+
*/
|
|
10
|
+
var createCache = function () {
|
|
11
|
+
var cachedInputs;
|
|
12
|
+
var cachedOutcome;
|
|
13
|
+
return {
|
|
14
|
+
invalidate: function () {
|
|
15
|
+
cachedOutcome = undefined;
|
|
16
|
+
cachedInputs = undefined;
|
|
17
|
+
},
|
|
18
|
+
result: function (inputs, calculation) {
|
|
19
|
+
if (cachedInputs) {
|
|
20
|
+
for (var i = 0; i < inputs.length; i++) {
|
|
21
|
+
if (cachedInputs[i] !== inputs[i]) {
|
|
22
|
+
cachedOutcome = undefined;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (!cachedOutcome) {
|
|
27
|
+
cachedOutcome = calculation();
|
|
28
|
+
cachedInputs = inputs;
|
|
29
|
+
}
|
|
30
|
+
return cachedOutcome;
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
3
35
|
var NAMESPACE_W3 = "http://www.w3.org/";
|
|
4
36
|
var NAMESPACE_SVG = "".concat(NAMESPACE_W3, "2000/svg");
|
|
5
37
|
var NAMESPACE_XLINK = "".concat(NAMESPACE_W3, "1999/xlink");
|
|
@@ -61,11 +93,7 @@ var checkDistinguishable = function (childNodes, indexToCheck, parentVNode, oper
|
|
|
61
93
|
if (i !== indexToCheck) {
|
|
62
94
|
var node = childNodes[i];
|
|
63
95
|
if (same(node, childNode)) {
|
|
64
|
-
throw {
|
|
65
|
-
error: new Error("".concat(parentVNode.vnodeSelector, " had a ").concat(childNode.vnodeSelector, " child ").concat(operation === "added" ? operation : "removed", ", but there is now more than one. You must add unique key properties to make them distinguishable.")),
|
|
66
|
-
parentNode: parentVNode,
|
|
67
|
-
childNode: childNode,
|
|
68
|
-
};
|
|
96
|
+
throw Object.assign(new Error("".concat(parentVNode.vnodeSelector, " had a ").concat(childNode.vnodeSelector, " child ").concat(operation === "added" ? operation : "removed", ", but there is now more than one. You must add unique key properties to make them distinguishable.")), { parentNode: parentVNode, childNode: childNode });
|
|
69
97
|
}
|
|
70
98
|
}
|
|
71
99
|
}
|
|
@@ -128,6 +156,7 @@ var nodeToRemove = function (vNode) {
|
|
|
128
156
|
}
|
|
129
157
|
};
|
|
130
158
|
var vnodeOnlyProps = [
|
|
159
|
+
"on",
|
|
131
160
|
"afterCreate",
|
|
132
161
|
"afterUpdate",
|
|
133
162
|
"afterRemoved",
|
|
@@ -178,19 +207,6 @@ var setProperties = function (domNode, properties, projectionOptions) {
|
|
|
178
207
|
}
|
|
179
208
|
}
|
|
180
209
|
}
|
|
181
|
-
else if (propName === "on" && propValue) {
|
|
182
|
-
// object with string keys and function values
|
|
183
|
-
for (var _i = 0, _a = Object.entries(properties.on); _i < _a.length; _i++) {
|
|
184
|
-
var _b = _a[_i], key = _b[0], handler = _b[1];
|
|
185
|
-
var listener = typeof handler === "function" ? handler : handler.listener;
|
|
186
|
-
if (eventHandlerInterceptor) {
|
|
187
|
-
listener = eventHandlerInterceptor(key, listener, domNode, properties);
|
|
188
|
-
}
|
|
189
|
-
if (listener) {
|
|
190
|
-
domNode.addEventListener(key, listener, typeof handler === "function" ? undefined : handler.options);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
210
|
else if (propName !== "key" && propValue !== null && propValue !== undefined) {
|
|
195
211
|
var type = typeof propValue;
|
|
196
212
|
if (type === "function") {
|
|
@@ -219,6 +235,19 @@ var setProperties = function (domNode, properties, projectionOptions) {
|
|
|
219
235
|
}
|
|
220
236
|
}
|
|
221
237
|
}
|
|
238
|
+
if (properties.on) {
|
|
239
|
+
// object with string keys and function values
|
|
240
|
+
for (var _i = 0, _a = Object.entries(properties.on); _i < _a.length; _i++) {
|
|
241
|
+
var _b = _a[_i], key = _b[0], handler = _b[1];
|
|
242
|
+
var listener = typeof handler === "function" ? handler : handler.listener;
|
|
243
|
+
if (eventHandlerInterceptor) {
|
|
244
|
+
listener = eventHandlerInterceptor(key, listener, domNode, properties);
|
|
245
|
+
}
|
|
246
|
+
if (listener) {
|
|
247
|
+
domNode.addEventListener(key, listener, typeof handler === "function" ? undefined : handler.options);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
222
251
|
};
|
|
223
252
|
var addChildren = function (domNode, children, projectionOptions) {
|
|
224
253
|
if (!children) {
|
|
@@ -450,7 +479,8 @@ var updateChildren = function (vnode, domNode, oldChildren, newChildren, project
|
|
|
450
479
|
var oldChild = oldIndex < oldChildrenLength ? oldChildren[oldIndex] : undefined;
|
|
451
480
|
var newChild = newChildren[newIndex];
|
|
452
481
|
if (oldChild !== undefined && same(oldChild, newChild)) {
|
|
453
|
-
textUpdated =
|
|
482
|
+
textUpdated =
|
|
483
|
+
updateDom(oldChild, newChild, projectionOptions, domNode, oldChildren) || textUpdated;
|
|
454
484
|
oldIndex++;
|
|
455
485
|
}
|
|
456
486
|
else {
|
|
@@ -462,7 +492,8 @@ var updateChildren = function (vnode, domNode, oldChildren, newChildren, project
|
|
|
462
492
|
checkDistinguishable(oldChildren, i, vnode, "removed");
|
|
463
493
|
}
|
|
464
494
|
textUpdated =
|
|
465
|
-
updateDom(oldChildren[findOldIndex], newChild, projectionOptions) ||
|
|
495
|
+
updateDom(oldChildren[findOldIndex], newChild, projectionOptions, domNode, oldChildren) ||
|
|
496
|
+
textUpdated;
|
|
466
497
|
oldIndex = findOldIndex + 1;
|
|
467
498
|
}
|
|
468
499
|
else {
|
|
@@ -483,7 +514,7 @@ var updateChildren = function (vnode, domNode, oldChildren, newChildren, project
|
|
|
483
514
|
}
|
|
484
515
|
return textUpdated;
|
|
485
516
|
};
|
|
486
|
-
updateDom = function (previous, vnode, projectionOptions) {
|
|
517
|
+
updateDom = function (previous, vnode, projectionOptions, parentNode, oldChildren) {
|
|
487
518
|
var domNode = previous.domNode;
|
|
488
519
|
var textUpdated = false;
|
|
489
520
|
if (previous === vnode) {
|
|
@@ -493,7 +524,13 @@ updateDom = function (previous, vnode, projectionOptions) {
|
|
|
493
524
|
if (vnode.vnodeSelector === "") {
|
|
494
525
|
if (vnode.text !== previous.text) {
|
|
495
526
|
var newTextNode = domNode.ownerDocument.createTextNode(vnode.text);
|
|
496
|
-
|
|
527
|
+
try {
|
|
528
|
+
parentNode.replaceChild(newTextNode, domNode);
|
|
529
|
+
}
|
|
530
|
+
catch (_a) {
|
|
531
|
+
// Text nodes can be substituted by google translate
|
|
532
|
+
parentNode.replaceChild(newTextNode, parentNode.childNodes[oldChildren.indexOf(previous)]);
|
|
533
|
+
}
|
|
497
534
|
vnode.domNode = newTextNode;
|
|
498
535
|
textUpdated = true;
|
|
499
536
|
return textUpdated;
|
|
@@ -547,7 +584,7 @@ var createProjection = function (vnode, projectionOptions) {
|
|
|
547
584
|
}
|
|
548
585
|
var previousVNode = vnode;
|
|
549
586
|
vnode = updatedVnode;
|
|
550
|
-
updateDom(previousVNode, updatedVnode, projectionOptions);
|
|
587
|
+
updateDom(previousVNode, updatedVnode, projectionOptions, previousVNode.domNode.parentNode, [previousVNode]);
|
|
551
588
|
},
|
|
552
589
|
domNode: vnode.domNode,
|
|
553
590
|
};
|
|
@@ -573,13 +610,13 @@ var applyDefaultProjectionOptions = function (projectorOptions) {
|
|
|
573
610
|
};
|
|
574
611
|
var dom = {
|
|
575
612
|
/**
|
|
576
|
-
* Creates a real DOM tree from `vnode`. The
|
|
577
|
-
* its
|
|
578
|
-
* This is a low-level method. Users will typically use a
|
|
579
|
-
* @param vnode - The root of the virtual DOM tree that was created using the
|
|
613
|
+
* Creates a real DOM tree from `vnode`. The {@link Projection} object returned will contain the resulting DOM Node in
|
|
614
|
+
* its {@link Projection.domNode | domNode} property.
|
|
615
|
+
* This is a low-level method. Users will typically use a {@link Projector} instead.
|
|
616
|
+
* @param vnode - The root of the virtual DOM tree that was created using the {@link h} function. NOTE: {@link VNode}
|
|
580
617
|
* objects may only be rendered once.
|
|
581
618
|
* @param projectionOptions - Options to be used to create and update the projection.
|
|
582
|
-
* @returns The
|
|
619
|
+
* @returns The {@link Projection} which also contains the DOM Node that was created.
|
|
583
620
|
*/
|
|
584
621
|
create: function (vnode, projectionOptions) {
|
|
585
622
|
projectionOptions = applyDefaultProjectionOptions(projectionOptions);
|
|
@@ -587,13 +624,13 @@ var dom = {
|
|
|
587
624
|
return createProjection(vnode, projectionOptions);
|
|
588
625
|
},
|
|
589
626
|
/**
|
|
590
|
-
* Appends a new child node to the DOM which is generated from a
|
|
591
|
-
* This is a low-level method. Users will typically use a
|
|
627
|
+
* Appends a new child node to the DOM which is generated from a {@link VNode}.
|
|
628
|
+
* This is a low-level method. Users will typically use a {@link Projector} instead.
|
|
592
629
|
* @param parentNode - The parent node for the new child node.
|
|
593
|
-
* @param vnode - The root of the virtual DOM tree that was created using the
|
|
630
|
+
* @param vnode - The root of the virtual DOM tree that was created using the {@link h} function. NOTE: {@link VNode}
|
|
594
631
|
* objects may only be rendered once.
|
|
595
|
-
* @param projectionOptions - Options to be used to create and update the
|
|
596
|
-
* @returns The
|
|
632
|
+
* @param projectionOptions - Options to be used to create and update the {@link Projection}.
|
|
633
|
+
* @returns The {@link Projection} that was created.
|
|
597
634
|
*/
|
|
598
635
|
append: function (parentNode, vnode, projectionOptions) {
|
|
599
636
|
projectionOptions = applyDefaultProjectionOptions(projectionOptions);
|
|
@@ -601,13 +638,13 @@ var dom = {
|
|
|
601
638
|
return createProjection(vnode, projectionOptions);
|
|
602
639
|
},
|
|
603
640
|
/**
|
|
604
|
-
* Inserts a new DOM node which is generated from a
|
|
605
|
-
* This is a low-level method. Users wil typically use a
|
|
641
|
+
* Inserts a new DOM node which is generated from a {@link VNode}.
|
|
642
|
+
* This is a low-level method. Users wil typically use a {@link Projector} instead.
|
|
606
643
|
* @param beforeNode - The node that the DOM Node is inserted before.
|
|
607
|
-
* @param vnode - The root of the virtual DOM tree that was created using the
|
|
608
|
-
* NOTE:
|
|
609
|
-
* @param projectionOptions - Options to be used to create and update the projection, see
|
|
610
|
-
* @returns The
|
|
644
|
+
* @param vnode - The root of the virtual DOM tree that was created using the {@link h} function.
|
|
645
|
+
* NOTE: {@link VNode} objects may only be rendered once.
|
|
646
|
+
* @param projectionOptions - Options to be used to create and update the projection, see {@link createProjector}.
|
|
647
|
+
* @returns The {@link Projection} that was created.
|
|
611
648
|
*/
|
|
612
649
|
insertBefore: function (beforeNode, vnode, projectionOptions) {
|
|
613
650
|
projectionOptions = applyDefaultProjectionOptions(projectionOptions);
|
|
@@ -615,15 +652,15 @@ var dom = {
|
|
|
615
652
|
return createProjection(vnode, projectionOptions);
|
|
616
653
|
},
|
|
617
654
|
/**
|
|
618
|
-
* Merges a new DOM node which is generated from a
|
|
655
|
+
* Merges a new DOM node which is generated from a {@link VNode} with an existing DOM Node.
|
|
619
656
|
* This means that the virtual DOM and the real DOM will have one overlapping element.
|
|
620
|
-
* Therefore the selector for the root
|
|
621
|
-
* This is a low-level method. Users wil typically use a
|
|
657
|
+
* Therefore the selector for the root {@link VNode} will be ignored, but its properties and children will be applied to the Element provided.
|
|
658
|
+
* This is a low-level method. Users wil typically use a {@link Projector} instead.
|
|
622
659
|
* @param element - The existing element to adopt as the root of the new virtual DOM. Existing attributes and child nodes are preserved.
|
|
623
|
-
* @param vnode - The root of the virtual DOM tree that was created using the
|
|
660
|
+
* @param vnode - The root of the virtual DOM tree that was created using the {@link h} function. NOTE: {@link VNode} objects
|
|
624
661
|
* may only be rendered once.
|
|
625
|
-
* @param projectionOptions - Options to be used to create and update the projection, see
|
|
626
|
-
* @returns The
|
|
662
|
+
* @param projectionOptions - Options to be used to create and update the projection, see {@link createProjector}.
|
|
663
|
+
* @returns The {@link Projection} that was created.
|
|
627
664
|
*/
|
|
628
665
|
merge: function (element, vnode, projectionOptions) {
|
|
629
666
|
projectionOptions = applyDefaultProjectionOptions(projectionOptions);
|
|
@@ -632,13 +669,13 @@ var dom = {
|
|
|
632
669
|
return createProjection(vnode, projectionOptions);
|
|
633
670
|
},
|
|
634
671
|
/**
|
|
635
|
-
* Replaces an existing DOM node with a node generated from a
|
|
636
|
-
* This is a low-level method. Users will typically use a
|
|
637
|
-
* @param element - The node for the
|
|
638
|
-
* @param vnode - The root of the virtual DOM tree that was created using the
|
|
672
|
+
* Replaces an existing DOM node with a node generated from a {@link VNode}.
|
|
673
|
+
* This is a low-level method. Users will typically use a {@link Projector} instead.
|
|
674
|
+
* @param element - The node for the {@link VNode} to replace.
|
|
675
|
+
* @param vnode - The root of the virtual DOM tree that was created using the {@link h} function. NOTE: {@link VNode}
|
|
639
676
|
* objects may only be rendered once.
|
|
640
|
-
* @param projectionOptions - Options to be used to create and update the
|
|
641
|
-
* @returns The
|
|
677
|
+
* @param projectionOptions - Options to be used to create and update the {@link Projection}.
|
|
678
|
+
* @returns The {@link Projection} that was created.
|
|
642
679
|
*/
|
|
643
680
|
replace: function (element, vnode, projectionOptions) {
|
|
644
681
|
projectionOptions = applyDefaultProjectionOptions(projectionOptions);
|
|
@@ -704,6 +741,57 @@ function h(selector, properties, children) {
|
|
|
704
741
|
};
|
|
705
742
|
}
|
|
706
743
|
|
|
744
|
+
/**
|
|
745
|
+
* Creates a {@link Mapping} instance that keeps an array of result objects synchronized with an array of source objects.
|
|
746
|
+
* See {@link http://maquettejs.org/docs/arrays.html Working with arrays}.
|
|
747
|
+
*
|
|
748
|
+
* @param <Source> The type of source items. A database-record for instance.
|
|
749
|
+
* @param <Target> The type of target items. A {@link MaquetteComponent} for instance.
|
|
750
|
+
* @param getSourceKey `function(source)` that must return a key to identify each source object. The result must either be a string or a number.
|
|
751
|
+
* @param createResult `function(source, index)` that must create a new result object from a given source. This function is identical
|
|
752
|
+
* to the `callback` argument in `Array.map(callback)`.
|
|
753
|
+
* @param updateResult `function(source, target, index)` that updates a result to an updated source.
|
|
754
|
+
*/
|
|
755
|
+
var createMapping = function (getSourceKey, createResult, updateResult) {
|
|
756
|
+
var keys = [];
|
|
757
|
+
var results = [];
|
|
758
|
+
return {
|
|
759
|
+
results: results,
|
|
760
|
+
map: function (newSources) {
|
|
761
|
+
var newKeys = newSources.map(getSourceKey);
|
|
762
|
+
var oldTargets = results.slice();
|
|
763
|
+
var oldIndex = 0;
|
|
764
|
+
for (var i = 0; i < newSources.length; i++) {
|
|
765
|
+
var source = newSources[i];
|
|
766
|
+
var sourceKey = newKeys[i];
|
|
767
|
+
if (sourceKey === keys[oldIndex]) {
|
|
768
|
+
results[i] = oldTargets[oldIndex];
|
|
769
|
+
updateResult(source, oldTargets[oldIndex], i);
|
|
770
|
+
oldIndex++;
|
|
771
|
+
}
|
|
772
|
+
else {
|
|
773
|
+
var found = false;
|
|
774
|
+
for (var j = 1; j < keys.length + 1; j++) {
|
|
775
|
+
var searchIndex = (oldIndex + j) % keys.length;
|
|
776
|
+
if (keys[searchIndex] === sourceKey) {
|
|
777
|
+
results[i] = oldTargets[searchIndex];
|
|
778
|
+
updateResult(newSources[i], oldTargets[searchIndex], i);
|
|
779
|
+
oldIndex = searchIndex + 1;
|
|
780
|
+
found = true;
|
|
781
|
+
break;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
if (!found) {
|
|
785
|
+
results[i] = createResult(source, i);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
results.length = newSources.length;
|
|
790
|
+
keys = newKeys;
|
|
791
|
+
},
|
|
792
|
+
};
|
|
793
|
+
};
|
|
794
|
+
|
|
707
795
|
var createParentNodePath = function (node, rootNode) {
|
|
708
796
|
var parentNodePath = [];
|
|
709
797
|
while (node && node !== rootNode) {
|
|
@@ -712,19 +800,12 @@ var createParentNodePath = function (node, rootNode) {
|
|
|
712
800
|
}
|
|
713
801
|
return parentNodePath;
|
|
714
802
|
};
|
|
715
|
-
var find;
|
|
716
|
-
if (Array.prototype.find) {
|
|
717
|
-
find = function (items, predicate) { return items.find(predicate); };
|
|
718
|
-
}
|
|
719
|
-
else {
|
|
720
|
-
find = function (items, predicate) { return items.filter(predicate)[0]; };
|
|
721
|
-
}
|
|
722
803
|
var findVNodeByParentNodePath = function (vnode, parentNodePath) {
|
|
723
804
|
var result = vnode;
|
|
724
805
|
parentNodePath.forEach(function (node) {
|
|
725
806
|
result =
|
|
726
807
|
result && result.children
|
|
727
|
-
?
|
|
808
|
+
? result.children.find(function (child) { return child.domNode === node; })
|
|
728
809
|
: undefined;
|
|
729
810
|
});
|
|
730
811
|
return result;
|
|
@@ -751,9 +832,9 @@ var createEventHandlerInterceptor = function (projector, getProjection, performa
|
|
|
751
832
|
}
|
|
752
833
|
};
|
|
753
834
|
/**
|
|
754
|
-
* Creates a
|
|
835
|
+
* Creates a {@link Projector} instance using the provided projectionOptions.
|
|
755
836
|
*
|
|
756
|
-
* For more information, see
|
|
837
|
+
* For more information, see {@link Projector}.
|
|
757
838
|
*
|
|
758
839
|
* @param projectorOptions Options that influence how the DOM is rendered and updated.
|
|
759
840
|
*/
|
|
@@ -838,89 +919,6 @@ var createProjector = function (projectorOptions) {
|
|
|
838
919
|
return projector;
|
|
839
920
|
};
|
|
840
921
|
|
|
841
|
-
/**
|
|
842
|
-
* Creates a [[CalculationCache]] object, useful for caching [[VNode]] trees.
|
|
843
|
-
* In practice, caching of [[VNode]] trees is not needed, because achieving 60 frames per second is almost never a problem.
|
|
844
|
-
* For more information, see [[CalculationCache]].
|
|
845
|
-
*
|
|
846
|
-
* @param <Result> The type of the value that is cached.
|
|
847
|
-
*/
|
|
848
|
-
var createCache = function () {
|
|
849
|
-
var cachedInputs;
|
|
850
|
-
var cachedOutcome;
|
|
851
|
-
return {
|
|
852
|
-
invalidate: function () {
|
|
853
|
-
cachedOutcome = undefined;
|
|
854
|
-
cachedInputs = undefined;
|
|
855
|
-
},
|
|
856
|
-
result: function (inputs, calculation) {
|
|
857
|
-
if (cachedInputs) {
|
|
858
|
-
for (var i = 0; i < inputs.length; i++) {
|
|
859
|
-
if (cachedInputs[i] !== inputs[i]) {
|
|
860
|
-
cachedOutcome = undefined;
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
if (!cachedOutcome) {
|
|
865
|
-
cachedOutcome = calculation();
|
|
866
|
-
cachedInputs = inputs;
|
|
867
|
-
}
|
|
868
|
-
return cachedOutcome;
|
|
869
|
-
},
|
|
870
|
-
};
|
|
871
|
-
};
|
|
872
|
-
|
|
873
|
-
/**
|
|
874
|
-
* Creates a {@link Mapping} instance that keeps an array of result objects synchronized with an array of source objects.
|
|
875
|
-
* See {@link http://maquettejs.org/docs/arrays.html Working with arrays}.
|
|
876
|
-
*
|
|
877
|
-
* @param <Source> The type of source items. A database-record for instance.
|
|
878
|
-
* @param <Target> The type of target items. A [[MaquetteComponent]] for instance.
|
|
879
|
-
* @param getSourceKey `function(source)` that must return a key to identify each source object. The result must either be a string or a number.
|
|
880
|
-
* @param createResult `function(source, index)` that must create a new result object from a given source. This function is identical
|
|
881
|
-
* to the `callback` argument in `Array.map(callback)`.
|
|
882
|
-
* @param updateResult `function(source, target, index)` that updates a result to an updated source.
|
|
883
|
-
*/
|
|
884
|
-
var createMapping = function (getSourceKey, createResult, updateResult) {
|
|
885
|
-
var keys = [];
|
|
886
|
-
var results = [];
|
|
887
|
-
return {
|
|
888
|
-
results: results,
|
|
889
|
-
map: function (newSources) {
|
|
890
|
-
var newKeys = newSources.map(getSourceKey);
|
|
891
|
-
var oldTargets = results.slice();
|
|
892
|
-
var oldIndex = 0;
|
|
893
|
-
for (var i = 0; i < newSources.length; i++) {
|
|
894
|
-
var source = newSources[i];
|
|
895
|
-
var sourceKey = newKeys[i];
|
|
896
|
-
if (sourceKey === keys[oldIndex]) {
|
|
897
|
-
results[i] = oldTargets[oldIndex];
|
|
898
|
-
updateResult(source, oldTargets[oldIndex], i);
|
|
899
|
-
oldIndex++;
|
|
900
|
-
}
|
|
901
|
-
else {
|
|
902
|
-
var found = false;
|
|
903
|
-
for (var j = 1; j < keys.length + 1; j++) {
|
|
904
|
-
var searchIndex = (oldIndex + j) % keys.length;
|
|
905
|
-
if (keys[searchIndex] === sourceKey) {
|
|
906
|
-
results[i] = oldTargets[searchIndex];
|
|
907
|
-
updateResult(newSources[i], oldTargets[searchIndex], i);
|
|
908
|
-
oldIndex = searchIndex + 1;
|
|
909
|
-
found = true;
|
|
910
|
-
break;
|
|
911
|
-
}
|
|
912
|
-
}
|
|
913
|
-
if (!found) {
|
|
914
|
-
results[i] = createResult(source, i);
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
results.length = newSources.length;
|
|
919
|
-
keys = newKeys;
|
|
920
|
-
},
|
|
921
|
-
};
|
|
922
|
-
};
|
|
923
|
-
|
|
924
922
|
exports.createCache = createCache;
|
|
925
923
|
exports.createMapping = createMapping;
|
|
926
924
|
exports.createProjector = createProjector;
|