@livingdocs/editable.js 3.1.2 → 3.1.4
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/dist/editable.js +1 -1
- package/dist/editable.js.map +1 -1
- package/package.json +4 -4
- package/src/clipboard.js +5 -1
- package/src/content.js +6 -0
- package/src/create-default-behavior.js +7 -0
- package/src/cursor.js +5 -0
- package/src/selection.js +25 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livingdocs/editable.js",
|
|
3
3
|
"description": "Friendly contenteditable API",
|
|
4
|
-
"version": "3.1.
|
|
4
|
+
"version": "3.1.4",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@babel/runtime": "^7.16.7",
|
|
7
7
|
"bowser": "2.11.0",
|
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
"isCi": true,
|
|
84
84
|
"name": "Drone",
|
|
85
85
|
"service": "drone",
|
|
86
|
-
"commit": "
|
|
87
|
-
"build": "
|
|
86
|
+
"commit": "8e2e6d9f59d4c8c9eddcf611b70be10faccb60ca",
|
|
87
|
+
"build": "556",
|
|
88
88
|
"branch": "master",
|
|
89
89
|
"isPr": false,
|
|
90
90
|
"slug": "livingdocsIO/editable.js",
|
|
91
|
-
"date": "2022-
|
|
91
|
+
"date": "2022-12-13T12:35:19.990Z"
|
|
92
92
|
}
|
|
93
93
|
}
|
package/src/clipboard.js
CHANGED
|
@@ -29,7 +29,11 @@ export function paste (element, cursor, clipboardContent) {
|
|
|
29
29
|
const document = element.ownerDocument
|
|
30
30
|
element.setAttribute(config.pastingAttribute, true)
|
|
31
31
|
|
|
32
|
-
if (cursor.isSelection)
|
|
32
|
+
if (cursor.isSelection) {
|
|
33
|
+
cursor = cursor.deleteExactSurroundingTags()
|
|
34
|
+
.deleteContainedTags()
|
|
35
|
+
.deleteContent()
|
|
36
|
+
}
|
|
33
37
|
|
|
34
38
|
// Create a placeholder to help parse HTML
|
|
35
39
|
const pasteHolder = document.createElement('div')
|
package/src/content.js
CHANGED
|
@@ -244,6 +244,12 @@ export function getInnerTags (range, filterFunc) {
|
|
|
244
244
|
return range.getNodes([nodeType.elementNode], filterFunc)
|
|
245
245
|
}
|
|
246
246
|
|
|
247
|
+
// Get all tags whose text is completely within the current selection.
|
|
248
|
+
export function getContainedTags (range, filterFunc) {
|
|
249
|
+
return range.getNodes([nodeType.elementNode], filterFunc)
|
|
250
|
+
.filter(elem => range.containsNodeText(elem))
|
|
251
|
+
}
|
|
252
|
+
|
|
247
253
|
// Transform an array of elements into an array
|
|
248
254
|
// of tagnames in uppercase
|
|
249
255
|
//
|
|
@@ -35,6 +35,13 @@ export default function createDefaultBehavior (editable) {
|
|
|
35
35
|
},
|
|
36
36
|
|
|
37
37
|
blur (element) {
|
|
38
|
+
// Note: there is a special case when the tab is changed where
|
|
39
|
+
// we can get a blur event even if the cursor is still in the editable.
|
|
40
|
+
// This blur would cause us to loose the cursor position (cause of cleanInternals()).
|
|
41
|
+
// To prevent this we check if the activeElement is still the editable.
|
|
42
|
+
// (Note: document.getSelection() did not work reliably in this case.)
|
|
43
|
+
if (document.activeElement === element) return
|
|
44
|
+
|
|
38
45
|
content.cleanInternals(element)
|
|
39
46
|
},
|
|
40
47
|
|
package/src/cursor.js
CHANGED
|
@@ -69,6 +69,11 @@ export default class Cursor {
|
|
|
69
69
|
return content.getInnerTags(this.range, filterFunc)
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
// Get all tags whose text is completely within the current selection.
|
|
73
|
+
getContainedTags (filterFunc) {
|
|
74
|
+
return content.getContainedTags(this.range, filterFunc)
|
|
75
|
+
}
|
|
76
|
+
|
|
72
77
|
// Get all tags that surround the current selection.
|
|
73
78
|
getAncestorTags (filterFunc) {
|
|
74
79
|
return content.getAncestorTags(this.host, this.range, filterFunc)
|
package/src/selection.js
CHANGED
|
@@ -245,8 +245,31 @@ export default class Selection extends Cursor {
|
|
|
245
245
|
this.setSelection()
|
|
246
246
|
}
|
|
247
247
|
|
|
248
|
-
// Delete the
|
|
249
|
-
//
|
|
248
|
+
// Delete the farest ancestor that is an exact selection
|
|
249
|
+
//
|
|
250
|
+
// @return Selection instance
|
|
251
|
+
deleteExactSurroundingTags () {
|
|
252
|
+
const ancestorTags = this.getAncestorTags().reverse()
|
|
253
|
+
for (const ancestorTag of ancestorTags) {
|
|
254
|
+
if (this.isExactSelection(ancestorTag)) {
|
|
255
|
+
ancestorTag.remove()
|
|
256
|
+
break
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return new Selection(this.host, this.range)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Delete all the tags whose text is completely within the current selection.
|
|
263
|
+
//
|
|
264
|
+
// @return Selection instance
|
|
265
|
+
deleteContainedTags () {
|
|
266
|
+
const containedTags = this.getContainedTags()
|
|
267
|
+
containedTags.forEach(containedTag => containedTag.remove())
|
|
268
|
+
return new Selection(this.host, this.range)
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Delete the contents inside the range and exact surrounding markups.
|
|
272
|
+
// After that the selection will be a cursor.
|
|
250
273
|
//
|
|
251
274
|
// @return Cursor instance
|
|
252
275
|
deleteContent () {
|