Skip to content

Commit 0421326

Browse files
committed
Merge pull request #58 from upfrontIO/bug-empty-document-fragment
Bug: Cursor#insertAfter and #insertBefore throw errors for empty documentFragments
2 parents c07d977 + 0635838 commit 0421326

File tree

4 files changed

+71
-2
lines changed

4 files changed

+71
-2
lines changed

spec/cursor.spec.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,14 @@ describe('Cursor', function() {
2727
});
2828

2929
describe('isAtEnd()', function() {
30+
3031
it('is true', function() {
3132
expect(this.cursor.isAtEnd()).toBe(true);
3233
});
3334
});
3435

3536
describe('isAtBeginning()', function() {
37+
3638
it('is false', function() {
3739
expect(this.cursor.isAtBeginning()).toBe(false);
3840
});
@@ -51,6 +53,28 @@ describe('Cursor', function() {
5153
expect(this.cursor.isAtEnd()).toBe(true);
5254
});
5355
});
54-
});
5556

57+
describe('insertAfter()', function() {
58+
59+
it('can deal with an empty documentFragment', function() {
60+
var test = function() {
61+
var frag = window.document.createDocumentFragment();
62+
this.cursor.insertAfter(frag);
63+
}
64+
expect($.proxy(test, this)).not.toThrow();
65+
});
66+
});
67+
68+
describe('insertBefore()', function() {
69+
70+
it('can deal with an empty documentFragment', function() {
71+
var test = function() {
72+
var frag = window.document.createDocumentFragment();
73+
this.cursor.insertBefore(frag);
74+
}
75+
expect($.proxy(test, this)).not.toThrow();
76+
});
77+
});
78+
79+
});
5680
});

spec/parser.spec.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,3 +361,29 @@ describe('Parser', function() {
361361
});
362362

363363
});
364+
365+
describe('isDocumentFragmentWithoutChildren()', function() {
366+
367+
beforeEach(function() {
368+
this.frag = window.document.createDocumentFragment();
369+
});
370+
371+
it('returns truthy for a fragment with no children', function() {
372+
expect(parser.isDocumentFragmentWithoutChildren(this.frag)).toBeTruthy()
373+
});
374+
375+
it('returns falsy for a documentFragment with an empty text node as child', function() {
376+
this.frag.appendChild(window.document.createTextNode());
377+
expect(parser.isDocumentFragmentWithoutChildren(this.frag)).toBeFalsy()
378+
});
379+
380+
it('returns falsy for undefined', function() {
381+
expect(parser.isDocumentFragmentWithoutChildren(undefined)).toBeFalsy()
382+
});
383+
384+
it('returns falsy for an element node', function() {
385+
var node = $('<div>')[0];
386+
expect(parser.isDocumentFragmentWithoutChildren(node)).toBeFalsy()
387+
});
388+
389+
});

src/cursor.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ var Cursor = (function() {
4848
* @param DOM node or document fragment
4949
*/
5050
insertBefore: function(element) {
51-
var preceedingElement = element;
51+
if (parser.isDocumentFragmentWithoutChildren(element)) return;
5252

53+
var preceedingElement = element;
5354
if (element.nodeType === 11) { // DOCUMENT_FRAGMENT_NODE
5455
var lastIndex = element.childNodes.length - 1;
5556
preceedingElement = element.childNodes[lastIndex];
@@ -66,6 +67,7 @@ var Cursor = (function() {
6667
* @param DOM node or document fragment
6768
*/
6869
insertAfter: function(element) {
70+
if (parser.isDocumentFragmentWithoutChildren(element)) return;
6971
this.range.insertNode(element);
7072
},
7173

src/parser.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,23 @@ var parser = (function() {
252252
return this.latestChild(container.lastChild);
253253
else
254254
return container;
255+
},
256+
257+
/**
258+
* Checks if a documentFragment has no children.
259+
* Fragments without children can cause errors if inserted into ranges.
260+
*
261+
* @method isDocumentFragmentWithoutChildren
262+
* @param {HTMLElement} DOM node.
263+
* @return {Boolean}
264+
*/
265+
isDocumentFragmentWithoutChildren: function(fragment) {
266+
if (fragment &&
267+
fragment.nodeType === 11 &&
268+
fragment.childNodes.length === 0) {
269+
return true;
270+
}
271+
return false;
255272
}
256273
};
257274
})();

0 commit comments

Comments
 (0)