@cocreate/selection 1.6.28 → 1.7.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/docs/index.html CHANGED
@@ -11,19 +11,19 @@
11
11
  sizes="32x32"
12
12
  href="https://cocreate.app/images/favicon.ico" />
13
13
  <meta
14
- name="description"
14
+ key="description"
15
15
  content="A headless javascript micro component. Easy configuration using HTML5 attributes or JavaScript api." />
16
16
  <meta
17
- name="keywords"
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
 
21
21
  <link
22
22
  rel="stylesheet"
23
23
  href="/docs/index.css"
24
- collection="files"
25
- document_id="60888216117c640e7596303f"
26
- name="src"
24
+ array="files"
25
+ object="60888216117c640e7596303f"
26
+ key="src"
27
27
  type="text/css"
28
28
  save="true" />
29
29
 
@@ -37,20 +37,20 @@
37
37
  scroll="sticky-nav,hide-nav"
38
38
  scroll-up="10"
39
39
  scroll-down="10"
40
- collection="files"
41
- document_id="60395ef42b3ac232657040fd"
42
- name="src"></nav>
40
+ array="files"
41
+ object="60395ef42b3ac232657040fd"
42
+ key="src"></nav>
43
43
  <sidenav
44
44
  id="menuL"
45
45
  class="position:fixed top:0px left:0px overflow:hidden background:whitesmoke height:100vh width:0px width:300px@xl"
46
46
  resizable
47
- resize-target="[content_id='content']"
47
+ resize-selector="[content_id='content']"
48
48
  resize-property="margin-left"
49
49
  resize-value="width">
50
50
  <menu
51
- collection="files"
52
- document_id="603717b07de7fb350ae9fec8"
53
- name="src"></menu>
51
+ array="files"
52
+ object="603717b07de7fb350ae9fec8"
53
+ key="src"></menu>
54
54
  <div resize="right"></div>
55
55
  </sidenav>
56
56
  <main
@@ -197,12 +197,12 @@
197
197
  <textarea
198
198
  type="code"
199
199
  lang="html"
200
- collection="demos"
201
- document_id=""
202
- name="demo"
200
+ array="demos"
201
+ object=""
202
+ key="demo"
203
203
  save="false"
204
204
  id="demo"
205
- input-target=".demopreview"
205
+ input-selector=".demopreview"
206
206
  input-attribute="value"
207
207
  input-events="input, onload"
208
208
  class="height:100% width:100% outline:none border:none resize:none padding:5px"></textarea>
@@ -225,7 +225,7 @@
225
225
  show="#eye-slash"
226
226
  hide="#eye, #demo-preview"
227
227
  toggle="code-height"
228
- toggle-target="#demo-code"
228
+ toggle-selector="#demo-code"
229
229
  ><i
230
230
  class="height:18px fill:#505050"
231
231
  src="/assets/svg/eye.svg"></i
@@ -237,7 +237,7 @@
237
237
  show="#eye, #demo-preview"
238
238
  hide="#eye-slash"
239
239
  toggle="code-height"
240
- toggle-target="#demo-code"
240
+ toggle-selector="#demo-code"
241
241
  ><i
242
242
  class="height:20px fill:#505050"
243
243
  src="/assets/svg/eye-slash.svg"></i
@@ -264,7 +264,7 @@
264
264
  <a
265
265
  class="margin-right:5px"
266
266
  fullscreen
267
- fullscreen-target="#playground"></a>
267
+ fullscreen-selector="#playground"></a>
268
268
  </div>
269
269
  </div>
270
270
  <!-- End SandBox -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocreate/selection",
3
- "version": "1.6.28",
3
+ "version": "1.7.0",
4
4
  "description": "A simple selection component in vanilla javascript. Easily configured using HTML5 data-attributes and/or JavaScript API.",
5
5
  "keywords": [
6
6
  "selection",
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "scripts": {
27
27
  "start": "npx webpack --config webpack.config.js",
28
- "build": "NODE_ENV=production npx webpack --config webpack.config.js",
28
+ "build": "npx webpack --mode=production --config webpack.config.js",
29
29
  "dev": "npx webpack --config webpack.config.js --watch",
30
30
  "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); } }\""
31
31
  },
@@ -34,7 +34,7 @@
34
34
  "url": "git+https://github.com/CoCreate-app/CoCreate-selection.git"
35
35
  },
