Skip to content
This repository was archived by the owner on Dec 14, 2021. It is now read-only.

Commit 49bca05

Browse files
feeslerinexorabletash
authored andcommitted
Add missing polyfills for firstElementChild, lastElementChild and childElementCount (#158)
* Move previous/nextElementSibling polyfills out of DOMTokenList scope * Add missing polyfills for firstElementChild, lastElementChild and childElementCount
1 parent cefa69e commit 49bca05

File tree

5 files changed

+175
-79
lines changed

5 files changed

+175
-79
lines changed

dom.js

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,13 @@
265265
}
266266
};
267267

268+
269+
function addToElementPrototype(p, f) {
270+
if ('Element' in global && Element.prototype && Object.defineProperty) {
271+
Object.defineProperty(Element.prototype, p, { get: f });
272+
}
273+
}
274+
268275
// DOMTokenList interface and Element.classList / Element.relList
269276
// Needed for: IE9-
270277
// Use getClassList(elem) instead of elem.classList() if IE7- support is needed
@@ -410,12 +417,6 @@
410417
}
411418
}
412419

413-
function addToElementPrototype(p, f) {
414-
if ('Element' in global && Element.prototype && Object.defineProperty) {
415-
Object.defineProperty(Element.prototype, p, { get: f });
416-
}
417-
}
418-
419420
// HTML - https://html.spec.whatwg.org
420421
// Element.classList
421422
if ('classList' in document.createElement('span')) {
@@ -455,29 +456,55 @@
455456
};
456457
}());
457458

459+
}());
458460

459-
// DOM - Interface NonDocumentTypeChildNode
460-
// Interface NonDocumentTypeChildNode
461-
// previousElementSibling / nextElementSibling - for IE8
462461

463-
if (!('previousElementSibling' in document.documentElement)) {
464-
addToElementPrototype('previousElementSibling', function() {
465-
var n = this.previousSibling;
466-
while (n && n.nodeType !== Node.ELEMENT_NODE)
467-
n = n.previousSibling;
468-
return n;
469-
});
470-
}
462+
// DOM - Interface NonDocumentTypeChildNode
463+
// Interface NonDocumentTypeChildNode
464+
// previousElementSibling / nextElementSibling - for IE8
465+
466+
if (!('previousElementSibling' in document.documentElement)) {
467+
addToElementPrototype('previousElementSibling', function() {
468+
var n = this.previousSibling;
469+
while (n && n.nodeType !== Node.ELEMENT_NODE)
470+
n = n.previousSibling;
471+
return n;
472+
});
473+
}
474+
475+
if (!('nextElementSibling' in document.documentElement)) {
476+
addToElementPrototype('nextElementSibling', function() {
477+
var n = this.nextSibling;
478+
while (n && n.nodeType !== Node.ELEMENT_NODE)
479+
n = n.nextSibling;
480+
return n;
481+
});
482+
}
483+
484+
if (!('firstElementChild' in document.documentElement)) {
485+
addToElementPrototype('firstElementChild', function() {
486+
for(var nodes = this.children, n, i = 0, l = nodes.length; i < l; ++i)
487+
if(n = nodes[i], 1 === n.nodeType) return n;
488+
return null;
489+
});
490+
}
491+
492+
if (!('lastElementChild' in document.documentElement)) {
493+
addToElementPrototype('lastElementChild', function() {
494+
for(var nodes = this.children, n, i = nodes.length - 1; i >= 0; --i)
495+
if(n = nodes[i], 1 === n.nodeType) return n;
496+
return null;
497+
});
498+
}
499+
500+
if (!('childElementCount' in document.documentElement)) {
501+
addToElementPrototype('childElementCount', function() {
502+
for(var c = 0, nodes = this.children, n, i = 0, l = nodes.length; i < l; ++i)
503+
(n = nodes[i], 1 === n.nodeType) && ++c;
504+
return c;
505+
});
506+
}
471507

472-
if (!('nextElementSibling' in document.documentElement)) {
473-
addToElementPrototype('nextElementSibling', function() {
474-
var n = this.nextSibling;
475-
while (n && n.nodeType !== Node.ELEMENT_NODE)
476-
n = n.nextSibling;
477-
return n;
478-
});
479-
}
480-
}());
481508

482509
// Element.matches
483510
// https://developer.mozilla.org/en/docs/Web/API/Element/matches

polyfill.js

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5053,6 +5053,13 @@ function __cons(t, a) {
50535053
}
50545054
};
50555055

