Skip to content

Commit 4c84521

Browse files
committed
fix(content): Prevent DOM mutation when calling getInnerHtmlOfFragment
1 parent 7223d46 commit 4c84521

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

spec/content.spec.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -552,6 +552,29 @@ describe('Content', function () {
552552
})
553553
})
554554

555+
describe('getInnerHtmlOfFragment()', function () {
556+
557+
it('returns the html content of a fragment', function () {
558+
const fragment = content.createFragmentFromString('<b>bold</b> text')
559+
expect(content.getInnerHtmlOfFragment(fragment)).to.equal('<b>bold</b> text')
560+
})
561+
562+
// Prevent regression where the child nodes were moved instead of cloned
563+
it('does not mutate the fragment when called', function () {
564+
const fragment = content.createFragmentFromString('hello')
565+
content.getInnerHtmlOfFragment(fragment)
566+
expect(fragment.childNodes.length).to.be.greaterThan(0)
567+
})
568+
569+
it('returns consistent results when called multiple times', function () {
570+
const fragment = content.createFragmentFromString('<b>bold</b> text')
571+
const first = content.getInnerHtmlOfFragment(fragment)
572+
const second = content.getInnerHtmlOfFragment(fragment)
573+
expect(first).to.equal('<b>bold</b> text')
574+
expect(second).to.equal('<b>bold</b> text')
575+
})
576+
})
577+
555578
describe('extractContent()', function () {
556579
it('extracts the content', function () {
557580
const element = createElement('<div>a</div>')

spec/dispatcher.spec.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,9 @@ describe('Dispatcher:', function () {
154154
expect(content.getInnerHtmlOfFragment(before)).to.equal('ba')
155155
expect(content.getInnerHtmlOfFragment(after)).to.equal('r')
156156
expect(cursor.isCursor).to.equal(true)
157+
// Check again to avoid regression (DOM was mutated)
158+
expect(content.getInnerHtmlOfFragment(before)).to.equal('ba')
159+
expect(content.getInnerHtmlOfFragment(after)).to.equal('r')
157160
})
158161

159162
const evt = new KeyboardEvent('keydown', {keyCode: key.enter})

src/content.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,10 @@ export function extractContent (element, keepUiElements) {
110110
}
111111

112112
export function getInnerHtmlOfFragment (documentFragment) {
113+
const deep = true
114+
const clonedDocumentFragment = documentFragment.cloneNode(deep)
113115
const div = document.createElement('div')
114-
div.appendChild(documentFragment)
116+
div.appendChild(clonedDocumentFragment)
115117
return div.innerHTML
116118
}
117119

0 commit comments

Comments
 (0)