@cocreate/events 1.4.1 → 1.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/CHANGELOG.md CHANGED
@@ -1,3 +1,22 @@
1
+ # [1.6.0](https://github.com/CoCreate-app/CoCreate-events/compare/v1.5.0...v1.6.0) (2023-03-16)
2
+
3
+
4
+ ### Features
5
+
6
+ * replaced get-value and set-value with a super charged version of CoCreate-events ([5407615](https://github.com/CoCreate-app/CoCreate-events/commit/54076157dc1e3ae764bc1e8d8ce4a84786501449))
7
+
8
+ # [1.5.0](https://github.com/CoCreate-app/CoCreate-events/compare/v1.4.1...v1.5.0) (2023-03-15)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * add events per element and observer to detect newely added elements ([dcbaa38](https://github.com/CoCreate-app/CoCreate-events/commit/dcbaa38a09fa75ddcf3c969c708fa1dbcf2e3ce4))
14
+
15
+
16
+ ### Features
17
+
18
+ * attribute for targeting parent and sibling elements ([842be58](https://github.com/CoCreate-app/CoCreate-events/commit/842be58541401574cd4d093d08468abe39decf9b))
19
+
1
20
  ## [1.4.1](https://github.com/CoCreate-app/CoCreate-events/compare/v1.4.0...v1.4.1) (2023-02-21)
2
21
 
3
22
 
package/demo/index.html CHANGED
@@ -68,9 +68,16 @@
68
68
 
69
69
  <!-- defining key example -->
70
70
  <div >
71
- <input input-target="#testing" input-value="" input-key="ty">
72
- <span id="testing" class="{{ty}}">other content</span>
71
+ <div observe-target=".testing" observe-attribute="value">testing this new value</div>
72
+ <input input-target=".testing" input-attribute="value" input-events="input, onload" value="great test">
73
+ <input class="testing {{ty}}">
74
+ <div class="testing {{ty}}">other content</div>
73
75
  </div>
76
+
77
+ <span id="keyname" clone-data='{"attributes": {"key": "{{keyname}}", "value": ""}}' {{keyname}}="test" style="margin-right:10px; padding:5px">
78
+ <svg class="svg" width="12" height="12" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg"><path d="M5 5V0h1v5h5v1H6v5H5V6H0V5h5z" fill-rule="nonzero" fill-opacity="1" fill="#fff" stroke="none"></path></svg>
79
+ </span>
80
+ <input placeholder="Search all attributes" input-value input-key="keyname" input-target="#keyname">
74
81
 
75
82
  <!--<script src="../dist/CoCreate-events.js"></script>-->
76
83
  <script src="../../../CoCreateJS/dist/CoCreate.js"></script>
package/docs/index.html CHANGED
@@ -134,7 +134,7 @@
134
134
  </div>
135
135
 
136
136
  <div id="demo-preview" class="position:relative overflow:auto background-color:white">
137
- <div get-value="#demo" class="padding:20px"></div>
137
+ <div class="demopreview" class="padding:20px"></div>
138
138
  </div>
139
139
 
140
140
  <div class="font-size:20px position:absolute top:10px right:10px opacity:0.6">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/events",
3
- "version": "1.4.1",
3
+ "version": "1.6.0",
4
4
  "description": "A simple events component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "events",
package/src/index.js CHANGED
@@ -1,62 +1,52 @@
1
1
  import {queryDocumentSelectorAll} from '@cocreate/utils';
2
2
  import action from '@cocreate/actions';
3
+ import observer from '@cocreate/observer';
4
+
3
5
 
4
6
  const CoCreateEvents = {
5
- // ToDo update to support config, ability to add custom prefix, for loop each defualt and custom prefix to support action
7
+
6
8
  init: function(prefix, events) {
7
9
  if (prefix && events)
8
- this.initElement(document, prefix, events);
10
+ this.initPrefix(prefix, events);
9
11
  else {
10
- this.initElement(document, 'toggle', ['click']);
11
- this.initElement(document, 'click', ['click']);
12
- this.initElement(document, 'hover', ['mouseover', 'mouseout']);
13
- this.initElement(document, 'mouseover', ['mouseover']);
14
- this.initElement(document, 'mouseout', ['mouseout']);
15
- this.initElement(document, 'input', ['input']);
16
- this.initElement(document, 'change', ['change']);
17
- this.initElement(document, 'selected', ['click']);
12
+ this.initPrefix('toggle', ['click']);
13
+ this.initPrefix('click', ['click']);
14
+ this.initPrefix('hover', ['mouseover', 'mouseout']);
15
+ this.initPrefix('mouseover', ['mouseover']);
16
+ this.initPrefix('mouseout', ['mouseout']);
17
+ this.initPrefix('input', ['input']);
18
+ this.initPrefix('change', ['change']);
19
+ this.initPrefix('selected', ['click']);
20
+ this.initPrefix('onload', ['onload']);
21
+ this.initPrefix('observe', ['observer']);
18
22
  }
19
- },
20
-
21
- initElement: function(element, prefix, events) {
22
- this.__initElementEvent(element || document, prefix, events);
23
- },
24
-
25
- __initElementEvent: function(element, prefix, events) {
26
- const self = this;
27
-
28
- events.forEach((eventName) => {
29
- let debounce;
30
- element.addEventListener(eventName, function(event) {
31
- // ToDo: apply debounce
32
- // clearTimeout(debounce);
33
- // debounce = setTimeout(function() {
34
- const target = event.target.closest(`[${prefix}], [${prefix}-value]`);
35
- if (target) {
36
- let attribute = target.getAttribute('actions') || ""
37
- if (attribute.includes(prefix))
38
- return;
39
- // if (target.closest(`[actions*="${prefix}"]`))
40
- // return;
41
- self.__updateElements(target, prefix);
42
-
43
- let parentElement = target.parentElement;
44
- if (parentElement) {
45
- do {
46
- parentElement = parentElement.closest(`[${prefix}], [${prefix}-value]`)
47
- if (parentElement)
48
- self.__updateElements(parentElement, prefix);
49
- }
50
- while (parentElement)
51
-
52
- }
53
-
54
- }
55
- // }, 500);
56
23
 
57
- });
24
+ let customEventEls = document.querySelectorAll('[event-name]')
25
+ let names = {}
26
+ for (let customEventEl of customEventEls) {
27
+ let name = customEventEl.getAttribute('event-name')
28
+ if(!names[name]) {
29
+ names[name] = name
30
+ this.initPrefix(name);
31
+ }
32
+ }
33
+
34
+ const self = this
35
+ observer.init({
36
+ name: 'CoCreateEventName',
37
+ observe: ['addedNodes'],
38
+ target: `[event-name]`,
39
+ callback: function(mutation) {
40
+ let name = mutation.target.getAttribute('event-name')
41
+ self.initPrefix(name);
42
+ }
58
43
  });
59
44
 
45
+ },
46
+
47
+ initPrefix: function(prefix, events) {
48
+ const self = this;
49
+
60
50
  action.init({
61
51
  name: prefix,
62
52
  endEvent: `${prefix}End`,
@@ -65,12 +55,129 @@ const CoCreateEvents = {
65
55
  }
66
56
  });
67
57
 
58
+ let selector = `[${prefix}], [${prefix}-value], [${prefix}-target], [${prefix}-closest], [${prefix}-parent], [${prefix}-next], [${prefix}-previous]`
59
+
60
+ observer.init({
61
+ name: 'CoCreateEventattributes',
62
+ observe: ['attributes', 'addedNodes'],
63
+ attributeName: [`${prefix}-events`],
64
+ target: selector,
65
+ callback: function(mutation) {
66
+ self.initElements([mutation.target], prefix, events)
67
+ }
68
+ });
69
+
70
+ if (events.includes('observer')) {
71
+ observer.init({
72
+ name: 'observerAttributes',
73
+ observe: ['attributes'],
74
+ attributeName: [`${prefix}-target`, `${prefix}-closest`, `${prefix}-parent`, `${prefix}-next`, `${prefix}-previous`],
75
+ callback: function(mutation) {
76
+ // remove previous observer
77
+ self.initElements([mutation.target], prefix, events)
78
+ }
79
+ });
80
+ }
81
+
82
+ let elements = document.querySelectorAll(selector)
83
+ this.initElements(elements, prefix, events);
68
84
  },
69
-
70
- __updateElements: function(element, prefix) {
85
+
86
+ elements: new Map(),
87
+ initElements: function(elements, prefix, events = []) {
88
+ const self = this
89
+ for (const el of elements) {
90
+ let prefixes = this.elements.get(el)
91
+ if (!prefixes) {
92
+ prefixes = {[prefix]: events}
93
+ this.elements.set(el, prefixes)
94
+ } else {
95
+ events = prefixes[prefix]
96
+ }
97
+
98
+ let customEvents = el.getAttribute(`${prefix}-events`)
99
+ if (customEvents) {
100
+ customEvents = customEvents.split(',')
101
+ for (let i = 0; i < customEvents.length; i++)
102
+ customEvents[i] = customEvents[i].trim()
103
+
104
+ for (let i = 0; i < events.length; i++)
105
+ el.removeEventListener(events[i], eventFunction)
106
+
107
+ events = customEvents
108
+ prefixes[prefix] = events
109
+ }
110
+
111
+ if (events.includes('onload'))
112
+ this.__updateElements(el, prefix);
113
+
114
+ if (events.includes('observer')) {
115
+ let target;
116
+ for (let attribute of el.attributes) {
117
+ if ([`${prefix}-target`, `${prefix}-closest`, `${prefix}-parent`, `${prefix}-next`, `${prefix}-previous`].includes(attribute.name)) {
118
+ target = attribute.value
119
+ break;
120
+ }
121
+ }
122
+
123
+ observer.init({
124
+ observe: ['addedNodes'],
125
+ target,
126
+ callback: function(mutation) {
127
+ self.__updateElements(el, prefix, mutation.target);
128
+ }
129
+ });
130
+ }
131
+
132
+ for (let i = 0; i < events.length; i++) {
133
+ if (events[i] !== 'onload' && events[i] !== 'observer')
134
+ el.addEventListener(events[i], eventFunction);
135
+ }
136
+
137
+ function eventFunction(event) {
138
+ // ToDo: apply debounce
139
+ // let debounce;
140
+ // clearTimeout(debounce);
141
+ // debounce = setTimeout(function() {
142
+ const target = event.currentTarget
143
+ if (target) {
144
+ if (target.id == "testtemplate1" || target.id == "testtemplate2")
145
+ console.log(target.id)
146
+ let attribute = target.getAttribute('actions') || ""
147
+ if (attribute.includes(prefix))
148
+ return;
149
+ // if (target.closest(`[actions*="${prefix}"]`))
150
+ // return;
151
+ self.__updateElements(target, prefix);
152
+
153
+ let selector = `[${prefix}], [${prefix}-value], [${prefix}-target], [${prefix}-closest], [${prefix}-parent], [${prefix}-next], [${prefix}-previous]`
154
+
155
+ let parentElement = target.parentElement;
156
+ if (parentElement) {
157
+ do {
158
+ parentElement = parentElement.closest(selector)
159
+ if (parentElement) {
160
+ self.__updateElements(parentElement, prefix);
161
+ parentElement = parentElement.parentElement
162
+ }
163
+ }
164
+ while (parentElement)
165
+
166
+ }
167
+
168
+ }
169
+ // }, 500);
170
+ }
171
+
172
+
173
+ }
174
+ },
175
+
176
+ __updateElements: function(element, prefix, target) {
71
177
  const self = this;
178
+ // ToDo: support empty value when prefix-attribute defined, add and remove the attribute
72
179
  let targetValue = element.getAttribute(`${prefix}-value`) || element.getAttribute(prefix);
73
- if (!targetValue && element.value)
180
+ if (!targetValue)
74
181
  targetValue = element.getValue()
75
182
  if (!targetValue) return
76
183
 
@@ -80,8 +187,14 @@ const CoCreateEvents = {
80
187
  }
81
188
 
82
189
  let targetAttribute = element.getAttribute(`${prefix}-attribute`) || 'class';
190
+ let targetText = element.getAttribute(`${prefix}-text`);
191
+ let targetHtml = element.getAttribute(`${prefix}-html`);
83
192
  let targetSelector = element.getAttribute(`${prefix}-target`);
84
193
  let targetClosest = element.getAttribute(`${prefix}-closest`);
194
+ let targetParent = element.getAttribute(`${prefix}-parent`);
195
+ let targetNext = element.getAttribute(`${prefix}-next`);
196
+ let targetPrevious = element.getAttribute(`${prefix}-previous`);
197
+
85
198
  let targetKey = element.getAttribute(`${prefix}-key`);
86
199
 
87
200
  let targetGroup = element.getAttribute(`${prefix}-group`);
@@ -97,6 +210,9 @@ const CoCreateEvents = {
97
210
 
98
211
  let groupTarget = el.getAttribute(`${prefix}-target`);
99
212
  let groupClosest = el.getAttribute(`${prefix}-closest`);
213
+ let groupParent = el.getAttribute(`${prefix}-parent`);
214
+ let groupNext = el.getAttribute(`${prefix}-next`);
215
+ let groupPrevious = el.getAttribute(`${prefix}-previous`);
100
216
  let groupAttribute = el.getAttribute(`${prefix}-attribute`) || 'class';
101
217
  let groupKey = el.getAttribute(`${prefix}-key`)
102
218
 
@@ -111,20 +227,46 @@ const CoCreateEvents = {
111
227
  if (element)
112
228
  self.setValue(prefix, element, groupAttribute, groupValues, groupKey, 'deactivate');
113
229
  }
230
+ else if (groupParent)
231
+ el.parentElement.querySelectorAll(groupParent).forEach((el) =>
232
+ self.setValue(prefix, el, groupAttribute, groupValues, groupKey, 'deactivate')
233
+ );
234
+ else if (groupNext)
235
+ el.nextElementSibling.querySelectorAll(groupNext).forEach((el) =>
236
+ self.setValue(prefix, el, groupAttribute, groupValues, groupKey, 'deactivate')
237
+ );
238
+ else if (groupPrevious)
239
+ el.previousElementSibling.querySelectorAll(groupPrevious).forEach((el) =>
240
+ self.setValue(prefix, el, groupAttribute, groupValues, groupKey, 'deactivate')
241
+ );
242
+
114
243
  });
115
244
  }
116
245
 
117
- let targetElements = [element];
118
- if (targetClosest) {
119
- element = element.closest(targetClosest);
120
- }
121
246
  values = values.map(x => x.trim());
122
- if (targetSelector) {
247
+ let targetElements = [element];
248
+ if (target) {
249
+ self.setValue(prefix, target, targetAttribute, values, targetKey);
250
+ } else if (targetSelector) {
123
251
  if (/{{\s*([\w\W]+)\s*}}/g.test(targetSelector)) return;
124
252
  targetElements = queryDocumentSelectorAll(targetSelector);
125
253
  targetElements.forEach((el) => self.setValue(prefix, el, targetAttribute, values, targetKey));
126
- } else
254
+ } else if (targetClosest) {
255
+ element = element.closest(targetClosest);
127
256
  self.setValue(prefix, element, targetAttribute, values, targetKey);
257
+ } else if (targetParent) {
258
+ element.parentElement.querySelectorAll(targetParent).forEach((el) =>
259
+ self.setValue(prefix, el, targetAttribute, values, targetKey)
260
+ );
261
+ } else if (targetNext) {
262
+ el.nextElementSibling.querySelectorAll(targetNext).forEach((el) =>
263
+ self.setValue(prefix, el, targetAttribute, values, targetKey)
264
+ );
265
+ } else if (targetPrevious) {
266
+ el.previousElementSibling.querySelectorAll(targetPrevious).forEach((el) =>
267
+ self.setValue(prefix, el, targetAttribute, values, targetKey)
268
+ );
269
+ }
128
270
 
129
271
  document.dispatchEvent(new CustomEvent(`${prefix}End`, {
130
272
  detail: {}
@@ -164,6 +306,12 @@ const CoCreateEvents = {
164
306
  } else {
165
307
  if (attrName === 'value') {
166
308
  oldValue = element.getValue()
309
+ } else if (attrName === 'text') {
310
+ attrValues = element.getAttribute(attrName).split(' ').map(x => x.trim());
311
+ oldValue = values.filter(x => attrValues.includes(x))[0] || '';
312
+ } else if (attrName === 'html') {
313
+ attrValues = element.getAttribute(attrName).split(' ').map(x => x.trim());
314
+ oldValue = values.filter(x => attrValues.includes(x))[0] || '';
167
315
  } else if (element.getAttribute(attrName)) {
168
316
  attrValues = element.getAttribute(attrName).split(' ').map(x => x.trim());
169
317
  oldValue = values.filter(x => attrValues.includes(x))[0] || '';
@@ -174,14 +322,14 @@ const CoCreateEvents = {
174
322
  newValue = ""
175
323
 
176
324
  if (attrName === 'class') {
177
- if (oldValue != '') {
325
+ if (oldValue) {
178
326
  element.classList.remove(oldValue);
179
327
  if (values.length === 1) {
180
328
  return;
181
329
  }
182
330
  }
183
331
 
184
- if (newValue != '') {
332
+ if (newValue) {
185
333
  element.classList.add(newValue);
186
334
  }
187
335
  } else if (attrName === 'value') {
@@ -206,6 +354,7 @@ const CoCreateEvents = {
206
354
 
207
355
  const eventElements = new Map();
208
356
  const eventKeys = new Map();
357
+ const elementAttributes = new Map();
209
358
 
210
359
  function replaceKey(prefix, element, key, values) {
211
360
  let currentValue = key
@@ -217,45 +366,67 @@ function replaceKey(prefix, element, key, values) {
217
366
  eventKeys.set(key, value)
218
367
  eventElements.set(element, eventKeys)
219
368
 
369
+ let attributes = elementAttributes.get(element)
370
+ if (!attributes) {
371
+ attributes = {}
372
+ elementAttributes.set(element, attributes)
373
+ }
374
+
375
+
220
376
  for (let attribute of element.attributes){
221
377
  let newName = attribute.name;
222
378
  let newValue = attribute.value;
223
379
  let attrName = attribute.name;
224
380
  let attrValue = attribute.value;
225
381
  let setAttr = false;
226
- if (attrValue.includes(currentValue) || attribute.valueKeys && attribute.valueKeys[key]){
227
- if (!attribute.originalValue)
228
- attribute.originalValue = attrValue
229
- if (!attribute.valueKeys)
230
- attribute.valueKeys = {[key]: value}
382
+
383
+ if(attrName === 'clone-data')
384
+ console.log('clone-data')
385
+ if (attrValue.includes(currentValue) || attributes[attrName] && attributes[attrName].valueKeys && attributes[attrName].valueKeys[key]){
386
+ if (!attributes[attrName])
387
+ attributes[attrName] = { originalValue: attrValue }
388
+ else if (!attributes[attrName].originalValue)
389
+ attributes[attrName].originalValue = attrValue
390
+ if (!attributes[attrName].valueKeys)
391
+ attributes[attrName].valueKeys = {[key]: value}
231
392
  else
232
- attribute.valueKeys[key] = value;
393
+ attributes[attrName].valueKeys[key] = value;
233
394
 
234
- newValue = attribute.originalValue
235
- for (let valueKey of Object.keys(attribute.valueKeys)) {
395
+ newValue = attributes[attrName].originalValue
396
+ for (let valueKey of Object.keys(attributes[attrName].valueKeys)) {
236
397
  const valueKeyRegex = new RegExp(valueKey, "g");
237
398
  newValue = newValue.replace(valueKeyRegex, value);
238
399
  }
239
400
  setAttr = true;
240
401
  }
241
- if (attrName.includes(currentValue) || attribute.nameKeys && attribute.nameKeys[key]){
242
- if (!attribute.originalName)
243
- attribute.originalName = attrName
244
- if (!attribute.nameKeys)
245
- attribute.nameKeys = {[key]: value}
246
- else
247
- attribute.nameKeys[key] = value;
402
+ // if (attrName.includes(currentValue) || attributes[attrName] && attributes[attrName].nameKeys && attributes[attrName].nameKeys[key]){
403
+ // if (!attributes[attrName])
404
+ // attributes[attrName] = { originalName: attrName }
405
+ // else if (!attributes[attrName].originalName)
406
+ // attributes[attrName].originalName = attrName
248
407
 
249
- newName = attribute.originalName
250
- for (let nameKey of Object.keys(attribute.nameKeys)) {
251
- const nameKeyRegex = new RegExp(nameKey, "g");
252
- newName = newName.replace(nameKeyRegex, value);
253
- }
408
+ // if (!attributes[attrName].nameKeys)
409
+ // attributes[attrName].nameKeys = {[key]: value}
254
410
 
255
- element.removeAttribute(attrName);
256
- setAttr = true;
411
+ // newName = attributes[attrName].originalName
412
+ // for (let nameKey of Object.keys(attributes[attrName].nameKeys)) {
413
+ // let r
414
+ // if (attrName === nameKey)
415
+ // r = nameKey
416
+ // else
417
+ // r = attributes[attrName].nameKeys[nameKey]
257
418
 
258
- }
419
+ // const nameKeyRegex = new RegExp(r, "g");
420
+ // newName = newName.replace(nameKeyRegex, value);
421
+ // }
422
+
423
+ // attributes[attrName].nameKeys[key] = value;
424
+
425
+
426
+ // element.removeAttribute(attrName);
427
+ // setAttr = true;
428
+
429
+ // }
259
430
  if (setAttr)
260
431
  element.setAttribute(newName, newValue);
261
432
  }
@@ -269,12 +440,14 @@ function replaceKey(prefix, element, key, values) {
269
440
  element.htmlKeys[key] = value;
270
441
 
271
442
  let newHTML = element.originalHTML
272
- for (let elementKey of Object.keys(element.htmlKeys)) {
273
- const htmlKeyRegex = new RegExp(elementKey, "g");
274
- newHTML = newHTML.replace(htmlKeyRegex, value);
275
- }
443
+ if (newHTML) {
444
+ for (let elementKey of Object.keys(element.htmlKeys)) {
445
+ const htmlKeyRegex = new RegExp(elementKey, "g");
446
+ newHTML = newHTML.replace(htmlKeyRegex, value);
447
+ }
276
448
 
277
- element.innerHTML = newHTML;
449
+ element.innerHTML = newHTML;
450
+ }
278
451
  }
279
452
 
280
453
  }