@cocreate/cursors 1.10.17 → 1.11.2
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 +36 -0
- package/package.json +8 -8
- package/src/index.css +5 -14
- package/src/index.js +142 -190
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,39 @@
|
|
|
1
|
+
## [1.11.2](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.11.1...v1.11.2) (2021-12-19)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* if pos.start and if pos.path case ([fdf7372](https://github.com/CoCreate-app/CoCreate-cursors/commit/fdf7372a59963548c421edfb080184de61e60e00))
|
|
7
|
+
|
|
8
|
+
## [1.11.1](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.11.0...v1.11.1) (2021-12-15)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* update dependencies ([186f745](https://github.com/CoCreate-app/CoCreate-cursors/commit/186f74551897f424450a5b3e31df2769d030bf01))
|
|
14
|
+
|
|
15
|
+
# [1.11.0](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.10.18...v1.11.0) (2021-12-14)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* add style top to cursor ([1e6d26c](https://github.com/CoCreate-app/CoCreate-cursors/commit/1e6d26c31919700399b3473a938f49f3cc2978b0))
|
|
21
|
+
* update dependencies ([9895f14](https://github.com/CoCreate-app/CoCreate-cursors/commit/9895f14bf1de1c133f0477134ccb654fb31f79d0))
|
|
22
|
+
* update dependencies ([2307656](https://github.com/CoCreate-app/CoCreate-cursors/commit/2307656877e1936cb8b5d978414df898a1de0b27))
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Features
|
|
26
|
+
|
|
27
|
+
* multi cursor support between many elements in window.top ([3b2dab9](https://github.com/CoCreate-app/CoCreate-cursors/commit/3b2dab9e1a6886026b7976eed44180d89a70ad83))
|
|
28
|
+
|
|
29
|
+
## [1.10.18](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.10.17...v1.10.18) (2021-12-08)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
### Bug Fixes
|
|
33
|
+
|
|
34
|
+
* check contenteditable element then iframe ([29bd7b4](https://github.com/CoCreate-app/CoCreate-cursors/commit/29bd7b4e7460c478cec37916fe9bb7439d2b8805))
|
|
35
|
+
* use attribute for socket_id instead of id ([db901da](https://github.com/CoCreate-app/CoCreate-cursors/commit/db901daa270551cd6b1b6b95124d785ed81643c9))
|
|
36
|
+
|
|
1
37
|
## [1.10.17](https://github.com/CoCreate-app/CoCreate-cursors/compare/v1.10.16...v1.10.17) (2021-11-27)
|
|
2
38
|
|
|
3
39
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cocreate/cursors",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.11.2",
|
|
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,13 +27,8 @@
|
|
|
27
27
|
white-space: nowrap;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
opacity: 0.6;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
.cursor-selection {
|
|
36
|
-
position: absolute;
|
|
30
|
+
selected-text {
|
|
31
|
+
opacity: 0.4;
|
|
37
32
|
}
|
|
38
33
|
|
|
39
34
|
.mirror {
|
|
@@ -49,7 +44,3 @@
|
|
|
49
44
|
background: rgba(0, 0, 0, 0.00);
|
|
50
45
|
width: 0px;
|
|
51
46
|
}
|
|
52
|
-
|
|
53
|
-
.users_selections {
|
|
54
|
-
opacity: 0.4;
|
|
55
|
-
}
|
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('.users_selections');
|
|
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,99 +58,155 @@ 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
|
-
if (element.
|
|
169
|
-
let domTextEditor = element
|
|
68
|
+
if (element.hasAttribute('contenteditable')) {
|
|
69
|
+
let domTextEditor = element;
|
|
70
|
+
if (element.tagName == 'IFRAME'){
|
|
71
|
+
let frameClientId = element.contentDocument.defaultView.CoCreateSockets.clientId;
|
|
72
|
+
if (frameClientId == selection.clientId) continue;
|
|
73
|
+
domTextEditor = element.contentDocument.documentElement;
|
|
74
|
+
}
|
|
170
75
|
let pos = getElementPosition(domTextEditor.htmlString, start, end);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
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
|
+
}
|
|
178
86
|
}
|
|
179
|
-
if(!element)
|
|
87
|
+
if(!element) continue;
|
|
180
88
|
let document = element.ownerDocument;
|
|
89
|
+
let mirrorDiv;
|
|
181
90
|
let id_mirror = element.getAttribute('mirror_id');
|
|
182
|
-
if (!id_mirror)
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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;
|
|
154
|
+
let details = {collection, document_id, name};
|
|
193
155
|
if (socket_id) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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();
|
|
198
161
|
}
|
|
199
|
-
});
|
|
200
|
-
cursor = elementMirror.querySelector('.cursor-container#socket_' + socket_id);
|
|
201
|
-
if (!cursor) {
|
|
202
|
-
let cursor_template = '<div class="cursor-container" \
|
|
203
|
-
id="socket_' + socket_id + '" \
|
|
204
|
-
style="background-color:' + selection.background + '"> \
|
|
205
|
-
<div class="cursor-flag" \
|
|
206
|
-
collection="users" \
|
|
207
|
-
document_id="' + selection.user_id + '" \
|
|
208
|
-
name="name">' + selection.userName + '</div>\
|
|
209
|
-
</div>';
|
|
210
|
-
elementMirror.innerHTML = cursor_template + elementMirror.innerHTML;
|
|
211
162
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
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);
|
|
175
|
+
}
|
|
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);
|
|
220
186
|
cursor.dataset.start = start;
|
|
221
187
|
cursor.dataset.end = end;
|
|
222
|
-
cursor.setAttribute('socket_id', socket_id);
|
|
223
188
|
cursor.setAttribute('user-name', selection.userName);
|
|
224
189
|
cursor.setAttribute('user-background', selection.background);
|
|
225
190
|
cursor.setAttribute('user-color', selection.color);
|
|
226
|
-
cursor.style["height"] = cursor_height + "px";
|
|
227
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');
|
|
228
205
|
cursorFlag.style["background"] = selection.background;
|
|
229
206
|
cursorFlag.innerHTML = selection.userName;
|
|
230
|
-
cursor.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
if (selection_user) {
|
|
234
|
-
selection_user.remove();
|
|
235
|
-
}
|
|
236
|
-
if ((start != end)) {
|
|
237
|
-
var scrollwidth = element.offsetWidth - element.scrollWidth;
|
|
238
|
-
var padding_right = parseInt(getComputedStyle(element)["paddingRight"]);
|
|
239
|
-
|
|
240
|
-
selection_user = document.createElement('span');
|
|
241
|
-
selection_user.id = 'sel-' + socket_id;
|
|
242
|
-
selection_user.className = 'users_selections';
|
|
243
|
-
let style_mirror = getComputedStyle(elementMirror);
|
|
244
|
-
selection_user.style["position"] = "absolute";
|
|
245
|
-
selection_user.style["top"] = style_mirror.paddingTop;
|
|
246
|
-
selection_user.style["left"] = style_mirror.paddingLeft;
|
|
247
|
-
selection_user.style["padding-right"] = scrollwidth + padding_right + "px";
|
|
248
|
-
elementMirror.insertBefore(selection_user, elementMirror.firstChild);
|
|
249
|
-
let selection_span_by_user = document.createElement('span');
|
|
250
|
-
selection_span_by_user.id = 'selection-' + socket_id;
|
|
251
|
-
selection_span_by_user.style.backgroundColor = selection.background;
|
|
252
|
-
let value_element = (['TEXTAREA', 'INPUT'].indexOf(element.nodeName) == -1) ? element.innerHTML : element.value;
|
|
253
|
-
selection_user.textContent = value_element.substring(0, start);
|
|
254
|
-
let value_span_selection = value_element.substring(start, end) || '';
|
|
255
|
-
selection_span_by_user.textContent = value_span_selection;
|
|
256
|
-
selection_user.appendChild(selection_span_by_user);
|
|
257
|
-
}
|
|
207
|
+
cursor.appendChild(cursorFlag);
|
|
208
|
+
|
|
209
|
+
selection_user.appendChild(span_end);
|
|
258
210
|
}
|
|
259
211
|
scrollMirror(element);
|
|
260
212
|
}
|
|
@@ -273,9 +225,9 @@ function updateCursors(element) {
|
|
|
273
225
|
}
|
|
274
226
|
for (let mirrorDiv of mirrorDivs) {
|
|
275
227
|
element = mirrorDiv.element;
|
|
276
|
-
let
|
|
228
|
+
let cursors = mirrorDiv.querySelectorAll('cursor');
|
|
277
229
|
|
|
278
|
-
|
|
230
|
+
cursors.forEach(function(child_cursor, index, array) {
|
|
279
231
|
let clientId = child_cursor.getAttribute('socket_id');
|
|
280
232
|
let userName = child_cursor.getAttribute('user-name');
|
|
281
233
|
let background = child_cursor.getAttribute('user-background');
|
|
@@ -297,12 +249,12 @@ function updateCursors(element) {
|
|
|
297
249
|
}
|
|
298
250
|
|
|
299
251
|
function removeCursor(clientId) {
|
|
300
|
-
let elements = document.querySelectorAll(
|
|
252
|
+
let elements = document.querySelectorAll(`cursor[socket_id="${clientId}"]`);
|
|
301
253
|
elements.forEach(function(element, index, array) {
|
|
302
254
|
element.parentNode.removeChild(element);
|
|
303
255
|
});
|
|
304
256
|
|
|
305
|
-
let sel_elements = document.querySelectorAll(
|
|
257
|
+
let sel_elements = document.querySelectorAll(`selection[socket_id="${clientId}"]`);
|
|
306
258
|
sel_elements.forEach(function(sel_element, index, array) {
|
|
307
259
|
sel_element.parentNode.removeChild(sel_element);
|
|
308
260
|
});
|
|
@@ -361,7 +313,7 @@ function sendPosition(info) {
|
|
|
361
313
|
|
|
362
314
|
|
|
363
315
|
message.listen('cursor', function(selection) {
|
|
364
|
-
if (selection.clientId == clientId) return;
|
|
316
|
+
// if (selection.clientId == clientId) return;
|
|
365
317
|
if (selection.start != null && selection.end != null)
|
|
366
318
|
drawCursors(selection);
|
|
367
319
|
else
|