Skip to content

Commit 11039c7

Browse files
committed
fix(focus): Use a null escape character instead of a br tag for focused elements
This makes editable elements more compatible with inline styles
1 parent c3125b4 commit 11039c7

File tree

3 files changed

+39
-7
lines changed

3 files changed

+39
-7
lines changed

spec/dispatcher.spec.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,39 @@ describe('Dispatcher', function () {
7171
editable.unload()
7272
})
7373

74-
describe('on Enter', function () {
74+
describe('on focus', function () {
75+
it('should trigger the focus event', function () {
76+
elem.blur()
77+
const focus = on('focus', function (element) {
78+
expect(element).toEqual(elem)
79+
})
80+
elem.focus()
81+
expect(focus.calls).toBe(1)
82+
})
83+
84+
it('should contain an empty textnode', function () {
85+
elem.blur()
86+
expect(elem.textContent).toEqual('')
87+
elem.focus()
88+
expect(elem.textContent).toEqual('\u0000')
89+
})
90+
91+
it('should not add an empty text node if there is content', function () {
92+
elem.blur()
93+
elem.appendChild(document.createTextNode('Hello'))
94+
elem.focus()
95+
expect(elem.textContent).toEqual('Hello')
96+
})
97+
98+
it('removes the empty text node again on blur', function () {
99+
elem.focus()
100+
expect(elem.textContent).toEqual('\u0000')
101+
elem.blur()
102+
expect(elem.textContent).toEqual('')
103+
})
104+
})
105+
106+
describe('on enter', function () {
75107

76108
beforeEach(function () {
77109
event = new Event('keydown')

src/content.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ function restoreRange (host, range, func) {
1414
const zeroWidthSpace = /\u200B/g
1515
const zeroWidthNonBreakingSpace = /\uFEFF/g
1616
const whitespaceExceptSpace = /[^\S ]/g
17+
const nullEscapeCharacter = /\u0000/g // eslint-disable-line no-control-regex
1718

1819
// Clean up the Html.
1920
export function tidyHtml (element) {
@@ -83,6 +84,7 @@ export function extractContent (element, keepUiElements) {
8384
? getInnerHtmlOfFragment(element)
8485
: element.innerHTML
8586
)
87+
.replace(nullEscapeCharacter, '') // Used to generate empty text nodes on focus event.
8688
.replace(zeroWidthNonBreakingSpace, '') // Used for forcing inline elements to have a height
8789
.replace(zeroWidthSpace, '<br>') // Used for cross-browser newlines
8890

src/create-default-behavior.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,11 @@ export default function createDefaultBehavior (editable) {
2424

2525
return {
2626
focus (element) {
27-
// Add a <br> element if the editable is empty to force it to have height
28-
// E.g. Firefox does not render empty block elements and most browsers do
29-
// not render empty inline elements.
27+
// Add an empty text node if the editable is empty to force it to have height
28+
// E.g. Firefox does not render empty block elements
29+
// and most browsers do not render empty inline elements.
3030
if (!parser.isVoid(element)) return
31-
const br = document.createElement('br')
32-
br.setAttribute('data-editable', 'remove')
33-
element.appendChild(br)
31+
element.appendChild(document.createTextNode('\u0000'))
3432
},
3533

3634
blur (element) {

0 commit comments

Comments
 (0)