@livingdocs/editable.js 3.0.9 → 3.0.13
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 +26 -26
- package/src/range-save-restore.js +39 -5
package/package.json
CHANGED
|
@@ -1,49 +1,49 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@livingdocs/editable.js",
|
|
3
3
|
"description": "Friendly contenteditable API",
|
|
4
|
-
"version": "3.0.
|
|
4
|
+
"version": "3.0.13",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@babel/runtime": "^7.
|
|
6
|
+
"@babel/runtime": "^7.16.7",
|
|
7
7
|
"bowser": "2.11.0",
|
|
8
8
|
"lodash-es": "^4.17.21",
|
|
9
9
|
"rangy": "^1.3.0"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
|
-
"@babel/cli": "^7.
|
|
13
|
-
"@babel/core": "^7.
|
|
14
|
-
"@babel/plugin-transform-runtime": "^7.
|
|
15
|
-
"@babel/preset-env": "^7.
|
|
16
|
-
"@babel/preset-react": "^7.
|
|
17
|
-
"@esm-bundle/chai": "^4.3.4-fix.0",
|
|
12
|
+
"@babel/cli": "^7.16.8",
|
|
13
|
+
"@babel/core": "^7.16.12",
|
|
14
|
+
"@babel/plugin-transform-runtime": "^7.16.10",
|
|
15
|
+
"@babel/preset-env": "^7.16.11",
|
|
16
|
+
"@babel/preset-react": "^7.16.7",
|
|
18
17
|
"babel-loader": "^8.2.3",
|
|
19
18
|
"babel-plugin-add-module-exports": "^1.0.4",
|
|
20
19
|
"babel-plugin-istanbul": "^6.1.1",
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"eslint
|
|
20
|
+
"chai": "^4.3.6",
|
|
21
|
+
"css-loader": "^6.5.1",
|
|
22
|
+
"eslint": "^8.8.0",
|
|
23
|
+
"eslint-plugin-react": "^7.28.0",
|
|
24
24
|
"font-awesome": "^4.7.0",
|
|
25
|
-
"gh-pages": "^3.
|
|
26
|
-
"karma": "^6.3.
|
|
25
|
+
"gh-pages": "^3.2.3",
|
|
26
|
+
"karma": "^6.3.13",
|
|
27
27
|
"karma-chrome-launcher": "^3.1.0",
|
|
28
|
-
"karma-coverage": "^2.0
|
|
29
|
-
"karma-firefox-launcher": "^2.1.
|
|
28
|
+
"karma-coverage": "^2.1.0",
|
|
29
|
+
"karma-firefox-launcher": "^2.1.2",
|
|
30
30
|
"karma-mocha": "^2.0.1",
|
|
31
31
|
"karma-safari-launcher": "^1.0.0",
|
|
32
32
|
"karma-sourcemap-loader": "^0.3.8",
|
|
33
33
|
"karma-webpack": "^5.0.0",
|
|
34
|
-
"mocha": "^9.
|
|
34
|
+
"mocha": "^9.2.0",
|
|
35
35
|
"normalize.css": "^8.0.1",
|
|
36
|
-
"prismjs": "^1.
|
|
36
|
+
"prismjs": "^1.26.0",
|
|
37
37
|
"react": "^17.0.2",
|
|
38
38
|
"react-dom": "^17.0.2",
|
|
39
|
-
"react-transition-group": "^4.4.
|
|
39
|
+
"react-transition-group": "^4.4.2",
|
|
40
40
|
"rimraf": "^3.0.2",
|
|
41
|
-
"sinon": "^
|
|
42
|
-
"style-loader": "^
|
|
41
|
+
"sinon": "^13.0.0",
|
|
42
|
+
"style-loader": "^3.3.1",
|
|
43
43
|
"url-loader": "^4.1.1",
|
|
44
|
-
"webpack": "^5.
|
|
45
|
-
"webpack-cli": "^4.9.
|
|
46
|
-
"webpack-dev-server": "^4.3
|
|
44
|
+
"webpack": "^5.68.0",
|
|
45
|
+
"webpack-cli": "^4.9.2",
|
|
46
|
+
"webpack-dev-server": "^4.7.3"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=12"
|
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
"isCi": true,
|
|
84
84
|
"name": "Drone",
|
|
85
85
|
"service": "drone",
|
|
86
|
-
"commit": "
|
|
87
|
-
"build": "
|
|
86
|
+
"commit": "4447c61e9237a173cb2513cb00e3d620a7c0e26c",
|
|
87
|
+
"build": "429",
|
|
88
88
|
"branch": "master",
|
|
89
89
|
"isPr": false,
|
|
90
90
|
"slug": "livingdocsIO/editable.js",
|
|
91
|
-
"date": "
|
|
91
|
+
"date": "2022-02-01T12:17:05.512Z"
|
|
92
92
|
}
|
|
93
93
|
}
|
|
@@ -11,17 +11,37 @@ let boundaryMarkerId = 0
|
|
|
11
11
|
// (U+FEFF) zero width no-break space
|
|
12
12
|
const markerTextChar = '\ufeff'
|
|
13
13
|
|
|
14
|
+
function isChildOf (parent, possibleChild) {
|
|
15
|
+
for (let i = 0; i < parent.children.length; i++) {
|
|
16
|
+
if (parent.children[i] === possibleChild) return true
|
|
17
|
+
}
|
|
18
|
+
return false
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function startContainerIsChild (range) {
|
|
22
|
+
const parent = range.commonAncestorContainer
|
|
23
|
+
if (parent.nodeType === 3) return false // if we are on the text node it can't be a parent
|
|
24
|
+
const possibleChild = range.startContainer.parentElement
|
|
25
|
+
return isChildOf(parent, possibleChild)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function endContainerIsChild (range) {
|
|
29
|
+
const parent = range.commonAncestorContainer
|
|
30
|
+
if (parent.nodeType === 3) return false // if we are on the text node it can't be a parent
|
|
31
|
+
const possibleChild = range.endContainer.parentElement
|
|
32
|
+
return isChildOf(parent, possibleChild)
|
|
33
|
+
}
|
|
34
|
+
|
|
14
35
|
export function insertRangeBoundaryMarker (range, atStart) {
|
|
15
36
|
const container = range.commonAncestorContainer
|
|
37
|
+
const directlyBeforeFormatTag = startContainerIsChild(range) && atStart
|
|
38
|
+
const directlyAfterFormatTag = endContainerIsChild(range) && !atStart
|
|
39
|
+
|
|
16
40
|
// If ownerDocument is null the commonAncestorContainer is window.document
|
|
17
41
|
if (container.ownerDocument === null || container.ownerDocument === undefined) {
|
|
18
42
|
error('Cannot save range: range is emtpy')
|
|
19
43
|
}
|
|
20
44
|
|
|
21
|
-
// Clone the Range and collapse to the appropriate boundary point
|
|
22
|
-
const boundaryRange = range.cloneRange()
|
|
23
|
-
boundaryRange.collapse(atStart)
|
|
24
|
-
|
|
25
45
|
// Create the marker element containing a single
|
|
26
46
|
// invisible character using DOM methods and insert it
|
|
27
47
|
const doc = container.ownerDocument.defaultView.document
|
|
@@ -32,7 +52,21 @@ export function insertRangeBoundaryMarker (range, atStart) {
|
|
|
32
52
|
markerEl.style.display = 'none'
|
|
33
53
|
markerEl.appendChild(doc.createTextNode(markerTextChar))
|
|
34
54
|
|
|
35
|
-
|
|
55
|
+
// if another tag is trailing exactly at the start or end, prepend
|
|
56
|
+
// or append the marker element directly on the parent in order to prevent breaking HTML markup.
|
|
57
|
+
if (directlyBeforeFormatTag) {
|
|
58
|
+
range.endContainer.parentElement.insertBefore(markerEl, range.startContainer.parentElement)
|
|
59
|
+
} else if (directlyAfterFormatTag) {
|
|
60
|
+
// emulating insertAfter with nextSibling
|
|
61
|
+
range.startContainer.parentElement.insertBefore(markerEl,
|
|
62
|
+
range.endContainer.parentElement.nextSibling)
|
|
63
|
+
} else {
|
|
64
|
+
// Clone the Range and collapse to the appropriate boundary point
|
|
65
|
+
const boundaryRange = range.cloneRange()
|
|
66
|
+
boundaryRange.collapse(atStart)
|
|
67
|
+
boundaryRange.insertNode(markerEl)
|
|
68
|
+
}
|
|
69
|
+
|
|
36
70
|
return markerEl
|
|
37
71
|
}
|
|
38
72
|
|