@cocreate/cursors 1.16.29 → 1.18.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 +22 -0
- package/CoCreate.config.js +2 -2
- package/LICENSE +177 -178
- package/demo/index.html +7 -7
- package/docs/index.html +22 -22
- package/package.json +10 -10
- package/src/index.js +76 -54
- package/webpack.config.js +79 -73
package/demo/index.html
CHANGED
|
@@ -24,21 +24,21 @@
|
|
|
24
24
|
</head>
|
|
25
25
|
|
|
26
26
|
<body>
|
|
27
|
-
<form
|
|
27
|
+
<form array="module_activities" class="margin:20px">
|
|
28
28
|
<input
|
|
29
29
|
type="text"
|
|
30
30
|
cursors="true"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
array="module_activities"
|
|
32
|
+
object="5edda7608d5c7a7d656edecd"
|
|
33
|
+
key="name"
|
|
34
34
|
placeholder="Text"
|
|
35
35
|
class="floating-label" />
|
|
36
36
|
|
|
37
37
|
<textarea
|
|
38
38
|
cursors="true"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
39
|
+
array="module_activities"
|
|
40
|
+
object="5edda7608d5c7a7d656edecd"
|
|
41
|
+
key="text_area"
|
|
42
42
|
placeholder="Text Area"
|
|
43
43
|
class="floating-label">
|
|
44
44
|
</textarea>
|
package/docs/index.html
CHANGED
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
sizes="32x32"
|
|
12
12
|
href="https://cocreate.app/images/favicon.ico" />
|
|
13
13
|
<meta
|
|
14
|
-
|
|
14
|
+
key="description"
|
|
15
15
|
content="A simple HTML5 and pure javascript component. Easy configuration using HTML5 attributes or Javscript api and highly styleable." />
|
|
16
16
|
<meta
|
|
17
|
-
|
|
17
|
+
key="keywords"
|
|
18
18
|
content="helper classes, utility classes, css framework, css library, inline style classes" />
|
|
19
19
|
<meta name="robots" content="index,follow" />
|
|
20
20
|
<meta
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
<link
|
|
24
24
|
rel="stylesheet"
|
|
25
25
|
href="/docs/index.css"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
array="files"
|
|
27
|
+
object="60888216117c640e7596303f"
|
|
28
|
+
key="src"
|
|
29
29
|
type="text/css"
|
|
30
30
|
save="true" />
|
|
31
31
|
<link rel="manifest" href="/manifest.webmanifest" />
|
|
@@ -38,20 +38,20 @@
|
|
|
38
38
|
scroll="sticky-nav,hide-nav"
|
|
39
39
|
scroll-up="10"
|
|
40
40
|
scroll-down="10"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
array="files"
|
|
42
|
+
object="60395ef42b3ac232657040fd"
|
|
43
|
+
key="src"></nav>
|
|
44
44
|
<sidenav
|
|
45
45
|
id="menuL"
|
|
46
46
|
class="position:fixed top:0px left:0px overflow:hidden background:whitesmoke height:100vh width:0px width:300px@xl"
|
|
47
47
|
resizable
|
|
48
|
-
resize-
|
|
48
|
+
resize-selector="[content_id='content']"
|
|
49
49
|
resize-property="margin-left"
|
|
50
50
|
resize-value="width">
|
|
51
51
|
<menu
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
array="files"
|
|
53
|
+
object="603717b07de7fb350ae9fec8"
|
|
54
|
+
key="src"></menu>
|
|
55
55
|
<div resize="right"></div>
|
|
56
56
|
</sidenav>
|
|
57
57
|
<main
|
|
@@ -137,12 +137,12 @@
|
|
|
137
137
|
<div class="flex-grow:1 min-width:300px width:100%">
|
|
138
138
|
<pre>
|
|
139
139
|
<code>
|
|
140
|
-
<form
|
|
140
|
+
<form array="module_activities" class="margin:20px">
|
|
141
141
|
<textarea
|
|
142
142
|
cursors="true"
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
array="module_activities"
|
|
144
|
+
object="5edda7608d5c7a7d656edecd"
|
|
145
|
+
key="text_area"
|
|
146
146
|
placeholder="Text Area"
|
|
147
147
|
class="floating-label">
|
|
148
148
|
</textarea>
|
|
@@ -196,9 +196,9 @@
|
|
|
196
196
|
<textarea
|
|
197
197
|
type="code"
|
|
198
198
|
lang="html"
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
array="demos"
|
|
200
|
+
object=""
|
|
201
|
+
key="demo"
|
|
202
202
|
save="false"
|
|
203
203
|
id="demo"
|
|
204
204
|
class="height:100% width:100% outline:none border:none resize:none padding:5px"></textarea>
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
show="#eye-slash"
|
|
222
222
|
hide="#eye, #demo-preview"
|
|
223
223
|
toggle="code-height"
|
|
224
|
-
toggle-
|
|
224
|
+
toggle-selector="#demo-code"
|
|
225
225
|
><i
|
|
226
226
|
class="height:18px fill:#505050"
|
|
227
227
|
src="/assets/svg/eye.svg"></i
|
|
@@ -233,7 +233,7 @@
|
|
|
233
233
|
show="#eye, #demo-preview"
|
|
234
234
|
hide="#eye-slash"
|
|
235
235
|
toggle="code-height"
|
|
236
|
-
toggle-
|
|
236
|
+
toggle-selector="#demo-code"
|
|
237
237
|
><i
|
|
238
238
|
class="height:20px fill:#505050"
|
|
239
239
|
src="/assets/svg/eye-slash.svg"></i
|
|
@@ -260,7 +260,7 @@
|
|
|
260
260
|
<a
|
|
261
261
|
class="margin-right:5px"
|
|
262
262
|
fullscreen
|
|
263
|
-
fullscreen-
|
|
263
|
+
fullscreen-selector="#playground"></a>
|
|
264
264
|
</div>
|
|
265
265
|
</div>
|
|
266
266
|
<!-- End SandBox -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/cursors",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "Collaborative user cursor position for inputs, textarea's and contenteditable elements.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cursors",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
28
|
"start": "npx webpack --config webpack.config.js",
|
|
29
|
-
"build": "
|
|
29
|
+
"build": "npx webpack --mode=production --config webpack.config.js",
|
|
30
30
|
"dev": "npx webpack --config webpack.config.js --watch",
|
|
31
31
|
"postinstall": "node -e \"const { execSync } = require('child_process'); try { execSync('coc --version', { stdio: 'ignore' }); } catch (error) { try { execSync('npm install -g @cocreate/cli', { stdio: 'inherit' }); console.log('Installed \"@cocreate/cli\" globally.'); } catch (error) { console.error('Failed to install \"@cocreate/cli\" globally:', error); } }\""
|
|
32
32
|
},
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"url": "git+https://github.com/CoCreate-app/CoCreate-cursors.git"
|
|
36
36
|
},
|
|
37
37
|
"author": "CoCreate LLC",
|
|
38
|
-
"license": "
|
|
38
|
+
"license": "AGPL-3.0",
|
|
39
39
|
"bugs": {
|
|
40
40
|
"url": "https://github.com/CoCreate-app/CoCreate-cursors/issues"
|
|
41
41
|
},
|
|
@@ -59,12 +59,12 @@
|
|
|
59
59
|
"webpack-log": "^3.0.1"
|
|
60
60
|
},
|
|
61
61
|
"dependencies": {
|
|
62
|
-
"@cocreate/
|
|
63
|
-
"@cocreate/
|
|
64
|
-
"@cocreate/
|
|
65
|
-
"@cocreate/
|
|
66
|
-
"@cocreate/
|
|
67
|
-
"@cocreate/
|
|
68
|
-
"@cocreate/uuid": "^1.
|
|
62
|
+
"@cocreate/local-storage": "^1.8.0",
|
|
63
|
+
"@cocreate/message-client": "^1.4.0",
|
|
64
|
+
"@cocreate/observer": "^1.9.0",
|
|
65
|
+
"@cocreate/random-color": "^1.5.0",
|
|
66
|
+
"@cocreate/selection": "^1.7.0",
|
|
67
|
+
"@cocreate/utils": "^1.22.0",
|
|
68
|
+
"@cocreate/uuid": "^1.5.0"
|
|
69
69
|
}
|
|
70
70
|
}
|
package/src/index.js
CHANGED
|
@@ -1,11 +1,33 @@
|
|
|
1
|
+
/********************************************************************************
|
|
2
|
+
* Copyright (C) 2023 CoCreate and Contributors.
|
|
3
|
+
*
|
|
4
|
+
* This program is free software: you can redistribute it and/or modify
|
|
5
|
+
* it under the terms of the GNU Affero General Public License as published
|
|
6
|
+
* by the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
* (at your option) any later version.
|
|
8
|
+
*
|
|
9
|
+
* This program is distributed in the hope that it will be useful,
|
|
10
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
* GNU Affero General Public License for more details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
15
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
********************************************************************************/
|
|
17
|
+
|
|
18
|
+
// Commercial Licensing Information:
|
|
19
|
+
// For commercial use of this software without the copyleft provisions of the AGPLv3,
|
|
20
|
+
// you must obtain a commercial license from CoCreate LLC.
|
|
21
|
+
// For details, visit <https://cocreate.app/licenses/> or contact us at sales@cocreate.app.
|
|
22
|
+
|
|
1
23
|
/*globals ResizeObserver*/
|
|
2
24
|
import observer from '@cocreate/observer';
|
|
3
|
-
import
|
|
25
|
+
import { getAttributeNames } from '@cocreate/utils';
|
|
4
26
|
import message from '@cocreate/message-client';
|
|
5
27
|
import uuid from '@cocreate/uuid';
|
|
6
28
|
import localStorage from '@cocreate/local-storage';
|
|
7
29
|
import { getElementPosition } from '@cocreate/selection';
|
|
8
|
-
import {randomColor} from '@cocreate/random-color';
|
|
30
|
+
import { randomColor } from '@cocreate/random-color';
|
|
9
31
|
import './index.css';
|
|
10
32
|
|
|
11
33
|
const clientId = message.socket.clientId || uuid.generate(12);
|
|
@@ -13,7 +35,7 @@ const cursorBackground = randomColor();
|
|
|
13
35
|
|
|
14
36
|
let environment_prod = true;
|
|
15
37
|
|
|
16
|
-
let selector = "[
|
|
38
|
+
let selector = "[array][object][key]:not([contentEditable='false'])";
|
|
17
39
|
|
|
18
40
|
function init() {
|
|
19
41
|
let elements = document.querySelectorAll(selector);
|
|
@@ -38,15 +60,15 @@ function initDocument(doc) {
|
|
|
38
60
|
let documents;
|
|
39
61
|
try {
|
|
40
62
|
documents = window.top.cursorDocuments;
|
|
41
|
-
} catch(e) {
|
|
63
|
+
} catch (e) {
|
|
42
64
|
console.log('cross-origin failed')
|
|
43
65
|
}
|
|
44
66
|
|
|
45
|
-
if (!documents){
|
|
67
|
+
if (!documents) {
|
|
46
68
|
documents = new Map();
|
|
47
69
|
try {
|
|
48
|
-
window.top.cursorDocuments = documents;
|
|
49
|
-
} catch(e) {
|
|
70
|
+
window.top.cursorDocuments = documents;
|
|
71
|
+
} catch (e) {
|
|
50
72
|
console.log('cross-origin failed')
|
|
51
73
|
}
|
|
52
74
|
}
|
|
@@ -58,14 +80,14 @@ function initDocument(doc) {
|
|
|
58
80
|
|
|
59
81
|
function drawCursors(selection) {
|
|
60
82
|
const socket_id = selection['clientId'];
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
const
|
|
83
|
+
const array = selection['array'];
|
|
84
|
+
const object = selection['object'];
|
|
85
|
+
const key = selection['key'];
|
|
64
86
|
let start = selection['start'];
|
|
65
87
|
let end = selection['end'];
|
|
66
88
|
let elements = selection.element;
|
|
67
89
|
if (!elements) {
|
|
68
|
-
let selector = '[
|
|
90
|
+
let selector = '[array="' + array + '"][object="' + object + '"][key="' + key + '"]';
|
|
69
91
|
selector += ':not(.codemirror, .monaco, [actions])';
|
|
70
92
|
elements = document.querySelectorAll(selector);
|
|
71
93
|
}
|
|
@@ -80,10 +102,10 @@ function drawCursors(selection) {
|
|
|
80
102
|
if (element.tagName != 'INPUT' && element.tagName != 'TEXTAREA')
|
|
81
103
|
if (contenteditable == 'false' || contenteditable == null)
|
|
82
104
|
if (cursors != 'true') continue;
|
|
83
|
-
|
|
105
|
+
|
|
84
106
|
if (element.hasAttribute('contenteditable')) {
|
|
85
107
|
let domTextEditor = element;
|
|
86
|
-
if (element.tagName == 'IFRAME'){
|
|
108
|
+
if (element.tagName == 'IFRAME') {
|
|
87
109
|
// let frameClientId = element.contentDocument.defaultView.CoCreateSockets.clientId;
|
|
88
110
|
// if (frameClientId == selection.clientId) continue;
|
|
89
111
|
domTextEditor = element.contentDocument.documentElement;
|
|
@@ -107,10 +129,10 @@ function drawCursors(selection) {
|
|
|
107
129
|
let document = element.ownerDocument;
|
|
108
130
|
let mirrorDiv;
|
|
109
131
|
let id_mirror = element.getAttribute('mirror_id');
|
|
110
|
-
if (!id_mirror){
|
|
132
|
+
if (!id_mirror) {
|
|
111
133
|
id_mirror = uuid.generate(8);
|
|
112
134
|
element.setAttribute('mirror_id', id_mirror);
|
|
113
|
-
|
|
135
|
+
|
|
114
136
|
mirrorDiv = document.createElement('cursor-container');
|
|
115
137
|
mirrorDiv.id = id_mirror;
|
|
116
138
|
mirrorDiv.className = (environment_prod) ? 'mirror mirror_scroll mirror_color' : 'mirror mirror_scroll';
|
|
@@ -131,16 +153,16 @@ function drawCursors(selection) {
|
|
|
131
153
|
}
|
|
132
154
|
else
|
|
133
155
|
mirrorDiv = document.getElementById(id_mirror);
|
|
134
|
-
|
|
156
|
+
|
|
135
157
|
let computed = getComputedStyle(element);
|
|
136
158
|
let rect = element.getBoundingClientRect();
|
|
137
|
-
|
|
159
|
+
|
|
138
160
|
let borderWidth = parseInt(computed['border-width']) * 2;
|
|
139
161
|
let scrollBarWidth = 0;
|
|
140
162
|
if (element.clientWidth != 0)
|
|
141
163
|
scrollBarWidth = element.offsetWidth - element.clientWidth - borderWidth;
|
|
142
|
-
|
|
143
|
-
let style = mirrorDiv.style;
|
|
164
|
+
|
|
165
|
+
let style = mirrorDiv.style;
|
|
144
166
|
style.position = 'absolute';
|
|
145
167
|
style.width = rect.width + 'px';
|
|
146
168
|
style.height = rect.height + 'px';
|
|
@@ -154,7 +176,7 @@ function drawCursors(selection) {
|
|
|
154
176
|
style.outlineColor = 'transparent';
|
|
155
177
|
style.boxSizing = computed['boxSizing'];
|
|
156
178
|
style.lineHeight = computed['lineHeight'];
|
|
157
|
-
|
|
179
|
+
|
|
158
180
|
if (element.parentElement.style['display'] == 'inline') {
|
|
159
181
|
style.top = element.clientTop + 'px';
|
|
160
182
|
style.left = element.clientLeft + 'px';
|
|
@@ -162,39 +184,39 @@ function drawCursors(selection) {
|
|
|
162
184
|
style.top = element.offsetTop + 'px';
|
|
163
185
|
style.left = element.offsetLeft + 'px';
|
|
164
186
|
}
|
|
165
|
-
|
|
187
|
+
|
|
166
188
|
if (element.nodeName !== 'INPUT') {
|
|
167
189
|
style.wordWrap = 'break-word';
|
|
168
190
|
style.whiteSpace = 'pre-wrap';
|
|
169
191
|
} else {
|
|
170
192
|
style.whiteSpace = 'pre';
|
|
171
193
|
}
|
|
172
|
-
|
|
194
|
+
|
|
173
195
|
let properties = ['fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'fontFamily', 'letterSpacing', 'lineHeight', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'textRendering', 'textTransform', 'textIndent', 'overflowWrap', 'tabSize', 'webkitWritingMode', 'wordSpacing'];
|
|
174
|
-
|
|
175
|
-
properties.forEach(function(prop) {
|
|
196
|
+
|
|
197
|
+
properties.forEach(function (prop) {
|
|
176
198
|
if (['left', 'top'].indexOf(prop.toLowerCase()) === -1)
|
|
177
199
|
style[prop] = computed[prop];
|
|
178
200
|
});
|
|
179
|
-
|
|
201
|
+
|
|
180
202
|
let spanText = mirrorDiv.querySelector('span-text');
|
|
181
203
|
if (!spanText)
|
|
182
204
|
spanText = document.createElement('span-text');
|
|
183
|
-
|
|
205
|
+
spanText.style['display'] = 'block';
|
|
184
206
|
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
185
|
-
|
|
207
|
+
|
|
186
208
|
spanText.textContent = value_element;
|
|
187
209
|
if (element.nodeName === 'INPUT')
|
|
188
210
|
spanText.textContent = mirrorDiv.textContent.replace(/\s/g, " ");
|
|
189
211
|
mirrorDiv.appendChild(spanText);
|
|
190
212
|
let cursor, cursorFlag;
|
|
191
|
-
let details = {
|
|
213
|
+
let details = { array, object, key };
|
|
192
214
|
if (socket_id) {
|
|
193
215
|
let userSelection = mirrorDiv.querySelector(`selection[socket_id="${socket_id}"]`);
|
|
194
216
|
if (userSelection && userSelection.details != details)
|
|
195
217
|
userSelection.remove();
|
|
196
218
|
let selection_user = mirrorDiv.querySelector(`selection[socket_id="${socket_id}"]`);
|
|
197
|
-
if (!selection_user){
|
|
219
|
+
if (!selection_user) {
|
|
198
220
|
selection_user = document.createElement('selection');
|
|
199
221
|
selection_user.setAttribute('socket_id', socket_id);
|
|
200
222
|
selection_user.style["position"] = "absolute";
|
|
@@ -202,18 +224,18 @@ function drawCursors(selection) {
|
|
|
202
224
|
selection_user.style["top"] = style_mirror.paddingTop;
|
|
203
225
|
selection_user.style["left"] = style_mirror.paddingLeft;
|
|
204
226
|
selection_user.style["width"] = mirrorDiv.clientWidth - parseInt(computed['padding-left']) - parseInt(computed['padding-right']) - scrollBarWidth + 'px';
|
|
205
|
-
selection_user.details = {
|
|
206
|
-
|
|
227
|
+
selection_user.details = { array, object, key };
|
|
228
|
+
|
|
207
229
|
mirrorDiv.appendChild(selection_user);
|
|
208
230
|
}
|
|
209
|
-
|
|
231
|
+
|
|
210
232
|
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
211
233
|
selection_user.textContent = value_element.substring(0, start);
|
|
212
|
-
|
|
234
|
+
|
|
213
235
|
let value_end = value_element.substring(end) || '';
|
|
214
236
|
let span_end = document.createElement('span-end');
|
|
215
237
|
span_end.textContent = value_end;
|
|
216
|
-
|
|
238
|
+
|
|
217
239
|
cursor = document.createElement('cursor');
|
|
218
240
|
cursor.setAttribute('socket_id', socket_id);
|
|
219
241
|
cursor.dataset.start = start;
|
|
@@ -222,23 +244,23 @@ function drawCursors(selection) {
|
|
|
222
244
|
cursor.setAttribute('user-background', selection.background);
|
|
223
245
|
cursor.setAttribute('user-color', selection.color);
|
|
224
246
|
cursor.style["background"] = selection.background;
|
|
225
|
-
cursor.details = {
|
|
247
|
+
cursor.details = { array, object, key };
|
|
226
248
|
cursor.textContent = "1";
|
|
227
249
|
span_end.prepend(cursor);
|
|
228
|
-
|
|
250
|
+
|
|
229
251
|
let selectedText = document.createElement('selected-text');
|
|
230
252
|
selectedText.style["backgroundColor"] = selection.background;
|
|
231
253
|
selectedText.textContent = value_element.substring(start, end) || '';
|
|
232
254
|
span_end.prepend(selectedText);
|
|
233
|
-
|
|
255
|
+
|
|
234
256
|
cursorFlag = document.createElement('cursor-flag');
|
|
235
|
-
cursorFlag.setAttribute('
|
|
236
|
-
cursorFlag.setAttribute('
|
|
237
|
-
cursorFlag.setAttribute('
|
|
257
|
+
cursorFlag.setAttribute('array', 'users');
|
|
258
|
+
cursorFlag.setAttribute('object', selection.user_id);
|
|
259
|
+
cursorFlag.setAttribute('key', 'name');
|
|
238
260
|
cursorFlag.style["background"] = selection.background;
|
|
239
261
|
cursorFlag.innerHTML = selection.userName;
|
|
240
262
|
cursor.appendChild(cursorFlag);
|
|
241
|
-
|
|
263
|
+
|
|
242
264
|
selection_user.appendChild(span_end);
|
|
243
265
|
}
|
|
244
266
|
scrollMirror(element);
|
|
@@ -260,7 +282,7 @@ function updateCursors(element) {
|
|
|
260
282
|
element = mirrorDiv.element;
|
|
261
283
|
let cursors = mirrorDiv.querySelectorAll('cursor');
|
|
262
284
|
|
|
263
|
-
cursors.forEach(function(child_cursor, index, array) {
|
|
285
|
+
cursors.forEach(function (child_cursor, index, array) {
|
|
264
286
|
let clientId = child_cursor.getAttribute('socket_id');
|
|
265
287
|
let userName = child_cursor.getAttribute('user-name');
|
|
266
288
|
let background = child_cursor.getAttribute('user-background');
|
|
@@ -283,22 +305,22 @@ function updateCursors(element) {
|
|
|
283
305
|
|
|
284
306
|
function removeCursor(clientId) {
|
|
285
307
|
let elements = document.querySelectorAll(`cursor[socket_id="${clientId}"]`);
|
|
286
|
-
elements.forEach(function(element, index, array) {
|
|
308
|
+
elements.forEach(function (element, index, array) {
|
|
287
309
|
element.parentNode.removeChild(element);
|
|
288
310
|
});
|
|
289
311
|
|
|
290
312
|
let sel_elements = document.querySelectorAll(`selection[socket_id="${clientId}"]`);
|
|
291
|
-
sel_elements.forEach(function(sel_element, index, array) {
|
|
313
|
+
sel_elements.forEach(function (sel_element, index, array) {
|
|
292
314
|
sel_element.parentNode.removeChild(sel_element);
|
|
293
315
|
});
|
|
294
316
|
}
|
|
295
317
|
|
|
296
318
|
function _initEvents(element) {
|
|
297
|
-
element.addEventListener('keydown', function(event) {
|
|
319
|
+
element.addEventListener('keydown', function (event) {
|
|
298
320
|
scrollMirror(element);
|
|
299
321
|
});
|
|
300
322
|
|
|
301
|
-
element.addEventListener('scroll', function() {
|
|
323
|
+
element.addEventListener('scroll', function () {
|
|
302
324
|
scrollMirror(element);
|
|
303
325
|
});
|
|
304
326
|
|
|
@@ -324,9 +346,9 @@ function sendPosition(info) {
|
|
|
324
346
|
room: "",
|
|
325
347
|
message: "cursor",
|
|
326
348
|
data: {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
349
|
+
array: info.array,
|
|
350
|
+
object: info.object,
|
|
351
|
+
key: info.key,
|
|
330
352
|
start: info.start,
|
|
331
353
|
end: info.end,
|
|
332
354
|
clientId: clientId,
|
|
@@ -344,7 +366,7 @@ function sendPosition(info) {
|
|
|
344
366
|
}
|
|
345
367
|
|
|
346
368
|
|
|
347
|
-
message.listen('cursor', function(response) {
|
|
369
|
+
message.listen('cursor', function (response) {
|
|
348
370
|
// if (selection.clientId == clientId) return;
|
|
349
371
|
let selection = response.data
|
|
350
372
|
if (selection.start != null && selection.end != null)
|
|
@@ -356,8 +378,8 @@ message.listen('cursor', function(response) {
|
|
|
356
378
|
observer.init({
|
|
357
379
|
name: 'CoCreateCursor',
|
|
358
380
|
observe: ['addedNodes'],
|
|
359
|
-
target: '[
|
|
360
|
-
callback: function(mutation) {
|
|
381
|
+
target: '[array][object][key]',
|
|
382
|
+
callback: function (mutation) {
|
|
361
383
|
initElement(mutation.target);
|
|
362
384
|
}
|
|
363
385
|
});
|
|
@@ -365,8 +387,8 @@ observer.init({
|
|
|
365
387
|
observer.init({
|
|
366
388
|
name: 'CoCreateCursorAtt',
|
|
367
389
|
observe: ['attributes'],
|
|
368
|
-
attributeName:
|
|
369
|
-
callback: function(mutation) {
|
|
390
|
+
attributeName: getAttributeNames(['array', 'object', 'key']),
|
|
391
|
+
callback: function (mutation) {
|
|
370
392
|
initElement(mutation.target);
|
|
371
393
|
}
|
|
372
394
|
});
|