Skip to content

Commit d460efc

Browse files
committed
v2.0
1 parent d8c9f41 commit d460efc

4 files changed

Lines changed: 228 additions & 49 deletions

File tree

browser.js

Lines changed: 184 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
hidden: { value: hiddenBind, writable: true, configurable: false, enumerable: false },
3434
enabled: { value: enabledBind, writable: true, configurable: false, enumerable: false },
3535
disabled: { value: disabledBind, writable: true, configurable: false, enumerable: false },
36+
class: { value: classToggleBind, writable: true, configurable: false, enumerable: false },
37+
attribute: { value: attributeBind, writable: true, configurable: false, enumerable: false },
3638

3739
input: { value: valueBind, writable: true, configurable: false, enumerable: false },
3840
input_checkbox: { value: checkBind, writable: true, configurable: false, enumerable: false },
@@ -122,7 +124,7 @@
122124

123125
var parent = element.parentElement;
124126

125-
while (parent !== rootElement) {
127+
while (parent && parent !== rootElement) {
126128

127129
if (parent.attributes.template || parent.attributes.link) { return true; }
128130

@@ -284,11 +286,11 @@
284286
if (!appendTemplate(keys[i])) { break; }
285287
}
286288

287-
if (i !== 0) {
289+
setTimeout(function () {
288290

289-
setTimeout(function () {
291+
if (_bindingContext?.value?._isDataContext) {
290292

291-
if (_bindingContext.value && typeof _bindingContext.value.on === "function") {
293+
if (isFunctionNotAdded('addTemplate')) {
292294

293295
_bindingContext.value.on(
294296
"-",
@@ -303,6 +305,9 @@
303305
},
304306
element
305307
);
308+
}
309+
310+
if (isFunctionNotAdded('removeTemplate')) {
306311

307312
_bindingContext.value.on(
308313
"-",
@@ -321,15 +326,20 @@
321326
element
322327
);
323328
}
324-
});
329+
}
330+
});
325331

326-
return;
327-
}
332+
return;
328333
}
329334

330335
return appendTemplate();
331336

332337