5056+
5057+
function addToElementPrototype(p, f) {
5058+
if ('Element' in global && Element.prototype && Object.defineProperty) {
5059+
Object.defineProperty(Element.prototype, p, { get: f });
5060+
}
5061+
}
5062+
50565063
// DOMTokenList interface and Element.classList / Element.relList
50575064
// Needed for: IE9-
50585065
// Use getClassList(elem) instead of elem.classList() if IE7- support is needed
@@ -5198,12 +5205,6 @@ function __cons(t, a) {
51985205
}
51995206
}
52005207

5201-
function addToElementPrototype(p, f) {
5202-
if ('Element' in global && Element.prototype && Object.defineProperty) {
5203-
Object.defineProperty(Element.prototype, p, { get: f });
5204-
}
5205-
}
5206-
52075208
// HTML - https://html.spec.whatwg.org
52085209
// Element.classList
52095210
if ('classList' in document.createElement('span')) {
@@ -5243,29 +5244,55 @@ function __cons(t, a) {
52435244
};
52445245
}());
52455246

5247+
}());
52465248

5247-
// DOM - Interface NonDocumentTypeChildNode
5248-
// Interface NonDocumentTypeChildNode
5249-
// previousElementSibling / nextElementSibling - for IE8
52505249

5251-
if (!('previousElementSibling' in document.documentElement)) {
5252-
addToElementPrototype('previousElementSibling', function() {
5253-
var n = this.previousSibling;
5254-
while (n && n.nodeType !== Node.ELEMENT_NODE)
5255-
n = n.previousSibling;
5256-
return n;
5257-
});
5258-
}
5250+
// DOM - Interface NonDocumentTypeChildNode
5251+
// Interface NonDocumentTypeChildNode
5252+
// previousElementSibling / nextElementSibling - for IE8
5253+
5254+
if (!('previousElementSibling' in document.documentElement)) {
5255+
addToElementPrototype('previousElementSibling', function() {
5256+
var n = this.previousSibling;
5257+
while (n && n.nodeType !== Node.ELEMENT_NODE)
5258+
n = n.previousSibling;
5259+
return n;
5260+
});
5261+
}
5262+
5263+
if (!('nextElementSibling' in document.documentElement)) {
5264+
addToElementPrototype('nextElementSibling', function() {
5265+
var n = this.nextSibling;
5266+
while (n && n.nodeType !== Node.ELEMENT_NODE)
5267+
n = n.nextSibling;
5268+
return n;
5269+
});
5270+
}
5271+
5272+
if (!('firstElementChild' in document.documentElement)) {
5273+
addToElementPrototype('firstElementChild', function() {
5274+
for(var nodes = this.children, n, i = 0, l = nodes.length; i < l; ++i)
5275+
if(n = nodes[i], 1 === n.nodeType) return n;
5276+
return null;
5277+
});
5278+
}
5279+
5280+
if (!('lastElementChild' in document.documentElement)) {
5281+
addToElementPrototype('lastElementChild', function() {
5282+
for(var nodes = this.children, n, i = nodes.length - 1; i >= 0; --i)
5283+
if(n = nodes[i], 1 === n.nodeType) return n;
5284+
return null;
5285+
});
5286+
}
5287+
5288+
if (!('childElementCount' in document.documentElement)) {
5289+
addToElementPrototype('childElementCount', function() {
5290+
for(var c = 0, nodes = this.children, n, i = 0, l = nodes.length; i < l; ++i)
5291+
(n = nodes[i], 1 === n.nodeType) && ++c;
5292+
return c;
5293+
});
5294+
}
52595295

5260-
if (!('nextElementSibling' in document.documentElement)) {
5261-
addToElementPrototype('nextElementSibling', function() {
5262-
var n = this.nextSibling;
5263-
while (n && n.nodeType !== Node.ELEMENT_NODE)
5264-
n = n.nextSibling;
5265-
return n;
5266-
});
5267-
}
5268-
}());
52695296

52705297
// Element.matches
52715298
// https://developer.mozilla.org/en/docs/Web/API/Element/matches

polyfill.min.js

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/dom.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,19 @@ QUnit.test('next/previousElementSibling', function(assert) {
169169
assert.equal(document.querySelector('#three').nextElementSibling, null);
170170
});
171171

