@cocreate/cursors 1.10.18 → 1.11.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 +14 -0
- package/package.json +8 -8
- package/src/index.css +4 -5
- package/src/index.js +126 -182
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.11.0](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.10.18...v1.11.0) (2021-12-14)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add style top to cursor ([1e6d26c](https://github.com/CoCreate-app/CoCreate-cursors/commit/1e6d26c31919700399b3473a938f49f3cc2978b0))
|
|
7
|
+
* update dependencies ([9895f14](https://github.com/CoCreate-app/CoCreate-cursors/commit/9895f14bf1de1c133f0477134ccb654fb31f79d0))
|
|
8
|
+
* update dependencies ([2307656](https://github.com/CoCreate-app/CoCreate-cursors/commit/2307656877e1936cb8b5d978414df898a1de0b27))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* multi cursor support between many elements in window.top ([3b2dab9](https://github.com/CoCreate-app/CoCreate-cursors/commit/3b2dab9e1a6886026b7976eed44180d89a70ad83))
|
|
14
|
+
|
|
1
15
|
## [1.10.18](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.10.17...v1.10.18) (2021-12-08)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/cursors",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.0",
|
|
4
4
|
"description": "Collaborative user cursor position for inputs, textarea's and contenteditable elements.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cursors",
|
|
@@ -62,12 +62,12 @@
|
|
|
62
62
|
"webpack-log": "^3.0.1"
|
|
63
63
|
},
|
|
64
64
|
"dependencies": {
|
|
65
|
-
"@cocreate/crud-client": "^1.4.
|
|
66
|
-
"@cocreate/docs": "^1.2.
|
|
67
|
-
"@cocreate/message-client": "^1.1.
|
|
68
|
-
"@cocreate/observer": "^1.3.
|
|
69
|
-
"@cocreate/random-color": "^1.2.
|
|
70
|
-
"@cocreate/selection": "^1.
|
|
71
|
-
"@cocreate/uuid": "^1.1.
|
|
65
|
+
"@cocreate/crud-client": "^1.4.39",
|
|
66
|
+
"@cocreate/docs": "^1.2.61",
|
|
67
|
+
"@cocreate/message-client": "^1.1.57",
|
|
68
|
+
"@cocreate/observer": "^1.3.53",
|
|
69
|
+
"@cocreate/random-color": "^1.2.14",
|
|
70
|
+
"@cocreate/selection": "^1.3.0",
|
|
71
|
+
"@cocreate/uuid": "^1.1.50"
|
|
72
72
|
}
|
|
73
73
|
}
|
package/src/index.css
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
cursor {
|
|
2
2
|
position: absolute;
|
|
3
3
|
display: inline-block;
|
|
4
4
|
width: 2px;
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/*z-index:10;*/
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
cursor-flag {
|
|
10
10
|
position: absolute;
|
|
11
11
|
background-color: inherit;
|
|
12
12
|
top: 0px;
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
pointer-events: auto;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
cursor-flag:hover {
|
|
22
22
|
height: 14px;
|
|
23
23
|
width: unset;
|
|
24
24
|
padding: 1px 5px 0px 5px;
|
|
@@ -27,8 +27,7 @@
|
|
|
27
27
|
white-space: nowrap;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
position: absolute;
|
|
30
|
+
selected-text {
|
|
32
31
|
opacity: 0.4;
|
|
33
32
|
}
|
|
34
33
|
|
package/src/index.js
CHANGED
|
@@ -10,7 +10,6 @@ const clientId = window.CoCreateSockets.clientId || uuid.generate(12);
|
|
|
10
10
|
const cursorBackground = randomColor();
|
|
11
11
|
|
|
12
12
|
let enviroment_prod = true;
|
|
13
|
-
let documents = new Map();
|
|
14
13
|
|
|
15
14
|
let selector = "[collection][document_id][name]:not([contentEditable='false'])";
|
|
16
15
|
|
|
@@ -34,120 +33,17 @@ function initElement(element) {
|
|
|
34
33
|
}
|
|
35
34
|
|
|
36
35
|
function initDocument(doc) {
|
|
37
|
-
|
|
36
|
+
let documents = window.top.cursorDocuments;
|
|
37
|
+
if (!documents){
|
|
38
|
+
documents = new Map();
|
|
39
|
+
window.top.cursorDocuments = documents;
|
|
40
|
+
}
|
|
41
|
+
if (!documents.has(doc)) {
|
|
38
42
|
initResizeObserver(doc.documentElement);
|
|
39
43
|
documents.set(doc);
|
|
40
44
|
}
|
|
41
45
|
}
|
|
42
46
|
|
|
43
|
-
var getCoordinates = function(element, position_start, position_end) {
|
|
44
|
-
var mirrorDiv;
|
|
45
|
-
let ID_MIRROR = element.getAttribute('mirror_id');
|
|
46
|
-
let document = element.ownerDocument;
|
|
47
|
-
mirrorDiv = document.getElementById(ID_MIRROR);
|
|
48
|
-
|
|
49
|
-
if (!mirrorDiv) {
|
|
50
|
-
mirrorDiv = document.createElement('div');
|
|
51
|
-
mirrorDiv.id = ID_MIRROR;
|
|
52
|
-
mirrorDiv.className = (enviroment_prod) ? 'mirror mirror_scroll mirror_color' : 'mirror mirror_scroll';
|
|
53
|
-
mirrorDiv.contentEditable = false;
|
|
54
|
-
mirrorDiv.element = element;
|
|
55
|
-
element.insertAdjacentElement('afterend', mirrorDiv);
|
|
56
|
-
_initEvents(element);
|
|
57
|
-
initDocument(document);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
let computed = getComputedStyle(element);
|
|
61
|
-
let rect = element.getBoundingClientRect();
|
|
62
|
-
let scrollBarWidth = 0;
|
|
63
|
-
if (element.clientWidth != 0)
|
|
64
|
-
scrollBarWidth = element.offsetWidth - element.clientWidth;
|
|
65
|
-
let style = mirrorDiv.style;
|
|
66
|
-
|
|
67
|
-
style.position = 'absolute';
|
|
68
|
-
style.top = element.offsetTop + 'px';
|
|
69
|
-
style.left = element.offsetLeft + 'px';
|
|
70
|
-
style.width = rect.width + 'px';
|
|
71
|
-
style.height = rect.height + 'px';
|
|
72
|
-
style.visibility = 'visible';
|
|
73
|
-
style.overflowX = computed['overflowX'];
|
|
74
|
-
style.overflowY = computed['overflowY'];
|
|
75
|
-
style.margin = '0px';
|
|
76
|
-
style.paddingRight = parseInt(computed['paddingRight']) + scrollBarWidth + 'px';
|
|
77
|
-
style.border = computed['border'];
|
|
78
|
-
style.borderColor = 'transparent';
|
|
79
|
-
|
|
80
|
-
if (element.nodeName !== 'INPUT') {
|
|
81
|
-
style.wordWrap = 'break-word';
|
|
82
|
-
style.whiteSpace = 'pre-wrap';
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
style.whiteSpace = 'pre';
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
let properties = ['boxSizing', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'paddingTop', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing', 'textRendering', 'webkitWritingMode', 'textTransform', 'textIndent', 'overflowWrap'];
|
|
89
|
-
|
|
90
|
-
properties.forEach(function(prop) {
|
|
91
|
-
if (['left', 'top'].indexOf(prop.toLowerCase()) === -1)
|
|
92
|
-
style[prop] = computed[prop];
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
let cursor_container = mirrorDiv.querySelectorAll('.cursor-container');
|
|
97
|
-
let users_selections = mirrorDiv.querySelectorAll('.cursor-selection');
|
|
98
|
-
|
|
99
|
-
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
100
|
-
mirrorDiv.textContent = value_element.substring(0, position_start);
|
|
101
|
-
|
|
102
|
-
if (element.nodeName === 'INPUT')
|
|
103
|
-
mirrorDiv.textContent = mirrorDiv.textContent.replace(/\s/g, " ");
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
var span = document.createElement('span');
|
|
107
|
-
span.id = element.nodeName + 'span_selections';
|
|
108
|
-
let value_span = value_element.substring(position_start, position_end) || '';
|
|
109
|
-
span.textContent = value_span;
|
|
110
|
-
mirrorDiv.appendChild(span);
|
|
111
|
-
|
|
112
|
-
if (cursor_container) {
|
|
113
|
-
cursor_container.forEach(function(child_cursor, index, array) {
|
|
114
|
-
mirrorDiv.appendChild(child_cursor);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
if (users_selections) {
|
|
119
|
-
users_selections.forEach(function(child_selection, index, array) {
|
|
120
|
-
mirrorDiv.appendChild(child_selection);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// create mirror text end
|
|
125
|
-
let value_end = value_element.substring(position_end) || '';
|
|
126
|
-
var span_end = document.createElement('span');
|
|
127
|
-
mirrorDiv.appendChild(span_end);
|
|
128
|
-
span_end.textContent = value_end;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
var coordinates = {
|
|
132
|
-
start: {
|
|
133
|
-
top: span.offsetTop,
|
|
134
|
-
left: span.offsetLeft
|
|
135
|
-
},
|
|
136
|
-
end: {
|
|
137
|
-
top: span_end.offsetTop,
|
|
138
|
-
left: span_end.offsetLeft
|
|
139
|
-
}
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
return coordinates;
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
function getStyle(el, styleProp) {
|
|
146
|
-
if (window.getComputedStyle)
|
|
147
|
-
var y = document.defaultView.getComputedStyle(el, null).getPropertyValue(styleProp);
|
|
148
|
-
return y;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
47
|
function drawCursors(selection) {
|
|
152
48
|
const socket_id = selection['clientId'];
|
|
153
49
|
const collection = selection['collection'];
|
|
@@ -162,13 +58,20 @@ function drawCursors(selection) {
|
|
|
162
58
|
elements = document.querySelectorAll(selector);
|
|
163
59
|
}
|
|
164
60
|
for (let element of elements) {
|
|
61
|
+
if (element.activeElement) {
|
|
62
|
+
element.activeElement = '';
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
165
65
|
let realtime = element.getAttribute('realtime');
|
|
166
66
|
let cursors = element.getAttribute('cursors');
|
|
167
67
|
if (realtime == 'false' || cursors == 'false') continue;
|
|
168
68
|
if (element.hasAttribute('contenteditable')) {
|
|
169
69
|
let domTextEditor = element;
|
|
170
|
-
if (element.tagName == 'IFRAME')
|
|
70
|
+
if (element.tagName == 'IFRAME'){
|
|
71
|
+
let frameClientId = element.contentDocument.defaultView.CoCreateSockets.clientId;
|
|
72
|
+
if (frameClientId == selection.clientId) continue;
|
|
171
73
|
domTextEditor = element.contentDocument.documentElement;
|
|
74
|
+
}
|
|
172
75
|
let pos = getElementPosition(domTextEditor.htmlString, start, end);
|
|
173
76
|
element = domTextEditor.querySelector(pos.path);
|
|
174
77
|
let endPos = end - start;
|
|
@@ -178,87 +81,129 @@ function drawCursors(selection) {
|
|
|
178
81
|
end = pos.start;
|
|
179
82
|
start = pos.start;
|
|
180
83
|
}
|
|
181
|
-
if(!element)
|
|
84
|
+
if(!element) continue;
|
|
182
85
|
let document = element.ownerDocument;
|
|
86
|
+
let mirrorDiv;
|
|
183
87
|
let id_mirror = element.getAttribute('mirror_id');
|
|
184
|
-
if (!id_mirror)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
88
|
+
if (!id_mirror){
|
|
89
|
+
id_mirror = uuid.generate(8);
|
|
90
|
+
element.setAttribute('mirror_id', id_mirror);
|
|
91
|
+
|
|
92
|
+
mirrorDiv = document.createElement('cursor-container');
|
|
93
|
+
mirrorDiv.id = id_mirror;
|
|
94
|
+
mirrorDiv.className = (enviroment_prod) ? 'mirror mirror_scroll mirror_color' : 'mirror mirror_scroll';
|
|
95
|
+
mirrorDiv.contentEditable = false;
|
|
96
|
+
mirrorDiv.element = element;
|
|
97
|
+
element.insertAdjacentElement('afterend', mirrorDiv);
|
|
98
|
+
_initEvents(element);
|
|
99
|
+
initDocument(document);
|
|
100
|
+
}
|
|
101
|
+
else
|
|
102
|
+
mirrorDiv = document.getElementById(id_mirror);
|
|
103
|
+
|
|
104
|
+
let computed = getComputedStyle(element);
|
|
105
|
+
let rect = element.getBoundingClientRect();
|
|
106
|
+
let borderWidth = parseInt(computed['border-width']) * 2;
|
|
107
|
+
let scrollBarWidth = 0;
|
|
108
|
+
if (element.clientWidth != 0)
|
|
109
|
+
scrollBarWidth = element.offsetWidth - element.clientWidth - borderWidth;
|
|
110
|
+
let style = mirrorDiv.style;
|
|
111
|
+
|
|
112
|
+
style.position = 'absolute';
|
|
113
|
+
style.top = element.offsetTop + 'px';
|
|
114
|
+
style.left = element.offsetLeft + 'px';
|
|
115
|
+
style.width = rect.width + 'px';
|
|
116
|
+
style.height = rect.height + 'px';
|
|
117
|
+
style.visibility = 'visible';
|
|
118
|
+
style.overflowX = computed['overflowX'];
|
|
119
|
+
style.overflowY = computed['overflowY'];
|
|
120
|
+
style.margin = '0px';
|
|
121
|
+
style.paddingRight = parseInt(computed['paddingRight']) + scrollBarWidth + 'px';
|
|
122
|
+
style.border = computed['border'];
|
|
123
|
+
style.borderColor = 'transparent';
|
|
124
|
+
|
|
125
|
+
if (element.nodeName !== 'INPUT') {
|
|
126
|
+
style.wordWrap = 'break-word';
|
|
127
|
+
style.whiteSpace = 'pre-wrap';
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
style.whiteSpace = 'pre';
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
let properties = ['boxSizing', 'borderTopWidth', 'borderRightWidth', 'borderBottomWidth', 'borderLeftWidth', 'paddingTop', 'paddingBottom', 'paddingLeft', 'fontStyle', 'fontVariant', 'fontWeight', 'fontStretch', 'fontSize', 'lineHeight', 'fontFamily', 'textAlign', 'textTransform', 'textIndent', 'textDecoration', 'letterSpacing', 'wordSpacing', 'textRendering', 'webkitWritingMode', 'textTransform', 'textIndent', 'overflowWrap'];
|
|
134
|
+
|
|
135
|
+
properties.forEach(function(prop) {
|
|
136
|
+
if (['left', 'top'].indexOf(prop.toLowerCase()) === -1)
|
|
137
|
+
style[prop] = computed[prop];
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
let spanText = mirrorDiv.querySelector('span-text');
|
|
141
|
+
if (!spanText)
|
|
142
|
+
spanText = document.createElement('span-text');
|
|
143
|
+
spanText.style['display'] = 'block';
|
|
144
|
+
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
145
|
+
|
|
146
|
+
spanText.textContent = value_element;
|
|
147
|
+
if (element.nodeName === 'INPUT')
|
|
148
|
+
spanText.textContent = mirrorDiv.textContent.replace(/\s/g, " ");
|
|
149
|
+
mirrorDiv.appendChild(spanText);
|
|
150
|
+
let cursor, cursorFlag;
|
|
192
151
|
let details = {collection, document_id, name};
|
|
193
152
|
if (socket_id) {
|
|
194
|
-
let
|
|
195
|
-
if (
|
|
196
|
-
for (
|
|
197
|
-
if (
|
|
198
|
-
|
|
153
|
+
let userSelections = document.querySelectorAll(`selection[socket_id="${socket_id}"]`);
|
|
154
|
+
if (userSelections) {
|
|
155
|
+
for (let userSelection of userSelections){
|
|
156
|
+
if (userSelection.details != details)
|
|
157
|
+
userSelection.remove();
|
|
199
158
|
}
|
|
200
159
|
}
|
|
201
|
-
|
|
202
|
-
if (!
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
160
|
+
let selection_user = mirrorDiv.querySelector(`selection[socket_id="${socket_id}"]`);
|
|
161
|
+
if (!selection_user){
|
|
162
|
+
selection_user = document.createElement('selection');
|
|
163
|
+
selection_user.setAttribute('socket_id', socket_id);
|
|
164
|
+
selection_user.style["position"] = "absolute";
|
|
165
|
+
let style_mirror = getComputedStyle(mirrorDiv);
|
|
166
|
+
selection_user.style["top"] = style_mirror.paddingTop;
|
|
167
|
+
selection_user.style["left"] = style_mirror.paddingLeft;
|
|
168
|
+
selection_user.style["width"] = mirrorDiv.clientWidth - parseInt(computed['padding-left']) - parseInt(computed['padding-right']) - scrollBarWidth + 'px';
|
|
169
|
+
selection_user.details = {collection, document_id, name};
|
|
170
|
+
|
|
171
|
+
mirrorDiv.appendChild(selection_user);
|
|
211
172
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
let
|
|
218
|
-
|
|
173
|
+
|
|
174
|
+
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
175
|
+
selection_user.textContent = value_element.substring(0, start);
|
|
176
|
+
|
|
177
|
+
let value_end = value_element.substring(end) || '';
|
|
178
|
+
let span_end = document.createElement('span-end');
|
|
179
|
+
span_end.textContent = value_end;
|
|
180
|
+
|
|
181
|
+
cursor = document.createElement('cursor');
|
|
182
|
+
cursor.setAttribute('socket_id', socket_id);
|
|
219
183
|
cursor.dataset.start = start;
|
|
220
184
|
cursor.dataset.end = end;
|
|
221
185
|
cursor.setAttribute('user-name', selection.userName);
|
|
222
186
|
cursor.setAttribute('user-background', selection.background);
|
|
223
187
|
cursor.setAttribute('user-color', selection.color);
|
|
224
|
-
cursor.style["height"] = cursor_height + "px";
|
|
225
188
|
cursor.style["background"] = selection.background;
|
|
189
|
+
cursor.details = {collection, document_id, name};
|
|
190
|
+
cursor.textContent = "1";
|
|
191
|
+
span_end.prepend(cursor);
|
|
192
|
+
|
|
193
|
+
let selectedText = document.createElement('selected-text');
|
|
194
|
+
selectedText.style["backgroundColor"] = selection.background;
|
|
195
|
+
selectedText.textContent = value_element.substring(start, end) || '';
|
|
196
|
+
span_end.prepend(selectedText);
|
|
197
|
+
|
|
198
|
+
cursorFlag = document.createElement('cursor-flag');
|
|
199
|
+
cursorFlag.setAttribute('collection', 'users');
|
|
200
|
+
cursorFlag.setAttribute('document_id', selection.user_id);
|
|
201
|
+
cursorFlag.setAttribute('name', 'name');
|
|
226
202
|
cursorFlag.style["background"] = selection.background;
|
|
227
203
|
cursorFlag.innerHTML = selection.userName;
|
|
228
|
-
cursor.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
let userSelections = document.querySelectorAll(`.cursor-selection[socket_id="${socket_id}"]`);
|
|
232
|
-
if (userSelections) {
|
|
233
|
-
for (selection of userSelections){
|
|
234
|
-
if (selection.details != details)
|
|
235
|
-
selection.remove();
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
if ((start != end)) {
|
|
239
|
-
var scrollwidth = element.offsetWidth - element.scrollWidth;
|
|
240
|
-
var padding_right = parseInt(getComputedStyle(element)["paddingRight"]);
|
|
241
|
-
|
|
242
|
-
let selection_user = document.createElement('span');
|
|
243
|
-
selection_user.id = 'sel-' + socket_id;
|
|
244
|
-
selection_user.setAttribute('socket_id', socket_id);
|
|
245
|
-
selection_user.className = 'cursor-selection';
|
|
246
|
-
let style_mirror = getComputedStyle(elementMirror);
|
|
247
|
-
selection_user.style["position"] = "absolute";
|
|
248
|
-
selection_user.style["top"] = style_mirror.paddingTop;
|
|
249
|
-
selection_user.style["left"] = style_mirror.paddingLeft;
|
|
250
|
-
selection_user.style["padding-right"] = scrollwidth + padding_right + "px";
|
|
251
|
-
selection_user.details = {collection, document_id, name};
|
|
252
|
-
elementMirror.insertBefore(selection_user, elementMirror.firstChild);
|
|
253
|
-
|
|
254
|
-
let selection_span_by_user = document.createElement('span');
|
|
255
|
-
selection_span_by_user.style.backgroundColor = selection.background;
|
|
256
|
-
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
257
|
-
selection_user.textContent = value_element.substring(0, start);
|
|
258
|
-
let value_span_selection = value_element.substring(start, end) || '';
|
|
259
|
-
selection_span_by_user.textContent = value_span_selection;
|
|
260
|
-
selection_user.appendChild(selection_span_by_user);
|
|
261
|
-
}
|
|
204
|
+
cursor.appendChild(cursorFlag);
|
|
205
|
+
|
|
206
|
+
selection_user.appendChild(span_end);
|
|
262
207
|
}
|
|
263
208
|
scrollMirror(element);
|
|
264
209
|
}
|
|
@@ -277,9 +222,9 @@ function updateCursors(element) {
|
|
|
277
222
|
}
|
|
278
223
|
for (let mirrorDiv of mirrorDivs) {
|
|
279
224
|
element = mirrorDiv.element;
|
|
280
|
-
let
|
|
225
|
+
let cursors = mirrorDiv.querySelectorAll('cursor');
|
|
281
226
|
|
|
282
|
-
|
|
227
|
+
cursors.forEach(function(child_cursor, index, array) {
|
|
283
228
|
let clientId = child_cursor.getAttribute('socket_id');
|
|
284
229
|
let userName = child_cursor.getAttribute('user-name');
|
|
285
230
|
let background = child_cursor.getAttribute('user-background');
|
|
@@ -301,12 +246,12 @@ function updateCursors(element) {
|
|
|
301
246
|
}
|
|
302
247
|
|
|
303
248
|
function removeCursor(clientId) {
|
|
304
|
-
let elements = document.querySelectorAll(
|
|
249
|
+
let elements = document.querySelectorAll(`cursor[socket_id="${clientId}"]`);
|
|
305
250
|
elements.forEach(function(element, index, array) {
|
|
306
251
|
element.parentNode.removeChild(element);
|
|
307
252
|
});
|
|
308
253
|
|
|
309
|
-
let sel_elements = document.querySelectorAll(
|
|
254
|
+
let sel_elements = document.querySelectorAll(`selection[socket_id="${clientId}"]`);
|
|
310
255
|
sel_elements.forEach(function(sel_element, index, array) {
|
|
311
256
|
sel_element.parentNode.removeChild(sel_element);
|
|
312
257
|
});
|
|
@@ -365,7 +310,6 @@ function sendPosition(info) {
|
|
|
365
310
|
|
|
366
311
|
|
|
367
312
|
message.listen('cursor', function(selection) {
|
|
368
|
-
if (selection.clientId == clientId) return;
|
|
369
313
|
if (selection.start != null && selection.end != null)
|
|
370
314
|
drawCursors(selection);
|
|
371
315
|
else
|