@slickgrid-universal/binding 2.5.0 → 2.6.0
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/commonjs/binding.helper.js +68 -68
- package/dist/commonjs/binding.service.js +146 -146
- package/dist/commonjs/index.js +19 -19
- package/dist/commonjs/interfaces.js +2 -2
- package/dist/esm/binding.helper.js +64 -64
- package/dist/esm/binding.service.js +142 -142
- package/dist/esm/index.js +3 -3
- package/dist/esm/interfaces.js +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/{commonjs → types}/binding.helper.d.ts +19 -18
- package/dist/types/binding.helper.d.ts.map +1 -0
- package/dist/{esm → types}/binding.service.d.ts +44 -43
- package/dist/types/binding.service.d.ts.map +1 -0
- package/dist/{esm → types}/index.d.ts +4 -3
- package/dist/types/index.d.ts.map +1 -0
- package/dist/{esm → types}/interfaces.d.ts +19 -18
- package/dist/types/interfaces.d.ts.map +1 -0
- package/package.json +6 -6
- package/dist/commonjs/binding.service.d.ts +0 -43
- package/dist/commonjs/index.d.ts +0 -3
- package/dist/commonjs/interfaces.d.ts +0 -18
- package/dist/esm/binding.helper.d.ts +0 -18
|
@@ -1,69 +1,69 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BindingHelper = void 0;
|
|
4
|
-
const binding_service_1 = require("./binding.service");
|
|
5
|
-
class BindingHelper {
|
|
6
|
-
get querySelectorPrefix() {
|
|
7
|
-
return this._querySelectorPrefix || '';
|
|
8
|
-
}
|
|
9
|
-
set querySelectorPrefix(prefix) {
|
|
10
|
-
this._querySelectorPrefix = prefix;
|
|
11
|
-
}
|
|
12
|
-
get observers() {
|
|
13
|
-
return this._observers;
|
|
14
|
-
}
|
|
15
|
-
constructor() {
|
|
16
|
-
this._observers = [];
|
|
17
|
-
this._querySelectorPrefix = '';
|
|
18
|
-
}
|
|
19
|
-
dispose() {
|
|
20
|
-
let observer = this._observers.pop();
|
|
21
|
-
while (observer) {
|
|
22
|
-
observer.dispose();
|
|
23
|
-
observer = this._observers.pop();
|
|
24
|
-
}
|
|
25
|
-
this._observers = [];
|
|
26
|
-
}
|
|
27
|
-
addElementBinding(variable, property, selector, attribute, events, callback) {
|
|
28
|
-
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
29
|
-
// before creating a new observer, first check if the variable already has an associated observer
|
|
30
|
-
// if we can't find an observer then we'll create a new one for it
|
|
31
|
-
let observer = this._observers.find(bind => bind.property === variable);
|
|
32
|
-
if (!observer) {
|
|
33
|
-
observer = new binding_service_1.BindingService({ variable, property });
|
|
34
|
-
}
|
|
35
|
-
// add event(s) binding
|
|
36
|
-
// when having multiple events, we'll loop through through them and add a binding for each
|
|
37
|
-
if (Array.isArray(events)) {
|
|
38
|
-
events.forEach(eventName => observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, eventName, callback));
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, events, callback);
|
|
42
|
-
}
|
|
43
|
-
this._observers.push(observer);
|
|
44
|
-
}
|
|
45
|
-
/** From a DOM element selector, which could be zero or multiple elements, add an event listener */
|
|
46
|
-
bindEventHandler(selector, eventName, callback, options) {
|
|
47
|
-
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
48
|
-
elements.forEach(elm => {
|
|
49
|
-
if (elm === null || elm === void 0 ? void 0 : elm.addEventListener) {
|
|
50
|
-
elm.addEventListener(eventName, callback, options);
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* From a DOM element selector, which could be zero or multiple elements, set the value on a given attribute name
|
|
56
|
-
* For example ('div.hello', 'textContent', 'world') => would set the textContent equal to 'world' on a div element having the class 'hello'
|
|
57
|
-
*/
|
|
58
|
-
setElementAttributeValue(selector, attribute, value) {
|
|
59
|
-
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
60
|
-
elements.forEach(elm => {
|
|
61
|
-
elm.textContent = '';
|
|
62
|
-
if (elm && attribute in elm) {
|
|
63
|
-
elm[attribute] = value;
|
|
64
|
-
}
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
exports.BindingHelper = BindingHelper;
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BindingHelper = void 0;
|
|
4
|
+
const binding_service_1 = require("./binding.service");
|
|
5
|
+
class BindingHelper {
|
|
6
|
+
get querySelectorPrefix() {
|
|
7
|
+
return this._querySelectorPrefix || '';
|
|
8
|
+
}
|
|
9
|
+
set querySelectorPrefix(prefix) {
|
|
10
|
+
this._querySelectorPrefix = prefix;
|
|
11
|
+
}
|
|
12
|
+
get observers() {
|
|
13
|
+
return this._observers;
|
|
14
|
+
}
|
|
15
|
+
constructor() {
|
|
16
|
+
this._observers = [];
|
|
17
|
+
this._querySelectorPrefix = '';
|
|
18
|
+
}
|
|
19
|
+
dispose() {
|
|
20
|
+
let observer = this._observers.pop();
|
|
21
|
+
while (observer) {
|
|
22
|
+
observer.dispose();
|
|
23
|
+
observer = this._observers.pop();
|
|
24
|
+
}
|
|
25
|
+
this._observers = [];
|
|
26
|
+
}
|
|
27
|
+
addElementBinding(variable, property, selector, attribute, events, callback) {
|
|
28
|
+
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
29
|
+
// before creating a new observer, first check if the variable already has an associated observer
|
|
30
|
+
// if we can't find an observer then we'll create a new one for it
|
|
31
|
+
let observer = this._observers.find(bind => bind.property === variable);
|
|
32
|
+
if (!observer) {
|
|
33
|
+
observer = new binding_service_1.BindingService({ variable, property });
|
|
34
|
+
}
|
|
35
|
+
// add event(s) binding
|
|
36
|
+
// when having multiple events, we'll loop through through them and add a binding for each
|
|
37
|
+
if (Array.isArray(events)) {
|
|
38
|
+
events.forEach(eventName => observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, eventName, callback));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, events, callback);
|
|
42
|
+
}
|
|
43
|
+
this._observers.push(observer);
|
|
44
|
+
}
|
|
45
|
+
/** From a DOM element selector, which could be zero or multiple elements, add an event listener */
|
|
46
|
+
bindEventHandler(selector, eventName, callback, options) {
|
|
47
|
+
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
48
|
+
elements.forEach(elm => {
|
|
49
|
+
if (elm === null || elm === void 0 ? void 0 : elm.addEventListener) {
|
|
50
|
+
elm.addEventListener(eventName, callback, options);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* From a DOM element selector, which could be zero or multiple elements, set the value on a given attribute name
|
|
56
|
+
* For example ('div.hello', 'textContent', 'world') => would set the textContent equal to 'world' on a div element having the class 'hello'
|
|
57
|
+
*/
|
|
58
|
+
setElementAttributeValue(selector, attribute, value) {
|
|
59
|
+
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
60
|
+
elements.forEach(elm => {
|
|
61
|
+
elm.textContent = '';
|
|
62
|
+
if (elm && attribute in elm) {
|
|
63
|
+
elm[attribute] = value;
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
exports.BindingHelper = BindingHelper;
|
|
69
69
|
//# sourceMappingURL=binding.helper.js.map
|
|
@@ -1,147 +1,147 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var _a;
|
|
3
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.BindingService = void 0;
|
|
5
|
-
/* eslint-disable no-bitwise */
|
|
6
|
-
const DOMPurify_ = require("dompurify");
|
|
7
|
-
const DOMPurify = ((_a = DOMPurify_ === null || DOMPurify_ === void 0 ? void 0 : DOMPurify_['default']) !== null && _a !== void 0 ? _a : DOMPurify_); // patch for rollup
|
|
8
|
-
/**
|
|
9
|
-
* Create 2 way Bindings for any variable that are primitive or object types, when it's an object type it will watch for property changes
|
|
10
|
-
* The following 2 articles helped in building this service:
|
|
11
|
-
* 1- https://blog.jeremylikness.com/blog/client-side-javascript-databinding-without-a-framework/
|
|
12
|
-
* 2- https://www.wintellect.com/data-binding-pure-javascript/
|
|
13
|
-
*/
|
|
14
|
-
class BindingService {
|
|
15
|
-
constructor(binding) {
|
|
16
|
-
this._value = null;
|
|
17
|
-
this._boundedEventWithListeners = [];
|
|
18
|
-
this._elementBindings = [];
|
|
19
|
-
this._binding = binding;
|
|
20
|
-
this._property = binding.property || '';
|
|
21
|
-
this._elementBindings = [];
|
|
22
|
-
if (binding.property && binding.variable && (binding.variable.hasOwnProperty(binding.property) || binding.property in binding.variable)) {
|
|
23
|
-
this._value = typeof binding.variable[binding.property] === 'string' ? this.sanitizeText(binding.variable[binding.property]) : binding.variable[binding.property];
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
this._value = typeof binding.variable === 'string' ? this.sanitizeText(binding.variable) : binding.variable;
|
|
27
|
-
}
|
|
28
|
-
if (typeof binding.variable === 'object') {
|
|
29
|
-
Object.defineProperty(binding.variable, binding.property, {
|
|
30
|
-
get: this.valueGetter.bind(this),
|
|
31
|
-
set: this.valueSetter.bind(this)
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
get boundedEventWithListeners() {
|
|
36
|
-
return this._boundedEventWithListeners;
|
|
37
|
-
}
|
|
38
|
-
get elementBindings() {
|
|
39
|
-
return this._elementBindings;
|
|
40
|
-
}
|
|
41
|
-
get property() {
|
|
42
|
-
return this._property;
|
|
43
|
-
}
|
|
44
|
-
dispose() {
|
|
45
|
-
this.unbindAll();
|
|
46
|
-
this._boundedEventWithListeners = [];
|
|
47
|
-
this._elementBindings = [];
|
|
48
|
-
}
|
|
49
|
-
valueGetter() {
|
|
50
|
-
return this._value;
|
|
51
|
-
}
|
|
52
|
-
valueSetter(val) {
|
|
53
|
-
this._value = typeof val === 'string' ? this.sanitizeText(val) : val;
|
|
54
|
-
if (Array.isArray(this._elementBindings)) {
|
|
55
|
-
for (const binding of this._elementBindings) {
|
|
56
|
-
if ((binding === null || binding === void 0 ? void 0 : binding.element) && (binding === null || binding === void 0 ? void 0 : binding.attribute)) {
|
|
57
|
-
binding.element[binding.attribute] = typeof val === 'string' ? this.sanitizeText(val) : val;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Add binding to 1 or more DOM Element by an object attribute and optionally on an event, we can do it in couple ways
|
|
64
|
-
* 1- if there's no event provided, it will simply replace the DOM elemnt (by an attribute), for example an innerHTML
|
|
65
|
-
* 2- when an event is provided, we will replace the DOM element (by an attribute) every time an event is triggered
|
|
66
|
-
* 2.1- we could also provide an extra callback method to execute when the event gets triggered
|
|
67
|
-
*/
|
|
68
|
-
bind(elements, attribute, eventName, eventCallback) {
|
|
69
|
-
if (elements && elements.forEach) {
|
|
70
|
-
// multiple DOM elements coming from a querySelectorAll() call
|
|
71
|
-
elements.forEach(elm => this.bindSingleElement(elm, attribute, eventName, eventCallback));
|
|
72
|
-
}
|
|
73
|
-
else if (elements) {
|
|
74
|
-
// single DOM element coming from a querySelector() call
|
|
75
|
-
this.bindSingleElement(elements, attribute, eventName, eventCallback);
|
|
76
|
-
}
|
|
77
|
-
return this;
|
|
78
|
-
}
|
|
79
|
-
/** Unbind (remove) an element event listener */
|
|
80
|
-
unbind(element, eventName, listener, options, eventUid) {
|
|
81
|
-
if (element) {
|
|
82
|
-
element.removeEventListener(eventName, listener, options);
|
|
83
|
-
const eventIdx = this._boundedEventWithListeners.findIndex(be => be.uid === eventUid);
|
|
84
|
-
if (eventIdx >= 0) {
|
|
85
|
-
this._boundedEventWithListeners.splice(eventIdx, 1);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
/** Unbind All (remove) bounded elements with listeners */
|
|
90
|
-
unbindAll() {
|
|
91
|
-
let boundedEvent = this._boundedEventWithListeners.pop();
|
|
92
|
-
while (boundedEvent) {
|
|
93
|
-
const { element, eventName, listener, uid } = boundedEvent;
|
|
94
|
-
this.unbind(element, eventName, listener, undefined, uid);
|
|
95
|
-
boundedEvent = this._boundedEventWithListeners.pop();
|
|
96
|
-
}
|
|
97
|
-
this._boundedEventWithListeners = [];
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Add binding to a single element by an object attribute and optionally on an event, we can do it in couple ways
|
|
101
|
-
* 1- if there's no event provided, it will simply replace the DOM element (by an attribute), for example an innerHTML
|
|
102
|
-
* 2- when an event is provided, we will replace the DOM element (by an attribute) every time an event is triggered
|
|
103
|
-
* 2.1- we could also provide an extra callback method to execute when the event gets triggered
|
|
104
|
-
*/
|
|
105
|
-
bindSingleElement(element, attribute, eventName, eventCallback) {
|
|
106
|
-
const binding = { element, attribute };
|
|
107
|
-
if (element) {
|
|
108
|
-
if (eventName) {
|
|
109
|
-
const listener = () => {
|
|
110
|
-
let elmValue = element[attribute];
|
|
111
|
-
if (this.hasData(elmValue) && (element === null || element === void 0 ? void 0 : element.type) === 'number') {
|
|
112
|
-
elmValue = +elmValue; // input is always string but we can parse to number when its type is number
|
|
113
|
-
}
|
|
114
|
-
this.valueSetter(elmValue);
|
|
115
|
-
if (this._binding.variable.hasOwnProperty(this._binding.property) || this._binding.property in this._binding.variable) {
|
|
116
|
-
this._binding.variable[this._binding.property] = this.valueGetter();
|
|
117
|
-
}
|
|
118
|
-
if (typeof eventCallback === 'function') {
|
|
119
|
-
return eventCallback(this.valueGetter());
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
binding.event = eventName;
|
|
123
|
-
binding.listener = listener;
|
|
124
|
-
element.addEventListener(eventName, listener);
|
|
125
|
-
this._boundedEventWithListeners.push({ element, eventName, listener, uid: this.generateUuidV4() });
|
|
126
|
-
}
|
|
127
|
-
this._elementBindings.push(binding);
|
|
128
|
-
element[attribute] = typeof this._value === 'string' ? this.sanitizeText(this._value) : this._value;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
/** Generate a UUID version 4 RFC compliant */
|
|
132
|
-
generateUuidV4() {
|
|
133
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
134
|
-
const r = Math.random() * 16 | 0;
|
|
135
|
-
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
136
|
-
return v.toString(16);
|
|
137
|
-
});
|
|
138
|
-
}
|
|
139
|
-
hasData(value) {
|
|
140
|
-
return value !== undefined && value !== null && value !== '';
|
|
141
|
-
}
|
|
142
|
-
sanitizeText(dirtyText) {
|
|
143
|
-
return (DOMPurify === null || DOMPurify === void 0 ? void 0 : DOMPurify.sanitize) ? DOMPurify.sanitize(dirtyText, {}) : dirtyText;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
exports.BindingService = BindingService;
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.BindingService = void 0;
|
|
5
|
+
/* eslint-disable no-bitwise */
|
|
6
|
+
const DOMPurify_ = require("dompurify");
|
|
7
|
+
const DOMPurify = ((_a = DOMPurify_ === null || DOMPurify_ === void 0 ? void 0 : DOMPurify_['default']) !== null && _a !== void 0 ? _a : DOMPurify_); // patch for rollup
|
|
8
|
+
/**
|
|
9
|
+
* Create 2 way Bindings for any variable that are primitive or object types, when it's an object type it will watch for property changes
|
|
10
|
+
* The following 2 articles helped in building this service:
|
|
11
|
+
* 1- https://blog.jeremylikness.com/blog/client-side-javascript-databinding-without-a-framework/
|
|
12
|
+
* 2- https://www.wintellect.com/data-binding-pure-javascript/
|
|
13
|
+
*/
|
|
14
|
+
class BindingService {
|
|
15
|
+
constructor(binding) {
|
|
16
|
+
this._value = null;
|
|
17
|
+
this._boundedEventWithListeners = [];
|
|
18
|
+
this._elementBindings = [];
|
|
19
|
+
this._binding = binding;
|
|
20
|
+
this._property = binding.property || '';
|
|
21
|
+
this._elementBindings = [];
|
|
22
|
+
if (binding.property && binding.variable && (binding.variable.hasOwnProperty(binding.property) || binding.property in binding.variable)) {
|
|
23
|
+
this._value = typeof binding.variable[binding.property] === 'string' ? this.sanitizeText(binding.variable[binding.property]) : binding.variable[binding.property];
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
this._value = typeof binding.variable === 'string' ? this.sanitizeText(binding.variable) : binding.variable;
|
|
27
|
+
}
|
|
28
|
+
if (typeof binding.variable === 'object') {
|
|
29
|
+
Object.defineProperty(binding.variable, binding.property, {
|
|
30
|
+
get: this.valueGetter.bind(this),
|
|
31
|
+
set: this.valueSetter.bind(this)
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
get boundedEventWithListeners() {
|
|
36
|
+
return this._boundedEventWithListeners;
|
|
37
|
+
}
|
|
38
|
+
get elementBindings() {
|
|
39
|
+
return this._elementBindings;
|
|
40
|
+
}
|
|
41
|
+
get property() {
|
|
42
|
+
return this._property;
|
|
43
|
+
}
|
|
44
|
+
dispose() {
|
|
45
|
+
this.unbindAll();
|
|
46
|
+
this._boundedEventWithListeners = [];
|
|
47
|
+
this._elementBindings = [];
|
|
48
|
+
}
|
|
49
|
+
valueGetter() {
|
|
50
|
+
return this._value;
|
|
51
|
+
}
|
|
52
|
+
valueSetter(val) {
|
|
53
|
+
this._value = typeof val === 'string' ? this.sanitizeText(val) : val;
|
|
54
|
+
if (Array.isArray(this._elementBindings)) {
|
|
55
|
+
for (const binding of this._elementBindings) {
|
|
56
|
+
if ((binding === null || binding === void 0 ? void 0 : binding.element) && (binding === null || binding === void 0 ? void 0 : binding.attribute)) {
|
|
57
|
+
binding.element[binding.attribute] = typeof val === 'string' ? this.sanitizeText(val) : val;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Add binding to 1 or more DOM Element by an object attribute and optionally on an event, we can do it in couple ways
|
|
64
|
+
* 1- if there's no event provided, it will simply replace the DOM elemnt (by an attribute), for example an innerHTML
|
|
65
|
+
* 2- when an event is provided, we will replace the DOM element (by an attribute) every time an event is triggered
|
|
66
|
+
* 2.1- we could also provide an extra callback method to execute when the event gets triggered
|
|
67
|
+
*/
|
|
68
|
+
bind(elements, attribute, eventName, eventCallback) {
|
|
69
|
+
if (elements && elements.forEach) {
|
|
70
|
+
// multiple DOM elements coming from a querySelectorAll() call
|
|
71
|
+
elements.forEach(elm => this.bindSingleElement(elm, attribute, eventName, eventCallback));
|
|
72
|
+
}
|
|
73
|
+
else if (elements) {
|
|
74
|
+
// single DOM element coming from a querySelector() call
|
|
75
|
+
this.bindSingleElement(elements, attribute, eventName, eventCallback);
|
|
76
|
+
}
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
/** Unbind (remove) an element event listener */
|
|
80
|
+
unbind(element, eventName, listener, options, eventUid) {
|
|
81
|
+
if (element) {
|
|
82
|
+
element.removeEventListener(eventName, listener, options);
|
|
83
|
+
const eventIdx = this._boundedEventWithListeners.findIndex(be => be.uid === eventUid);
|
|
84
|
+
if (eventIdx >= 0) {
|
|
85
|
+
this._boundedEventWithListeners.splice(eventIdx, 1);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/** Unbind All (remove) bounded elements with listeners */
|
|
90
|
+
unbindAll() {
|
|
91
|
+
let boundedEvent = this._boundedEventWithListeners.pop();
|
|
92
|
+
while (boundedEvent) {
|
|
93
|
+
const { element, eventName, listener, uid } = boundedEvent;
|
|
94
|
+
this.unbind(element, eventName, listener, undefined, uid);
|
|
95
|
+
boundedEvent = this._boundedEventWithListeners.pop();
|
|
96
|
+
}
|
|
97
|
+
this._boundedEventWithListeners = [];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Add binding to a single element by an object attribute and optionally on an event, we can do it in couple ways
|
|
101
|
+
* 1- if there's no event provided, it will simply replace the DOM element (by an attribute), for example an innerHTML
|
|
102
|
+
* 2- when an event is provided, we will replace the DOM element (by an attribute) every time an event is triggered
|
|
103
|
+
* 2.1- we could also provide an extra callback method to execute when the event gets triggered
|
|
104
|
+
*/
|
|
105
|
+
bindSingleElement(element, attribute, eventName, eventCallback) {
|
|
106
|
+
const binding = { element, attribute };
|
|
107
|
+
if (element) {
|
|
108
|
+
if (eventName) {
|
|
109
|
+
const listener = () => {
|
|
110
|
+
let elmValue = element[attribute];
|
|
111
|
+
if (this.hasData(elmValue) && (element === null || element === void 0 ? void 0 : element.type) === 'number') {
|
|
112
|
+
elmValue = +elmValue; // input is always string but we can parse to number when its type is number
|
|
113
|
+
}
|
|
114
|
+
this.valueSetter(elmValue);
|
|
115
|
+
if (this._binding.variable.hasOwnProperty(this._binding.property) || this._binding.property in this._binding.variable) {
|
|
116
|
+
this._binding.variable[this._binding.property] = this.valueGetter();
|
|
117
|
+
}
|
|
118
|
+
if (typeof eventCallback === 'function') {
|
|
119
|
+
return eventCallback(this.valueGetter());
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
binding.event = eventName;
|
|
123
|
+
binding.listener = listener;
|
|
124
|
+
element.addEventListener(eventName, listener);
|
|
125
|
+
this._boundedEventWithListeners.push({ element, eventName, listener, uid: this.generateUuidV4() });
|
|
126
|
+
}
|
|
127
|
+
this._elementBindings.push(binding);
|
|
128
|
+
element[attribute] = typeof this._value === 'string' ? this.sanitizeText(this._value) : this._value;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/** Generate a UUID version 4 RFC compliant */
|
|
132
|
+
generateUuidV4() {
|
|
133
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
134
|
+
const r = Math.random() * 16 | 0;
|
|
135
|
+
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
|
136
|
+
return v.toString(16);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
hasData(value) {
|
|
140
|
+
return value !== undefined && value !== null && value !== '';
|
|
141
|
+
}
|
|
142
|
+
sanitizeText(dirtyText) {
|
|
143
|
+
return (DOMPurify === null || DOMPurify === void 0 ? void 0 : DOMPurify.sanitize) ? DOMPurify.sanitize(dirtyText, {}) : dirtyText;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.BindingService = BindingService;
|
|
147
147
|
//# sourceMappingURL=binding.service.js.map
|
package/dist/commonjs/index.js
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./binding.helper"), exports);
|
|
18
|
-
__exportStar(require("./binding.service"), exports);
|
|
19
|
-
__exportStar(require("./interfaces"), exports);
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./binding.helper"), exports);
|
|
18
|
+
__exportStar(require("./binding.service"), exports);
|
|
19
|
+
__exportStar(require("./interfaces"), exports);
|
|
20
20
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
//# sourceMappingURL=interfaces.js.map
|
|
@@ -1,65 +1,65 @@
|
|
|
1
|
-
import { BindingService } from './binding.service';
|
|
2
|
-
export class BindingHelper {
|
|
3
|
-
get querySelectorPrefix() {
|
|
4
|
-
return this._querySelectorPrefix || '';
|
|
5
|
-
}
|
|
6
|
-
set querySelectorPrefix(prefix) {
|
|
7
|
-
this._querySelectorPrefix = prefix;
|
|
8
|
-
}
|
|
9
|
-
get observers() {
|
|
10
|
-
return this._observers;
|
|
11
|
-
}
|
|
12
|
-
constructor() {
|
|
13
|
-
this._observers = [];
|
|
14
|
-
this._querySelectorPrefix = '';
|
|
15
|
-
}
|
|
16
|
-
dispose() {
|
|
17
|
-
let observer = this._observers.pop();
|
|
18
|
-
while (observer) {
|
|
19
|
-
observer.dispose();
|
|
20
|
-
observer = this._observers.pop();
|
|
21
|
-
}
|
|
22
|
-
this._observers = [];
|
|
23
|
-
}
|
|
24
|
-
addElementBinding(variable, property, selector, attribute, events, callback) {
|
|
25
|
-
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
26
|
-
// before creating a new observer, first check if the variable already has an associated observer
|
|
27
|
-
// if we can't find an observer then we'll create a new one for it
|
|
28
|
-
let observer = this._observers.find(bind => bind.property === variable);
|
|
29
|
-
if (!observer) {
|
|
30
|
-
observer = new BindingService({ variable, property });
|
|
31
|
-
}
|
|
32
|
-
// add event(s) binding
|
|
33
|
-
// when having multiple events, we'll loop through through them and add a binding for each
|
|
34
|
-
if (Array.isArray(events)) {
|
|
35
|
-
events.forEach(eventName => observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, eventName, callback));
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, events, callback);
|
|
39
|
-
}
|
|
40
|
-
this._observers.push(observer);
|
|
41
|
-
}
|
|
42
|
-
/** From a DOM element selector, which could be zero or multiple elements, add an event listener */
|
|
43
|
-
bindEventHandler(selector, eventName, callback, options) {
|
|
44
|
-
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
45
|
-
elements.forEach(elm => {
|
|
46
|
-
if (elm === null || elm === void 0 ? void 0 : elm.addEventListener) {
|
|
47
|
-
elm.addEventListener(eventName, callback, options);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* From a DOM element selector, which could be zero or multiple elements, set the value on a given attribute name
|
|
53
|
-
* For example ('div.hello', 'textContent', 'world') => would set the textContent equal to 'world' on a div element having the class 'hello'
|
|
54
|
-
*/
|
|
55
|
-
setElementAttributeValue(selector, attribute, value) {
|
|
56
|
-
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
57
|
-
elements.forEach(elm => {
|
|
58
|
-
elm.textContent = '';
|
|
59
|
-
if (elm && attribute in elm) {
|
|
60
|
-
elm[attribute] = value;
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
1
|
+
import { BindingService } from './binding.service';
|
|
2
|
+
export class BindingHelper {
|
|
3
|
+
get querySelectorPrefix() {
|
|
4
|
+
return this._querySelectorPrefix || '';
|
|
5
|
+
}
|
|
6
|
+
set querySelectorPrefix(prefix) {
|
|
7
|
+
this._querySelectorPrefix = prefix;
|
|
8
|
+
}
|
|
9
|
+
get observers() {
|
|
10
|
+
return this._observers;
|
|
11
|
+
}
|
|
12
|
+
constructor() {
|
|
13
|
+
this._observers = [];
|
|
14
|
+
this._querySelectorPrefix = '';
|
|
15
|
+
}
|
|
16
|
+
dispose() {
|
|
17
|
+
let observer = this._observers.pop();
|
|
18
|
+
while (observer) {
|
|
19
|
+
observer.dispose();
|
|
20
|
+
observer = this._observers.pop();
|
|
21
|
+
}
|
|
22
|
+
this._observers = [];
|
|
23
|
+
}
|
|
24
|
+
addElementBinding(variable, property, selector, attribute, events, callback) {
|
|
25
|
+
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
26
|
+
// before creating a new observer, first check if the variable already has an associated observer
|
|
27
|
+
// if we can't find an observer then we'll create a new one for it
|
|
28
|
+
let observer = this._observers.find(bind => bind.property === variable);
|
|
29
|
+
if (!observer) {
|
|
30
|
+
observer = new BindingService({ variable, property });
|
|
31
|
+
}
|
|
32
|
+
// add event(s) binding
|
|
33
|
+
// when having multiple events, we'll loop through through them and add a binding for each
|
|
34
|
+
if (Array.isArray(events)) {
|
|
35
|
+
events.forEach(eventName => observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, eventName, callback));
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
observer === null || observer === void 0 ? void 0 : observer.bind(elements, attribute, events, callback);
|
|
39
|
+
}
|
|
40
|
+
this._observers.push(observer);
|
|
41
|
+
}
|
|
42
|
+
/** From a DOM element selector, which could be zero or multiple elements, add an event listener */
|
|
43
|
+
bindEventHandler(selector, eventName, callback, options) {
|
|
44
|
+
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
45
|
+
elements.forEach(elm => {
|
|
46
|
+
if (elm === null || elm === void 0 ? void 0 : elm.addEventListener) {
|
|
47
|
+
elm.addEventListener(eventName, callback, options);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* From a DOM element selector, which could be zero or multiple elements, set the value on a given attribute name
|
|
53
|
+
* For example ('div.hello', 'textContent', 'world') => would set the textContent equal to 'world' on a div element having the class 'hello'
|
|
54
|
+
*/
|
|
55
|
+
setElementAttributeValue(selector, attribute, value) {
|
|
56
|
+
const elements = document.querySelectorAll(`${this.querySelectorPrefix}${selector}`);
|
|
57
|
+
elements.forEach(elm => {
|
|
58
|
+
elm.textContent = '';
|
|
59
|
+
if (elm && attribute in elm) {
|
|
60
|
+
elm[attribute] = value;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
65
|
//# sourceMappingURL=binding.helper.js.map
|