| 1 |
wakaba |
1.1 |
<!DOCTYPE HTML> |
| 2 |
|
|
<title>Properties</title> |
| 3 |
|
|
<link rel=stylesheet href="/www/style/html/xhtml"> |
| 4 |
|
|
|
| 5 |
|
|
<style> |
| 6 |
|
|
[name=result_ta] { |
| 7 |
|
|
height: 40em; |
| 8 |
|
|
} |
| 9 |
|
|
</style> |
| 10 |
|
|
|
| 11 |
|
|
<body onload=" |
| 12 |
|
|
var xhr = new XMLHttpRequest (); |
| 13 |
|
|
xhr.open ('GET', 'prop-list.txt?' + Math.random (), false); |
| 14 |
|
|
xhr.send (null); |
| 15 |
|
|
document.getElementsByName ('known_props_ta')[0].value = xhr.responseText; |
| 16 |
|
|
"> |
| 17 |
|
|
|
| 18 |
|
|
<h1>Properties</h1> |
| 19 |
|
|
|
| 20 |
|
|
<form> |
| 21 |
|
|
<p><label>Code:<br><textarea name=code_ta></textarea></label> |
| 22 |
|
|
|
| 23 |
|
|
<p><label>List of known properties:<br> |
| 24 |
|
|
<textarea name=known_props_ta> |
| 25 |
|
|
</textarea></label> |
| 26 |
|
|
|
| 27 |
|
|
<p><button type=submit>Start</button> |
| 28 |
|
|
|
| 29 |
|
|
<h2>Result</h2> |
| 30 |
|
|
|
| 31 |
|
|
<p><textarea name=result_ta> |
| 32 |
|
|
</textarea> |
| 33 |
|
|
|
| 34 |
|
|
</form> |
| 35 |
|
|
|
| 36 |
|
|
<script> |
| 37 |
|
|
document.forms[0].onsubmit = function (event) { |
| 38 |
|
|
if (window.event) window.event.returnValue = false; |
| 39 |
|
|
if (event && event.preventDefault) event.preventDefault (); |
| 40 |
|
|
|
| 41 |
|
|
var objCode = this.code_ta.value; |
| 42 |
|
|
var obj = eval (objCode); |
| 43 |
|
|
|
| 44 |
|
|
if (typeof (obj) === "undefined" || obj === null) { |
| 45 |
|
|
obj = {}; |
| 46 |
|
|
objCode = '{}'; |
| 47 |
|
|
} |
| 48 |
|
|
|
| 49 |
|
|
var knownProps = this.known_props_ta.value.split (/[\r\n]+/); |
| 50 |
|
|
|
| 51 |
|
|
var newKnownProps = []; |
| 52 |
|
|
var newKnownPropNames = {}; |
| 53 |
|
|
|
| 54 |
|
|
var props = {}; |
| 55 |
|
|
var noProps = {}; |
| 56 |
|
|
|
| 57 |
|
|
for (var i = 0; i < knownProps.length; i++) { |
| 58 |
|
|
var propName = knownProps[i]; |
| 59 |
|
|
if (propName == '') continue; |
| 60 |
|
|
if (propName.match (/^\s/)) continue; |
| 61 |
|
|
propName = propName.replace (/\s+$/, ''); |
| 62 |
|
|
|
| 63 |
|
|
try { |
| 64 |
|
|
if (typeof (obj[propName]) !== 'undefined') { |
| 65 |
|
|
if (!newKnownPropNames["name=" + propName]) newKnownProps.push (propName); |
| 66 |
|
|
newKnownPropNames["name=" + propName] = true; |
| 67 |
|
|
props["name="+propName] = {dontEnum: true}; |
| 68 |
|
|
} else { |
| 69 |
|
|
if (!newKnownPropNames["name=" + propName]) newKnownProps.push (propName); |
| 70 |
|
|
newKnownPropNames["name=" + propName] = true; |
| 71 |
|
|
noProps["name="+propName] = {}; |
| 72 |
|
|
} |
| 73 |
|
|
} catch (e) { |
| 74 |
|
|
if (!newKnownPropNames["name=" + propName]) newKnownProps.push (propName); |
| 75 |
|
|
newKnownPropNames["name=" + propName] = true; |
| 76 |
|
|
props["name="+propName] = {error: '' + e}; |
| 77 |
|
|
} |
| 78 |
|
|
} |
| 79 |
|
|
|
| 80 |
|
|
for (var propName in obj) { |
| 81 |
|
|
if (!props["name="+propName]) { |
| 82 |
|
|
props["name="+propName] = {notInList: true}; |
| 83 |
|
|
newKnownProps.push (propName); |
| 84 |
|
|
} |
| 85 |
|
|
props["name="+propName].dontEnum = false; |
| 86 |
|
|
} |
| 87 |
|
|
|
| 88 |
|
|
var n = function (s) { |
| 89 |
|
|
s = s || ''; |
| 90 |
|
|
s = s.toLowerCase () |
| 91 |
|
|
.replace (/_/g, ''); |
| 92 |
|
|
return s; |
| 93 |
|
|
}; |
| 94 |
|
|
|
| 95 |
|
|
var sort = function (l) { |
| 96 |
|
|
var m; |
| 97 |
|
|
try { |
| 98 |
|
|
m = l.sort (function (a, b) { |
| 99 |
|
|
a = n (a); b = n (b); |
| 100 |
|
|
return a < b ? -1 : a > b ? 1 : 0; |
| 101 |
|
|
}); |
| 102 |
|
|
} catch (e) { } // IE sometimes fails. Why? |
| 103 |
|
|
return m || l; |
| 104 |
|
|
}; |
| 105 |
|
|
|
| 106 |
|
|
var propNames = []; |
| 107 |
|
|
for (var propName in props) { |
| 108 |
|
|
propNames.push (propName); |
| 109 |
|
|
} |
| 110 |
|
|
propNames = sort (propNames); |
| 111 |
|
|
|
| 112 |
|
|
var noPropNames = []; |
| 113 |
|
|
for (var propName in noProps) { |
| 114 |
|
|
noPropNames.push (propName); |
| 115 |
|
|
} |
| 116 |
|
|
noPropNames = sort (noPropNames); |
| 117 |
|
|
|
| 118 |
|
|
var result = 'UA: ' + navigator.userAgent + "\n"; |
| 119 |
|
|
result += 'Object: ' + objCode + "\n"; |
| 120 |
|
|
result += "\n"; |
| 121 |
|
|
result += 'Properties:\n'; |
| 122 |
|
|
for (var i = 0; i < propNames.length; i++) { |
| 123 |
|
|
result += propNames[i].replace (/^name=/, ''); |
| 124 |
|
|
if (props[propNames[i]].dontEnum) result += '\tDontEnum'; |
| 125 |
|
|
if (props[propNames[i]].notInList) result += '\t_not_in_list_'; |
| 126 |
|
|
if (props[propNames[i]].error) result += '\t_error(' + props[propNames[i]].error + ')_'; |
| 127 |
|
|
result += '\n'; |
| 128 |
|
|
} |
| 129 |
|
|
result += "\n"; |
| 130 |
|
|
result += "Not found:\n" |
| 131 |
|
|
for (var i = 0; i < noPropNames.length; i++) { |
| 132 |
|
|
result += noPropNames[i].replace (/^name=/, '') + '\n'; |
| 133 |
|
|
} |
| 134 |
|
|
this.result_ta.value = result; |
| 135 |
|
|
|
| 136 |
|
|
this.known_props_ta.value = sort (newKnownProps).join ("\n"); |
| 137 |
|
|
|
| 138 |
|
|
return false; |
| 139 |
|
|
}; |
| 140 |
|
|
</script> |