Skip to content

Commit

Permalink
Factor out the tag name case conversions into a single function to re…
Browse files Browse the repository at this point in the history
…duce minified code size and clarify usage
  • Loading branch information
SteveSanderson committed Feb 26, 2012
1 parent 7c62b80 commit dd179ad
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 46 deletions.
8 changes: 4 additions & 4 deletions src/binding/defaultBindings.js
Expand Up @@ -156,7 +156,7 @@ ko.bindingHandlers['value'] = {
});
},
'update': function (element, valueAccessor) {
var valueIsSelectOption = element.tagName.toLowerCase() == "select";
var valueIsSelectOption = ko.utils.tagNameUpper(element) === "SELECT";
var newValue = ko.utils.unwrapObservable(valueAccessor());
var elementValue = ko.selectExtensions.readValue(element);
var valueHasChanged = (newValue != elementValue);
Expand Down Expand Up @@ -187,12 +187,12 @@ ko.bindingHandlers['value'] = {

ko.bindingHandlers['options'] = {
'update': function (element, valueAccessor, allBindingsAccessor) {
if (element.tagName.toLowerCase() != "select")
if (ko.utils.tagNameUpper(element) !== "SELECT")
throw new Error("options binding applies only to SELECT elements");

var selectWasPreviouslyEmpty = element.length == 0;
var previousSelectedValues = ko.utils.arrayMap(ko.utils.arrayFilter(element.childNodes, function (node) {
return node.tagName && node.tagName.toLowerCase() == "option" && node.selected;
return node.tagName && (ko.utils.tagNameUpper(node) === "OPTION") && node.selected;
}), function (node) {
return ko.selectExtensions.readValue(node) || node.innerText || node.textContent;
});
Expand Down Expand Up @@ -308,7 +308,7 @@ ko.bindingHandlers['selectedOptions'] = {
var nodes = element.childNodes;
for (var i = 0, j = nodes.length; i < j; i++) {
var node = nodes[i];
if (node.tagName.toLowerCase() == "option")
if (ko.utils.tagNameUpper(node) === "OPTION")
ko.utils.setOptionNodeSelectionState(node, ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(node)) >= 0);
}
}
Expand Down
80 changes: 40 additions & 40 deletions src/binding/selectExtensions.js
Expand Up @@ -6,52 +6,52 @@
// that are arbitrary objects. This is very convenient when implementing things like cascading dropdowns.
ko.selectExtensions = {
readValue : function(element) {
switch (element.tagName.toLowerCase()) {
case 'option':
if (element[hasDomDataExpandoProperty] === true)
return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey);
return element.getAttribute("value");
case 'select':
return element.selectedIndex >= 0 ? ko.selectExtensions.readValue(element.options[element.selectedIndex]) : undefined;
default:
return element.value;
switch (ko.utils.tagNameUpper(element)) {
case 'OPTION':
if (element[hasDomDataExpandoProperty] === true)
return ko.utils.domData.get(element, ko.bindingHandlers.options.optionValueDomDataKey);
return element.getAttribute("value");
case 'SELECT':
return element.selectedIndex >= 0 ? ko.selectExtensions.readValue(element.options[element.selectedIndex]) : undefined;
default:
return element.value;
}
},

writeValue: function(element, value) {
switch (element.tagName.toLowerCase()) {
case 'option':
switch(typeof value) {
case "string":
ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, undefined);
if (hasDomDataExpandoProperty in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node
delete element[hasDomDataExpandoProperty];
}
element.value = value;
break;
default:
// Store arbitrary object using DomData
ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, value);
element[hasDomDataExpandoProperty] = true;
switch (ko.utils.tagNameUpper(element)) {
case 'OPTION':
switch(typeof value) {
case "string":
ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, undefined);
if (hasDomDataExpandoProperty in element) { // IE <= 8 throws errors if you delete non-existent properties from a DOM node
delete element[hasDomDataExpandoProperty];
}
element.value = value;
break;
default:
// Store arbitrary object using DomData
ko.utils.domData.set(element, ko.bindingHandlers.options.optionValueDomDataKey, value);
element[hasDomDataExpandoProperty] = true;

// Special treatment of numbers is just for backward compatibility. KO 1.2.1 wrote numerical values to element.value.
element.value = typeof value === "number" ? value : "";
break;
}
break;
case 'select':
for (var i = element.options.length - 1; i >= 0; i--) {
if (ko.selectExtensions.readValue(element.options[i]) == value) {
element.selectedIndex = i;
break;
// Special treatment of numbers is just for backward compatibility. KO 1.2.1 wrote numerical values to element.value.
element.value = typeof value === "number" ? value : "";
break;
}
break;
case 'SELECT':
for (var i = element.options.length - 1; i >= 0; i--) {
if (ko.selectExtensions.readValue(element.options[i]) == value) {
element.selectedIndex = i;
break;
}
}
}
break;
default:
if ((value === null) || (value === undefined))
value = "";
element.value = value;
break;
break;
default:
if ((value === null) || (value === undefined))
value = "";
element.value = value;
break;
}
}
};
Expand Down
10 changes: 8 additions & 2 deletions src/utils.js
Expand Up @@ -29,7 +29,7 @@ ko.utils = new (function () {
isIe7 = ieVersion === 7;

function isClickOnCheckableElement(element, eventType) {
if ((element.tagName.toLowerCase() != "input") || !element.type) return false;
if ((ko.utils.tagNameUpper(element) !== "INPUT") || !element.type) return false;
if (eventType.toLowerCase() != "click") return false;
var inputType = element.type.toLowerCase();
return (inputType == "checkbox") || (inputType == "radio");
Expand Down Expand Up @@ -204,6 +204,12 @@ ko.utils = new (function () {
return ko.utils.domNodeIsContainedBy(node, document);
},

tagNameUpper: function(element) {
// Possible future optimization: If we know it's an element from an HTML document (not XHTML),
// we don't need to do the .toUpperCase() as it will always be uppercase anyway
return element.tagName.toUpperCase();
},

registerEventHandler: function (element, eventType, handler) {
if (typeof jQuery != "undefined") {
if (isClickOnCheckableElement(element, eventType)) {
Expand Down Expand Up @@ -369,7 +375,7 @@ ko.utils = new (function () {
var url = urlOrForm;

// If we were given a form, use its 'action' URL and pick out any requested field values
if((typeof urlOrForm == 'object') && (urlOrForm.tagName.toLowerCase() == "form")) {
if((typeof urlOrForm == 'object') && (ko.utils.tagNameUpper(urlOrForm) === "FORM")) {
var originalForm = urlOrForm;
url = originalForm.action;
for (var i = includeFields.length - 1; i >= 0; i--) {
Expand Down

0 comments on commit dd179ad

Please sign in to comment.