@cocreate/selection 1.6.28 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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 };