36
36
  "author": "CoCreate LLC",
37
- "license": "SEE LICENSE",
37
+ "license": "AGPL-3.0",
38
38
  "bugs": {
39
39
  "url": "https://github.com/CoCreate-app/CoCreate-selection/issues"
40
40
  },
@@ -58,6 +58,6 @@
58
58
  "webpack-log": "^3.0.1"
59
59
  },
60
60
  "dependencies": {
61
- "@cocreate/utils": "^1.21.15"
61
+ "@cocreate/utils": "^1.21.16"
62
62
  }
63
63
  }
package/src/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import {cssPath, domParser} from '@cocreate/utils';
1
+ import { cssPath, domParser } from '@cocreate/utils';
2
2
 
3
- String.prototype.customSplice = function(index, absIndex, string) {
3
+ String.prototype.customSplice = function (index, absIndex, string) {
4
4
  return this.slice(0, index) + string + this.slice(index + Math.abs(absIndex));
5
5
  };
6
6
 
@@ -10,162 +10,162 @@ export function getSelection(element) {
10
10
  start: element.selectionStart,
11
11
  end: element.selectionEnd
12
12
  };
13
- }
13
+ }
14
14
  else {
15
- let Document = element.ownerDocument;
16
- let selection = Document.getSelection();
17
- if (!selection.rangeCount) return { start: 0, end: 0 };
15
+ let Document = element.ownerDocument;
16
+ let selection = Document.getSelection();
17
+ if (!selection.rangeCount) return { start: 0, end: 0 };
18
18
 
19
- let range = selection.getRangeAt(0);
19
+ let range = selection.getRangeAt(0);
20
20
  let start = range.startOffset;
21
21
  let end = range.endOffset;
22
22
  let previousSibling = range.startContainer.previousSibling;
23
- if (element.innerHTML && previousSibling && previousSibling.nodeType == 3) {
24
- let length = 0;
25
- do {
26
- length += previousSibling.length;
27
- previousSibling = previousSibling.previousSibling;
28
- } while (previousSibling);
29
- start += length;
30
- end += length;
31
- }
32
-
33
- if (range.startContainer != range.endContainer) {
23
+ if (element.innerHTML && previousSibling && previousSibling.nodeType == 3) {
24
+ let length = 0;
25
+ do {
26
+ length += previousSibling.length;
27
+ previousSibling = previousSibling.previousSibling;
28
+ } while (previousSibling);
29
+ start += length;
30
+ end += length;
31
+ }
32
+
33
+ if (range.startContainer != range.endContainer) {
34
34
  // TODO: replace common ancestor value
35
- }
36
- let contenteditable = range.startContainer.parentElement.closest('[contenteditable][collection][document_id][name]');
37
- if (contenteditable){
35
+ }
36
+ let contenteditable = range.startContainer.parentElement.closest('[contenteditable][array][object][key]');
37
+ if (contenteditable) {
38
38
  element = contenteditable;
39
39
  }
40
- let domTextEditor = element;
41
- if (!domTextEditor.htmlString){
42
- domTextEditor = element.closest('[contenteditable]');
43
- }
44
- let elementStart = start, elementEnd = end;
45
- if (domTextEditor && domTextEditor.htmlString){
46
- let nodePos = getStringPosition({ string: domTextEditor.htmlString, target: range.startContainer.parentElement, position: 'afterbegin'});
47
- if (nodePos){
40
+ let domTextEditor = element;
41
+ if (!domTextEditor.htmlString) {
42
+ domTextEditor = element.closest('[contenteditable]');
43
+ }
44
+ let elementStart = start, elementEnd = end;
45
+ if (domTextEditor && domTextEditor.htmlString) {
46
+ let nodePos = getStringPosition({ string: domTextEditor.htmlString, target: range.startContainer.parentElement, position: 'afterbegin' });
47
+ if (nodePos) {
48
48
  elementStart = nodePos.start;
49
49
  elementEnd = nodePos.end;
50
50
  start = start + nodePos.start;
51
51
  end = end + nodePos.end;
52
52
  }
53
- }
54
-
55
- let startContainer = range.startContainer;
56
- if (startContainer.nodeType == 3)
57
- startContainer = range.startContainer.parentElement;
58
-
59
- let endContainer = range.endContainer;
60
- if (endContainer.nodeType == 3)
61
- endContainer = range.endContainer.parentElement;
53
+ }
54
+
55
+ let startContainer = range.startContainer;
56
+ if (startContainer.nodeType == 3)
57
+ startContainer = range.startContainer.parentElement;
58
+
59
+ let endContainer = range.endContainer;
60
+ if (endContainer.nodeType == 3)
61
+ endContainer = range.endContainer.parentElement;
62
62
 
63
63
  let rangeObj = {
64
64
  element: contenteditable,
65
65
  // domTextEditor,
66
- startOffset: range.startOffset,
67
- endOffset: range.endOffset,
68
- startContainer,
69
- endContainer,
70
- elementStart,
71
- elementEnd
66
+ startOffset: range.startOffset,
67
+ endOffset: range.endOffset,
68
+ startContainer,
69
+ endContainer,
70
+ elementStart,
71
+ elementEnd
72
72
  };
73
- return { start, end, range: rangeObj};
73
+ return { start, end, range: rangeObj };
74
74
  }
75
-
75
+
76
76
  }
77
77
 
78
78
  export function processSelection(element, value = "", prev_start, prev_end, start, end, range) {
79
- let prevStart = prev_start;
80
- let prevEnd = prev_end;
81
- if (prev_start >= start) {
82
- if (value == "") {
83
- prev_start -= end - start;
84
- prev_end -= end - start;
85
- prev_start = prev_start < start ? start : prev_start;
86
- }
87
- else {
88
- prev_start += value.length;
89
- prev_end += value.length;
90
- }
91
- } {
92
- if (value == "" && prev_end >= start) {
93
- prev_end = (prev_end >= end) ? prev_end - (end - start) : start;
94
- }
95
- }
96
- if (range) {
97
- if (prevStart > prev_start){
98
- let length = prevStart - prev_start;
99
- if (Math.sign(length) === 1 && range.startOffset >= length)
100
- range.startOffset -= length;
101
- }
102
- else if (prevStart < prev_start){
103
- let length = prev_start - prevStart;
104
- if (Math.sign(length) === 1)
105
- if (range.startOffset == 0 || range.startOffset >= length)
106
- range.startOffset += length;
107
- }
108
- if (prevEnd > prev_end){
109
- let length = prevEnd - prev_end;
110
- if (Math.sign(length) === 1 && range.endOffset >= length)
111
- range.endOffset -= length;
112
- }
113
- else if (prevEnd < prev_end){
114
- let length = prev_end - prevEnd;
115
- if (Math.sign(length) === 1)
116
- if (range.endOffset == 0 || range.endOffset >= length)
117
- range.endOffset += length;
118
- }
119
- }
120
-
79
+ let prevStart = prev_start;
80
+ let prevEnd = prev_end;
81
+ if (prev_start >= start) {
82
+ if (value == "") {
83
+ prev_start -= end - start;
84
+ prev_end -= end - start;
85
+ prev_start = prev_start < start ? start : prev_start;
86
+ }
87
+ else {
88
+ prev_start += value.length;
89
+ prev_end += value.length;
90
+ }
91
+ } {
92
+ if (value == "" && prev_end >= start) {
93
+ prev_end = (prev_end >= end) ? prev_end - (end - start) : start;
94
+ }
95
+ }
96
+ if (range) {
97
+ if (prevStart > prev_start) {
98
+ let length = prevStart - prev_start;
99
+ if (Math.sign(length) === 1 && range.startOffset >= length)
100
+ range.startOffset -= length;
101
+ }
102
+ else if (prevStart < prev_start) {
103
+ let length = prev_start - prevStart;
104
+ if (Math.sign(length) === 1)
105
+ if (range.startOffset == 0 || range.startOffset >= length)
106
+ range.startOffset += length;
107
+ }
108
+ if (prevEnd > prev_end) {
109
+ let length = prevEnd - prev_end;
110
+ if (Math.sign(length) === 1 && range.endOffset >= length)
111
+ range.endOffset -= length;
112
+ }
113
+ else if (prevEnd < prev_end) {
114
+ let length = prev_end - prevEnd;
115
+ if (Math.sign(length) === 1)
116
+ if (range.endOffset == 0 || range.endOffset >= length)
117
+ range.endOffset += length;
118
+ }
119
+ }
120
+
121
121
  setSelection(element, prev_start, prev_end, range);
122
- return {element, value, start, end, prev_start, prev_end};
122
+ return { element, value, start, end, prev_start, prev_end };
123
123
  }
124
124
 
125
125
  export function setSelection(element, start, end, range) {
126
126
  if (element.tagName === "INPUT" || element.tagName === "TEXTAREA") {
127
127
  element.selectionStart = start;
128
128
  element.selectionEnd = end;
129
- }
129
+ }
130
130
  else {
131
131
  if (!range) return;
132
- let Document = element.ownerDocument;
133
-
134
- let startContainer = getContainer(range.startContainer, range.startOffset);
135
- let endContainer = getContainer(range.endContainer, range.endOffset);
136
-
137
- if (!startContainer || !endContainer)
138
- return;
139
-
140
- let selection = Document.getSelection();
141
- selection.removeAllRanges();
142
-
143
- const newRange = Document.createRange();
144
- newRange.setStart(startContainer, range.startOffset);
145
- newRange.setEnd(endContainer, range.endOffset);
146
-
147
- selection.addRange(newRange);
148
- }
132
+ let Document = element.ownerDocument;
133
+
134
+ let startContainer = getContainer(range.startContainer, range.startOffset);
135
+ let endContainer = getContainer(range.endContainer, range.endOffset);
136
+
137
+ if (!startContainer || !endContainer)
138
+ return;
139
+
140
+ let selection = Document.getSelection();
141
+ selection.removeAllRanges();
142
+
143
+ const newRange = Document.createRange();
144
+ newRange.setStart(startContainer, range.startOffset);
145
+ newRange.setEnd(endContainer, range.endOffset);
146
+
147
+ selection.addRange(newRange);
148
+ }
149
149
  }
