Skip to content

Commit 884d888

Browse files
committed
v2.0
1 parent d460efc commit 884d888

6 files changed

Lines changed: 130 additions & 153 deletions

File tree

browser.js

Lines changed: 103 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44

55
(function () {
66

7-
exportModule("data-context-binding", ["data-context"], function factory(DC) {
7+
exportModule('data-context-binding', ['data-context'], function factory(DC) {
88

99
var globalScope = this,
10-
{ createDataContext, parse, stringify } = DC;
10+
{ createDataContext, parse, stringify } = DC,
11+
isDebug = document && Array.from(document.scripts).find(function (s) { return s.src.includes('data-context-binding'); })?.attributes.debug || false;
1112

1213

1314
//TODO [ x ] default bind ...
1415
//TODO [ x ] template binding
1516
//TODO [ x ] Event > : 'new', 'set', 'reposition', 'delete', '-change', 'bind', 'unbind'
16-
//TODO [ x ] DOM Attribute: 'path', 'bind', 'unbinded'
17+
//TODO [ x ] DOM Attribute: 'path', 'bind', 'unbinded', 'template', 'templates', 'rebinding', 'onbind', 'link'
1718

1819
var DataContextBinding = Object.defineProperties(bindDataContext, {
1920

@@ -23,6 +24,7 @@
2324
bindElement: { value: bindElement, writable: false, configurable: false, enumerable: false },
2425
bindingContext: { value: bindingContext, writable: false, configurable: false, enumerable: false },
2526

27+
context: { value: contextBind, writable: false, configurable: false, enumerable: false },
2628
change: { value: changeBind, writable: false, configurable: false, enumerable: false },
2729
innerHTML: { value: innerHTMLBind, writable: true, configurable: false, enumerable: false },
2830
value: { value: valueBind, writable: true, configurable: false, enumerable: false },
@@ -70,7 +72,7 @@
7072
*/
7173
function bindDataContext(value) {
7274

73-
var htmlElement = document.querySelector("html");
75+
var htmlElement = document.documentElement;
7476

7577
if (htmlElement) {
7678

@@ -89,6 +91,8 @@
8991
}
9092
}
9193

94+
globalScope.datacontext = htmlElement?.datacontext;
95+
9296
return htmlElement?.datacontext;
9397
}
9498

@@ -102,24 +106,34 @@
102106

103107
function bindAllElements(rootElement, rebinding = false) {
104108

105-
if (!rootElement) { rootElement = document.querySelector("html"); }
109+
if (!rootElement) { rootElement = document.documentElement; }
106110

107111
bindElement(rootElement, rebinding);
108112

109-
rootElement.querySelectorAll(`[bind],[onbind],[template],[templates],[rebinding],[link]`)
110-
.forEach(function (element) {
113+
rootElement
114+
.querySelectorAll(`[bind],[onbind],[template],[templates],[rebinding],[link],[unbinded]`)
115+
.forEach(bind);
116+
117+
if (rootElement !== document.documentElement) {
111118

112-
if (isParentTemplateOrLink(element)) { return; }
119+
document
120+
.documentElement.querySelectorAll(`[unbinded]`)
121+
.forEach(bind);
122+
}
113123

114-
if (!element.contextValue || rebinding) {
115124

116-
Promise.resolve(1).then((function (element, rebinding) {
125+
function bind(element) {
117126

118-
bindElement(element, rebinding);
119-
})(element, rebinding));
120-
}
121-
});
127+
if (isParentTemplateOrLink(element)) { return; }
122128

129+
if (!element.contextValue || rebinding || element.attributes.unbinded) {
130+
131+
Promise.resolve(1).then((function (element, rebinding) {
132+
133+
bindElement(element, rebinding);
134+
})(element, Boolean(rebinding || element.attributes.unbinded)));
135+
}
136+
}
123137
function isParentTemplateOrLink(element) {
124138

125139
var parent = element.parentElement;
@@ -134,19 +148,6 @@
134148
}
135149
}
136150

137-
function rebindAllElements(rootElement) {
138-
139-
if (!rootElement) { rootElement = document.body; }
140-
141-
bindElement(rootElement);
142-
143-
rootElement.querySelectorAll("[rebinding]")
144-
.forEach(function (element) { bindElement(element); });
145-
// TODO [ ] test
146-
document.head.querySelectorAll("[rebinding]")
147-
.forEach(function (element) { bindElement(element); });
148-
}
149-
150151
function bindElement(element, rebinding = false) {
151152

152153
if (!element instanceof HTMLTemplateElement || !element?.isConnected || (
@@ -207,10 +208,8 @@
207208

208209
if (CreateLink) {
209210

210-
//element.setAttribute("linked", path);
211-
//element.removeAttribute("link");
212211
element.linked = true;
213-
element.wsLink = WsUser.CreateLink(path, element);
212+
element.wsLink = CreateLink(path, element);
214213
element.wsLink.bindAllElements = function (elem, rebind = false) { bindAllElements(elem, rebind); };
215214
}
216215
}
@@ -443,25 +442,24 @@
443442

444443
return;
445444

446-
function _bind(fnBind) {
447445

448-
fnBind = (function (fn) {
446+
function _bind(fnBind) {
449447

450-
return function (event) {
448+
var _fnBind = function _fnBind(event) {
451449

452-
if (element.contextValue?.() === undefined) {
450+
if (_bindingContext.value === undefined && element.isConnected) {
453451

454-
element.setAttribute("unbinded", "");
455-
event.named = "unbind";
456-
}
457-
else { element.removeAttribute("unbinded"); }
452+
element.setAttribute("unbinded", "");
453+
event.eventName = "unbind";
454+
}
458455

459-
return fn.call(this, event);
460-
};
456+
return fnBind.call(element, event);
457+
};
461458

462-
})(fnBind);
459+
_fnBind.element = element;
460+
element.removeAttribute("unbinded");
463461

464-
if (fnBind.call(element, {
462+
if (_fnBind.call(element, {
465463
eventName: "bind",
466464
isValueInverted,
467465
bindArgs,
@@ -475,7 +473,7 @@
475473

476474
_bindingContext.source.on(
477475
_bindingContext.property,
478-
fnBind.bind(element),
476+
_fnBind,
479477
element
480478
);
481479
}
@@ -485,7 +483,7 @@
485483

486484
function _error(...args) {
487485

488-
console.log(args, element);
486+
pDebug(args, element);
489487
}
490488
}
491489

@@ -553,6 +551,8 @@
553551
isActive: { value: _isActive, writable: false, configurable: false, enumerable: false },
554552

555553
remove: { value: _remove, writable: false, configurable: false, enumerable: false },
554+
555+
removeParent: { value: _removeParent, writable: false, configurable: false, enumerable: false }
556556
});
557557

558558
elem.contextValue = _bindingContext.contextValue;
@@ -749,31 +749,53 @@
749749

750750
if (Array.isArray(_bindingContext.source)) {
751751

752-
var index = _bindingContext.source.indexOf(_bindingContext.value);
752+
_bindingContext.source.splice(_bindingContext.property, 1);
753+
}
754+
else {
753755

754-
if (index > -1) {
756+
delete _bindingContext.source[_bindingContext.property];
757+
}
758+
}
755759

756-
_bindingContext.source.splice(index, 1);
757-
}
760+
function _removeParent() {
761+
762+
if (Array.isArray(_bindingContext.source._parent)) {
763+
764+
var index = _bindingContext.source._propertyName;
765+
766+
_bindingContext.source._parent.splice(index, 1);
758767
}
759768
else {
760769

761-
delete _bindingContext.source[_bindingContext.property]
770+
delete _bindingContext.source._parent[_bindingContext.source._propertyName];
762771
}
763772
}
764773

765774
function _error(...args) {
766775

767-
console.log(args, d.rootElement);
776+
pDebug(args, d.rootElement);
768777
}
769778
}
770779

771780
function bindHandler(event) {
772781

773782
if (event.eventName === "delete") {
774783

775-
//debugger;
776-
rebinding(event.oldValue);
784+
var deletePropPath = event.propertyPath.join(".");
785+
786+
if (event.target._events[deletePropPath]) {
787+
788+
var current_events = event.oldValue._events;
789+
event.oldValue._events = event.target._events[deletePropPath];
790+
emitProperties(event.newValue, event.oldValue, event.eventName);
791+
delete event.target._events[deletePropPath];
792+
event.oldValue._events = current_events;
793+
}
794+
795+
else {
796+
797+
emitProperties(event.newValue, event.oldValue, event.eventName);
798+
}
777799

778800
return true;
779801
}
@@ -782,67 +804,59 @@
782804

783805
if (event.eventName === "set") {
784806

785-
//debugger;
786-
event.newValue._events = event.oldValue._events || {};
787-
event.oldValue._events = {};
807+
event.newValue._events = event.oldValue._events;
788808

789809
emitProperties(event.newValue, event.oldValue, event.eventName);
790810
}
791811

792812
else if (event.eventName === "reposition") {
793813

794-
//debugger;
795-
rebinding(event.newValue);
796-
rebinding(event.oldValue);
797-
}
814+
var currentPropPath = event.propertyPath.join(".");
815+
var newPropPath = event.target._propertyName + "." + event.newValue._propertyName;
798816

799-
//else if (event.eventName === "new") { debugger; }
817+
event.target._events[newPropPath] = event.newValue._events;
800818

819+
if (event.target._events[currentPropPath]) {
801820

802-
return true;
821+
event.newValue._events = event.target._events[currentPropPath];
822+
delete event.target._events[currentPropPath];
823+
}
824+
else {
803825

804-
function emitProperties(newValue, oldValue, eventName) {
826+
event.newValue._events = event.oldValue._events || {};
827+
}
805828

806-
if (newValue?.emit) {
829+
emitProperties(event.newValue, event.oldValue, event.eventName);
830+
}
807831

808-
Object.keys(newValue).forEach(function (k) {
832+
//else if (event.eventName === "new") { debugger; }
809833

810-
newValue.emit(k, { eventName, target: newValue, propertyPath: [k], oldValue: oldValue[k], newValue: newValue[k] });
811-
emitProperties(newValue[k], oldValue[k], eventName);
812-
});
813-
}
814-
}
815834

816-
function rebinding(val) {
835+
return true;
817836

818-
if (val?._events) {
837+
function emitProperties(newValue, oldValue, eventName) {
819838

820-
Object.keys(val._events).forEach(function (k) {
839+
var value = eventName === 'delete' ? oldValue : newValue;
821840

822-
val._events[k].forEach(function (l) {
841+
if (value?.emit) {
823842

824-
if (l.isActive instanceof Node) {
843+
Object.keys(value).forEach(function (k) {
825844

826-
l.isActive.setAttribute("rebinding", "");
827-
l.isActive = false;
828-
}
829-
});
845+
value.emit(k, { eventName, target: value, propertyPath: [k], oldValue: oldValue?.[k], newValue: newValue?.[k] });
846+
emitProperties(newValue?.[k], oldValue?.[k], eventName);
830847
});
831-
val._events = {};
832848
}
833-
834-
clearTimeout(rebindAllElements.timeout);
835-
rebindAllElements.timeout = setTimeout(function () {
836-
//console.log("RebindingAll");
837-
rebindAllElements();
838-
});
839849
}
840850
}
841851

842852
function getType(v) { return v === null ? "null" : Array.isArray(v) ? "array" : typeof v; }
843853

844854
//#region *** Default bind ***
845855

856+
function contextBind(event) {
857+
858+
return false;
859+
}
846860
function innerHTMLBind(event) {
847861

848862
if (event?.eventName === "unbind") {
@@ -1182,6 +1196,10 @@
11821196
}
11831197

11841198
//#endregion
1199+
1200+
// Debugging
1201+
function pDebug(...args) { if (isDebug) { console.log(`[ DEBUG ] `, ...args); } }
1202+
function pError(...args) { if (isDebug) { console.error(`[ ERROR ] `, ...args); } }
11851203
});
11861204

11871205

0 commit comments

Comments
 (0)