172+
QUnit.test('first/lastElementChild, childElementCount', function(assert) {
173+
assert.expect(6);
174+
175+
assert.equal(document.querySelector('#mixed').firstElementChild, document.querySelector('#one'));
176+
assert.equal(document.querySelector('#one').firstElementChild, null);
177+
178+
assert.equal(document.querySelector('#mixed').lastElementChild, document.querySelector('#three'));
179+
assert.equal(document.querySelector('#one').lastElementChild, null);
180+
181+
assert.equal(document.querySelector('#mixed').childElementCount, 3);
182+
assert.equal(document.querySelector('#one').childElementCount, 0);
183+
});
184+
172185
QUnit.test("matches", function(assert) {
173186
assert.ok(document.querySelector('#foo').matches('.alpha'));
174187
assert.ok(document.querySelector('#baz').matches('.beta'));

web.js

Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,13 @@
454454
}
455455
};
456456

457+
458+
function addToElementPrototype(p, f) {
459+
if ('Element' in global && Element.prototype && Object.defineProperty) {
460+
Object.defineProperty(Element.prototype, p, { get: f });
461+
}
462+
}
463+
457464
// DOMTokenList interface and Element.classList / Element.relList
458465
// Needed for: IE9-
459466
// Use getClassList(elem) instead of elem.classList() if IE7- support is needed
@@ -599,12 +606,6 @@
599606
}
600607
}
601608

602-
function addToElementPrototype(p, f) {
603-
if ('Element' in global && Element.prototype && Object.defineProperty) {
604-
Object.defineProperty(Element.prototype, p, { get: f });
605-
}
606-
}
607-
608609
// HTML - https://html.spec.whatwg.org
609610
// Element.classList
610611
if ('classList' in document.createElement('span')) {
@@ -644,29 +645,55 @@
644645
};
645646
}());
646647

648+
}());
647649

648-
// DOM - Interface NonDocumentTypeChildNode
649-
// Interface NonDocumentTypeChildNode
650-
// previousElementSibling / nextElementSibling - for IE8
651650

652-
if (!('previousElementSibling' in document.documentElement)) {
653-
addToElementPrototype('previousElementSibling', function() {
654-
var n = this.previousSibling;
655-
while (n && n.nodeType !== Node.ELEMENT_NODE)
656-
n = n.previousSibling;
657-
return n;
658-
});
659-
}
651+
// DOM - Interface NonDocumentTypeChildNode
652+
// Interface NonDocumentTypeChildNode
653+
// previousElementSibling / nextElementSibling - for IE8
654+
655+
if (!('previousElementSibling' in document.documentElement)) {
656+
addToElementPrototype('previousElementSibling', function() {
657+
var n = this.previousSibling;
658+
while (n && n.nodeType !== Node.ELEMENT_NODE)
659+
n = n.previousSibling;
660+
return n;
661+
});
662+
}
663+
664+
if (!('nextElementSibling' in document.documentElement)) {
665+
addToElementPrototype('nextElementSibling', function() {
666+
var n = this.nextSibling;
667+
while (n && n.nodeType !== Node.ELEMENT_NODE)
668+
n = n.nextSibling;
669+
return n;
670+
});
671+
}
672+
673+
if (!('firstElementChild' in document.documentElement)) {
674+
addToElementPrototype('firstElementChild', function() {
675+
for(var nodes = this.children, n, i = 0, l = nodes.length; i < l; ++i)
676+
if(n = nodes[i], 1 === n.nodeType) return n;
677+
return null;
678+
});
679+
}
680+
681+
if (!('lastElementChild' in document.documentElement)) {
682+
addToElementPrototype('lastElementChild', function() {
683+
for(var nodes = this.children, n, i = nodes.length - 1; i >= 0; --i)
684+
if(n = nodes[i], 1 === n.nodeType) return n;
685+
return null;
686+
});
687+
}
688+
689+
if (!('childElementCount' in document.documentElement)) {
690+
addToElementPrototype('childElementCount', function() {
691+
for(var c = 0, nodes = this.children, n, i = 0, l = nodes.length; i < l; ++i)
692+
(n = nodes[i], 1 === n.nodeType) && ++c;
693+
return c;
694+
});
695+
}
660696

661-
if (!('nextElementSibling' in document.documentElement)) {
662-
addToElementPrototype('nextElementSibling', function() {
663-
var n = this.nextSibling;
664-
while (n && n.nodeType !== Node.ELEMENT_NODE)
665-
n = n.nextSibling;
666-
return n;
667-
});
668-
}
669-
}());
670697

671698
// Element.matches
672699
// https://developer.mozilla.org/en/docs/Web/API/Element/matches

0 commit comments

Comments
 (0)