150
150
 
151
- function getContainer(element, offset){
152
- let nodeLengths = 0;
153
- for (let node of element.childNodes){
154
- if (node.nodeType == 3) {
155
- let length = node.length + nodeLengths;
156
- if (length >= offset)
157
- return node;
158
- else
159
- nodeLengths += length;
160
- }
161
- }
151
+ function getContainer(element, offset) {
152
+ let nodeLengths = 0;
153
+ for (let node of element.childNodes) {
154
+ if (node.nodeType == 3) {
155
+ let length = node.length + nodeLengths;
156
+ if (length >= offset)
157
+ return node;
158
+ else
159
+ nodeLengths += length;
160
+ }
161
+ }
162
162
  }
163
163
 
164
164
  export function hasSelection(el) {
165
- let { start, end } = getSelection(el);
166
- if (start != end) {
167
- return true;
168
- }
165
+ let { start, end } = getSelection(el);
166
+ if (start != end) {
167
+ return true;
168
+ }
169
169
  }
170
170
 
171
171
  export function getElementPosition(str, start, end) {
@@ -190,11 +190,11 @@ export function getElementPosition(str, start, end) {
190
190
  type = 'insertAdjacent';
191
191
  if (!position)
192
192
  type = 'textNode';
193
- if (position == 'beforeend' && findEl.previousSibling && findEl.previousSibling.nodeType == 3 )
193
+ if (position == 'beforeend' && findEl.previousSibling && findEl.previousSibling.nodeType == 3)
194
194
  type = 'textNode';
195
195
  if (type == 'textNode' || position == 'afterbegin')
196
196
  nodeStart = start - angleEnd - 1;
197
-
197
+
198
198
  findEl.remove();
199
199
  }
200
200
  }
@@ -245,7 +245,7 @@ export function getElementPosition(str, start, end) {
245
245
  }
246
246
  }
