@livingdocs/editable.js 3.0.4 → 3.0.8
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 +19 -20
- package/src/content.js +15 -2
- package/src/cursor.js +8 -2
- package/src/plugins/highlighting/text-highlighting.js +2 -2
- package/src/selection.js +9 -1
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.0.
|
|
4
|
+
"version": "3.0.8",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@babel/runtime": "^7.13.17",
|
|
7
7
|
"bowser": "2.11.0",
|
|
@@ -9,21 +9,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.
|
|
12
|
+
"@babel/cli": "^7.15.7",
|
|
13
|
+
"@babel/core": "^7.15.8",
|
|
14
|
+
"@babel/plugin-transform-runtime": "^7.15.8",
|
|
15
|
+
"@babel/preset-env": "^7.15.8",
|
|
16
16
|
"@babel/preset-react": "^7.13.13",
|
|
17
17
|
"@esm-bundle/chai": "^4.3.4-fix.0",
|
|
18
|
-
"babel-loader": "^8.2.
|
|
18
|
+
"babel-loader": "^8.2.3",
|
|
19
19
|
"babel-plugin-add-module-exports": "^1.0.4",
|
|
20
|
-
"babel-plugin-istanbul": "^6.
|
|
21
|
-
"css-loader": "^
|
|
22
|
-
"eslint": "^7.
|
|
20
|
+
"babel-plugin-istanbul": "^6.1.1",
|
|
21
|
+
"css-loader": "^6.4.0",
|
|
22
|
+
"eslint": "^7.32.0",
|
|
23
23
|
"eslint-plugin-react": "^7.23.2",
|
|
24
24
|
"font-awesome": "^4.7.0",
|
|
25
25
|
"gh-pages": "^3.1.0",
|
|
26
|
-
"karma": "^6.3.
|
|
26
|
+
"karma": "^6.3.6",
|
|
27
27
|
"karma-chrome-launcher": "^3.1.0",
|
|
28
28
|
"karma-coverage": "^2.0.3",
|
|
29
29
|
"karma-firefox-launcher": "^2.1.0",
|
|
@@ -31,9 +31,9 @@
|
|
|
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.1.3",
|
|
35
35
|
"normalize.css": "^8.0.1",
|
|
36
|
-
"prismjs": "^1.
|
|
36
|
+
"prismjs": "^1.25.0",
|
|
37
37
|
"react": "^17.0.2",
|
|
38
38
|
"react-dom": "^17.0.2",
|
|
39
39
|
"react-transition-group": "^4.4.1",
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"sinon": "^10.0.0",
|
|
42
42
|
"style-loader": "^2.0.0",
|
|
43
43
|
"url-loader": "^4.1.1",
|
|
44
|
-
"webpack": "^5.
|
|
45
|
-
"webpack-cli": "^4.
|
|
46
|
-
"webpack-dev-server": "^4.
|
|
44
|
+
"webpack": "^5.60.0",
|
|
45
|
+
"webpack-cli": "^4.9.1",
|
|
46
|
+
"webpack-dev-server": "^4.3.1"
|
|
47
47
|
},
|
|
48
48
|
"engines": {
|
|
49
49
|
"node": ">=12"
|
|
@@ -74,8 +74,7 @@
|
|
|
74
74
|
"test:all": "npm run test:karma -s -- --browsers Chrome,Firefox,Safari",
|
|
75
75
|
"test:karma": "karma start",
|
|
76
76
|
"test:watch": "npm run test:karma -s -- --single-run false",
|
|
77
|
-
"lint": "eslint --ignore-path .gitignore ."
|
|
78
|
-
"postversion": "/release/node_modules/.bin/set-ci"
|
|
77
|
+
"lint": "eslint --ignore-path .gitignore ."
|
|
79
78
|
},
|
|
80
79
|
"release": {
|
|
81
80
|
"extends": "@livingdocs/semantic-release-presets/npm-github-verify"
|
|
@@ -84,11 +83,11 @@
|
|
|
84
83
|
"isCi": true,
|
|
85
84
|
"name": "Drone",
|
|
86
85
|
"service": "drone",
|
|
87
|
-
"commit": "
|
|
88
|
-
"build": "
|
|
86
|
+
"commit": "e4c7383e5620ccbb13b71e155a8f26d5f245b64d",
|
|
87
|
+
"build": "398",
|
|
89
88
|
"branch": "master",
|
|
90
89
|
"isPr": false,
|
|
91
90
|
"slug": "livingdocsIO/editable.js",
|
|
92
|
-
"date": "2021-
|
|
91
|
+
"date": "2021-12-15T14:59:21.802Z"
|
|
93
92
|
}
|
|
94
93
|
}
|
package/src/content.js
CHANGED
|
@@ -29,6 +29,12 @@ export function tidyHtml (element) {
|
|
|
29
29
|
export function normalizeTags (element) {
|
|
30
30
|
const fragment = document.createDocumentFragment()
|
|
31
31
|
|
|
32
|
+
// Remove line breaks at the beginning of a content block
|
|
33
|
+
removeWhitespaces(element, 'firstChild')
|
|
34
|
+
|
|
35
|
+
// Remove line breaks at the end of a content block
|
|
36
|
+
removeWhitespaces(element, 'lastChild')
|
|
37
|
+
|
|
32
38
|
for (const node of element.childNodes) {
|
|
33
39
|
// skip empty tags, so they'll get removed
|
|
34
40
|
if (node.nodeName !== 'BR' && !node.textContent) continue
|
|
@@ -136,7 +142,7 @@ export function cloneRangeContents (range) {
|
|
|
136
142
|
return fragment
|
|
137
143
|
}
|
|
138
144
|
|
|
139
|
-
function removeWhitespaces (node, type) {
|
|
145
|
+
function removeWhitespaces (node, type, firstCall = true) {
|
|
140
146
|
let elem
|
|
141
147
|
while ((elem = node[type])) {
|
|
142
148
|
if (elem.nodeType === nodeType.textNode) {
|
|
@@ -145,10 +151,17 @@ function removeWhitespaces (node, type) {
|
|
|
145
151
|
} else if (elem.nodeName === 'BR') {
|
|
146
152
|
elem.remove()
|
|
147
153
|
} else {
|
|
148
|
-
if (elem[type]) removeWhitespaces(elem, type)
|
|
154
|
+
if (elem[type]) removeWhitespaces(elem, type, false)
|
|
149
155
|
break
|
|
150
156
|
}
|
|
151
157
|
}
|
|
158
|
+
|
|
159
|
+
if (!firstCall) return
|
|
160
|
+
elem = node[type]
|
|
161
|
+
if (elem?.nodeType !== nodeType.textNode) return
|
|
162
|
+
// Remove whitespaces at the end or start of a block with content
|
|
163
|
+
// e.g. ' Hello world' > 'Hello World'
|
|
164
|
+
elem.textContent = elem.textContent.replace(type.startsWith('last') ? /\s+$/ : /^\s+/, '')
|
|
152
165
|
}
|
|
153
166
|
|
|
154
167
|
// Remove elements that were inserted for internal or user interface purposes
|
package/src/cursor.js
CHANGED
|
@@ -96,7 +96,7 @@ export default class Cursor {
|
|
|
96
96
|
hostRange.collapse(false)
|
|
97
97
|
const hostCoords = getRangeBoundingClientRect(hostRange, this.win)
|
|
98
98
|
const cursorCoords = getRangeBoundingClientRect(this.range.nativeRange, this.win)
|
|
99
|
-
return hostCoords.bottom
|
|
99
|
+
return isCloseTo(hostCoords.bottom, cursorCoords.bottom)
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
isAtFirstLine () {
|
|
@@ -105,7 +105,7 @@ export default class Cursor {
|
|
|
105
105
|
hostRange.collapse(true)
|
|
106
106
|
const hostCoords = getRangeBoundingClientRect(hostRange, this.win)
|
|
107
107
|
const cursorCoords = getRangeBoundingClientRect(this.range.nativeRange, this.win)
|
|
108
|
-
return hostCoords.top
|
|
108
|
+
return isCloseTo(hostCoords.top, cursorCoords.top)
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
isAtBeginning () {
|
|
@@ -368,3 +368,9 @@ function getRangeBoundingClientRect (range, win) {
|
|
|
368
368
|
el.remove()
|
|
369
369
|
return coords
|
|
370
370
|
}
|
|
371
|
+
|
|
372
|
+
function isCloseTo (a, b) {
|
|
373
|
+
if (a === b) return true
|
|
374
|
+
if (Math.abs(a - b) <= 2) return true
|
|
375
|
+
return false
|
|
376
|
+
}
|
|
@@ -9,8 +9,8 @@ export default class WordHighlighting {
|
|
|
9
9
|
|
|
10
10
|
isElement (obj) {
|
|
11
11
|
try {
|
|
12
|
-
|
|
13
|
-
return obj instanceof HTMLElement
|
|
12
|
+
if (!obj) return false
|
|
13
|
+
return obj instanceof obj.ownerDocument?.defaultView.HTMLElement
|
|
14
14
|
} catch (e) {
|
|
15
15
|
// Browsers not supporting W3 DOM2 don't have HTMLElement and
|
|
16
16
|
// an exception is thrown and we end up here. Testing some
|
package/src/selection.js
CHANGED
|
@@ -78,7 +78,15 @@ export default class Selection extends Cursor {
|
|
|
78
78
|
link (href, attrs = {}) {
|
|
79
79
|
if (href) attrs.href = href
|
|
80
80
|
const link = this.createElement(config.linkMarkup.name, config.linkMarkup.attribs)
|
|
81
|
-
for (const key in attrs)
|
|
81
|
+
for (const key in attrs) {
|
|
82
|
+
const value = attrs[key]
|
|
83
|
+
if (value === undefined) continue
|
|
84
|
+
if (value === null) {
|
|
85
|
+
link.removeAttribute(key)
|
|
86
|
+
} else {
|
|
87
|
+
link.setAttribute(key, value)
|
|
88
|
+
}
|
|
89
|
+
}
|
|
82
90
|
this.forceWrap(link)
|
|
83
91
|
}
|
|
84
92
|
|