Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit dafb8a3

Browse files
Yuri Sulymapetebacondarwin
Yuri Sulyma
authored andcommitted
fix(Angular): nodeName should always be lowercase
XHTML uses lowercase node names, while HTML often uses uppercase. The generally accepted convention is to always lowercase them. Fixes #3987
1 parent ebff4c1 commit dafb8a3

9 files changed

+25
-24
lines changed

src/Angular.js

+9-7
Original file line numberDiff line numberDiff line change
@@ -615,12 +615,14 @@ function makeMap(str) {
615615
if (msie < 9) {
616616
nodeName_ = function(element) {
617617
element = element.nodeName ? element : element[0];
618-
return (element.scopeName && element.scopeName != 'HTML')
619-
? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName;
618+
return lowercase(
619+
(element.scopeName && element.scopeName != 'HTML')
620+
? element.scopeName + ':' + element.nodeName : element.nodeName
621+
);
620622
};
621623
} else {
622624
nodeName_ = function(element) {
623-
return element.nodeName ? element.nodeName : element[0].nodeName;
625+
return lowercase(element.nodeName ? element.nodeName : element[0].nodeName);
624626
};
625627
}
626628

@@ -683,10 +685,10 @@ function arrayRemove(array, value) {
683685

684686
function isLeafNode (node) {
685687
if (node) {
686-
switch (node.nodeName) {
687-
case "OPTION":
688-
case "PRE":
689-
case "TITLE":
688+
switch (nodeName_(node)) {
689+
case "option":
690+
case "pre":
691+
case "title":
690692
return true;
691693
}
692694
}

src/jqLite.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,7 @@ forEach('multiple,selected,checked,disabled,readOnly,required,open'.split(','),
482482
});
483483
var BOOLEAN_ELEMENTS = {};
484484
forEach('input,select,option,textarea,button,form,details'.split(','), function(value) {
485-
BOOLEAN_ELEMENTS[uppercase(value)] = true;
485+
BOOLEAN_ELEMENTS[value] = true;
486486
});
487487
var ALIASED_ATTR = {
488488
'ngMinlength' : 'minlength',
@@ -495,7 +495,7 @@ function getBooleanAttrName(element, name) {
495495
var booleanAttr = BOOLEAN_ATTR[name.toLowerCase()];
496496

497497
// booleanAttr is here twice to minimize DOM access
498-
return booleanAttr && BOOLEAN_ELEMENTS[element.nodeName] && booleanAttr;
498+
return booleanAttr && BOOLEAN_ELEMENTS[nodeName_(element)] && booleanAttr;
499499
}
500500

501501
function getAliasedAttrName(element, name) {
@@ -605,7 +605,7 @@ forEach({
605605

606606
val: function(element, value) {
607607
if (isUndefined(value)) {
608-
if (nodeName_(element) === 'SELECT' && element.multiple) {
608+
if (element.multiple && nodeName_(element) === 'select') {
609609
var result = [];
610610
forEach(element.options, function (option) {
611611
if (option.selected) {

src/ng/anchorScroll.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ function $AnchorScrollProvider() {
6767
function getFirstAnchor(list) {
6868
var result = null;
6969
forEach(list, function(element) {
70-
if (!result && lowercase(element.nodeName) === 'a') result = element;
70+
if (!result && nodeName_(element) === 'a') result = element;
7171
});
7272
return result;
7373
}

src/ng/compile.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -759,8 +759,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
759759
nodeName = nodeName_(this.$$element);
760760

761761
// sanitize a[href] and img[src] values
762-
if ((nodeName === 'A' && key === 'href') ||
763-
(nodeName === 'IMG' && key === 'src')) {
762+
if ((nodeName === 'a' && key === 'href') ||
763+
(nodeName === 'img' && key === 'src')) {
764764
this[key] = value = $$sanitizeUri(value, key === 'src');
765765
}
766766

@@ -1030,7 +1030,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
10301030
case 1: /* Element */
10311031
// use the node name: <directive>
10321032
addDirective(directives,
1033-
directiveNormalize(nodeName_(node).toLowerCase()), 'E', maxPriority, ignoreDirective);
1033+
directiveNormalize(nodeName_(node)), 'E', maxPriority, ignoreDirective);
10341034

10351035
// iterate over the attributes
10361036
for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,
@@ -1897,8 +1897,8 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
18971897
var tag = nodeName_(node);
18981898
// maction[xlink:href] can source SVG. It's not limited to <maction>.
18991899
if (attrNormalizedName == "xlinkHref" ||
1900-
(tag == "FORM" && attrNormalizedName == "action") ||
1901-
(tag != "IMG" && (attrNormalizedName == "src" ||
1900+
(tag == "form" && attrNormalizedName == "action") ||
1901+
(tag != "img" && (attrNormalizedName == "src" ||
19021902
attrNormalizedName == "ngSrc"))) {
19031903
return $sce.RESOURCE_URL;
19041904
}
@@ -1912,7 +1912,7 @@ function $CompileProvider($provide, $$sanitizeUriProvider) {
19121912
if (!interpolateFn) return;
19131913

19141914

1915-
if (name === "multiple" && nodeName_(node) === "SELECT") {
1915+
if (name === "multiple" && nodeName_(node) === "select") {
19161916
throw $compileMinErr("selmulti",
19171917
"Binding to the 'multiple' attribute is not supported. Element: {0}",
19181918
startingTag(node));

src/ng/location.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ function $LocationProvider(){
636636
var elm = jqLite(event.target);
637637

638638
// traverse the DOM up to find first A tag
639-
while (lowercase(elm[0].nodeName) !== 'a') {
639+
while (nodeName_(elm[0]) !== 'a') {
640640
// ignore rewriting if no A tag (reached root element, or no parent - removed from document)
641641
if (elm[0] === $rootElement[0] || !(elm = elm.parent())[0]) return;
642642
}

src/ngScenario/browserTrigger.js

-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434

3535
var inputType = (element.type) ? element.type.toLowerCase() : null,
3636
nodeName = element.nodeName.toLowerCase();
37-
3837
if (!eventType) {
3938
eventType = {
4039
'text': 'change',

src/ngScenario/dsl.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ angular.scenario.dsl('element', function() {
377377
var href = elements.attr('href');
378378
var eventProcessDefault = elements.trigger('click')[0];
379379

380-
if (href && elements[0].nodeName.toUpperCase() === 'A' && eventProcessDefault) {
380+
if (href && elements[0].nodeName.toLowerCase() === 'a' && eventProcessDefault) {
381381
this.application.navigateTo(href, function() {
382382
done();
383383
}, done);
@@ -394,7 +394,7 @@ angular.scenario.dsl('element', function() {
394394
var href = elements.attr('href');
395395
var eventProcessDefault = elements.trigger('dblclick')[0];
396396

397-
if (href && elements[0].nodeName.toUpperCase() === 'A' && eventProcessDefault) {
397+
if (href && elements[0].nodeName.toLowerCase() === 'a' && eventProcessDefault) {
398398
this.application.navigateTo(href, function() {
399399
done();
400400
}, done);

test/AngularSpec.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -951,7 +951,7 @@ describe('angular', function() {
951951
var div = jqLite('<div xmlns:ngtest="http://angularjs.org/">' +
952952
'<ngtest:foo ngtest:attr="bar"></ngtest:foo>' +
953953
'</div>')[0];
954-
expect(nodeName_(div.childNodes[0])).toBe('NGTEST:FOO');
954+
expect(nodeName_(div.childNodes[0])).toBe('ngtest:foo');
955955
expect(div.childNodes[0].getAttribute('ngtest:attr')).toBe('bar');
956956
});
957957

@@ -960,7 +960,7 @@ describe('angular', function() {
960960
var div = jqLite('<div xmlns:ngtest="http://angularjs.org/">' +
961961
'<ngtest:foo ngtest:attr="bar"></ng-test>' +
962962
'</div>')[0];
963-
expect(nodeName_(div.childNodes[0])).toBe('NGTEST:FOO');
963+
expect(nodeName_(div.childNodes[0])).toBe('ngtest:foo');
964964
expect(div.childNodes[0].getAttribute('ngtest:attr')).toBe('bar');
965965
});
966966
}

test/ng/compileSpec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -4625,7 +4625,7 @@ describe('$compile', function() {
46254625
inject(function($compile, $rootScope) {
46264626
var element = jqLite('<div>before<div transclude></div>after</div>').contents();
46274627
expect(element.length).toEqual(3);
4628-
expect(nodeName_(element[1])).toBe('DIV');
4628+
expect(nodeName_(element[1])).toBe('div');
46294629
$compile(element)($rootScope);
46304630
expect(nodeName_(element[1])).toBe('#comment');
46314631
expect(nodeName_(comment)).toBe('#comment');

0 commit comments

Comments
 (0)