@livingdocs/editable.js 3.0.14 → 3.1.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/dist/editable.js +1 -1
- package/dist/editable.js.map +1 -1
- package/package.json +4 -4
- package/src/config.js +1 -0
- package/src/content.js +4 -1
- package/src/dispatcher.js +7 -1
- package/src/highlight-text.js +2 -2
- package/src/selection.js +4 -4
- package/src/util/string.js +18 -0
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.1.0",
|
|
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": "2e7b8ed5efd8fb418a159ded67be45ddf9941999",
|
|
87
|
+
"build": "482",
|
|
88
88
|
"branch": "master",
|
|
89
89
|
"isPr": false,
|
|
90
90
|
"slug": "livingdocsIO/editable.js",
|
|
91
|
-
"date": "2022-
|
|
91
|
+
"date": "2022-03-22T20:40:52.111Z"
|
|
92
92
|
}
|
|
93
93
|
}
|
package/src/config.js
CHANGED
package/src/content.js
CHANGED
|
@@ -4,6 +4,7 @@ import * as rangeSaveRestore from './range-save-restore'
|
|
|
4
4
|
import * as parser from './parser'
|
|
5
5
|
import * as string from './util/string'
|
|
6
6
|
import {createElement} from './util/dom'
|
|
7
|
+
import config from './config'
|
|
7
8
|
|
|
8
9
|
function restoreRange (host, range, func) {
|
|
9
10
|
range = rangeSaveRestore.save(range)
|
|
@@ -161,7 +162,9 @@ function removeWhitespaces (node, type, firstCall = true) {
|
|
|
161
162
|
if (elem?.nodeType !== nodeType.textNode) return
|
|
162
163
|
// Remove whitespaces at the end or start of a block with content
|
|
163
164
|
// e.g. ' Hello world' > 'Hello World'
|
|
164
|
-
|
|
165
|
+
if (config.trimLeadingAndTrailingWhitespaces) {
|
|
166
|
+
elem.textContent = elem.textContent.replace(type.startsWith('last') ? / +$/ : /^ +/, '')
|
|
167
|
+
}
|
|
165
168
|
}
|
|
166
169
|
|
|
167
170
|
// Remove elements that were inserted for internal or user interface purposes
|
package/src/dispatcher.js
CHANGED
|
@@ -5,6 +5,7 @@ import SelectionWatcher from './selection-watcher'
|
|
|
5
5
|
import config from './config'
|
|
6
6
|
import Keyboard from './keyboard'
|
|
7
7
|
import {closest} from './util/dom'
|
|
8
|
+
import {replaceLast, endsWithSingleSpace} from './util/string'
|
|
8
9
|
|
|
9
10
|
// This will be set to true once we detect the input event is working.
|
|
10
11
|
// Input event description on MDN:
|
|
@@ -134,7 +135,12 @@ export default class Dispatcher {
|
|
|
134
135
|
|
|
135
136
|
const {blocks, cursor} = clipboard.paste(block, selection, clipboardContent)
|
|
136
137
|
if (blocks.length) {
|
|
137
|
-
|
|
138
|
+
if (endsWithSingleSpace(evt.target.innerText)) {
|
|
139
|
+
block.innerHTML = replaceLast(block.innerHTML, ' ', ' ')
|
|
140
|
+
this.notify('paste', block, blocks, this.editable.createCursorAtEnd(block))
|
|
141
|
+
} else {
|
|
142
|
+
this.notify('paste', block, blocks, cursor)
|
|
143
|
+
}
|
|
138
144
|
|
|
139
145
|
// The input event does not fire when we process the content manually
|
|
140
146
|
// and insert it via script
|
package/src/highlight-text.js
CHANGED
|
@@ -134,7 +134,7 @@ export default {
|
|
|
134
134
|
// This has two notable behaviours:
|
|
135
135
|
// - It uses a NodeIterator which will skip elements
|
|
136
136
|
// with data-editable="remove"
|
|
137
|
-
// - It returns a
|
|
137
|
+
// - It returns a \n for <br> elements
|
|
138
138
|
// (The only block level element allowed inside of editables)
|
|
139
139
|
function getText (element, callback) {
|
|
140
140
|
const iterator = new NodeIterator(element)
|
|
@@ -143,7 +143,7 @@ function getText (element, callback) {
|
|
|
143
143
|
if (next.nodeType === nodeType.textNode && next.data !== '') {
|
|
144
144
|
callback(next.data)
|
|
145
145
|
} else if (next.nodeType === nodeType.elementNode && next.nodeName === 'BR') {
|
|
146
|
-
callback('
|
|
146
|
+
callback('\n')
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
}
|
package/src/selection.js
CHANGED
|
@@ -94,10 +94,10 @@ export default class Selection extends Cursor {
|
|
|
94
94
|
|
|
95
95
|
// trims whitespaces on the left and right of a selection, i.e. what you want in case of links
|
|
96
96
|
trimRange () {
|
|
97
|
-
const
|
|
98
|
-
const whitespacesOnTheLeft =
|
|
99
|
-
const lastNonWhitespace =
|
|
100
|
-
const whitespacesOnTheRight = lastNonWhitespace === -1 ? 0 :
|
|
97
|
+
const textToTrim = this.range.toString()
|
|
98
|
+
const whitespacesOnTheLeft = textToTrim.search(/\S|$/)
|
|
99
|
+
const lastNonWhitespace = textToTrim.search(/\S[\s]+$/)
|
|
100
|
+
const whitespacesOnTheRight = lastNonWhitespace === -1 ? 0 : textToTrim.length - (lastNonWhitespace + 1)
|
|
101
101
|
this.range.setStart(this.range.startContainer, this.range.startOffset + whitespacesOnTheLeft)
|
|
102
102
|
this.range.setEnd(this.range.endContainer, this.range.endOffset - whitespacesOnTheRight)
|
|
103
103
|
}
|
package/src/util/string.js
CHANGED
|
@@ -61,3 +61,21 @@ export function browserEscapeHtml (str) {
|
|
|
61
61
|
div.appendChild(document.createTextNode(str))
|
|
62
62
|
return div.innerHTML
|
|
63
63
|
}
|
|
64
|
+
|
|
65
|
+
export function replaceLast (text, searchValue, replaceValue) {
|
|
66
|
+
if (!text) return ''
|
|
67
|
+
text = `${text}`
|
|
68
|
+
if (!searchValue || replaceValue == null) return text
|
|
69
|
+
const lastOccurrenceIndex = text.lastIndexOf(searchValue)
|
|
70
|
+
return `${
|
|
71
|
+
text.slice(0, lastOccurrenceIndex)
|
|
72
|
+
}${
|
|
73
|
+
replaceValue
|
|
74
|
+
}${
|
|
75
|
+
text.slice(lastOccurrenceIndex + searchValue.length)
|
|
76
|
+
}`
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function endsWithSingleSpace (text) {
|
|
80
|
+
return /\S+\s{1}$/.test(text)
|
|
81
|
+
}
|