@cocreate/text 1.26.5 → 1.27.1

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,25 @@
1
+ ## [1.27.1](https://github.com/CoCreate-app/CoCreate-text/compare/v1.27.0...v1.27.1) (2024-06-19)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * apply custom setValue function on element ([938088a](https://github.com/CoCreate-app/CoCreate-text/commit/938088a9d2caa3046fbac34d7bebf6858296ab74))
7
+
8
+ # [1.27.0](https://github.com/CoCreate-app/CoCreate-text/compare/v1.26.5...v1.27.0) (2024-06-12)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * bump cocreate dependencies ([5f04198](https://github.com/CoCreate-app/CoCreate-text/commit/5f0419854eca2a8707a0140d31547308fb1ae604))
14
+ * dispatch input event when value is set in contenteditable elements ([1509928](https://github.com/CoCreate-app/CoCreate-text/commit/1509928a5df4d2d70d7d0d06d1124ae924901ae6))
15
+ * formating ([5f751e7](https://github.com/CoCreate-app/CoCreate-text/commit/5f751e718f71b07b754022fea8d4f55e84b11158))
16
+ * svg icon class ([3716b92](https://github.com/CoCreate-app/CoCreate-text/commit/3716b929a9806d585ba16c40c015a3cb469d4ab4))
17
+
18
+
19
+ ### Features
20
+
21
+ * set activeSelection on document ([e85b59a](https://github.com/CoCreate-app/CoCreate-text/commit/e85b59a89af4a2951e63600e88ea3a7927b33581))
22
+
1
23
  ## [1.26.5](https://github.com/CoCreate-app/CoCreate-text/compare/v1.26.4...v1.26.5) (2024-05-08)
2
24
 
3
25
 
@@ -348,9 +348,7 @@
348
348
  href="https://github.com/CoCreate-app/CoCreate-website/tree/master/src/index.html?message=docs%3A%20describe%20your%20change..."
349
349
  target="_blank"
350
350
  class="position:fixed bottom:15px right:15px padding:15px background:dodgerblue color:#fff font-size:1.5rem grow-hover border-radius:50% border-width:0 box-shadow:0px_2px_10px_0px_rgba(0,_0,_0,_0.4)">
351
- <i
352
- class="height:20px fill:#505050"
353
- src="/assets/svg/pencil-alt.svg"></i>
351
+ <i src="/assets/svg/pencil-alt.svg"></i>
354
352
  </button>
355
353
  </main>
356
354
 
package/docs/index.html CHANGED
@@ -72,41 +72,31 @@
72
72
  href="https://github.com/CoCreate-app/CoCreate-text"
73
73
  target="_blank"
74
74
  class="margin-right:15px"
75
- ><i
76
- class="height:20px fill:#505050"
77
- src="/assets/svg/github.svg"></i
75
+ ><i src="/assets/svg/github.svg"></i
78
76
  ></a>
79
77
  <a
80
78
  class="margin-right:15px share"
81
79
  share-network="twitter"
82
80
  title="Share on twitter"
83
- ><i
84
- class="height:20px fill:#505050"
85
- src="/assets/svg/twitter.svg"></i
81
+ ><i src="/assets/svg/twitter.svg"></i
86
82
  ></a>
87
83
  <a
88
84
  class="margin-right:15px share"
89
85
  share-network="facebook"
90
86
  title="Share on Facebook"
91
- ><i
92
- class="height:20px fill:#505050"
93
- src="/assets/svg/facebook.svg"></i
87
+ ><i src="/assets/svg/facebook.svg"></i
94
88
  ></a>
95
89
  <a
96
90
  class="margin-right:15px share"
97
91
  share-network="instagram"
98
92
  title="Share on instagram"
99
- ><i
100
- class="height:20px fill:#505050"
101
- src="/assets/svg/instagram.svg"></i
93
+ ><i src="/assets/svg/instagram.svg"></i
102
94
  ></a>
103
95
  <a
104
96
  class="margin-right:15px share"
105
97
  share-network="share"
106
98
  title="Share on share"
107
- ><i
108
- class="height:20px fill:#505050"
109
- src="/assets/svg/share-alt.svg"></i
99
+ ><i src="/assets/svg/share-alt.svg"></i
110
100
  ></a>
111
101
  </div>
112
102
  </div>
@@ -224,7 +214,7 @@
224
214
  toggle="code-height"
225
215
  toggle-selector="#demo-code"
226
216
  ><i
227
- class="height:18px fill:#505050"
217
+ class="height:18px"
228
218
  src="/assets/svg/eye.svg"></i
229
219
  ></a>
230
220
  <a
@@ -235,18 +225,14 @@
235
225
  hide="#eye-slash"
236
226
  toggle="code-height"
237
227
  toggle-selector="#demo-code"
238
- ><i
239
- class="height:20px fill:#505050"
240
- src="/assets/svg/eye-slash.svg"></i
228
+ ><i src="/assets/svg/eye-slash.svg"></i
241
229
  ></a>
242
230
  <a
243
231
  class="margin-right:10px"
244
232
  id="code"
245
233
  show="#code-slash"
246
234
  hide="#code, #demo-code"
247
- ><i
248
- class="height:20px fill:#505050"
249
- src="/assets/svg/code.svg"></i
235
+ ><i src="/assets/svg/code.svg"></i
250
236
  ></a>
251
237
  <a
252
238
  class="margin-right:10px"
@@ -255,7 +241,7 @@
255
241
  show="#code, #demo-code"
256
242
  hide="#code-slash"
257
243
  ><i
258
- class="display:flex height:18px fill:#505050"
244
+ class="height:18px"
259
245
  src="/assets/svg/code.svg"></i
260
246
  ></a>
261
247
  <a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/text",
3
- "version": "1.26.5",
3
+ "version": "1.27.1",
4
4
  "description": "A simple text component in vanilla javascript. Easily configured using HTML5 attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "text",
@@ -58,12 +58,12 @@
58
58
  "webpack-log": "^3.0.1"
59
59
  },
60
60
  "dependencies": {
61
- "@cocreate/actions": "^1.18.1",
62
- "@cocreate/crdt": "^1.27.3",
63
- "@cocreate/cursors": "^1.23.3",
64
- "@cocreate/observer": "^1.16.0",
65
- "@cocreate/selection": "^1.12.1",
66
- "@cocreate/utils": "^1.33.6",
67
- "@cocreate/uuid": "^1.11.1"
61
+ "@cocreate/actions": "^1.18.2",
62
+ "@cocreate/crdt": "^1.27.4",
63
+ "@cocreate/cursors": "^1.23.4",
64
+ "@cocreate/observer": "^1.16.1",
65
+ "@cocreate/selection": "^1.12.2",
66
+ "@cocreate/utils": "^1.33.7",
67
+ "@cocreate/uuid": "^1.11.2"
68
68
  }
69
69
  }
package/src/index.js CHANGED
@@ -103,6 +103,10 @@ function initElement(element) {
103
103
  element.getValue = async () => {
104
104
  return await crdt.getText({ array, object, key })
105
105
  }
106
+ element.setValue = (value) => {
107
+ crdt.replaceText({ array, object, key, value, crud: isCrud, save: isSave, read: isRead });
108
+
109
+ }
106
110
  }
107
111
  }
108
112
 
@@ -128,8 +132,10 @@ function initDocument(doc) {
128
132
  let element = doc.activeElement;
129
133
  let { isRealtime, isCrdt } = getAttributes(element);
130
134
 
131
- if (isRealtime && isCrdt)
135
+ if (isRealtime && isCrdt) {
136
+ doc.activeSelection = getSelection(element);
132
137
  sendPosition(element);
138
+ }
133
139
  });
134
140
  }
135
141
  }
@@ -294,6 +300,7 @@ export function sendPosition(element) {
294
300
  if (JSON.stringify(currentPosition) === JSON.stringify(previousPosition))
295
301
  return;
296
302
  previousPosition = currentPosition;
303
+ // console.log('activeElement: ', element)
297
304
  element.activeElement = element;
298
305
  window.activeElement = element;
299
306
  cursors.sendPosition({ array, object, key, start, end });
@@ -307,6 +314,9 @@ function updateText({ element, value, start, end, range, undoRedo }) {
307
314
  if (element.tagName == 'HTML' && !element.hasAttribute('array'))
308
315
  element = element.ownerDocument.defaultView.frameElement;
309
316
  }
317
+
318
+ if (!element) return
319
+
310
320
  const { array, object, key, isCrud, isCrdt, isSave } = getAttributes(element);
311
321
  if (isCrdt == "false" || !array || !object || !key) return;
312
322
 
package/src/updateDom.js CHANGED
@@ -1,209 +1,216 @@
1
- import {sendPosition, _dispatchInputEvent} from './index';
2
- import {getSelection, processSelection, getElementPosition} from '@cocreate/selection';
3
- import {domParser} from '@cocreate/utils';
4
-
5
- export function updateDom({domTextEditor, value, start, end, html}) {
6
- if (!domTextEditor.htmlString)
7
- domTextEditor.htmlString = html;
8
- if (start < 0 || start > domTextEditor.htmlString.length)
9
- throw new Error('position is out of range');
10
-
11
- let {element, path, position, type} = getElementPosition(domTextEditor.htmlString, start, end);
12
- parseHtml(domTextEditor, html);
13
-
14
- let domEl, oldEl, curCaret, newEl;
15
- // console.log('element', element)
16
- // console.log('path', path)
17
-
18
- try {
19
- newEl = domTextEditor.newHtml.querySelector(path);
20
- } catch(err){
21
- console.log('error', err)
22
- }
23
-
24
- if (path && !newEl){
25
- let index
26
- do {
27
- index = path.lastIndexOf(' >')
28
- if (index != -1)
29
- path = path.slice(0, index)
30
- newEl = domTextEditor.newHtml.querySelector(path);
31
- } while (!newEl && index != -1)
32
- }
33
-
34
- if (!newEl){
35
- // console.log("no newEL", path)
36
- newEl = domTextEditor.cloneNode(true);
37
- if (html != undefined)
38
- newEl.innerHTML = html;
39
- else
40
- newEl.innerHTML = domTextEditor.htmlString;
41
- domEl = domTextEditor;
42
- type = 'innerHTML';
43
- }
44
- else if (element.tagName == 'HTML') {
45
- // console.log('element = html')
46
- domEl = domTextEditor;
47
- type = 'innerHTML';
48
- }
49
- else if (path) {
50
- // console.log("else path", path)
51
- domEl = domTextEditor.querySelector(path);
52
- // if (!domEl || !oldEl){
53
- // let eid = newEl.getAttribute('eid');
54
- // if (!domEl && eid){
55
- // domEl = domTextEditor.querySelector(`[eid='${eid}']`);
56
- // }
57
- // if (!oldEl && eid){
58
- // oldEl = domTextEditor.oldHtml.querySelector(`[eid='${eid}']`);
59
- // }
60
- // }
61
- }
62
-
63
- if (!domEl) {
64
- // console.log('no domEl')
65
- let index
66
- do {
67
- index = path.lastIndexOf(' >')
68
- if (index != -1)
69
- path = path.slice(0, index)
70
- domEl = domTextEditor.querySelector(path);
71
- } while (!domEl && index != -1)
72
-
73
- if (domEl) {
74
- newEl = domTextEditor.newHtml.querySelector(path);
75
- }
76
-
77
- if (!domEl || !newEl){
78
- newEl = domTextEditor.cloneNode(true);
79
- if (html != undefined)
80
- newEl.innerHTML = html;
81
- else
82
- newEl.innerHTML = domTextEditor.htmlString;
83
- domEl = domTextEditor;
84
- type = 'innerHTML';
85
- }
86
- }
87
-
88
- if (domEl && newEl) {
89
- let activeElement = domEl.ownerDocument.activeElement;
90
- if (activeElement == domEl)
91
- curCaret = getSelection(activeElement);
92
- else if (activeElement && activeElement.tagName == 'BODY')
93
- curCaret = getSelection(domEl);
94
- else
95
- curCaret = getSelection(activeElement);
96
-
97
-
98
- if (!value && type != 'isStartTag' && type != 'textNode'){
99
- type = 'innerHTML';
100
- }
101
-
102
- // console.log('domEl', domEl)
103
- // console.log('newEl', newEl)
104
- if (start != end && type == 'innerHTML') {
105
- domTextEditor.htmlString = html;
106
- if (domEl.tagName != 'HTML'){
107
- if (newEl.parentElement) {
108
- domEl.parentElement.replaceChildren(...newEl.parentElement.childNodes);
109
- // console.log('parent', domEl.parentElement)
110
- } else {
111
- domEl.replaceChildren(...newEl.childNodes);
112
- // console.log('domEl', domEl)
113
- }
114
- }
115
- else {
116
- domEl.replaceChildren(...newEl.childNodes);
117
- // console.log('Html tag', domEl)
118
- }
119
- if (curCaret && curCaret.range) {
120
- curCaret.range.startContainer = domEl;
121
- curCaret.range.endContainer = domEl;
122
- }
123
- }
124
- else if (type == 'isStartTag') {
125
- oldEl = domTextEditor.oldHtml.querySelector(path);
126
- if (!oldEl && domEl.tagName == 'HTML')
127
- oldEl = domTextEditor.oldHtml
128
- assignAttributes(newEl, oldEl, domEl);
129
- // console.log('isStartTag', domEl, newEl)
130
-
131
- }
132
- else if (type == 'insertAdjacent') {
133
- domEl.insertAdjacentHTML(position, value);
134
- // console.log('insertAdjacent', domEl, value)
135
- }
136
- else if (type == 'textNode'){
137
- if (start != end)
138
- domTextEditor.htmlString = html;
139
- domEl.innerHTML = newEl.innerHTML;
140
- // console.log('textnode', domEl.innerHTML, newEl.innerHTML)
141
-
142
- }
143
- else if (type == 'innerHTML') {
144
- domEl.replaceChildren(...newEl.childNodes);
145
- // console.log('innerHtml', domEl, newEl)
146
- }
147
- domTextEditor.htmlString = html;
148
-
149
- if (curCaret && start >= 0 && end >= 0) {
150
- if (curCaret.range && curCaret.range.startContainer == domEl)
151
- if (curCaret.start >= curCaret.range.startOffset) {
152
- let p = processSelection(domEl, value, curCaret.start, curCaret.end, start, end, curCaret.range);
153
- sendPosition(domEl);
154
- _dispatchInputEvent(p.element, p.value, p.start, p.end, p.prev_start, p.prev_end);
155
- }
156
- }
157
-
158
- if (['HTML', 'HEAD', 'BODY', 'SCRIPT'].includes(newEl.tagName)){
159
- let scripts;
160
- if (newEl.tagName == 'SCRIPT'){
161
- scripts = [newEl];
162
- }
163
- else{
164
- scripts = domEl.querySelectorAll('script');
165
- }
166
- for (let script of scripts) {
167
- let newScript = domEl.ownerDocument.createElement('script');
168
- for(let attribute of script.attributes) {
169
- newScript.setAttribute(attribute.name, attribute.value);
170
- }
171
- newScript.innerHTML = script.innerHTML;
172
- script.replaceWith(newScript);
173
- }
174
- }
175
- }
1
+ import { sendPosition, _dispatchInputEvent } from './index';
2
+ import { getSelection, processSelection, getElementPosition } from '@cocreate/selection';
3
+ import { domParser } from '@cocreate/utils';
4
+
5
+ export function updateDom({ domTextEditor, value, start, end, html }) {
6
+ if (!domTextEditor.htmlString)
7
+ domTextEditor.htmlString = html;
8
+ if (start < 0 || start > domTextEditor.htmlString.length)
9
+ throw new Error('position is out of range');
10
+
11
+ let { element, path, position, type } = getElementPosition(domTextEditor.htmlString, start, end);
12
+ parseHtml(domTextEditor, html);
13
+
14
+ let domEl, oldEl, curCaret, newEl;
15
+ // console.log('element', element)
16
+ // console.log('path', path)
17
+
18
+ try {
19
+ newEl = domTextEditor.newHtml.querySelector(path);
20
+ } catch (err) {
21
+ console.log('error', err)
22
+ }
23
+
24
+ if (path && !newEl) {
25
+ let index
26
+ do {
27
+ index = path.lastIndexOf(' >')
28
+ if (index != -1)
29
+ path = path.slice(0, index)
30
+ newEl = domTextEditor.newHtml.querySelector(path);
31
+ } while (!newEl && index != -1)
32
+ }
33
+
34
+ if (!newEl) {
35
+ // console.log("no newEL", path)
36
+ newEl = domTextEditor.cloneNode(true);
37
+ if (html != undefined)
38
+ newEl.innerHTML = html;
39
+ else
40
+ newEl.innerHTML = domTextEditor.htmlString;
41
+ domEl = domTextEditor;
42
+ type = 'innerHTML';
43
+ }
44
+ else if (element.tagName == 'HTML') {
45
+ // console.log('element = html')
46
+ domEl = domTextEditor;
47
+ type = 'innerHTML';
48
+ }
49
+ else if (path) {
50
+ // console.log("else path", path)
51
+ domEl = domTextEditor.querySelector(path);
52
+ // if (!domEl || !oldEl){
53
+ // let eid = newEl.getAttribute('eid');
54
+ // if (!domEl && eid){
55
+ // domEl = domTextEditor.querySelector(`[eid='${eid}']`);
56
+ // }
57
+ // if (!oldEl && eid){
58
+ // oldEl = domTextEditor.oldHtml.querySelector(`[eid='${eid}']`);
59
+ // }
60
+ // }
61
+ }
62
+
63
+ if (!domEl) {
64
+ // console.log('no domEl')
65
+ let index
66
+ do {
67
+ index = path.lastIndexOf(' >')
68
+ if (index != -1)
69
+ path = path.slice(0, index)
70
+ domEl = domTextEditor.querySelector(path);
71
+ } while (!domEl && index != -1)
72
+
73
+ if (domEl) {
74
+ newEl = domTextEditor.newHtml.querySelector(path);
75
+ }
76
+
77
+ if (!domEl || !newEl) {
78
+ newEl = domTextEditor.cloneNode(true);
79
+ if (html != undefined)
80
+ newEl.innerHTML = html;
81
+ else
82
+ newEl.innerHTML = domTextEditor.htmlString;
83
+ domEl = domTextEditor;
84
+ type = 'innerHTML';
85
+ }
86
+ }
87
+
88
+ if (domEl && newEl) {
89
+ let activeElement = domEl.ownerDocument.activeElement;
90
+ if (activeElement == domEl)
91
+ curCaret = getSelection(activeElement);
92
+ else if (activeElement && activeElement.tagName == 'BODY')
93
+ curCaret = getSelection(domEl);
94
+ else
95
+ curCaret = getSelection(activeElement);
96
+
97
+
98
+ if (!value && type != 'isStartTag' && type != 'textNode') {
99
+ type = 'innerHTML';
100
+ }
101
+
102
+ // console.log('domEl', domEl)
103
+ // console.log('newEl', newEl)
104
+ if (start != end && type == 'innerHTML') {
105
+ domTextEditor.htmlString = html;
106
+ if (domEl.tagName != 'HTML') {
107
+ if (newEl.parentElement) {
108
+ domEl.parentElement.replaceChildren(...newEl.parentElement.childNodes);
109
+ // console.log('parent', domEl.parentElement)
110
+ } else {
111
+ domEl.replaceChildren(...newEl.childNodes);
112
+ // console.log('domEl', domEl)
113
+ }
114
+ }
115
+ else {
116
+ domEl.replaceChildren(...newEl.childNodes);
117
+ // console.log('Html tag', domEl)
118
+ }
119
+ if (curCaret && curCaret.range) {
120
+ curCaret.range.startContainer = domEl;
121
+ curCaret.range.endContainer = domEl;
122
+ }
123
+ }
124
+ else if (type == 'isStartTag') {
125
+ oldEl = domTextEditor.oldHtml.querySelector(path);
126
+ if (!oldEl && domEl.tagName == 'HTML')
127
+ oldEl = domTextEditor.oldHtml
128
+ assignAttributes(newEl, oldEl, domEl);
129
+ // console.log('isStartTag', domEl, newEl)
130
+
131
+ }
132
+ else if (type == 'insertAdjacent') {
133
+ domEl.insertAdjacentHTML(position, value);
134
+ // console.log('insertAdjacent', domEl, value)
135
+ }
136
+ else if (type == 'textNode') {
137
+ if (start != end)
138
+ domTextEditor.htmlString = html;
139
+ domEl.innerHTML = newEl.innerHTML;
140
+ // console.log('textnode', domEl.innerHTML, newEl.innerHTML)
141
+
142
+ }
143
+ else if (type == 'innerHTML') {
144
+ domEl.replaceChildren(...newEl.childNodes);
145
+ // console.log('innerHtml', domEl, newEl)
146
+ }
147
+ domTextEditor.htmlString = html;
148
+
149
+ if (curCaret && start >= 0 && end >= 0) {
150
+ if (curCaret.range && curCaret.range.startContainer == domEl) {
151
+ if (curCaret.start >= curCaret.range.startOffset) {
152
+ let p = processSelection(domEl, value, curCaret.start, curCaret.end, start, end, curCaret.range);
153
+ sendPosition(domEl);
154
+ _dispatchInputEvent(p.element, p.value, p.start, p.end, p.prev_start, p.prev_end);
155
+ }
156
+ } else {
157
+ let p = processSelection(domEl, value, curCaret.start, curCaret.end, start, end, curCaret.range);
158
+ _dispatchInputEvent(p.element, p.value, p.start, p.end, p.prev_start, p.prev_end);
159
+
160
+ }
161
+ } else {
162
+ _dispatchInputEvent(domTextEditor);
163
+ }
164
+
165
+ if (['HTML', 'HEAD', 'BODY', 'SCRIPT'].includes(newEl.tagName)) {
166
+ let scripts;
167
+ if (newEl.tagName == 'SCRIPT') {
168
+ scripts = [newEl];
169
+ }
170
+ else {
171
+ scripts = domEl.querySelectorAll('script');
172
+ }
173
+ for (let script of scripts) {
174
+ let newScript = domEl.ownerDocument.createElement('script');
175
+ for (let attribute of script.attributes) {
176
+ newScript.setAttribute(attribute.name, attribute.value);
177
+ }
178
+ newScript.innerHTML = script.innerHTML;
179
+ script.replaceWith(newScript);
180
+ }
181
+ }
182
+ }
176
183
  }
177
184
 
178
185
  function parseHtml(domTextEditor, html) {
179
- var dom = domParser(html);
180
- if (domTextEditor.newHtml) {
181
- domTextEditor.oldHtml = domTextEditor.newHtml;
182
- } else {
183
- domTextEditor.oldHtml = dom;
184
- }
185
- domTextEditor.newHtml = dom;
186
+ var dom = domParser(html);
187
+ if (domTextEditor.newHtml) {
188
+ domTextEditor.oldHtml = domTextEditor.newHtml;
189
+ } else {
190
+ domTextEditor.oldHtml = dom;
191
+ }
192
+ domTextEditor.newHtml = dom;
186
193
  }
187
194
 
188
195
  function assignAttributes(newEl, oldEl, domEl) {
189
- if (!oldEl) return;
190
- for(let newElAtt of newEl.attributes) {
191
- if (!oldEl.attributes[newElAtt.name] || oldEl.attributes[newElAtt.name].value !== newElAtt.value)
192
- try {
193
- domEl.setAttribute(newElAtt.name, newElAtt.value);
194
- }
195
- catch(err) {
196
- throw new Error("assignAttributes: " + err.message, err.name);
197
- }
198
- }
199
-
200
- if (newEl.attributes.length !== oldEl.attributes.length) {
201
- for(let i = 0, len = oldEl.attributes.length; i < len; i++) {
202
- let oldElAtt = oldEl.attributes[i];
203
- if (!newEl.attributes[oldElAtt.name]) {
204
- domEl.removeAttribute(oldElAtt.name);
205
- i--, len--;
206
- }
207
- }
208
- }
196
+ if (!oldEl) return;
197
+ for (let newElAtt of newEl.attributes) {
198
+ if (!oldEl.attributes[newElAtt.name] || oldEl.attributes[newElAtt.name].value !== newElAtt.value)
199
+ try {
200
+ domEl.setAttribute(newElAtt.name, newElAtt.value);
201
+ }
202
+ catch (err) {
203
+ throw new Error("assignAttributes: " + err.message, err.name);
204
+ }
205
+ }
206
+
207
+ if (newEl.attributes.length !== oldEl.attributes.length) {
208
+ for (let i = 0, len = oldEl.attributes.length; i < len; i++) {
209
+ let oldElAtt = oldEl.attributes[i];
210
+ if (!newEl.attributes[oldElAtt.name]) {
211
+ domEl.removeAttribute(oldElAtt.name);
212
+ i--, len--;
213
+ }
214
+ }
215
+ }
209
216
  }