247
247
  }
248
-
248
+
249
249
  if (element) {
250
250
  response.element = element;
251
251
  response.path = cssPath(element);
@@ -258,7 +258,7 @@ export function getElementPosition(str, start, end) {
258
258
  return response;
259
259
  }
260
260
 
261
- function getInsertPosition(element){
261
+ function getInsertPosition(element) {
262
262
  let target, position;
263
263
  let previousSibling = element.previousSibling;
264
264
  let nextSibling = element.nextSibling;
@@ -287,15 +287,15 @@ function getInsertPosition(element){
287
287
  target = element.parentElement;
288
288
  position = 'afterbegin';
289
289
  }
290
- return {target, position};
290
+ return { target, position };
291
291
  }
292
292
 
293
- export function getStringPosition({string, target, position, attribute, property, value, remove}) {
293
+ export function getStringPosition({ string, target, position, attribute, property, value, remove }) {
294
294
  try {
295
295
  let element;
296
296
  let selector = cssPath(target, '[contenteditable]');
297
297
  let dom = domParser(string);
298
- if (!selector.includes('[eid=') && dom.tagName == "DOM-PARSER"){
298
+ if (!selector.includes('[eid=') && dom.tagName == "DOM-PARSER") {
299
299
  let containerEl = document.createElement('div');
300
300
  containerEl.appendChild(dom)
301
301
  selector = `dom-parser > ${selector}`
@@ -303,26 +303,26 @@ export function getStringPosition({string, target, position, attribute, property
303
303
  }
304
304
  else
305
305
  element = dom.querySelector(selector);
306
- if (!element){
306
+ if (!element) {
307
307
  // console.log('element could not be found using selector:', selector);
308
308
  return;
309
309
  }
310
310
  let start = 0, end = 0;
311
-
311
+
312
312
  if (position) {
313
313
  if (position == 'beforebegin')
314
314
  start = getElFromString(dom, string, element, position, true);
315
315
  else
316
- start = getElFromString(dom, string, element, position);
316
+ start = getElFromString(dom, string, element, position);
317
317
  end = start;
318
318
  }
319
319
  else if (attribute) {
320
- if (!element.hasAttribute(attribute)){
321
- start = getElFromString(dom, string, element, 'afterbegin', true) - 1;
320
+ if (!element.hasAttribute(attribute)) {
321
+ start = getElFromString(dom, string, element, 'afterbegin', true) - 1;
322
322
  end = start;
323
323
  }
324
324
  else {
325
- start = getElFromString(dom, string, element, 'beforebegin');
325
+ start = getElFromString(dom, string, element, 'beforebegin');
326
326
  let elString = string.substring(start);
327
327
  let attrValue = element.getAttribute(attribute);
328
328
  let attrStart = elString.indexOf(` ${attribute}=`);
@@ -336,8 +336,8 @@ export function getStringPosition({string, target, position, attribute, property
336
336
  }
337
337
  else if (attribute == 'class') {
338
338
  let [prop, val] = value.split(':');
339
- if (prop && val){
340
- if (attrValue.includes(`${prop}:`)){
339
+ if (prop && val) {
340
+ if (attrValue.includes(`${prop}:`)) {
341
341
  let propStart = attrValue.indexOf(`${prop}:`);
342
342
  let propString = attrValue.substring(propStart);
343
343
  let propEnd = propString.indexOf(" ");
@@ -348,11 +348,11 @@ export function getStringPosition({string, target, position, attribute, property
348
348
  }
349
349
  if (!remove)
350
350
  element.classList.add(value);
351
- value = element.getAttribute(attribute);
351
+ value = element.getAttribute(attribute);
352
352
  }
353
353
  else {
354
354
  element.setAttribute(attribute, value);
355
- value = element.getAttribute(attribute);
355
+ value = element.getAttribute(attribute);
356
356
  }
357
357
  end = start + attribute.length + attrValue.length + 4;
358
358
  }
@@ -367,9 +367,9 @@ export function getStringPosition({string, target, position, attribute, property
367
367
  end = getElFromString(dom, string, element, 'afterend', true);
368
368
  }
369
369
 
370
- return {start, end, newValue: value};
370
+ return { start, end, newValue: value };
371
371
  }
372
- catch (e){
372
+ catch (e) {
373
373
  console.log(e);
374
374
  }
375
375
  }
@@ -379,56 +379,56 @@ function getElFromString(dom, string, element, position, isAttribute) {
379
379
  let start, angle, documentTypeAngles;
380
380
  if (position == 'afterbegin') {
381
381
  element.insertAdjacentElement('afterbegin', findEl);
382
- angle = '>';
382
+ angle = '>';
383
383
  }
384
384
  else if (position == 'afterend') {
385
385
  element.insertAdjacentElement('afterend', findEl);
386
- angle = '>';
386
+ angle = '>';
387
387
  }
388
- else if (position == 'beforebegin'){
388
+ else if (position == 'beforebegin') {
389
389
  element.insertAdjacentElement('afterbegin', findEl);
390
- angle = '<';
391
- }
392
- else if (position == 'beforeend'){
390
+ angle = '<';
391
+ }
392
+ else if (position == 'beforeend') {
393
393
  element.insertAdjacentElement('afterend', findEl);
394
- angle = '<';
395
- }
394
+ angle = '<';
395
+ }
396
396
  if (dom.tagName == 'HTML')
397
- start = dom.outerHTML.indexOf("<findelement></findelement>");
397
+ start = dom.outerHTML.indexOf("<findelement></findelement>");
398
398
  else
399
- start = dom.innerHTML.indexOf("<findelement></findelement>");
400
-
401
- if (start == -1){
399
+ start = dom.innerHTML.indexOf("<findelement></findelement>");
400
+
401
+ if (start == -1) {
402
402
  position = 'singleton';
403
403
  element.insertAdjacentElement('afterend', findEl);
404
404
  if (dom.tagName == 'HTML')
405
- start = dom.outerHTML.indexOf("<findelement></findelement>");
405
+ start = dom.outerHTML.indexOf("<findelement></findelement>");
406
406
  else
407
- start = dom.innerHTML.indexOf("<findelement></findelement>");
407
+ start = dom.innerHTML.indexOf("<findelement></findelement>");
408
408
  }
409
-
409
+
410
410
  findEl.remove();
411
-
411
+
412
412
  let domString = dom.outerHTML.substring(0, start);
413
413
 
414
414
  if (dom.tagName == "HTML") {
415
- let htmlIndex = string.indexOf('<html');
416
- let documentType = string.substring(0, htmlIndex);
417
- documentTypeAngles = documentType.split(angle).length -1;
415
+ let htmlIndex = string.indexOf('<html');
416
+ let documentType = string.substring(0, htmlIndex);
417
+ documentTypeAngles = documentType.split(angle).length - 1;
418
418
  }
419
419
  let angles = domString.split(angle);
420
420
  let angleLength = angles.length - 1;
421
421
  if (documentTypeAngles)
422
- angleLength += documentTypeAngles;
422
+ angleLength += documentTypeAngles;
423
423
  let elStart = getPosition(string, angle, angleLength);
424
-
425
- if (position == 'afterbegin')
424
+
425
+ if (position == 'afterbegin')
426
426
  elStart += 1;
427
427
  else if (position == 'beforeend')
428
428
  elStart += 1;
429
- else if (position == 'afterend')
429
+ else if (position == 'afterend')
430
430
  elStart += 1;
431
- else if (position == 'singleton'){
431
+ else if (position == 'singleton') {
432
432
  let newString = string.substring(0, elStart);
433
433
  if (newString.lastIndexOf('/') == newString.length - 1 && isAttribute)
434
434
  elStart;
@@ -446,4 +446,4 @@ function getPosition(string, subString, index) {
446
446
  // return string.split(subString, index).join(subString).length;
447
447
  }
448
448
 
449
- export default {getSelection, setSelection, hasSelection, processSelection, getStringPosition, getElementPosition};
449
+ export default { getSelection, setSelection, hasSelection, processSelection, getStringPosition, getElementPosition };