(function(){
var BOOLEAN_PROPERTIES = [
"allowfullscreen",
"allowpaymentrequest",
"allowusermedia",
"async",
"autofocus",
"autoplay",
"checked",
"compact",
"complete",
"controls",
"declare",
"default",
"defaultchecked",
"defaultselected",
"defer",
"disabled",
"ended",
"formnovalidate",
"hidden",
"indeterminate",
"iscontenteditable",
"ismap",
"itemscope",
"loop",
"multiple",
"muted",
"nohref",
"nomodule",
"noresize",
"noshade",
"novalidate",
"nowrap",
"open",
"paused",
"playsinline",
"pubdate",
"readonly",
"required",
"reversed",
"scoped",
"seamless",
"seeking",
"selected",
"truespeed",
"typemustmatch",
"willvalidate"
];
var PROPERTY_ALIASES = {
"class": "className",
"readonly": "readOnly"
};
function isSelectable(element){
var tagName = element.tagName.toUpperCase();
if (tagName == "OPTION"){
return true;
}
if (tagName == "INPUT") {
var type = element.type.toLowerCase();
return type == "checkbox" || type == "radio";
}
return false;
}
function isSelected(element){
var propertyName = "selected";
var type = element.type && element.type.toLowerCase();
if ("checkbox" == type || "radio" == type) {
propertyName = "checked";
}
return !!element[propertyName];
}
function getAttributeValue(element, name){
var attr = element.getAttributeNode(name);
return (attr && attr.specified) ? attr.value : null;
}
return function get(element, attribute){
var value = null;
var name = attribute.toLowerCase();
if ("style" == name) {
value = element.style;
if (value && (typeof value != "string")) {
value = value.cssText;
}
return value;
}
if (("selected" == name || "checked" == name) &&
isSelectable(element)) {
return isSelected(element) ? "true" : null;
}
tagName = element.tagName.toUpperCase();
// The property is consistent. Return that in preference to the attribute for links and images.
if (((tagName == "IMG") && name == "src") ||
((tagName == "A") && name == "href")) {
value = getAttributeValue(element, name);
if (value) {
// We want the full URL if present
value = element[name];
}
return value;
}
if ("spellcheck" == name) {
value = getAttributeValue(element, name);
if (!(value === null)) {
if (value.toLowerCase() == "false") {
return "false";
} else if (value.toLowerCase() == "true") {
return "true";
}
}
// coerce the property value to a string
return element[name] + "";
}
var propName = PROPERTY_ALIASES[attribute] || attribute;
if (BOOLEAN_PROPERTIES.some(function(prop){ prop == name })) {
value = getAttributeValue(element, name);
value = !(value === null) || element[propName];
return value ? "true" : null;
}
var property;
try {
property = element[propName]
} catch (e) {
// Leaves property undefined or null
}
// 1- Call getAttribute if getProperty fails,
// i.e. property is null or undefined.
// This happens for event handlers in Firefox.
// For example, calling getProperty for 'onclick' would
// fail while getAttribute for 'onclick' will succeed and
// return the JS code of the handler.
//
// 2- When property is an object we fall back to the
// actual attribute instead.
// See issue http://code.google.com/p/selenium/issues/detail?id=966
if ((property == null) || (typeof property == "object") || (typeof property == "function")) {
value = getAttributeValue(element, attribute);
} else {
value = property;
};
// The empty string is a valid return value.
return value != null ? value.toString() : null;
};
})()