Skip to content

Commit 261600f

Browse files
committed
Broken firefox and Safari - Multiple implementations for repeater
1 parent 57fb21c commit 261600f

File tree

3 files changed

+295
-245
lines changed

3 files changed

+295
-245
lines changed

Slim.js

Lines changed: 148 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
3131
isIE11: !!window['MSInputMethodContext'] && !!document['documentMode']
3232
};
3333

34-
var _$2 = Symbol('Slim');
34+
try {
35+
__flags.isChrome = /Chrome/.test(navigator.userAgent);
36+
} catch (err) {
37+
__flags.isChrome = false;
38+
}
39+
40+
var _$2 = '_slim_internals_'; //Symbol('Slim')
3541

3642
var Internals = function Internals() {
3743
_classCallCheck(this, Internals);
@@ -257,7 +263,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
257263
var collection = [];
258264
var search = function search(node, force) {
259265
collection.push(node);
260-
var allow = !(node instanceof Slim) || node instanceof Slim && !node.template || force;
266+
var allow = !node.__isSlim || node.__isSlim && !node.template || force;
261267
if (allow) {
262268
[].concat(_toConsumableArray(node.children)).forEach(function (childNode) {
263269
search(childNode, force);
@@ -401,6 +407,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
401407

402408
var _this2 = _possibleConstructorReturn(this, (Slim.__proto__ || Object.getPrototypeOf(Slim)).call(this));
403409

410+
_this2.__isSlim = true;
404411
Slim.debug('ctor', _this2.localName);
405412
if (Slim.checkCreationBlocking(_this2)) {
406413
return _possibleConstructorReturn(_this2);
@@ -694,115 +701,12 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
694701
);
695702
}, function () {}, true);
696703

697-
Slim.customDirective(function (attr) {
698-
return (/^s:repeat$/.test(attr.nodeName)
699-
);
700-
}, function (source, templateNode, attribute) {
701-
var path = attribute.nodeValue;
702-
var tProp = 'data';
703-
if (path.indexOf(' as')) {
704-
tProp = path.split(' as ')[1] || tProp;
705-
path = path.split(' as ')[0];
706-
}
707-
708-
var clones = [];
709-
var hook = document.createComment(templateNode.localName + ' s:repeat="' + attribute.nodeValue + '"');
710-
Slim._$(hook);
711-
Slim.selectRecursive(templateNode, true).forEach(function (e) {
712-
return Slim._$(e).excluded = true;
713-
});
714-
templateNode.parentElement.insertBefore(hook, templateNode);
715-
templateNode.remove();
716-
Slim.unbind(source, templateNode);
717-
Slim.asap(function () {
718-
templateNode.setAttribute('s:iterate', '');
719-
templateNode.removeAttribute('s:repeat');
720-
});
721-
var oldDataSource = [];
722-
Slim.bind(source, hook, path, function () {
723-
var dataSource = Slim.lookup(source, path) || [];
724-
var offset = 0;
725-
var restOfData = [];
726-
// get the diff
727-
var diff = Array(dataSource.length);
728-
dataSource.forEach(function (d, i) {
729-
if (oldDataSource[i] !== d) {
730-
diff[i] = true;
731-
}
732-
});
733-
oldDataSource = dataSource.concat();
734-
var indices = Object.keys(diff);
735-
if (dataSource.length < clones.length) {
736-
var disposables = clones.slice(dataSource.length);
737-
clones = clones.slice(0, dataSource.length);
738-
disposables.forEach(function (clone) {
739-
return clone.remove();
740-
});
741-
// unbind disposables?
742-
indices.forEach(function (index) {
743-
var clone = clones[index];[clone].concat(Slim.qSelectAll(clone, '*')).forEach(function (t) {
744-
t[_$2].repeater[tProp] = dataSource[index];
745-
Slim.commit(t, tProp);
746-
});
747-
});
748-
} else {
749-
// recycle
750-
clones.length && indices.forEach(function (index) {
751-
var clone = clones[index];
752-
if (!clone) return;
753-
[clone].concat(Slim.qSelectAll(clone, '*')).forEach(function (t) {
754-
t[_$2].repeater[tProp] = dataSource[index];
755-
Slim.commit(t, tProp);
756-
});
757-
});
758-
restOfData = dataSource.slice(clones.length);
759-
offset = clones.length;
760-
}
761-
if (!restOfData.length) return;
762-
// new clones
763-
var range = document.createRange();
764-
range.setStartBefore(hook);
765-
var html = Array(restOfData.length).fill(templateNode.outerHTML).join('');
766-
var frag = range.createContextualFragment(html);
767-
var all = [];
768-
var i = 0;
769-
while (i < frag.children.length) {
770-
var e = frag.children.item(i);
771-
clones.push(e);
772-
all.push(e);
773-
Slim._$(e).repeater[tProp] = dataSource[i + offset];
774-
var subTree = Slim.qSelectAll(e, '*');
775-
subTree.forEach(function (t) {
776-
all.push(t);
777-
Slim._$(t).repeater[tProp] = dataSource[i + offset];
778-
Slim.commit(t, tProp);
779-
});
780-
i++;
781-
}
782-
source._bindChildren(all);
783-
all.forEach(function (t) {
784-
if (t instanceof Slim) {
785-
t.createdCallback();
786-
Slim.asap(function () {
787-
Slim.commit(t, tProp);
788-
t[tProp] = t[_$2].repeater[tProp];
789-
});
790-
} else {
791-
Slim.commit(t, tProp);
792-
t[tProp] = t[_$2].repeater[tProp];
793-
}
794-
});
795-
hook.parentElement.insertBefore(frag, hook);
796-
});
797-
source[_$2].reversed[tProp] = true;
798-
}, true);
799-
800704
// supported events (i.e. click, mouseover, change...)
801705
Slim.customDirective(function (attr) {
802706
return Slim[_$2].supportedNativeEvents.indexOf(attr.nodeName) >= 0;
803707
}, function (source, target, attribute) {
804708
var eventName = attribute.nodeName;
805-
var delegate = attribute.nodeValue;
709+
var delegate = attribute.value;
806710
Slim._$(target).eventHandlers = target[_$2].eventHandlers || {};
807711
var allHandlers = target[_$2].eventHandlers;
808712
allHandlers[eventName] = allHandlers[eventName] || [];
@@ -823,7 +727,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
823727
return (/^s:if$/.exec(attr.nodeName)
824728
);
825729
}, function (source, target, attribute) {
826-
var expression = attribute.nodeValue;
730+
var expression = attribute.value;
827731
var path = expression;
828732
var isNegative = false;
829733
if (path.charAt(0) === '!') {
@@ -907,7 +811,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
907811
return (/^s:id$/.test(attr.nodeName)
908812
);
909813
}, function (source, target, attribute) {
910-
Slim._$(target).boundParent[attribute.nodeValue] = target;
814+
Slim._$(target).boundParent[attribute.value] = target;
911815
});
912816

913817
// bind:property
@@ -917,7 +821,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
917821
}, function (source, target, attribute, match) {
918822
var tAttr = match[2];
919823
var tProp = Slim.dashToCamel(tAttr);
920-
var expression = attribute.nodeValue;
824+
var expression = attribute.value;
921825
var oldValue = void 0;
922826
var rxM = Slim.rxMethod.exec(expression);
923827
if (rxM) {
@@ -948,6 +852,136 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
948852
}
949853
});
950854

855+
__flags.isChrome && Slim.customDirective(function (attr) {
856+
return (/^s:repeat$/.test(attr.nodeName)
857+
);
858+
}, function (source, templateNode, attribute) {
859+
var path = attribute.value;
860+
var tProp = 'data';
861+
if (path.indexOf(' as')) {
862+
tProp = path.split(' as ')[1] || tProp;
863+
path = path.split(' as ')[0];
864+
}
865+
866+
var clones = [];
867+
var hook = document.createComment(templateNode.localName + ' s:repeat="' + attribute.value + '"');
868+
Slim._$(hook);
869+
Slim.selectRecursive(templateNode, true).forEach(function (e) {
870+
return Slim._$(e).excluded = true;
871+
});
872+
templateNode.parentElement.insertBefore(hook, templateNode);
873+
templateNode.remove();
874+
Slim.unbind(source, templateNode);
875+
Slim.asap(function () {
876+
templateNode.setAttribute('s:iterate', '');
877+
templateNode.removeAttribute('s:repeat');
878+
});
879+
var oldDataSource = [];
880+
Slim.bind(source, hook, path, function () {
881+
var dataSource = Slim.lookup(source, path) || [];
882+
var offset = 0;
883+
var restOfData = [];
884+
// get the diff
885+
var diff = Array(dataSource.length);
886+
dataSource.forEach(function (d, i) {
887+
if (oldDataSource[i] !== d) {
888+
diff[i] = true;
889+
}
890+
});
891+
oldDataSource = dataSource.concat();
892+
var indices = Object.keys(diff);
893+
if (dataSource.length < clones.length) {
894+
var disposables = clones.slice(dataSource.length);
895+
clones = clones.slice(0, dataSource.length);
896+
disposables.forEach(function (clone) {
897+
return clone.remove();
898+
});
899+
// unbind disposables?
900+
indices.forEach(function (index) {
901+
var clone = clones[index];[clone].concat(Slim.qSelectAll(clone, '*')).forEach(function (t) {
902+
t[_$2].repeater[tProp] = dataSource[index];
903+
Slim.commit(t, tProp);
904+
});
905+
});
906+
} else {
907+
// recycle
908+
clones.length && indices.forEach(function (index) {
909+
var clone = clones[index];
910+
if (!clone) return;
911+
[clone].concat(Slim.qSelectAll(clone, '*')).forEach(function (t) {
912+
t[_$2].repeater[tProp] = dataSource[index];
913+
Slim.commit(t, tProp);
914+
});
915+
});
916+
restOfData = dataSource.slice(clones.length);
917+
offset = clones.length;
918+
}
919+
if (!restOfData.length) return;
920+
// new clones
921+
var range = document.createRange();
922+
range.setStartBefore(hook);
923+
var html = Array(restOfData.length).fill(templateNode.outerHTML).join('');
924+
var frag = range.createContextualFragment(html);
925+
var all = [];
926+
var i = 0;
927+
while (i < frag.children.length) {
928+
var e = frag.children.item(i);
929+
clones.push(e);
930+
all.push(e);
931+
Slim._$(e).repeater[tProp] = dataSource[i + offset];
932+
var subTree = Slim.qSelectAll(e, '*');
933+
subTree.forEach(function (t) {
934+
all.push(t);
935+
Slim._$(t).repeater[tProp] = dataSource[i + offset];
936+
Slim.commit(t, tProp);
937+
});
938+
i++;
939+
}
940+
source._bindChildren(all);
941+
all.forEach(function (t) {
942+
if (t.__isSlim) {
943+
t.createdCallback();
944+
Slim.asap(function () {
945+
Slim.commit(t, tProp);
946+
t[tProp] = t[_$2].repeater[tProp];
947+
});
948+
} else {
949+
Slim.commit(t, tProp);
950+
t[tProp] = t[_$2].repeater[tProp];
951+
}
952+
});
953+
hook.parentElement.insertBefore(frag, hook);
954+
});
955+
source[_$2].reversed[tProp] = true;
956+
}, true);
957+
958+
!__flags.isChrome && Slim.customDirective(function (attr) {
959+
return (/^s:repeat$/.test(attr.nodeName)
960+
);
961+
}, function (source, templateNode, attribute) {
962+
var path = attribute.nodeValue;
963+
var tProp = 'data';
964+
if (path.indexOf(' as')) {
965+
tProp = path.split(' as ')[1] || tProp;
966+
path = path.split(' as ')[0];
967+
}
968+
969+
var repeater = document.createElement('slim-repeat');
970+
repeater[_$2].boundParent = source;
971+
repeater.dataProp = tProp;
972+
repeater.dataPath = attribute.nodeValue;
973+
repeater.templateNode = templateNode.cloneNode(true);
974+
repeater.templateNode.removeAttribute('s:repeat');
975+
templateNode.parentNode.insertBefore(repeater, templateNode);
976+
Slim.removeChild(templateNode);
977+
Slim.bind(source, repeater, path, function () {
978+
var dataSource = Slim.lookup(source, path);
979+
repeater.dataSource = dataSource || [];
980+
});
981+
982+
// source._executeBindings()
983+
}, true);
984+
951985
var SlimRepeater = function (_Slim) {
952986
_inherits(SlimRepeater, _Slim);
953987

@@ -968,7 +1002,7 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
9681002
});
9691003
directChildren.forEach(function (child, index) {
9701004
child.setAttribute('s:iterate', _this7.dataPath + ' : ' + index);
971-
Slim.selectRecursive(child, true).forEach(function (e) {
1005+
Slim.selectRecursive(child).forEach(function (e) {
9721006
Slim._$(e).repeater[_this7.dataProp] = _this7.dataSource[index];
9731007
if (e instanceof Slim) {
9741008
e[_this7.dataProp] = _this7.dataSource[index];
@@ -994,12 +1028,11 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
9941028
Slim.unbind(_this8.boundParent, e);
9951029
});
9961030
if (!this.dataSource || !this.templateNode || !this.boundParent) {
997-
_get(SlimRepeater.prototype.__proto__ || Object.getPrototypeOf(SlimRepeater.prototype), 'render', this).call(this, '');
998-
} else {
999-
var newTemplate = Array(this.dataSource.length).fill(this.templateNode.outerHTML).join('');
1000-
this.innerHTML = '';
1001-
_get(SlimRepeater.prototype.__proto__ || Object.getPrototypeOf(SlimRepeater.prototype), 'render', this).call(this, newTemplate);
1031+
return _get(SlimRepeater.prototype.__proto__ || Object.getPrototypeOf(SlimRepeater.prototype), 'render', this).call(this, '');
10021032
}
1033+
var newTemplate = Array(this.dataSource.length).fill(this.templateNode.outerHTML).join('');
1034+
this.innerHTML = '';
1035+
_get(SlimRepeater.prototype.__proto__ || Object.getPrototypeOf(SlimRepeater.prototype), 'render', this).call(this, newTemplate);
10031036
}
10041037
}, {
10051038
key: 'dataSource',

0 commit comments

Comments
 (0)