338+
function isFunctionNotAdded(fnName) {
339+
340+
return _bindingContext?.value?._events?.["-"]
341+
?.find(function (fn) { return fn.name.includes(fnName); }) === undefined;
342+
}
333343
function appendTemplate(key, target) {
334344

335345
var ret = false;
@@ -394,9 +404,21 @@
394404

395405
try {
396406

397-
var fnName = element.attributes.bind.value;
407+
var fnName = element.attributes.bind.value,
408+
isValueInverted = false,
409+
bindArgs = [];
398410

399-
if (!fnName) {
411+
if (fnName) {
412+
413+
//!fnName(bindArg1,bindArg2,...)
414+
if (fnName.startsWith("!")) { isValueInverted = true; fnName = fnName.substring(1); }
415+
bindArgs = fnName.split(/[\(\)]/);
416+
fnName = bindArgs.shift().trim();
417+
if (bindArgs[0]) { bindArgs = bindArgs[0].split(/,/); }
418+
bindArgs = bindArgs.map(function (arg) { return arg.trim(); });
419+
}
420+
421+
else {
400422

401423
fnName = element.tagName.toLowerCase();
402424

@@ -423,15 +445,37 @@
423445

424446
function _bind(fnBind) {
425447

426-
if (fnBind.call(element, { eventName: "bind", target: _bindingContext.source, propertyPath: [_bindingContext.property], oldValue: _bindingContext.value, newValue: _bindingContext.value })) {
448+
fnBind = (function (fn) {
427449

428-
if (_bindingContext.source && typeof _bindingContext.source.on === "function") {
450+
return function (event) {
451+
452+
if (element.contextValue?.() === undefined) {
453+
454+
element.setAttribute("unbinded", "");
455+
event.named = "unbind";
456+
}
457+
else { element.removeAttribute("unbinded"); }
458+
459+
return fn.call(this, event);
460+
};
429461

430-
element.removeAttribute("unbinded");
462+
})(fnBind);
463+
464+
if (fnBind.call(element, {
465+
eventName: "bind",
466+
isValueInverted,
467+
bindArgs,
468+
target: _bindingContext.source,
469+
propertyPath: [_bindingContext.property],
470+
oldValue: _bindingContext.value,
471+
newValue: _bindingContext.value
472+
})) {
473+
474+
if (_bindingContext.source && typeof _bindingContext.source.on === "function") {
431475

432476
_bindingContext.source.on(
433477
_bindingContext.property,
434-
function (event) { return fnBind.call(element, event); },
478+
fnBind.bind(element),
435479
element
436480
);
437481
}
@@ -915,7 +959,16 @@
915959
return false;
916960
}
917961

918-
this.contextValue() ? this.removeAttribute("hidden") : this.setAttribute("hidden", "");
962+
if (event.eventName === "bind") {
963+
964+
this.isValueInverted = event.isValueInverted;
965+
}
966+
967+
updateAttributeBinding.call(this,
968+
this.isValueInverted ? this.contextValue() : !this.contextValue(),
969+
'hidden',
970+
'hidden'
971+
);
919972

920973
// I am alive!
921974
return this.contextValue() === undefined ? false : true;
@@ -928,7 +981,16 @@
928981
return false;
929982
}
930983

931-
this.contextValue() ? this.setAttribute("hidden", "") : this.removeAttribute("hidden");
984+
if (event.eventName === "bind") {
985+
986+
this.isValueInverted = event.isValueInverted;
987+
}
988+
989+
updateAttributeBinding.call(this,
990+
this.isValueInverted ? !this.contextValue() : this.contextValue(),
991+
'hidden',
992+
'hidden'
993+
);
932994

933995
// I am alive!
934996
return this.contextValue() === undefined ? false : true;
@@ -991,6 +1053,16 @@
9911053
return false;
9921054
}
9931055

1056+
if (event.eventName === "bind") {
1057+
1058+
this.isValueInverted = event.isValueInverted;
1059+
}
1060+
1061+
updateAttributeBinding.call(this,
1062+
this.isValueInverted ? this.contextValue() : !this.contextValue(),
1063+
'disabled',
1064+
'disabled'
1065+
);
9941066
if (this.contextValue()) { this.removeAttribute('disabled'); }
9951067
else { this.setAttribute('disabled', 'disabled'); }
9961068

@@ -1007,13 +1079,107 @@
10071079
return false;
10081080
}
10091081

1010-
if (this.contextValue()) { this.setAttribute('disabled', 'disabled'); }
1011-
else { this.removeAttribute('disabled'); }
1082+
if (event.eventName === "bind") {
1083+
1084+
this.isValueInverted = event.isValueInverted;
1085+
}
1086+
1087+
updateAttributeBinding.call(this,
1088+
this.isValueInverted ? !this.contextValue() : this.contextValue(),
1089+
'disabled',
1090+
'disabled'
1091+
);
10121092

10131093
// I am alive!
1014-
return true;
1094+
return this.contextValue() === undefined ? false : true;
10151095
};
1096+
function classToggleBind(event) {
1097+
1098+
if (event.eventName === "unbind") {
1099+
1100+
toggle(this, false);
1101+
1102+
// I am dead!
1103+
return false;
1104+
}
10161105

1106+
if (event.eventName === "bind") {
1107+
1108+
this.isValueInverted = event.isValueInverted;
1109+
1110+
if (event.bindArgs.length > 1) {
1111+
1112+
this.primaryClasses = parseClassNames(event.bindArgs[0]);
1113+
this.secondaryClasses = parseClassNames(event.bindArgs[1]);
1114+
}
1115+
else {
1116+
1117+
this.primaryClasses = parseClassNames(event.bindArgs[0]);
1118+
this.secondaryClasses = [];
1119+
}
1120+
}
1121+
1122+
toggle(this, this.isValueInverted ? !this.contextValue() : this.contextValue());
1123+
1124+
// I am alive!
1125+
return true;
1126+
1127+
1128+
function parseClassNames(classNames) {
1129+
1130+
return classNames
1131+
.split(/\s/)
1132+
.filter(function (c) { return c; });
1133+
}
1134+
function toggle(element, isPrimary) {
1135+
1136+
if (isPrimary) {
1137+
element.primaryClasses.forEach(function (c) { element.classList.add(c); });
1138+
element.secondaryClasses.forEach(function (c) { element.classList.remove(c); });
1139+
}
1140+
else {
1141+
element.primaryClasses.forEach(function (c) { element.classList.remove(c); });
1142+
element.secondaryClasses.forEach(function (c) { element.classList.add(c); });
1143+
}
1144+
}
1145+
}
1146+
function attributeBind(event) {
1147+
1148+
if (event.eventName === "unbind") {
1149+
1150+
updateAttributeBinding.call(this, false, this.attributeBindingName, this.attributeBindingValue);
1151+
1152+
// I am dead!
1153+
return false;
1154+
}
1155+
1156+
if (event.eventName === "bind") {
1157+
1158+
this.isValueInverted = event.isValueInverted;
1159+
this.attributeBindingName = event.bindArgs[0] || '';
1160+
this.attributeBindingValue = event.bindArgs[1] || '';
1161+
}
1162+
1163+
updateAttributeBinding.call(this,
1164+
this.isValueInverted ? !this.contextValue() : this.contextValue(),
1165+
this.attributeBindingName,
1166+
this.attributeBindingValue
1167+
);
1168+
1169+
// I am alive!
1170+
return this.contextValue() === undefined ? false : true;
1171+
}
1172+
1173+
1174+
function updateAttributeBinding(isEnabled, attributeName, attributeValue = '') {
1175+
1176+
if (attributeName) {
1177+
1178+
if (isEnabled) { this.setAttribute(attributeName, attributeValue); }
1179+
1180+
else { this.removeAttribute(attributeName); }
1181+
}
1182+
}
10171183

10181184
//#endregion
10191185
});

0 commit comments

Comments
 (0)