@cocreate/cursors 1.10.18 → 1.11.3
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 +35 -0
- package/package.json +8 -8
- package/src/index.css +4 -5
- package/src/index.js +137 -189
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,38 @@
|
|
|
1
|
+
## [1.11.3](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.11.2...v1.11.3) (2021-12-23)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* if elementActive and clientId is self return ([170ee7a](https://github.com/CoCreate-app/CoCreate-cursors/commit/170ee7a233f32e4fda9010e1ae18b9328489c6ed))
|
|
7
|
+
|
|
8
|
+
## [1.11.2](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.11.1...v1.11.2) (2021-12-19)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* if pos.start and if pos.path case ([fdf7372](https://github.com/CoCreate-app/CoCreate-cursors/commit/fdf7372a59963548c421edfb080184de61e60e00))
|
|
14
|
+
|
|
15
|
+
## [1.11.1](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.11.0...v1.11.1) (2021-12-15)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* update dependencies ([186f745](https://github.com/CoCreate-app/CoCreate-cursors/commit/186f74551897f424450a5b3e31df2769d030bf01))
|
|
21
|
+
|
|
22
|
+
# [1.11.0](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.10.18...v1.11.0) (2021-12-14)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* add style top to cursor ([1e6d26c](https://github.com/CoCreate-app/CoCreate-cursors/commit/1e6d26c31919700399b3473a938f49f3cc2978b0))
|
|
28
|
+
* update dependencies ([9895f14](https://github.com/CoCreate-app/CoCreate-cursors/commit/9895f14bf1de1c133f0477134ccb654fb31f79d0))
|
|
29
|
+
* update dependencies ([2307656](https://github.com/CoCreate-app/CoCreate-cursors/commit/2307656877e1936cb8b5d978414df898a1de0b27))
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Features
|
|
33
|
+
|
|
34
|
+
* multi cursor support between many elements in window.top ([3b2dab9](https://github.com/CoCreate-app/CoCreate-cursors/commit/3b2dab9e1a6886026b7976eed44180d89a70ad83))
|
|
35
|
+
|
|
1
36
|
## [1.10.18](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.10.17...v1.10.18) (2021-12-08)
|
|
2
37
|
|
|
3
38
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/cursors",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.3",
|
|
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.40",
|
|
66
|
+
"@cocreate/docs": "^1.2.62",
|
|
67
|
+
"@cocreate/message-client": "^1.1.58",
|
|
68
|
+
"@cocreate/observer": "^1.3.54",
|
|
69
|
+
"@cocreate/random-color": "^1.2.15",
|
|
70
|
+
"@cocreate/selection": "^1.3.1",
|
|
71
|
+
"@cocreate/uuid": "^1.1.51"
|
|
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,103 +58,155 @@ function drawCursors(selection) {
|
|
|
162
58
|
elements = document.querySelectorAll(selector);
|
|
163
59
|
}
|
|
164
60
|
for (let element of elements) {
|
|
61
|
+
if (element.activeElement && selection.clientId == clientId) {
|
|
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
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
76
|
+
if (pos.start){
|
|
77
|
+
if(pos.path)
|
|
78
|
+
element = domTextEditor.querySelector(pos.path);
|
|
79
|
+
let endPos = end - start;
|
|
80
|
+
if (endPos > 0)
|
|
81
|
+
end = pos.start + endPos;
|
|
82
|
+
else
|
|
83
|
+
end = pos.start;
|
|
84
|
+
start = pos.start;
|
|
85
|
+
}
|
|
180
86
|
}
|
|
181
|
-
if(!element)
|
|
87
|
+
if(!element) continue;
|
|
182
88
|
let document = element.ownerDocument;
|
|
89
|
+
let mirrorDiv;
|
|
183
90
|
let id_mirror = element.getAttribute('mirror_id');
|
|
184
|
-
if (!id_mirror)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
91
|
+
if (!id_mirror){
|
|
92
|
+
id_mirror = uuid.generate(8);
|
|
93
|
+
element.setAttribute('mirror_id', id_mirror);
|
|
94
|
+
|
|
95
|
+
mirrorDiv = document.createElement('cursor-container');
|
|
96
|
+
mirrorDiv.id = id_mirror;
|
|
97
|
+
mirrorDiv.className = (enviroment_prod) ? 'mirror mirror_scroll mirror_color' : 'mirror mirror_scroll';
|
|
98
|
+
mirrorDiv.contentEditable = false;
|
|
99
|
+
mirrorDiv.element = element;
|
|
100
|
+
element.insertAdjacentElement('afterend', mirrorDiv);
|
|
101
|
+
_initEvents(element);
|
|
102
|
+
initDocument(document);
|
|
103
|
+
}
|
|
104
|
+
else
|
|
105
|
+
mirrorDiv = document.getElementById(id_mirror);
|
|
106
|
+
|
|
107
|
+
let computed = getComputedStyle(element);
|
|
108
|
+
let rect = element.getBoundingClientRect();
|
|
109
|
+
let borderWidth = parseInt(computed['border-width']) * 2;
|
|
110
|
+
let scrollBarWidth = 0;
|
|
111
|
+
if (element.clientWidth != 0)
|
|
112
|
+
scrollBarWidth = element.offsetWidth - element.clientWidth - borderWidth;
|
|
113
|
+
let style = mirrorDiv.style;
|
|
114
|
+
|
|
115
|
+
style.position = 'absolute';
|
|
116
|
+
style.top = element.offsetTop + 'px';
|
|
117
|
+
style.left = element.offsetLeft + 'px';
|
|
118
|
+
style.width = rect.width + 'px';
|
|
119
|
+
style.height = rect.height + 'px';
|
|
120
|
+
style.visibility = 'visible';
|
|
121
|
+
style.overflowX = computed['overflowX'];
|
|
122
|
+
style.overflowY = computed['overflowY'];
|
|
123
|
+
style.margin = '0px';
|
|
124
|
+
style.paddingRight = parseInt(computed['paddingRight']) + scrollBarWidth + 'px';
|
|
125
|
+
style.border = computed['border'];
|
|
126
|
+
style.borderColor = 'transparent';
|
|
127
|
+
|
|
128
|
+
if (element.nodeName !== 'INPUT') {
|
|
129
|
+
style.wordWrap = 'break-word';
|
|
130
|
+
style.whiteSpace = 'pre-wrap';
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
style.whiteSpace = 'pre';
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
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'];
|
|
137
|
+
|
|
138
|
+
properties.forEach(function(prop) {
|
|
139
|
+
if (['left', 'top'].indexOf(prop.toLowerCase()) === -1)
|
|
140
|
+
style[prop] = computed[prop];
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
let spanText = mirrorDiv.querySelector('span-text');
|
|
144
|
+
if (!spanText)
|
|
145
|
+
spanText = document.createElement('span-text');
|
|
146
|
+
spanText.style['display'] = 'block';
|
|
147
|
+
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
148
|
+
|
|
149
|
+
spanText.textContent = value_element;
|
|
150
|
+
if (element.nodeName === 'INPUT')
|
|
151
|
+
spanText.textContent = mirrorDiv.textContent.replace(/\s/g, " ");
|
|
152
|
+
mirrorDiv.appendChild(spanText);
|
|
153
|
+
let cursor, cursorFlag;
|
|
192
154
|
let details = {collection, document_id, name};
|
|
193
155
|
if (socket_id) {
|
|
194
|
-
let
|
|
195
|
-
if (
|
|
196
|
-
for (
|
|
197
|
-
if (
|
|
198
|
-
|
|
156
|
+
let userSelections = document.querySelectorAll(`selection[socket_id="${socket_id}"]`);
|
|
157
|
+
if (userSelections) {
|
|
158
|
+
for (let userSelection of userSelections){
|
|
159
|
+
if (userSelection.details != details)
|
|
160
|
+
userSelection.remove();
|
|
199
161
|
}
|
|
200
162
|
}
|
|
201
|
-
|
|
202
|
-
if (!
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
163
|
+
let selection_user = mirrorDiv.querySelector(`selection[socket_id="${socket_id}"]`);
|
|
164
|
+
if (!selection_user){
|
|
165
|
+
selection_user = document.createElement('selection');
|
|
166
|
+
selection_user.setAttribute('socket_id', socket_id);
|
|
167
|
+
selection_user.style["position"] = "absolute";
|
|
168
|
+
let style_mirror = getComputedStyle(mirrorDiv);
|
|
169
|
+
selection_user.style["top"] = style_mirror.paddingTop;
|
|
170
|
+
selection_user.style["left"] = style_mirror.paddingLeft;
|
|
171
|
+
selection_user.style["width"] = mirrorDiv.clientWidth - parseInt(computed['padding-left']) - parseInt(computed['padding-right']) - scrollBarWidth + 'px';
|
|
172
|
+
selection_user.details = {collection, document_id, name};
|
|
173
|
+
|
|
174
|
+
mirrorDiv.appendChild(selection_user);
|
|
211
175
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
let
|
|
218
|
-
|
|
176
|
+
|
|
177
|
+
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
178
|
+
selection_user.textContent = value_element.substring(0, start);
|
|
179
|
+
|
|
180
|
+
let value_end = value_element.substring(end) || '';
|
|
181
|
+
let span_end = document.createElement('span-end');
|
|
182
|
+
span_end.textContent = value_end;
|
|
183
|
+
|
|
184
|
+
cursor = document.createElement('cursor');
|
|
185
|
+
cursor.setAttribute('socket_id', socket_id);
|
|
219
186
|
cursor.dataset.start = start;
|
|
220
187
|
cursor.dataset.end = end;
|
|
221
188
|
cursor.setAttribute('user-name', selection.userName);
|
|
222
189
|
cursor.setAttribute('user-background', selection.background);
|
|
223
190
|
cursor.setAttribute('user-color', selection.color);
|
|
224
|
-
cursor.style["height"] = cursor_height + "px";
|
|
225
191
|
cursor.style["background"] = selection.background;
|
|
192
|
+
cursor.details = {collection, document_id, name};
|
|
193
|
+
cursor.textContent = "1";
|
|
194
|
+
span_end.prepend(cursor);
|
|
195
|
+
|
|
196
|
+
let selectedText = document.createElement('selected-text');
|
|
197
|
+
selectedText.style["backgroundColor"] = selection.background;
|
|
198
|
+
selectedText.textContent = value_element.substring(start, end) || '';
|
|
199
|
+
span_end.prepend(selectedText);
|
|
200
|
+
|
|
201
|
+
cursorFlag = document.createElement('cursor-flag');
|
|
202
|
+
cursorFlag.setAttribute('collection', 'users');
|
|
203
|
+
cursorFlag.setAttribute('document_id', selection.user_id);
|
|
204
|
+
cursorFlag.setAttribute('name', 'name');
|
|
226
205
|
cursorFlag.style["background"] = selection.background;
|
|
227
206
|
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
|
-
}
|
|
207
|
+
cursor.appendChild(cursorFlag);
|
|
208
|
+
|
|
209
|
+
selection_user.appendChild(span_end);
|
|
262
210
|
}
|
|
263
211
|
scrollMirror(element);
|
|
264
212
|
}
|
|
@@ -277,9 +225,9 @@ function updateCursors(element) {
|
|
|
277
225
|
}
|
|
278
226
|
for (let mirrorDiv of mirrorDivs) {
|
|
279
227
|
element = mirrorDiv.element;
|
|
280
|
-
let
|
|
228
|
+
let cursors = mirrorDiv.querySelectorAll('cursor');
|
|
281
229
|
|
|
282
|
-
|
|
230
|
+
cursors.forEach(function(child_cursor, index, array) {
|
|
283
231
|
let clientId = child_cursor.getAttribute('socket_id');
|
|
284
232
|
let userName = child_cursor.getAttribute('user-name');
|
|
285
233
|
let background = child_cursor.getAttribute('user-background');
|
|
@@ -301,12 +249,12 @@ function updateCursors(element) {
|
|
|
301
249
|
}
|
|
302
250
|
|
|
303
251
|
function removeCursor(clientId) {
|
|
304
|
-
let elements = document.querySelectorAll(
|
|
252
|
+
let elements = document.querySelectorAll(`cursor[socket_id="${clientId}"]`);
|
|
305
253
|
elements.forEach(function(element, index, array) {
|
|
306
254
|
element.parentNode.removeChild(element);
|
|
307
255
|
});
|
|
308
256
|
|
|
309
|
-
let sel_elements = document.querySelectorAll(
|
|
257
|
+
let sel_elements = document.querySelectorAll(`selection[socket_id="${clientId}"]`);
|
|
310
258
|
sel_elements.forEach(function(sel_element, index, array) {
|
|
311
259
|
sel_element.parentNode.removeChild(sel_element);
|
|
312
260
|
});
|
|
@@ -365,7 +313,7 @@ function sendPosition(info) {
|
|
|
365
313
|
|
|
366
314
|
|
|
367
315
|
message.listen('cursor', function(selection) {
|
|
368
|
-
if (selection.clientId == clientId) return;
|
|
316
|
+
// if (selection.clientId == clientId) return;
|
|
369
317
|
if (selection.start != null && selection.end != null)
|
|
370
318
|
drawCursors(selection);
|
|
371
319
|
else
|