1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/imptests/html/microdata/microdata-dom-api/test_001.html Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,3661 @@ 1.4 +<!doctype html> 1.5 +<html> 1.6 + <head> 1.7 + <meta charset="UTF-8"> 1.8 + <title>Microdata tests</title> 1.9 + <script type="text/javascript" src="/resources/testharness.js"></script> 1.10 + <script type="text/javascript" src="/resources/testharnessreport.js"></script> 1.11 + <link rel="help" href="http://dev.w3.org/html5/md/#microdata-dom-api"> 1.12 + <link rel="help" href="http://dev.w3.org/html5/md/#encoding-microdata"> 1.13 + </head> 1.14 + <body> 1.15 + <noscript><p>Enable JavaScript and reload</p></noscript> 1.16 + <div id="log">Running test...</div> 1.17 + <div itemscope itemtype="http://example.com/bar data:text/plain, http://example.com/foo" id="one"></div> 1.18 + <div itemscope itemtype="http://example.com/bar" id="two"></div> 1.19 + <div itemscope itemtype="http://example.com/foo http://example.com/bar" id="three"> 1.20 + <div itemscope itemtype="http://example.com/bar data:text/plain," id="four"></div> 1.21 + </div> 1.22 + <div itemscope id="five"></div> 1.23 + <script type="text/javascript"> 1.24 +/* All tests are stand-alone. 1.25 +To reduce this testsuite to show only a single desired test, 1.26 +simply remove all test(...) blocks before and after it. */ 1.27 + 1.28 +function makeEl(eltype,props,contents) { 1.29 + var elem = document.createElement(eltype); 1.30 + for( var i in props ) { 1.31 + //just in case the framework extends object... 1.32 + if( props.hasOwnProperty(i) ) { 1.33 + elem.setAttribute(i,props[i]); 1.34 + } 1.35 + } 1.36 + if( contents ) { 1.37 + elem.innerHTML = contents; 1.38 + } 1.39 + return elem; 1.40 +} 1.41 + 1.42 +/* getItem tests */ 1.43 +test(function () { 1.44 + assert_true( !!document.getItems ); 1.45 +}, 'document.getItems must exist'); 1.46 +test(function () { 1.47 + assert_true( document.getItems() instanceof NodeList, 'instanceof test' ); 1.48 + NodeList.prototype.customProperty = true; 1.49 + assert_true( document.getItems().customProperty, 'inheritance test' ); 1.50 +}, 'document.getItems must return a NodeList'); 1.51 +test(function () { 1.52 + assert_equals( document.getItems().length, 5 ); 1.53 +}, 'document.getItems must locate the correct number of items'); 1.54 +test(function () { 1.55 + var nlist = document.getItems(); 1.56 + var foo = makeEl('div',{itemscope:'itemscope'}); 1.57 + document.body.appendChild(foo); 1.58 + var templength = nlist.length; 1.59 + document.body.removeChild(foo); 1.60 + assert_equals( templength, 6 ); 1.61 + assert_equals( nlist.length, 5 ); 1.62 +}, 'document.getItems must return a live NodeList'); 1.63 +test(function () { 1.64 + var nlist = document.getItems(); 1.65 + document.getElementById('one').removeAttribute('itemscope'); 1.66 + var templength = nlist.length; 1.67 + document.getElementById('one').setAttribute('itemscope','itemscope'); 1.68 + assert_equals( templength, 4 ); 1.69 + assert_equals( nlist.length, 5 ); 1.70 +}, 'live NodeList must notice when itemscope changes'); 1.71 +test(function () { 1.72 + document.getElementById('one').removeAttribute('itemscope'); 1.73 + var templength = document.getItems().length; 1.74 + document.getElementById('one').setAttribute('itemscope','itemscope'); 1.75 + assert_equals( templength, 4 ); 1.76 + assert_equals( document.getItems().length, 5 ); 1.77 +}, 'next request must notice when itemscope changes'); 1.78 +test(function () { 1.79 + assert_equals( document.getItems('http://example.com/').length, 0, 'http://example.com/' ); 1.80 + assert_equals( document.getItems('example').length, 0, 'example' ); 1.81 + assert_equals( document.getItems('http://example.com/foo').length, 2, 'http://example.com/foo' ); 1.82 + assert_equals( document.getItems('http://example.com/bar').length, 4, 'http://example.com/bar' ); 1.83 + assert_equals( document.getItems('data:text/plain,').length, 2, 'data:text/plain,' ); 1.84 +}, 'document.getItems must locate the right number of items for each itemtype'); 1.85 +test(function () { 1.86 + assert_equals( document.getItems('http://example.com/Foo').length, 0, 'http://example.com/Foo' ); 1.87 + assert_equals( document.getItems('HTTP://example.com/foo').length, 0, 'HTTP://example.com/foo' ); 1.88 +}, 'document.getItems must be case sensitive'); 1.89 +test(function () { 1.90 + var nlist = document.getItems('http://example.com/foo'); 1.91 + var foo = makeEl('div',{itemscope:'itemscope',itemtype:'http://example.com/foo'}); 1.92 + document.body.appendChild(foo); 1.93 + var templength = nlist.length; 1.94 + document.body.removeChild(foo); 1.95 + assert_equals( templength, 3 ); 1.96 + assert_equals( nlist.length, 2 ); 1.97 +}, 'document.getItems must return a live NodeList when using URLs'); 1.98 +test(function () { 1.99 + var nlist = document.getItems('http://example.com/foo'); 1.100 + document.getElementById('one').removeAttribute('itemtype'); 1.101 + var templength = nlist.length; 1.102 + document.getElementById('one').setAttribute('itemtype','http://example.com/bar data:text/plain, http://example.com/foo'); 1.103 + assert_equals( templength, 1 ); 1.104 + assert_equals( nlist.length, 2 ); 1.105 +}, 'live NodeList must notice when itemtype changes'); 1.106 +test(function () { 1.107 + document.getElementById('one').removeAttribute('itemtype'); 1.108 + var templength = document.getItems('http://example.com/foo').length; 1.109 + document.getElementById('one').setAttribute('itemtype','http://example.com/bar data:text/plain, http://example.com/foo'); 1.110 + assert_equals( templength, 1 ); 1.111 + assert_equals( document.getItems('http://example.com/foo').length, 2 ); 1.112 +}, 'next request must notice when itemtype changes'); 1.113 +test(function () { 1.114 + assert_equals( document.getItems('http://example.com/foo data:text/plain,').length, 1, 'basic spaces' ); 1.115 + assert_equals( document.getItems(' http://example.com/foo data:text/plain, ').length, 1, 'extraneous spaces' ); 1.116 +}, 'document.getItems must locate items when parameters are separated by spaces'); 1.117 +test(function () { 1.118 + assert_equals( document.getItems('http://example.com/foo data:text/plain, http://example.com/foo').length, 1 ); 1.119 +}, 'document.getItems must ignore duplicated tokens'); 1.120 +test(function () { 1.121 + var testitems = document.getItems('http://example.com/bar'); 1.122 + assert_equals( testitems[0].id, 'one' ); 1.123 + assert_equals( testitems[1].id, 'two' ); 1.124 + assert_equals( testitems[2].id, 'three' ); 1.125 + assert_equals( testitems[3].id, 'four' ); 1.126 +}, 'document.getItems NodeList must be in source tree order'); 1.127 +test(function () { 1.128 + assert_true( document.getItems('http://example.com/abc') != document.getItems('http://example.com/def'), 'different tokens' ); 1.129 + assert_true( document.getItems() != document.getItems(' '), 'no tokens' ); 1.130 +}, 'document.getItems must not return the same NodeList for different parameters'); 1.131 +test(function () { 1.132 + assert_equals( document.getItems('').length, 5, 'empty string' ); 1.133 + assert_equals( document.getItems(' ').length, 5, 'string with spaces' ); 1.134 +}, 'document.getItems must treat no tokens as no parameter'); 1.135 +//removed due to disputed Web compatibility of casting null with DOM methods 1.136 +/* 1.137 +test(function () { 1.138 + assert_equals( document.getItems(null).length, 0, 'null' ); 1.139 + assert_equals( document.getItems(window.undefined).length, 0, 'undefined' ); 1.140 +}, 'document.getItems must cast null and undefined to strings'); 1.141 +*/ 1.142 +test(function () { 1.143 + var foo = makeEl('div',{itemtype:'http://example.com/foo'}); 1.144 + document.body.appendChild(foo); 1.145 + var templength = document.getItems('http://example.com/foo').length; 1.146 + document.body.removeChild(foo); 1.147 + assert_equals( templength, 2 ); 1.148 +}, 'document.getItems must not find items with itemtype but not itemscope'); 1.149 +test(function () { 1.150 + var foo = makeEl('div',{itemscope:'itemscope',itemtype:'baz'}), 1.151 + bar = makeEl('div',{itemscope:'itemscope',itemtype:location.href.replace(/\/[^\/]*$/,'/baz')}); 1.152 + document.body.appendChild(foo); 1.153 + document.body.appendChild(bar); 1.154 + var unrezlength = document.getItems('baz').length; 1.155 + var rezlength = document.getItems(location.href.replace(/\/[^\/]*$/,'/baz')).length; 1.156 + document.body.removeChild(foo); 1.157 + document.body.removeChild(bar); 1.158 + assert_equals( unrezlength, 1, 'unresolved URL' ); 1.159 + assert_equals( rezlength, 1, 'resolved URL' ); 1.160 +}, 'document.getItems and itemtype must not resolve URLs'); 1.161 +test(function () { 1.162 + document.getElementById('one').setAttribute('itemprop','test'); 1.163 + document.getElementById('four').setAttribute('itemprop','test'); 1.164 + var templength = document.getItems().length; 1.165 + document.getElementById('one').removeAttribute('itemprop'); 1.166 + document.getElementById('four').removeAttribute('itemprop'); 1.167 + assert_equals( templength, 3 ); 1.168 +}, 'document.getItems must not see items that have the itemprop attribute set'); 1.169 + 1.170 +/* itemScope property tests */ 1.171 +test(function () { 1.172 + assert_true(makeEl('div',{itemscope:'itemscope'}).itemScope); 1.173 + assert_false(makeEl('div',{}).itemScope); 1.174 +}, 'the itemscope attribute must be reflected by the .itemScope property'); 1.175 +test(function () { 1.176 + assert_equals( typeof makeEl('div',{itemscope:'itemscope'}).itemScope, 'boolean', 'attribute exists' ); 1.177 + assert_equals( typeof makeEl('div',{}).itemScope, 'boolean', 'attribute does not exist' ); 1.178 +}, 'the itemScope property must be boolean'); 1.179 +test(function () { 1.180 + var testEl = makeEl('div',{}); 1.181 + testEl.itemScope = true; 1.182 + assert_true(testEl.itemScope,'writing true'); 1.183 + testEl.itemScope = false; 1.184 + assert_false(testEl.itemScope,'writing false'); 1.185 +}, 'the itemScope property must be read/write'); 1.186 +test(function () { 1.187 + var testEl = makeEl('div',{}); 1.188 + testEl.itemScope = true; 1.189 + assert_true(testEl.hasAttribute('itemscope'),'writing true'); 1.190 + testEl.itemScope = false; 1.191 + assert_false(testEl.hasAttribute('itemscope'),'writing false'); 1.192 +}, 'writing to the itemScope property must toggle existence of the itemscope content attribute'); 1.193 +test(function () { 1.194 + var testEl = makeEl('div',{}); 1.195 + document.body.appendChild(testEl); 1.196 + var numAppend = document.getItems().length; 1.197 + testEl.itemScope = true; 1.198 + var numTrue = document.getItems().length; 1.199 + testEl.itemScope = false; 1.200 + var numFalse = document.getItems().length; 1.201 + document.body.removeChild(testEl); 1.202 + assert_equals(numAppend,5,'after appending the new item'); 1.203 + assert_equals(numTrue,6,'after setting the property to true'); 1.204 + assert_equals(numFalse,5,'after setting the property to false'); 1.205 +}, 'writing to the itemScope property must affect whether the element is returned by getItems'); 1.206 +test(function () { 1.207 + var testEl = makeEl('div',{}), nlist = document.getItems(); 1.208 + document.body.appendChild(testEl); 1.209 + var numAppend = nlist.length; 1.210 + testEl.itemScope = true; 1.211 + var numTrue = nlist.length; 1.212 + testEl.itemScope = false; 1.213 + var numFalse = nlist.length; 1.214 + document.body.removeChild(testEl); 1.215 + assert_equals(numAppend,5,'after appending the new item'); 1.216 + assert_equals(numTrue,6,'after setting the property to true'); 1.217 + assert_equals(numFalse,5,'after setting the property to false'); 1.218 +}, 'writing to the itemScope property must affect membership of live NodeLists'); 1.219 + 1.220 +/* itemType property tests (properties collection tests are done later) */ 1.221 +test(function () { 1.222 + assert_equals(makeEl('div',{}).itemType.toString(),'','no attribute'); 1.223 + assert_equals(makeEl('div',{itemtype:' foo bar '}).itemType.toString(),' foo bar ','with simple tokens'); 1.224 + var testEl = makeEl('div',{itemtype:'foo'}); 1.225 + testEl.removeAttribute('itemtype'); 1.226 + assert_equals(testEl.itemType.toString(),'','removed attribute'); 1.227 +}, 'the itemType attribute must be reflected by the .itemRef property'); 1.228 +test(function () { 1.229 + assert_equals( typeof makeEl('div',{}).itemType, 'object' ); 1.230 +}, 'the itemType property must be an object'); 1.231 +test(function () { 1.232 + assert_true( makeEl('div',{}).itemType instanceof DOMTokenList, 'instanceof test' ); 1.233 + DOMTokenList.prototype.customProperty = true; 1.234 + assert_true( makeEl('div',{}).itemType.customProperty, 'inheritance test' ); 1.235 +}, 'the itemType property must implement DOMTokenList'); 1.236 +test(function () { 1.237 + var testEl = makeEl('div',{}); 1.238 + assert_equals( testEl.itemType, testEl.itemType ); 1.239 +}, 'the itemType property must always reference the same object'); 1.240 +test(function () { 1.241 + assert_equals( makeEl('div',{itemtype:'test test'}).itemType.length, 2, 'duplicates in initial string should be preserved' ); 1.242 + assert_equals( makeEl('div',{itemtype:'test test'}).itemType.item(0), 'test' ); 1.243 + assert_true( makeEl('div',{itemtype:'test test'}).itemType.contains('test') ); 1.244 +}, 'itemType must be correct for an element that has itemtype tokens'); 1.245 +test(function () { 1.246 + assert_equals( makeEl('div',{itemtype:' '}).itemType.length, 0 ); 1.247 +}, 'itemType.length must be 0 for an element that has no tokens'); 1.248 +test(function () { 1.249 + assert_false( makeEl('div',{itemtype:' '}).itemType.contains('foo') ); 1.250 +}, 'itemType must not contain an undefined class'); 1.251 +test(function () { 1.252 + assert_equals( makeEl('div',{itemtype:' '}).itemType.item(0), null ); 1.253 +}, 'itemType.item() must return null for out-of-range index'); 1.254 +test(function () { 1.255 + assert_equals( makeEl('div',{itemtype:' '}).itemType.item(-1), null ); 1.256 +}, 'itemType.item() must return null for negative index'); 1.257 +test(function () { 1.258 + /* the normative part of the spec states that: 1.259 + "unless the length is zero, in which case there are no supported property indices" 1.260 + ... 1.261 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.262 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.263 + assert_equals( makeEl('div',{itemtype:' '}).itemType[0], window.undefined ); 1.264 +}, 'itemType[index] must be undefined for out-of-range index'); 1.265 +test(function () { 1.266 + assert_equals( makeEl('div',{itemtype:' '}).itemType[-1], window.undefined ); 1.267 +}, 'itemType[index] must be undefined for negative index'); 1.268 +test(function () { 1.269 + assert_equals( makeEl('div',{itemType:' '}).itemType.toString(), ' ' ); 1.270 +}, 'empty itemType should stringify to contain the attribute\'s whitespace'); 1.271 +test(function () { 1.272 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.contains(''); } ); 1.273 +}, 'itemType.contains(empty_string) must throw a SYNTAX_ERR'); 1.274 +test(function () { 1.275 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.add(''); } ); 1.276 +}, 'itemType.add(empty_string) must throw a SYNTAX_ERR'); 1.277 +test(function () { 1.278 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.remove(''); } ); 1.279 +}, 'itemType.remove(empty_string) must throw a SYNTAX_ERR'); 1.280 +test(function () { 1.281 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.toggle(''); } ); 1.282 +}, 'itemType.toggle(empty_string) must throw a SYNTAX_ERR'); 1.283 +test(function () { 1.284 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.contains('a b'); } ); 1.285 +}, 'itemType.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.286 +test(function () { 1.287 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.add('a b'); } ); 1.288 +}, 'itemType.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.289 +test(function () { 1.290 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.remove('a b'); } ); 1.291 +}, 'itemType.remove(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.292 +test(function () { 1.293 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.toggle('a b'); } ); 1.294 +}, 'itemType.toggle(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.295 +test(function () { 1.296 + var testEl = makeEl('div',{itemtype:'foo'}); 1.297 + assert_true( testEl.itemType.contains('foo'), 'before change' ); 1.298 + testEl.setAttribute('itemtype','bar'); 1.299 + assert_true( testEl.itemType.contains('bar'), 'after change' ); 1.300 + assert_false( testEl.itemType.contains('foo'), 'after change' ); 1.301 +}, 'itemType.contains must update when the underlying attribute is changed'); 1.302 +test(function () { 1.303 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('FOO') ); 1.304 +}, 'itemType.contains must be case sensitive'); 1.305 +test(function () { 1.306 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo.') ); 1.307 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo)') ); 1.308 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo\'') ); 1.309 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo$') ); 1.310 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo~') ); 1.311 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo?') ); 1.312 + assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo\\') ); 1.313 +}, 'itemType.contains must not match when punctuation characters are added'); 1.314 +test(function () { 1.315 + var elem = makeEl('div',{itemtype:'foo'}); 1.316 + elem.itemType.add('FOO'); 1.317 + assert_true( elem.itemType.contains('foo') ); 1.318 +}, 'itemType.add must not remove existing tokens'); 1.319 +test(function () { 1.320 + assert_true( makeEl('div',{itemtype:'foo FOO'}).itemType.contains('FOO') ); 1.321 +}, 'itemType.contains case sensitivity must match a case-specific string'); 1.322 +test(function () { 1.323 + assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType.length, 2 ); 1.324 +}, 'itemType.length must correctly reflect the number of tokens'); 1.325 +test(function () { 1.326 + assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType.item(0), 'foo' ); 1.327 +}, 'itemType.item(0) must return the first token'); 1.328 +test(function () { 1.329 + var elem = makeEl('div',{itemtype:'foo'}); 1.330 + elem.itemType.add('FOO'); 1.331 + assert_equals( elem.itemType.item(1), 'FOO' ); 1.332 +}, 'itemType.item must return case-sensitive strings and preserve token order'); 1.333 +test(function () { 1.334 + assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType[0], 'foo' ); 1.335 +}, 'itemType[0] must return the first token'); 1.336 +test(function () { 1.337 + assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType[1], 'FOO' ); 1.338 +}, 'itemType[index] must return case-sensitive strings and preserve token order'); 1.339 +test(function () { 1.340 + /* the normative part of the spec states that: 1.341 + "unless the length is zero, in which case there are no supported property indices" 1.342 + ... 1.343 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.344 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.345 + assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType[2], window.undefined ); 1.346 +}, 'itemType[index] must still be undefined for out-of-range index when earlier indexes exist'); 1.347 +test(function () { 1.348 + var elem = makeEl('div',{}); 1.349 + elem.itemType.add('foo'); 1.350 + elem.itemType.add('FOO'); 1.351 + assert_equals( elem.getAttribute('itemtype'), 'foo FOO' ); 1.352 +}, 'itemtype attribute must update correctly when items have been added through itemType'); 1.353 +test(function () { 1.354 + var elem = makeEl('div',{}); 1.355 + elem.itemType.add('foo'); 1.356 + elem.itemType.add('FOO'); 1.357 + assert_equals( elem.itemType + '', 'foo FOO' ); 1.358 +}, 'itemType must stringify correctly when items have been added'); 1.359 +test(function () { 1.360 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.361 + elem.itemType.add('foo'); 1.362 + assert_equals( elem.itemType.length, 2 ); 1.363 + assert_equals( elem.itemType + '', 'foo FOO' ); 1.364 +}, 'itemType.add must not make any changes if an existing token is added'); 1.365 +test(function () { 1.366 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.367 + elem.itemType.remove('bar'); 1.368 + assert_equals( elem.itemType.length, 2 ); 1.369 + assert_equals( elem.itemType + '', 'foo FOO' ); 1.370 +}, 'itemType.remove must not make any changes if a non-existing token is removed'); 1.371 +test(function () { 1.372 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.373 + elem.itemType.remove('foo'); 1.374 + assert_equals( elem.itemType.length, 1 ); 1.375 + assert_equals( elem.itemType.toString(), 'FOO' ); 1.376 + assert_false( elem.itemType.contains('foo') ); 1.377 + assert_true( elem.itemType.contains('FOO') ); 1.378 +}, 'itemType.remove must remove existing tokens'); 1.379 +test(function () { 1.380 + var elem = makeEl('div',{itemtype:'test test'}); 1.381 + elem.itemType.remove('test'); 1.382 + assert_equals( elem.itemType.length, 0 ); 1.383 + assert_false( elem.itemType.contains('test') ); 1.384 +}, 'itemType.remove must remove duplicated tokens'); 1.385 +test(function () { 1.386 + var elem = makeEl('div',{itemtype:'token1 token2 token3'}); 1.387 + elem.itemType.remove('token2'); 1.388 + assert_equals( elem.itemType.toString(), 'token1 token3' ); 1.389 +}, 'itemType.remove must collapse whitespace around removed tokens'); 1.390 +test(function () { 1.391 + var elem = makeEl('div',{itemtype:' token1 token2 '}); 1.392 + elem.itemType.remove('token2'); 1.393 + assert_equals( elem.itemType.toString(), 'token1' ); 1.394 +}, 'itemType.remove must remove all useless whitespace'); 1.395 +test(function () { 1.396 + var elem = makeEl('div',{itemtype:' token1 token2 token3 '}); 1.397 + elem.itemType.remove('token2'); 1.398 + assert_equals( elem.itemType.toString(), 'token1 token3' ); 1.399 +}, 'itemType.remove must collapse multiple whitespace around removed tokens'); 1.400 +test(function () { 1.401 + var elem = makeEl('div',{itemtype:' token1 token2 token1 '}); 1.402 + elem.itemType.remove('token2'); 1.403 + assert_equals( elem.itemType.toString(), 'token1' ); 1.404 +}, 'itemType.remove must remove duplicates when removing tokens'); 1.405 +test(function () { 1.406 + var elem = makeEl('div',{itemtype:' token1 token2 token3 '}); 1.407 + elem.itemType.remove('token1', 'token3'); 1.408 + assert_equals( elem.itemType.toString(), 'token2' ); 1.409 +}, 'itemType.remove must collapse whitespace when removing multiple tokens'); 1.410 +test(function () { 1.411 + var elem = makeEl('div',{itemtype:' token1 token2 '}); 1.412 + elem.itemType.add('token1'); 1.413 + assert_equals( elem.itemType.toString(), 'token1 token2' ); 1.414 +}, 'itemType.add must remove unused whitespace when the token already exists'); 1.415 +test(function () { 1.416 + var elem = makeEl('div',{itemtype:'FOO'}); 1.417 + assert_true(elem.itemType.toggle('foo')); 1.418 + assert_equals( elem.itemType.length, 2 ); 1.419 + assert_true( elem.itemType.contains('foo') ); 1.420 + assert_true( elem.itemType.contains('FOO') ); 1.421 +}, 'itemType.toggle must toggle tokens case-sensitively when adding'); 1.422 +test(function () { 1.423 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.424 + assert_false(elem.itemType.toggle('foo')); 1.425 + assert_false(elem.itemType.toggle('FOO')); 1.426 + assert_false( elem.itemType.contains('foo') ); 1.427 + assert_false( elem.itemType.contains('FOO') ); 1.428 +}, 'itemType.toggle must be able to remove tokens case-sensitively'); 1.429 +test(function () { 1.430 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.431 + elem.itemType.toggle('foo'); 1.432 + elem.itemType.toggle('FOO'); 1.433 + assert_equals( elem.getAttribute('itemtype'), '' ); 1.434 +}, 'itemtype attribute must be empty when all classes have been removed'); 1.435 +test(function () { 1.436 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.437 + elem.itemType.toggle('foo'); 1.438 + elem.itemType.toggle('FOO'); 1.439 + assert_equals( elem.itemType.toString(), '' ); 1.440 +}, 'itemType must stringify to an empty string when all classes have been removed'); 1.441 +test(function () { 1.442 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.443 + elem.itemType.toggle('foo'); 1.444 + elem.itemType.toggle('FOO'); 1.445 + assert_equals( elem.itemType.item(0), null ); 1.446 +}, 'itemType.item(0) must return null when all classes have been removed'); 1.447 +test(function () { 1.448 + /* the normative part of the spec states that: 1.449 + "unless the length is zero, in which case there are no supported property indices" 1.450 + ... 1.451 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.452 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.453 + var elem = makeEl('div',{itemtype:'foo FOO'}); 1.454 + elem.itemType.toggle('foo'); 1.455 + elem.itemType.toggle('FOO'); 1.456 + assert_equals( elem.itemType[0], window.undefined ); 1.457 +}, 'itemType[0] must be undefined when all classes have been removed'); 1.458 +//if the last character of DOMTokenSting underlying character is not a space character, append U+0020", where "space character" is from " \t\r\n\f" 1.459 +test(function () { 1.460 + var elem = makeEl('div',{itemtype:'a '}); 1.461 + elem.itemType.add('b'); 1.462 + assert_equals(elem.itemType.toString(),'a b'); 1.463 +}, 'itemType.add should treat " " as a space'); 1.464 +test(function () { 1.465 + var elem = makeEl('div',{itemtype:'a\t'}); 1.466 + elem.itemType.add('b'); 1.467 + assert_equals(elem.itemType.toString(),'a b'); 1.468 +}, 'itemType.add should normalize \\t as a space'); 1.469 +test(function () { 1.470 + var elem = makeEl('div',{itemtype:'a\r'}); 1.471 + elem.itemType.add('b'); 1.472 + assert_equals(elem.itemType.toString(),'a b'); 1.473 +}, 'itemType.add should normalize \\r as a space'); 1.474 +test(function () { 1.475 + var elem = makeEl('div',{itemtype:'a\n'}); 1.476 + elem.itemType.add('b'); 1.477 + assert_equals(elem.itemType.toString(),'a b'); 1.478 +}, 'itemType.add should normalize \\n as a space'); 1.479 +test(function () { 1.480 + var elem = makeEl('div',{itemtype:'a\f'}); 1.481 + elem.itemType.add('b'); 1.482 + assert_equals(elem.itemType.toString(),'a b'); 1.483 +}, 'itemType.add should normalize \\f as a space'); 1.484 +test(function () { 1.485 + var elem = makeEl('div',{itemtype:'foo'}); 1.486 + elem.itemType.remove('foo'); 1.487 + elem.removeAttribute('itemtype'); 1.488 + assert_true( elem.itemType.toggle('foo') ); 1.489 +}, 'itemType.toggle must work after removing the itemtype attribute'); 1.490 +test(function () { 1.491 + //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter 1.492 + //ES5 makes [[Put]] fail but not throw 1.493 + var failed = false; 1.494 + var elem = makeEl('div',{itemtype:'token1'}); 1.495 + try { 1.496 + elem.itemType.length = 0; 1.497 + } catch(e) { 1.498 + failed = e; 1.499 + } 1.500 + assert_equals(elem.itemType.length,1); 1.501 + assert_false(failed,'an error was thrown'); 1.502 +}, 'itemType.length must be read-only'); 1.503 +test(function () { 1.504 + var failed = false, elem = makeEl('div',{itemtype:'test'}), realList = elem.itemType; 1.505 + try { 1.506 + elem.itemType = 'dummy'; 1.507 + } catch(e) { 1.508 + failed = e; 1.509 + } 1.510 + assert_equals(elem.itemType,realList); 1.511 + assert_equals(elem.itemType.toString(),'dummy','attempting to write should modify the underlying string'); 1.512 + assert_false(failed,'an error was thrown'); 1.513 +}, 'itemType must be read-only'); 1.514 + 1.515 +/* itemProp property tests (properties collection tests are done later) */ 1.516 +test(function () { 1.517 + assert_equals(makeEl('div',{}).itemProp.toString(),'','no attribute'); 1.518 + assert_equals(makeEl('div',{itemprop:' http://example.com/foo#bar test '}).itemProp.toString(),' http://example.com/foo#bar test ','with URL and simple tokens'); 1.519 + var testEl = makeEl('div',{itemprop:'http://example.com/foo#bar'}); 1.520 + testEl.removeAttribute('itemprop'); 1.521 + assert_equals(testEl.itemProp.toString(),'','removed attribute'); 1.522 +}, 'the itemprop attribute must be reflected by the .itemProp property'); 1.523 +test(function () { 1.524 + assert_equals( typeof makeEl('div',{}).itemProp, 'object' ); 1.525 +}, 'the itemProp property must be an object'); 1.526 +test(function () { 1.527 + assert_true( makeEl('div',{}).itemProp instanceof DOMTokenList, 'instanceof test' ); 1.528 + DOMTokenList.prototype.customProperty = true; 1.529 + assert_true( makeEl('div',{}).itemProp.customProperty, 'inheritance test' ); 1.530 +}, 'the itemProp property must implement DOMTokenList'); 1.531 +test(function () { 1.532 + var testEl = makeEl('div',{}); 1.533 + assert_equals( testEl.itemProp, testEl.itemProp ); 1.534 +}, 'the itemProp property must always reference the same object'); 1.535 +test(function () { 1.536 + assert_equals( makeEl('div',{itemprop:'test test'}).itemProp.length, 2, 'duplicates in initial string should be preserved' ); 1.537 + assert_equals( makeEl('div',{itemprop:'test test'}).itemProp.item(0), 'test' ); 1.538 + assert_true( makeEl('div',{itemprop:'test test'}).itemProp.contains('test') ); 1.539 +}, 'itemProp must be correct for an element that has itemprop tokens'); 1.540 +test(function () { 1.541 + assert_equals( makeEl('div',{itemprop:' '}).itemProp.length, 0 ); 1.542 +}, 'itemProp.length must be 0 for an element that has no tokens'); 1.543 +test(function () { 1.544 + assert_false( makeEl('div',{itemprop:' '}).itemProp.contains('foo') ); 1.545 +}, 'itemProp must not contain an undefined class'); 1.546 +test(function () { 1.547 + assert_equals( makeEl('div',{itemprop:' '}).itemProp.item(0), null ); 1.548 +}, 'itemProp.item() must return null for out-of-range index'); 1.549 +test(function () { 1.550 + assert_equals( makeEl('div',{itemprop:' '}).itemProp.item(-1), null ); 1.551 +}, 'itemProp.item() must return null for negative index'); 1.552 +test(function () { 1.553 + /* the normative part of the spec states that: 1.554 + "unless the length is zero, in which case there are no supported property indices" 1.555 + ... 1.556 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.557 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.558 + assert_equals( makeEl('div',{itemprop:' '}).itemProp[0], window.undefined ); 1.559 +}, 'itemProp[index] must be undefined for out-of-range index'); 1.560 +test(function () { 1.561 + assert_equals( makeEl('div',{itemprop:' '}).itemProp[-1], window.undefined ); 1.562 +}, 'itemProp[index] must be undefined for negative index'); 1.563 +test(function () { 1.564 + assert_equals( makeEl('div',{itemprop:' '}).itemProp.toString(), ' ' ); 1.565 +}, 'empty itemProp should stringify to contain the attribute\'s whitespace'); 1.566 +test(function () { 1.567 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.contains(''); } ); 1.568 +}, 'itemProp.contains(empty_string) must throw a SYNTAX_ERR'); 1.569 +test(function () { 1.570 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.add(''); } ); 1.571 +}, 'itemProp.add(empty_string) must throw a SYNTAX_ERR'); 1.572 +test(function () { 1.573 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.remove(''); } ); 1.574 +}, 'itemProp.remove(empty_string) must throw a SYNTAX_ERR'); 1.575 +test(function () { 1.576 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.toggle(''); } ); 1.577 +}, 'itemProp.toggle(empty_string) must throw a SYNTAX_ERR'); 1.578 +test(function () { 1.579 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.contains('a b'); } ); 1.580 +}, '.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.581 +test(function () { 1.582 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.add('a b'); } ); 1.583 +}, 'itemProp.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.584 +test(function () { 1.585 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.remove('a b'); } ); 1.586 +}, 'itemProp.remove(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.587 +test(function () { 1.588 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.toggle('a b'); } ); 1.589 +}, 'itemProp.toggle(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.590 +test(function () { 1.591 + var testEl = makeEl('div',{itemprop:'foo'}); 1.592 + assert_true( testEl.itemProp.contains('foo'), 'before change' ); 1.593 + testEl.setAttribute('itemprop','bar'); 1.594 + assert_true( testEl.itemProp.contains('bar'), 'after change' ); 1.595 + assert_false( testEl.itemProp.contains('foo'), 'after change' ); 1.596 +}, 'itemProp.contains must update when the underlying attribute is changed'); 1.597 +test(function () { 1.598 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('FOO') ); 1.599 +}, 'itemProp.contains must be case sensitive'); 1.600 +test(function () { 1.601 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo.') ); 1.602 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo)') ); 1.603 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo\'') ); 1.604 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo$') ); 1.605 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo~') ); 1.606 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo?') ); 1.607 + assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo\\') ); 1.608 +}, 'itemProp.contains must not match when punctuation characters are added'); 1.609 +test(function () { 1.610 + var elem = makeEl('div',{itemprop:'foo'}); 1.611 + elem.itemProp.add('FOO'); 1.612 + assert_true( elem.itemProp.contains('foo') ); 1.613 +}, 'itemProp.add must not remove existing tokens'); 1.614 +test(function () { 1.615 + assert_true( makeEl('div',{itemprop:'foo FOO'}).itemProp.contains('FOO') ); 1.616 +}, 'itemProp.contains case sensitivity must match a case-specific string'); 1.617 +test(function () { 1.618 + assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp.length, 2 ); 1.619 +}, 'itemProp.length must correctly reflect the number of tokens'); 1.620 +test(function () { 1.621 + assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp.item(0), 'foo' ); 1.622 +}, 'itemProp.item(0) must return the first token'); 1.623 +test(function () { 1.624 + var elem = makeEl('div',{itemprop:'foo'}); 1.625 + elem.itemProp.add('FOO'); 1.626 + assert_equals( elem.itemProp.item(1), 'FOO' ); 1.627 +}, 'itemProp.item must return case-sensitive strings and preserve token order'); 1.628 +test(function () { 1.629 + assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp[0], 'foo' ); 1.630 +}, 'itemProp[0] must return the first token'); 1.631 +test(function () { 1.632 + assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp[1], 'FOO' ); 1.633 +}, 'itemProp[index] must return case-sensitive strings and preserve token order'); 1.634 +test(function () { 1.635 + /* the normative part of the spec states that: 1.636 + "unless the length is zero, in which case there are no supported property indices" 1.637 + ... 1.638 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.639 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.640 + assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp[2], window.undefined ); 1.641 +}, 'itemProp[index] must still be undefined for out-of-range index when earlier indexes exist'); 1.642 +test(function () { 1.643 + var elem = makeEl('div',{}); 1.644 + elem.itemProp.add('foo'); 1.645 + elem.itemProp.add('FOO'); 1.646 + assert_equals( elem.getAttribute('itemprop'), 'foo FOO' ); 1.647 +}, 'itemprop attribute must update correctly when items have been added through itemProp'); 1.648 +test(function () { 1.649 + var elem = makeEl('div',{}); 1.650 + elem.itemProp.add('foo'); 1.651 + elem.itemProp.add('FOO'); 1.652 + assert_equals( elem.itemProp + '', 'foo FOO' ); 1.653 +}, 'itemProp must stringify correctly when items have been added'); 1.654 +test(function () { 1.655 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.656 + elem.itemProp.add('foo'); 1.657 + assert_equals( elem.itemProp.length, 2 ); 1.658 + assert_equals( elem.itemProp + '', 'foo FOO' ); 1.659 +}, 'itemProp.add must not make any changes if an existing token is added'); 1.660 +test(function () { 1.661 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.662 + elem.itemProp.remove('bar'); 1.663 + assert_equals( elem.itemProp.length, 2 ); 1.664 + assert_equals( elem.itemProp + '', 'foo FOO' ); 1.665 +}, 'itemProp.remove must not make any changes if a non-existing token is removed'); 1.666 +test(function () { 1.667 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.668 + elem.itemProp.remove('foo'); 1.669 + assert_equals( elem.itemProp.length, 1 ); 1.670 + assert_equals( elem.itemProp.toString(), 'FOO' ); 1.671 + assert_false( elem.itemProp.contains('foo') ); 1.672 + assert_true( elem.itemProp.contains('FOO') ); 1.673 +}, 'itemProp.remove must remove existing tokens'); 1.674 +test(function () { 1.675 + var elem = makeEl('div',{itemprop:'test test'}); 1.676 + elem.itemProp.remove('test'); 1.677 + assert_equals( elem.itemProp.length, 0 ); 1.678 + assert_false( elem.itemProp.contains('test') ); 1.679 +}, 'itemProp.remove must remove duplicated tokens'); 1.680 +test(function () { 1.681 + var elem = makeEl('div',{itemprop:'token1 token2 token3'}); 1.682 + elem.itemProp.remove('token2'); 1.683 + assert_equals( elem.itemProp.toString(), 'token1 token3' ); 1.684 +}, 'itemProp.remove must collapse whitespace around removed tokens'); 1.685 +test(function () { 1.686 + var elem = makeEl('div',{itemprop:' token1 token2 token3 '}); 1.687 + elem.itemProp.remove('token2'); 1.688 + assert_equals( elem.itemProp.toString(), 'token1 token3' ); 1.689 +}, 'itemProp.remove must remove all useless whitespace'); 1.690 +test(function () { 1.691 + var elem = makeEl('div',{itemprop:' token1 token2 token3 '}); 1.692 + elem.itemProp.remove('token1', 'token3'); 1.693 + assert_equals( elem.itemProp.toString(), 'token2' ); 1.694 +}, 'itemProp.remove must remove useless whitespace when removing multiple tokens'); 1.695 +test(function () { 1.696 + var elem = makeEl('div',{itemprop:' token1 token1 '}); 1.697 + elem.itemProp.add('token1'); 1.698 + assert_equals( elem.itemProp.toString(), 'token1' ); 1.699 +}, 'itemProp.add must remove useless whitespace and duplicates when the token already exists'); 1.700 +test(function () { 1.701 + var elem = makeEl('div',{itemprop:'FOO'}); 1.702 + assert_true(elem.itemProp.toggle('foo')); 1.703 + assert_equals( elem.itemProp.length, 2 ); 1.704 + assert_true( elem.itemProp.contains('foo') ); 1.705 + assert_true( elem.itemProp.contains('FOO') ); 1.706 +}, 'itemProp.toggle must toggle tokens case-sensitively when adding'); 1.707 +test(function () { 1.708 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.709 + assert_false(elem.itemProp.toggle('foo')); 1.710 + assert_false(elem.itemProp.toggle('FOO')); 1.711 + assert_false( elem.itemProp.contains('foo') ); 1.712 + assert_false( elem.itemProp.contains('FOO') ); 1.713 +}, 'itemProp.toggle must be able to remove tokens case-sensitively'); 1.714 +test(function () { 1.715 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.716 + elem.itemProp.toggle('foo'); 1.717 + elem.itemProp.toggle('FOO'); 1.718 + assert_equals( elem.getAttribute('itemprop'), '' ); 1.719 +}, 'itemprop attribute must be empty when all classes have been removed'); 1.720 +test(function () { 1.721 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.722 + elem.itemProp.toggle('foo'); 1.723 + elem.itemProp.toggle('FOO'); 1.724 + assert_equals( elem.itemProp.toString(), '' ); 1.725 +}, 'itemProp must stringify to an empty string when all classes have been removed'); 1.726 +test(function () { 1.727 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.728 + elem.itemProp.toggle('foo'); 1.729 + elem.itemProp.toggle('FOO'); 1.730 + assert_equals( elem.itemProp.item(0), null ); 1.731 +}, 'itemProp.item(0) must return null when all classes have been removed'); 1.732 +test(function () { 1.733 + /* the normative part of the spec states that: 1.734 + "unless the length is zero, in which case there are no supported property indices" 1.735 + ... 1.736 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.737 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.738 + var elem = makeEl('div',{itemprop:'foo FOO'}); 1.739 + elem.itemProp.toggle('foo'); 1.740 + elem.itemProp.toggle('FOO'); 1.741 + assert_equals( elem.itemProp[0], window.undefined ); 1.742 +}, 'itemProp[0] must be undefined when all classes have been removed'); 1.743 +//if the last character of DOMTokenSting underlying character is not a space character, append U+0020", where "space character" is from " \t\r\n\f" 1.744 +test(function () { 1.745 + var elem = makeEl('div',{itemprop:'a '}); 1.746 + elem.itemProp.add('b'); 1.747 + assert_equals(elem.itemProp.toString(),'a b'); 1.748 +}, 'itemProp.add should treat " " as a space'); 1.749 +test(function () { 1.750 + var elem = makeEl('div',{itemprop:'a\t'}); 1.751 + elem.itemProp.add('b'); 1.752 + assert_equals(elem.itemProp.toString(),'a b'); 1.753 +}, 'itemProp.add should normalize \\t as a space'); 1.754 +test(function () { 1.755 + var elem = makeEl('div',{itemprop:'a\r'}); 1.756 + elem.itemProp.add('b'); 1.757 + assert_equals(elem.itemProp.toString(),'a b'); 1.758 +}, 'itemProp.add should normalize \\r as a space'); 1.759 +test(function () { 1.760 + var elem = makeEl('div',{itemprop:'a\n'}); 1.761 + elem.itemProp.add('b'); 1.762 + assert_equals(elem.itemProp.toString(),'a b'); 1.763 +}, 'itemProp.add should normalize \\n as a space'); 1.764 +test(function () { 1.765 + var elem = makeEl('div',{itemprop:'a\f'}); 1.766 + elem.itemProp.add('b'); 1.767 + assert_equals(elem.itemProp.toString(),'a b'); 1.768 +}, 'itemProp.add should normalize \\f as a space'); 1.769 +test(function () { 1.770 + var elem = makeEl('div',{itemprop:'foo'}); 1.771 + elem.itemProp.remove('foo'); 1.772 + elem.removeAttribute('itemprop'); 1.773 + assert_true( elem.itemProp.toggle('foo') ); 1.774 +}, 'itemProp.toggle must work after removing the itemprop attribute'); 1.775 +test(function () { 1.776 + //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter 1.777 + //ES5 makes [[Put]] fail but not throw 1.778 + var failed = false; 1.779 + var elem = makeEl('div',{itemprop:'token1'}); 1.780 + try { 1.781 + elem.itemProp.length = 0; 1.782 + } catch(e) { 1.783 + failed = e; 1.784 + } 1.785 + assert_equals(elem.itemProp.length,1); 1.786 + assert_false(failed,'an error was thrown'); 1.787 +}, 'itemProp.length must be read-only'); 1.788 +test(function () { 1.789 + var failed = false, elem = makeEl('div',{itemprop:'test'}), realList = elem.itemProp; 1.790 + try { 1.791 + elem.itemProp = 'dummy'; 1.792 + } catch(e) { 1.793 + failed = e; 1.794 + } 1.795 + assert_equals(elem.itemProp,realList); 1.796 + assert_equals(elem.itemProp.toString(),'dummy','attempting to write should modify the underlying string'); 1.797 + assert_false(failed,'an error was thrown'); 1.798 +}, 'itemProp must be read-only'); 1.799 + 1.800 +/* itemId property tests */ 1.801 +test(function () { 1.802 + assert_equals( makeEl('div',{itemid:'http://example.com/foo'}).itemId, 'http://example.com/foo' ); 1.803 + assert_equals( makeEl('div',{itemid:'http://example.com/FOO'}).itemId, 'http://example.com/FOO', 'case-sensitive' ); 1.804 + assert_equals( makeEl('div',{itemid:' http://example.com/foo '}).itemId, 'http://example.com/foo', 'whitespace' ); 1.805 + assert_equals( makeEl('div',{itemid:'data:text/plain,'}).itemId, 'data:text/plain,' ); 1.806 + assert_equals( makeEl('div',{itemid:'madeup:onthespot'}).itemId, 'madeup:onthespot' ); 1.807 + assert_equals( makeEl('div',{}).itemId, '' ); 1.808 +}, 'the itemid attribute must be reflected by the .itemId property'); 1.809 +test(function () { 1.810 + var testEl = makeEl('div',{}); 1.811 + testEl.itemId = 'http://example.com/foo'; 1.812 + assert_equals(testEl.itemId,'http://example.com/foo','writing a URL'); 1.813 + testEl.itemId = ''; 1.814 + assert_equals(testEl.itemId,location.href,'writing an empty string'); 1.815 +}, 'the itemId property must be read/write'); 1.816 +test(function () { 1.817 + var testEl = makeEl('div',{}); 1.818 + testEl.itemId = 'http://example.com/foo'; 1.819 + assert_true(testEl.hasAttribute('itemid'),'writing a URL'); 1.820 + assert_equals(testEl.getAttribute('itemid'),'http://example.com/foo','writing a URL'); 1.821 + testEl = makeEl('div',{}) 1.822 + testEl.itemId = ''; 1.823 + assert_true(testEl.hasAttribute('itemid'),'writing an empty string'); 1.824 + assert_equals(testEl.getAttribute('itemid'),'','writing an empty string'); 1.825 +}, 'writing to the itemId property must create the itemid content attribute'); 1.826 +test(function () { 1.827 + assert_equals( makeEl('div',{itemid:'foo'}).itemId, location.href.replace(/\/[^\/]*$/,'\/foo'),'foo' ); 1.828 + assert_equals( makeEl('div',{itemid:'foo bar'}).itemId, location.href.replace(/\/[^\/]*$/,'\/foo%20bar'),'foo bar' ); 1.829 + assert_equals( makeEl('div',{itemid:'foo\u0129 bar'}).itemId, location.href.replace(/\/[^\/]*$/,'\/foo%C4%A9%20bar'),'foo\u0129 bar' ); 1.830 +}, 'the itemId property must see the resolved itemid URL'); 1.831 +test(function () { 1.832 + var testEl = makeEl('div',{}); 1.833 + testEl.itemId = 'foo'; 1.834 + assert_equals( testEl.itemId, location.href.replace(/\/[^\/]*$/,'\/foo') ); 1.835 +}, 'the itemId property must see the resolved itemId property URL on setting'); 1.836 +test(function () { 1.837 + var testEl = makeEl('div',{}); 1.838 + testEl.itemId = 'foo'; 1.839 + assert_equals( testEl.getAttribute('itemid'), 'foo' ); 1.840 +}, 'the itemid attribute must see the resolved itemId URL'); 1.841 + 1.842 +/* itemRef property tests (properties collection tests are done later) */ 1.843 +test(function () { 1.844 + assert_equals(makeEl('div',{}).itemRef.toString(),'','no attribute'); 1.845 + assert_equals(makeEl('div',{itemref:' foo bar '}).itemRef.toString(),' foo bar ','with simple tokens'); 1.846 + var testEl = makeEl('div',{itemref:'foo'}); 1.847 + testEl.removeAttribute('itemref'); 1.848 + assert_equals(testEl.itemRef.toString(),'','removed attribute'); 1.849 +}, 'the itemref attribute must be reflected by the .itemRef property'); 1.850 +test(function () { 1.851 + assert_equals( typeof makeEl('div',{}).itemRef, 'object' ); 1.852 +}, 'the itemRef property must be an object'); 1.853 +test(function () { 1.854 + assert_true( makeEl('div',{}).itemRef instanceof DOMTokenList, 'instanceof test' ); 1.855 + DOMTokenList.prototype.customProperty = true; 1.856 + assert_true( makeEl('div',{}).itemRef.customProperty, 'inheritance test' ); 1.857 +}, 'the itemRef property must implement DOMTokenList'); 1.858 +test(function () { 1.859 + var testEl = makeEl('div',{}); 1.860 + assert_equals( testEl.itemRef, testEl.itemRef ); 1.861 +}, 'the itemRef property must always reference the same object'); 1.862 +test(function () { 1.863 + assert_equals( makeEl('div',{itemref:'test test'}).itemRef.length, 2, 'duplicates in initial string should be preserved' ); 1.864 + assert_equals( makeEl('div',{itemref:'test test'}).itemRef.item(0), 'test' ); 1.865 + assert_true( makeEl('div',{itemref:'test test'}).itemRef.contains('test') ); 1.866 +}, 'itemRef must be correct for an element that has itemref tokens'); 1.867 +test(function () { 1.868 + assert_equals( makeEl('div',{itemref:' '}).itemRef.length, 0 ); 1.869 +}, 'itemRef.length must be 0 for an element that has no tokens'); 1.870 +test(function () { 1.871 + assert_false( makeEl('div',{itemref:' '}).itemRef.contains('foo') ); 1.872 +}, 'itemRef must not contain an undefined class'); 1.873 +test(function () { 1.874 + assert_equals( makeEl('div',{itemref:' '}).itemRef.item(0), null ); 1.875 +}, 'itemRef.item() must return null for out-of-range index'); 1.876 +test(function () { 1.877 + assert_equals( makeEl('div',{itemref:' '}).itemRef.item(-1), null ); 1.878 +}, 'itemRef.item() must return null for negative index'); 1.879 +test(function () { 1.880 + /* the normative part of the spec states that: 1.881 + "unless the length is zero, in which case there are no supported property indices" 1.882 + ... 1.883 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.884 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.885 + assert_equals( makeEl('div',{itemref:' '}).itemRef[0], window.undefined ); 1.886 +}, 'itemRef[index] must be undefined for out-of-range index'); 1.887 +test(function () { 1.888 + assert_equals( makeEl('div',{itemref:' '}).itemRef[-1], window.undefined ); 1.889 +}, 'itemRef[index] must be undefined for negative index'); 1.890 +test(function () { 1.891 + assert_equals( makeEl('div',{itemref:' '}).itemRef.toString(), ' ' ); 1.892 +}, 'empty itemRef should stringify to contain the attribute\'s whitespace'); 1.893 +test(function () { 1.894 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.contains(''); } ); 1.895 +}, 'itemRef.contains(empty_string) must throw a SYNTAX_ERR'); 1.896 +test(function () { 1.897 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.add(''); } ); 1.898 +}, 'itemRef.add(empty_string) must throw a SYNTAX_ERR'); 1.899 +test(function () { 1.900 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.remove(''); } ); 1.901 +}, 'itemRef.remove(empty_string) must throw a SYNTAX_ERR'); 1.902 +test(function () { 1.903 + assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.toggle(''); } ); 1.904 +}, 'itemRef.toggle(empty_string) must throw a SYNTAX_ERR'); 1.905 +test(function () { 1.906 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.contains('a b'); } ); 1.907 +}, 'itemRef.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.908 +test(function () { 1.909 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.add('a b'); } ); 1.910 +}, 'itemRef.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.911 +test(function () { 1.912 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.remove('a b'); } ); 1.913 +}, 'itemRef.remove(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.914 +test(function () { 1.915 + assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.toggle('a b'); } ); 1.916 +}, 'itemRef.toggle(string_with_spaces) must throw an INVALID_CHARACTER_ERR'); 1.917 +test(function () { 1.918 + var testEl = makeEl('div',{itemref:'foo'}); 1.919 + assert_true( testEl.itemRef.contains('foo'), 'before change' ); 1.920 + testEl.setAttribute('itemref','bar'); 1.921 + assert_true( testEl.itemRef.contains('bar'), 'after change' ); 1.922 + assert_false( testEl.itemRef.contains('foo'), 'after change' ); 1.923 +}, 'itemRef.contains must update when the underlying attribute is changed'); 1.924 +test(function () { 1.925 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('FOO') ); 1.926 +}, 'itemRef.contains must be case sensitive'); 1.927 +test(function () { 1.928 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo.') ); 1.929 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo)') ); 1.930 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo\'') ); 1.931 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo$') ); 1.932 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo~') ); 1.933 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo?') ); 1.934 + assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo\\') ); 1.935 +}, 'itemRef.contains must not match when punctuation characters are added'); 1.936 +test(function () { 1.937 + var elem = makeEl('div',{itemref:'foo'}); 1.938 + elem.itemRef.add('FOO'); 1.939 + assert_true( elem.itemRef.contains('foo') ); 1.940 +}, 'itemRef.add must not remove existing tokens'); 1.941 +test(function () { 1.942 + assert_true( makeEl('div',{itemref:'foo FOO'}).itemRef.contains('FOO') ); 1.943 +}, 'itemRef.contains case sensitivity must match a case-specific string'); 1.944 +test(function () { 1.945 + assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef.length, 2 ); 1.946 +}, 'itemRef.length must correctly reflect the number of tokens'); 1.947 +test(function () { 1.948 + assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef.item(0), 'foo' ); 1.949 +}, 'itemRef.item(0) must return the first token'); 1.950 +test(function () { 1.951 + var elem = makeEl('div',{itemref:'foo'}); 1.952 + elem.itemRef.add('FOO'); 1.953 + assert_equals( elem.itemRef.item(1), 'FOO' ); 1.954 +}, 'itemRef.item must return case-sensitive strings and preserve token order'); 1.955 +test(function () { 1.956 + assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef[0], 'foo' ); 1.957 +}, 'itemRef[0] must return the first token'); 1.958 +test(function () { 1.959 + assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef[1], 'FOO' ); 1.960 +}, 'itemRef[index] must return case-sensitive strings and preserve token order'); 1.961 +test(function () { 1.962 + /* the normative part of the spec states that: 1.963 + "unless the length is zero, in which case there are no supported property indices" 1.964 + ... 1.965 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.966 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.967 + assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef[2], window.undefined ); 1.968 +}, 'itemRef[index] must still be undefined for out-of-range index when earlier indexes exist'); 1.969 +test(function () { 1.970 + var elem = makeEl('div',{}); 1.971 + elem.itemRef.add('foo'); 1.972 + elem.itemRef.add('FOO'); 1.973 + assert_equals( elem.getAttribute('itemref'), 'foo FOO' ); 1.974 +}, 'itemref attribute must update correctly when items have been added through itemRef'); 1.975 +test(function () { 1.976 + var elem = makeEl('div',{}); 1.977 + elem.itemRef.add('foo'); 1.978 + elem.itemRef.add('FOO'); 1.979 + assert_equals( elem.itemRef + '', 'foo FOO' ); 1.980 +}, 'itemRef must stringify correctly when items have been added'); 1.981 +test(function () { 1.982 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.983 + elem.itemRef.add('foo'); 1.984 + assert_equals( elem.itemRef.length, 2 ); 1.985 + assert_equals( elem.itemRef + '', 'foo FOO' ); 1.986 +}, 'itemRef.add must not make any changes if an existing token is added'); 1.987 +test(function () { 1.988 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.989 + elem.itemRef.remove('bar'); 1.990 + assert_equals( elem.itemRef.length, 2 ); 1.991 + assert_equals( elem.itemRef + '', 'foo FOO' ); 1.992 +}, 'itemRef.remove must not make any changes if a non-existing token is removed'); 1.993 +test(function () { 1.994 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.995 + elem.itemRef.remove('foo'); 1.996 + assert_equals( elem.itemRef.length, 1 ); 1.997 + assert_equals( elem.itemRef.toString(), 'FOO' ); 1.998 + assert_false( elem.itemRef.contains('foo') ); 1.999 + assert_true( elem.itemRef.contains('FOO') ); 1.1000 +}, 'itemRef.remove must remove existing tokens'); 1.1001 +test(function () { 1.1002 + var elem = makeEl('div',{itemref:'test test'}); 1.1003 + elem.itemRef.remove('test'); 1.1004 + assert_equals( elem.itemRef.length, 0 ); 1.1005 + assert_false( elem.itemRef.contains('test') ); 1.1006 +}, 'itemRef.remove must remove duplicated tokens'); 1.1007 +test(function () { 1.1008 + var elem = makeEl('div',{itemref:'token1 token2 token3'}); 1.1009 + elem.itemRef.remove('token2'); 1.1010 + assert_equals( elem.itemRef.toString(), 'token1 token3' ); 1.1011 +}, 'itemRef.remove must collapse whitespace around removed tokens'); 1.1012 +test(function () { 1.1013 + var elem = makeEl('div',{itemref:' token1 token2 '}); 1.1014 + elem.itemRef.remove('token2'); 1.1015 + assert_equals( elem.itemRef.toString(), 'token1' ); 1.1016 +}, 'itemRef.remove must remove useless whitespace when removing tokens'); 1.1017 +test(function () { 1.1018 + var elem = makeEl('div',{itemref:' token1 token2 token3 '}); 1.1019 + elem.itemRef.remove('token2'); 1.1020 + assert_equals( elem.itemRef.toString(), 'token1 token3' ); 1.1021 +}, 'itemRef.remove must remove useless whitespace when removing tokens'); 1.1022 +test(function () { 1.1023 + var elem = makeEl('div',{itemref:' token1 token2 token3 '}); 1.1024 + elem.itemRef.remove('token1', 'token3'); 1.1025 + assert_equals( elem.itemRef.toString(), 'token2' ); 1.1026 +}, 'itemRef.remove must collapse whitespace when removing multiple tokens'); 1.1027 +test(function () { 1.1028 + var elem = makeEl('div',{itemref:' token1 token1 '}); 1.1029 + elem.itemRef.add('token1'); 1.1030 + assert_equals( elem.itemRef.toString(), 'token1' ); 1.1031 +}, 'itemRef.add must remove whitespace and duplicate when the token already exists'); 1.1032 +test(function () { 1.1033 + var elem = makeEl('div',{itemref:'FOO'}); 1.1034 + assert_true(elem.itemRef.toggle('foo')); 1.1035 + assert_equals( elem.itemRef.length, 2 ); 1.1036 + assert_true( elem.itemRef.contains('foo') ); 1.1037 + assert_true( elem.itemRef.contains('FOO') ); 1.1038 +}, 'itemRef.toggle must toggle tokens case-sensitively when adding'); 1.1039 +test(function () { 1.1040 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.1041 + assert_false(elem.itemRef.toggle('foo')); 1.1042 + assert_false(elem.itemRef.toggle('FOO')); 1.1043 + assert_false( elem.itemRef.contains('foo') ); 1.1044 + assert_false( elem.itemRef.contains('FOO') ); 1.1045 +}, 'itemRef.toggle must be able to remove tokens case-sensitively'); 1.1046 +test(function () { 1.1047 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.1048 + elem.itemRef.toggle('foo'); 1.1049 + elem.itemRef.toggle('FOO'); 1.1050 + assert_equals( elem.getAttribute('itemref'), '' ); 1.1051 +}, 'itemref attribute must be empty when all classes have been removed'); 1.1052 +test(function () { 1.1053 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.1054 + elem.itemRef.toggle('foo'); 1.1055 + elem.itemRef.toggle('FOO'); 1.1056 + assert_equals( elem.itemRef.toString(), '' ); 1.1057 +}, 'itemRef must stringify to an empty string when all classes have been removed'); 1.1058 +test(function () { 1.1059 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.1060 + elem.itemRef.toggle('foo'); 1.1061 + elem.itemRef.toggle('FOO'); 1.1062 + assert_equals( elem.itemRef.item(0), null ); 1.1063 +}, 'itemRef.item(0) must return null when all classes have been removed'); 1.1064 +test(function () { 1.1065 + /* the normative part of the spec states that: 1.1066 + "unless the length is zero, in which case there are no supported property indices" 1.1067 + ... 1.1068 + "The term[...] supported property indices [is] used as defined in the WebIDL specification." 1.1069 + WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */ 1.1070 + var elem = makeEl('div',{itemref:'foo FOO'}); 1.1071 + elem.itemRef.toggle('foo'); 1.1072 + elem.itemRef.toggle('FOO'); 1.1073 + assert_equals( elem.itemRef[0], window.undefined ); 1.1074 +}, 'itemRef[0] must be undefined when all classes have been removed'); 1.1075 +//if the last character of DOMTokenSting underlying character is not a space character, append U+0020", where "space character" is from " \t\r\n\f" 1.1076 +test(function () { 1.1077 + var elem = makeEl('div',{itemref:'a '}); 1.1078 + elem.itemRef.add('b'); 1.1079 + assert_equals(elem.itemRef.toString(),'a b'); 1.1080 +}, 'itemRef.add should treat " " as a space'); 1.1081 +test(function () { 1.1082 + var elem = makeEl('div',{itemref:'a\t'}); 1.1083 + elem.itemRef.add('b'); 1.1084 + assert_equals(elem.itemRef.toString(),'a b'); 1.1085 +}, 'itemRef.add should normalize \\t as a space'); 1.1086 +test(function () { 1.1087 + var elem = makeEl('div',{itemref:'a\r'}); 1.1088 + elem.itemRef.add('b'); 1.1089 + assert_equals(elem.itemRef.toString(),'a b'); 1.1090 +}, 'itemRef.add should normalize \\r as a space'); 1.1091 +test(function () { 1.1092 + var elem = makeEl('div',{itemref:'a\n'}); 1.1093 + elem.itemRef.add('b'); 1.1094 + assert_equals(elem.itemRef.toString(),'a b'); 1.1095 +}, 'itemRef.add should normalize \\n as a space'); 1.1096 +test(function () { 1.1097 + var elem = makeEl('div',{itemref:'a\f'}); 1.1098 + elem.itemRef.add('b'); 1.1099 + assert_equals(elem.itemRef.toString(),'a b'); 1.1100 +}, 'itemRef.add should normalize \\f as a space'); 1.1101 +test(function () { 1.1102 + var elem = makeEl('div',{itemref:'foo'}); 1.1103 + elem.itemRef.remove('foo'); 1.1104 + elem.removeAttribute('itemref'); 1.1105 + assert_true( elem.itemRef.toggle('foo') ); 1.1106 +}, 'itemRef.toggle must work after removing the itemref attribute'); 1.1107 +test(function () { 1.1108 + //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter 1.1109 + //ES5 makes [[Put]] fail but not throw 1.1110 + var failed = false; 1.1111 + var elem = makeEl('div',{itemref:'token1'}); 1.1112 + try { 1.1113 + elem.itemRef.length = 0; 1.1114 + } catch(e) { 1.1115 + failed = e; 1.1116 + } 1.1117 + assert_equals(elem.itemRef.length,1); 1.1118 + assert_false(failed,'an error was thrown'); 1.1119 +}, 'itemRef.length must be read-only'); 1.1120 +test(function () { 1.1121 + var failed = false, elem = makeEl('div',{itemref:'test'}), realList = elem.itemRef; 1.1122 + try { 1.1123 + elem.itemRef = 'dummy'; 1.1124 + } catch(e) { 1.1125 + failed = e; 1.1126 + } 1.1127 + assert_equals(elem.itemRef,realList); 1.1128 + assert_equals(elem.itemRef.toString(),'dummy','attempting to write should modify the underlying string'); 1.1129 + assert_false(failed,'an error was thrown'); 1.1130 +}, 'itemRef must be read-only'); 1.1131 + 1.1132 +/* itemValue property tests */ 1.1133 +test(function () { 1.1134 + assert_equals( makeEl('meta',{content:'test'}).itemValue, null, 'meta' ); 1.1135 + assert_equals( makeEl('audio',{src:'test'}).itemValue, null, 'audio' ); 1.1136 + assert_equals( makeEl('embed',{src:'test'}).itemValue, null, 'embed' ); 1.1137 + assert_equals( makeEl('iframe',{src:'test'}).itemValue, null, 'iframe' ); 1.1138 + assert_equals( makeEl('img',{src:'test'}).itemValue, null, 'img' ); 1.1139 + assert_equals( makeEl('source',{src:'test'}).itemValue, null, 'source' ); 1.1140 + assert_equals( makeEl('track',{src:'test'}).itemValue, null, 'track' ); 1.1141 + assert_equals( makeEl('video',{src:'test'}).itemValue, null, 'video' ); 1.1142 + assert_equals( makeEl('a',{href:'test'}).itemValue, null, 'a' ); 1.1143 + assert_equals( makeEl('area',{href:'test'}).itemValue, null, 'area' ); 1.1144 + assert_equals( makeEl('link',{href:'test'}).itemValue, null, 'link' ); 1.1145 + assert_equals( makeEl('object',{data:'test'}).itemValue, null, 'object' ); 1.1146 + assert_equals( makeEl('time',{}).itemValue, null, 'time without datetime' ); 1.1147 + assert_equals( makeEl('time',{datetime:'test'}).itemValue, null, 'time with datetime' ); 1.1148 + assert_equals( makeEl('div',{},'test').itemValue, null, 'otherwise' ); 1.1149 + assert_equals( makeEl('madeuponthespot',{},'test').itemValue, null, 'unknown element' ); 1.1150 +}, 'itemValue must be null if the element does not have an itemprop attribute'); 1.1151 +test(function () { 1.1152 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('meta',{content:'test'}); testEl.itemValue = 'test2'; }, 'meta' ); 1.1153 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('audio',{content:'test'}); testEl.itemValue = 'test2'; }, 'audio' ); 1.1154 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('embed',{content:'test'}); testEl.itemValue = 'test2'; }, 'embed' ); 1.1155 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('iframe',{content:'test'}); testEl.itemValue = 'test2'; }, 'iframe' ); 1.1156 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('img',{content:'test'}); testEl.itemValue = 'test2'; }, 'img' ); 1.1157 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('source',{content:'test'}); testEl.itemValue = 'test2'; }, 'source' ); 1.1158 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('track',{content:'test'}); testEl.itemValue = 'test2'; }, 'track' ); 1.1159 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('video',{content:'test'}); testEl.itemValue = 'test2'; }, 'video' ); 1.1160 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('a',{href:'test'}); testEl.itemValue = 'test2'; }, 'a' ); 1.1161 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('area',{href:'test'}); testEl.itemValue = 'test2'; }, 'area' ); 1.1162 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('link',{href:'test'}); testEl.itemValue = 'test2'; }, 'link' ); 1.1163 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('object',{data:'test'}); testEl.itemValue = 'test2'; }, 'object' ); 1.1164 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('time',{}); testEl.itemValue = 'test2'; }, 'time without datetime' ); 1.1165 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('time',{datetime:'test'}); testEl.itemValue = 'test2'; }, 'time with datetime' ); 1.1166 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('div',{},'test'); testEl.itemValue = 'test2'; }, 'otherwise' ); 1.1167 + assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('madeuponthespot',{},'test'); testEl.itemValue = 'test2'; }, 'unknown element' ); 1.1168 +}, 'writing to itemValue must throw an INVALID_ACCESS_ERR error if the element does not have an itemprop attribute'); 1.1169 +test(function () { 1.1170 + var testEl; 1.1171 + testEl = makeEl('meta',{itemscope:'itemscope',itemprop:'foo',content:'test'}); 1.1172 + assert_equals( testEl.itemValue, testEl, 'meta' ); 1.1173 + testEl = makeEl('audio',{itemscope:'itemscope',itemprop:'foo',src:'test'},'fail'); 1.1174 + assert_equals( testEl.itemValue, testEl, 'audio' ); 1.1175 + testEl = makeEl('embed',{itemscope:'itemscope',itemprop:'foo',src:'test'}); 1.1176 + assert_equals( testEl.itemValue, testEl, 'embed' ); 1.1177 + testEl = makeEl('iframe',{itemscope:'itemscope',itemprop:'foo',src:'test'},'fail'); 1.1178 + assert_equals( testEl.itemValue, testEl, 'iframe' ); 1.1179 + testEl = makeEl('img',{itemscope:'itemscope',itemprop:'foo',src:'test'}); 1.1180 + assert_equals( testEl.itemValue, testEl, 'img' ); 1.1181 + testEl = makeEl('source',{itemscope:'itemscope',itemprop:'foo',src:'test'}); 1.1182 + assert_equals( testEl.itemValue, testEl, 'source' ); 1.1183 + testEl = makeEl('track',{itemscope:'itemscope',itemprop:'foo',src:'test'}); 1.1184 + assert_equals( testEl.itemValue, testEl, 'track' ); 1.1185 + testEl = makeEl('video',{itemscope:'itemscope',itemprop:'foo',src:'test'},'fail'); 1.1186 + assert_equals( testEl.itemValue, testEl, 'video' ); 1.1187 + testEl = makeEl('a',{itemscope:'itemscope',itemprop:'foo',href:'test'},'fail'); 1.1188 + assert_equals( testEl.itemValue, testEl, 'a' ); 1.1189 + testEl = makeEl('area',{itemscope:'itemscope',itemprop:'foo',href:'test'}); 1.1190 + assert_equals( testEl.itemValue, testEl, 'area' ); 1.1191 + testEl = makeEl('link',{itemscope:'itemscope',itemprop:'foo',href:'test'}); 1.1192 + assert_equals( testEl.itemValue, testEl, 'link' ); 1.1193 + testEl = makeEl('object',{itemscope:'itemscope',itemprop:'foo',data:'test'},'fail'); 1.1194 + assert_equals( testEl.itemValue, testEl, 'object' ); 1.1195 + testEl = makeEl('time',{itemscope:'itemscope',itemprop:'foo'},'fail'); 1.1196 + assert_equals( testEl.itemValue, testEl, 'time without datetime' ); 1.1197 + testEl = makeEl('time',{itemscope:'itemscope',itemprop:'foo',datetime:'test'},'fail'); 1.1198 + assert_equals( testEl.itemValue, testEl, 'time with datetime' ); 1.1199 + testEl = makeEl('div',{itemscope:'itemscope',itemprop:'foo'},'test'); 1.1200 + assert_equals( testEl.itemValue, testEl, 'otherwise' ); 1.1201 + testEl = makeEl('madeuponthespot',{itemscope:'itemscope',itemprop:'foo'},'test'); 1.1202 + assert_equals( testEl.itemValue, testEl, 'unknown element' ); 1.1203 + testEl = makeEl('madeuponthespot',{itemscope:'itemscope',itemprop:'foo',content:'test',src:'test',href:'test',data:'test',datetime:'test',value:'test'},'test'); 1.1204 + assert_equals( testEl.itemValue, testEl, 'unknown element with known attributes' ); 1.1205 + testEl = makeEl('input',{itemscope:'itemscope',itemprop:'foo',value:'test'},'test'); 1.1206 + assert_equals( testEl.itemValue, testEl, 'input' ); 1.1207 +}, 'itemValue must return the element if the element has an itemscope attribute'); 1.1208 +test(function () { 1.1209 + var testEl = makeEl('meta',{itemprop:'foo',content:'test'}); 1.1210 + assert_equals( testEl.itemValue, 'test', 'reading' ); 1.1211 + testEl.content = 'retest'; 1.1212 + assert_equals( testEl.itemValue, 'retest', 'reading after change' ); 1.1213 + testEl.itemValue = 'bar'; 1.1214 + assert_equals( testEl.content, 'bar', 'writing (checking content)' ); 1.1215 + assert_equals( testEl.textContent, '', 'writing (checking textContent)' ); 1.1216 +}, 'itemValue must reflect the content attribute on meta elements'); 1.1217 +test(function () { 1.1218 + var testEl = makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text'); 1.1219 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1220 + testEl.src = 'http://example.net/'; 1.1221 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1222 + testEl.itemValue = 'http://example.com/'; 1.1223 + assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' ); 1.1224 + assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' ); 1.1225 + assert_equals( makeEl('audio',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' ); 1.1226 + testEl.src = 'bar'; 1.1227 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1228 +}, 'itemValue must reflect the src attribute on audio elements'); 1.1229 +test(function () { 1.1230 + var testEl = makeEl('embed',{itemprop:'foo',src:'http://example.org/'}); 1.1231 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1232 + testEl.src = 'http://example.net/'; 1.1233 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1234 + testEl.itemValue = 'http://example.com/'; 1.1235 + assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' ); 1.1236 + assert_equals( testEl.textContent, '', 'writing (checking textContent)' ); 1.1237 + testEl.src = 'bar'; 1.1238 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1239 +}, 'itemValue must reflect the src attribute on embed elements'); 1.1240 +test(function () { 1.1241 + var testEl = makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text'); 1.1242 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1243 + testEl.src = 'http://example.net/'; 1.1244 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1245 + testEl.itemValue = 'http://example.com/'; 1.1246 + assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' ); 1.1247 + assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' ); 1.1248 + assert_equals( makeEl('iframe',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' ); 1.1249 + testEl.src = 'bar'; 1.1250 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1251 +}, 'itemValue must reflect the src attribute on iframe elements'); 1.1252 +test(function () { 1.1253 + var testEl = makeEl('img',{itemprop:'foo',src:'http://example.org/'}); 1.1254 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1255 + testEl.src = 'http://example.net/'; 1.1256 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1257 + testEl.itemValue = 'http://example.com/'; 1.1258 + assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' ); 1.1259 + assert_equals( testEl.textContent, '', 'writing (checking textContent)' ); 1.1260 + testEl.src = 'bar'; 1.1261 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1262 +}, 'itemValue must reflect the src attribute on img elements'); 1.1263 +test(function () { 1.1264 + var testEl = makeEl('source',{itemprop:'foo',src:'http://example.org/'}); 1.1265 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1266 + testEl.src = 'http://example.net/'; 1.1267 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1268 + testEl.itemValue = 'http://example.com/'; 1.1269 + assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' ); 1.1270 + assert_equals( testEl.textContent, '', 'writing (checking textContent)' ); 1.1271 + testEl.src = 'bar'; 1.1272 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1273 +}, 'itemValue must reflect the src attribute on source elements'); 1.1274 +test(function () { 1.1275 + var testEl = makeEl('track',{itemprop:'foo',src:'http://example.org/'}); 1.1276 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1277 + testEl.src = 'http://example.net/'; 1.1278 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1279 + testEl.itemValue = 'http://example.com/'; 1.1280 + assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' ); 1.1281 + assert_equals( testEl.textContent, '', 'writing (checking textContent)' ); 1.1282 + testEl.src = 'bar'; 1.1283 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1284 +}, 'itemValue must reflect the src attribute on track elements'); 1.1285 +test(function () { 1.1286 + var testEl = makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text'); 1.1287 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1288 + testEl.src = 'http://example.net/'; 1.1289 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1290 + testEl.itemValue = 'http://example.com/'; 1.1291 + assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' ); 1.1292 + assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' ); 1.1293 + assert_equals( makeEl('video',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' ); 1.1294 + testEl.src = 'bar'; 1.1295 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1296 +}, 'itemValue must reflect the src attribute on video elements'); 1.1297 +test(function () { 1.1298 + var testEl = makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text'); 1.1299 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1300 + testEl.href = 'http://example.net/'; 1.1301 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1302 + testEl.itemValue = 'http://example.com/'; 1.1303 + assert_equals( testEl.href, 'http://example.com/', 'writing (checking href)' ); 1.1304 + assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' ); 1.1305 + assert_equals( makeEl('a',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' ); 1.1306 + testEl.href = 'bar'; 1.1307 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1308 +}, 'itemValue must reflect the src attribute on anchor elements'); 1.1309 +test(function () { 1.1310 + var testEl = makeEl('area',{itemprop:'foo',href:'http://example.org/'}); 1.1311 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1312 + testEl.href = 'http://example.net/'; 1.1313 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1314 + testEl.itemValue = 'http://example.com/'; 1.1315 + assert_equals( testEl.href, 'http://example.com/', 'writing (checking href)' ); 1.1316 + assert_equals( testEl.textContent, '', 'writing (checking textContent)' ); 1.1317 + testEl.href = 'bar'; 1.1318 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1319 +}, 'itemValue must reflect the src attribute on area elements'); 1.1320 +test(function () { 1.1321 + var testEl = makeEl('link',{itemprop:'foo',href:'http://example.org/'}); 1.1322 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1323 + testEl.href = 'http://example.net/'; 1.1324 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1325 + testEl.itemValue = 'http://example.com/'; 1.1326 + assert_equals( testEl.href, 'http://example.com/', 'writing (checking href)' ); 1.1327 + assert_equals( testEl.textContent, '', 'writing (checking textContent)' ); 1.1328 + testEl.href = 'bar'; 1.1329 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1330 +}, 'itemValue must reflect the src attribute on link elements'); 1.1331 +test(function () { 1.1332 + var testEl = makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text'); 1.1333 + assert_equals( testEl.itemValue, 'http://example.org/', 'reading' ); 1.1334 + testEl.data = 'http://example.net/'; 1.1335 + assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' ); 1.1336 + testEl.itemValue = 'http://example.com/'; 1.1337 + assert_equals( testEl.data, 'http://example.com/', 'writing (checking data)' ); 1.1338 + assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' ); 1.1339 + assert_equals( makeEl('object',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' ); 1.1340 + testEl.data = 'bar'; 1.1341 + assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' ); 1.1342 +}, 'itemValue must reflect the src attribute on object elements'); 1.1343 +test(function () { 1.1344 + var testEl = makeEl('time',{itemprop:'foo'},'te <span itemprop="bar" itemscope>st</span> ing'); 1.1345 + assert_equals( testEl.itemValue, 'te st ing', 'reading' ); 1.1346 + testEl.innerHTML = 'retest'; 1.1347 + assert_equals( testEl.itemValue, 'retest', 'reading after change' ); 1.1348 + testEl.itemValue = '2001-02-03T04:05:06Z'; 1.1349 + assert_equals( testEl.dateTime, '2001-02-03T04:05:06Z', 'writing (checking dateTime)' ); 1.1350 + assert_equals( testEl.textContent, 'retest', 'writing (checking textContent)' ); 1.1351 + assert_equals( testEl.itemValue, '2001-02-03T04:05:06Z', 'writing (checking itemValue)' ); 1.1352 +}, 'itemValue must reflect the dateTime attribute of time elements with no datetime attribute'); 1.1353 +test(function () { 1.1354 + var testEl = makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="bar" itemscope>st</span> ing'); 1.1355 + assert_equals( testEl.itemValue, 'test', 'reading' ); 1.1356 + testEl.dateTime = 'retest'; 1.1357 + assert_equals( testEl.itemValue, 'retest', 'reading after change' ); 1.1358 + testEl.itemValue = '2001-02-03T04:05:06Z'; 1.1359 + assert_equals( testEl.dateTime, '2001-02-03T04:05:06Z', 'writing (checking dateTime)' ); 1.1360 + assert_equals( testEl.textContent, 'te st ing', 'writing (checking textContent)' ); 1.1361 +}, 'itemValue must reflect the datetime attribute of time elements with a datetime attribute'); 1.1362 +test(function () { 1.1363 + var testEl = makeEl('div',{itemprop:'foo'},'te <span itemprop="bar" itemscope>st</span> ing'); 1.1364 + assert_equals( testEl.itemValue, 'te st ing', 'reading' ); 1.1365 + testEl.innerHTML = 're<strong>te</strong>st'; 1.1366 + assert_equals( testEl.itemValue, 'retest', 'reading after change' ); 1.1367 + testEl.itemValue = 'test'; 1.1368 + assert_equals( testEl.textContent, 'test', 'writing' ); 1.1369 +}, 'itemValue must reflect the textContent of other elements'); 1.1370 +test(function () { 1.1371 + var testEl = makeEl('madeuponthespot',{itemprop:'foo'},'te <span itemprop="bar" itemscope>st</span> ing'); 1.1372 + assert_equals( testEl.itemValue, 'te st ing', 'reading' ); 1.1373 + testEl.innerHTML = 're<strong>te</strong>st'; 1.1374 + assert_equals( testEl.itemValue, 'retest', 'reading after change' ); 1.1375 + testEl.itemValue = 'test'; 1.1376 + assert_equals( testEl.textContent, 'test', 'writing' ); 1.1377 +}, 'itemValue must reflect the textContent of unknown elements'); 1.1378 +test(function () { 1.1379 + var testEl = makeEl('madeuponthespot',{itemprop:'foo',content:'test',src:'test',href:'test',data:'test',datetime:'test',value:'test'},'te <span itemprop="bar" itemscope>st</span> ing'); 1.1380 + assert_equals( testEl.itemValue, 'te st ing', 'reading' ); 1.1381 + testEl.innerHTML = 're<strong>te</strong>st'; 1.1382 + assert_equals( testEl.itemValue, 'retest', 'reading after change' ); 1.1383 + testEl.itemValue = 'test'; 1.1384 + assert_equals( testEl.textContent, 'test', 'writing' ); 1.1385 +}, 'itemValue must reflect the textContent of unknown elements with known attributes'); 1.1386 +test(function () { 1.1387 + var testEl = makeEl('input',{itemprop:'foo',value:'test'}); 1.1388 + assert_equals( testEl.itemValue, '', 'reading' ); 1.1389 + testEl.value = 'retest'; 1.1390 + assert_equals( testEl.itemValue, '', 'reading after change' ); 1.1391 +}, 'itemValue must not reflect the value of input elements'); 1.1392 +test(function () { 1.1393 + var testEl, eltypes = [ 1.1394 + makeEl('meta',{itemprop:'foo',content:'test'}), 1.1395 + makeEl('audio',{itemprop:'foo',src:'test'},'fail'), 1.1396 + makeEl('embed',{itemprop:'foo',src:'test'}), 1.1397 + makeEl('iframe',{itemprop:'foo',src:'test'},'fail'), 1.1398 + makeEl('img',{itemprop:'foo',src:'test'}), 1.1399 + makeEl('source',{itemprop:'foo',src:'test'}), 1.1400 + makeEl('track',{itemprop:'foo',src:'test'}), 1.1401 + makeEl('video',{itemprop:'foo',src:'test'},'fail'), 1.1402 + makeEl('a',{itemprop:'foo',href:'test'},'fail'), 1.1403 + makeEl('area',{itemprop:'foo',href:'test'}), 1.1404 + makeEl('link',{itemprop:'foo',href:'test'}), 1.1405 + makeEl('object',{itemprop:'foo',data:'test'},'fail'), 1.1406 + makeEl('time',{itemprop:'foo'},'fail'), 1.1407 + makeEl('time',{itemprop:'foo',datetime:'test'},'fail'), 1.1408 + makeEl('div',{itemprop:'foo'},'test'), 1.1409 + makeEl('madeuponthespot',{itemprop:'foo'},'test'), 1.1410 + makeEl('madeuponthespot',{itemprop:'foo',content:'test',src:'test',href:'test',data:'test',datetime:'test',value:'test'},'test'), 1.1411 + makeEl('input',{itemprop:'foo',value:'test'},'test') 1.1412 + ], beforeValues, i; 1.1413 + for( i = 0; i < eltypes.length; i++ ) { 1.1414 + testEl = eltypes[i]; 1.1415 + beforeValues = testEl.itemValue; 1.1416 + testEl.itemScope = true; 1.1417 + assert_equals( testEl.itemValue, testEl, 'itemscope enabled on '+testEl.tagName+' index '+i ); 1.1418 + testEl.itemScope = false; 1.1419 + assert_equals( testEl.itemValue, beforeValues, 'itemscope disabled on '+testEl.tagName+' index '+i ); 1.1420 + testEl.itemScope = true; 1.1421 + testEl.removeAttribute('itemscope'); 1.1422 + assert_equals( testEl.itemValue, beforeValues, 'itemscope attribute removed on '+testEl.tagName+' index '+i ); 1.1423 + } 1.1424 +}, 'dynamic changes of itemscope should change the value exposed through itemValue'); 1.1425 + 1.1426 +test(function () { 1.1427 + var testEl, eltypes = [ 1.1428 + makeEl('meta',{itemprop:'foo',content:'test'}), 1.1429 + makeEl('audio',{itemprop:'foo',src:'test'},'fail'), 1.1430 + makeEl('embed',{itemprop:'foo',src:'test'}), 1.1431 + makeEl('iframe',{itemprop:'foo',src:'test'},'fail'), 1.1432 + makeEl('img',{itemprop:'foo',src:'test'}), 1.1433 + makeEl('source',{itemprop:'foo',src:'test'}), 1.1434 + makeEl('track',{itemprop:'foo',src:'test'}), 1.1435 + makeEl('video',{itemprop:'foo',src:'test'},'fail'), 1.1436 + makeEl('a',{itemprop:'foo',href:'test'},'fail'), 1.1437 + makeEl('area',{itemprop:'foo',href:'test'}), 1.1438 + makeEl('link',{itemprop:'foo',href:'test'}), 1.1439 + makeEl('object',{itemprop:'foo',data:'test'},'fail'), 1.1440 + makeEl('time',{itemprop:'foo'},'fail'), 1.1441 + makeEl('time',{itemprop:'foo',datetime:'test'},'fail'), 1.1442 + makeEl('div',{itemprop:'foo'},'test'), 1.1443 + makeEl('madeuponthespot',{itemprop:'foo'},'test'), 1.1444 + makeEl('madeuponthespot',{itemprop:'foo',content:'test',src:'test',href:'test',data:'test',datetime:'test',value:'test'},'test'), 1.1445 + makeEl('input',{itemprop:'foo',value:'test'},'test') 1.1446 + ], beforeValues, i; 1.1447 + for( i = 0; i < eltypes.length; i++ ) { 1.1448 + testEl = eltypes[i]; 1.1449 + beforeValues = testEl.itemValue; 1.1450 + testEl.itemProp.remove('foo'); 1.1451 + assert_equals( testEl.itemValue, beforeValues, 'itemprop tokens removed on '+testEl.tagName+' index '+i ); 1.1452 + testEl.removeAttribute('itemprop'); 1.1453 + assert_equals( testEl.itemValue, null, 'itemprop attribute removed on '+testEl.tagName+' index '+i ); 1.1454 + testEl.itemProp.toggle('foo'); 1.1455 + assert_equals( testEl.itemValue, beforeValues, 'itemprop tokens added on '+testEl.tagName+' index '+i ); 1.1456 + } 1.1457 +}, 'dynamic changes of itemprop should change the value exposed through itemValue'); 1.1458 + 1.1459 +/* properties */ 1.1460 +test(function () { 1.1461 + assert_equals( typeof makeEl('div',{}).properties, 'object' ); 1.1462 +}, 'the properties property must be an object'); 1.1463 +test(function () { 1.1464 + var testEl = makeEl('div',{}); 1.1465 + assert_true( testEl.properties instanceof HTMLPropertiesCollection, 'instanceof HTMLPropertiesCollection' ); 1.1466 + assert_true( testEl.properties instanceof HTMLCollection, 'instanceof HTMLCollection' ); 1.1467 + HTMLPropertiesCollection.prototype.customProperty = true; 1.1468 + HTMLCollection.prototype.anotherCustomProperty = true; 1.1469 + assert_true( testEl.properties.customProperty, 'inheritance from HTMLPropertiesCollection' ); 1.1470 + assert_true( testEl.properties.anotherCustomProperty, 'inheritance from HTMLCollection' ); 1.1471 + HTMLPropertiesCollection.prototype.anotherCustomProperty = false; 1.1472 + assert_false( testEl.properties.anotherCustomProperty, 'shadowing by HTMLPropertiesCollection' ); 1.1473 +}, 'the properties property must implement HTMLPropertiesCollection and HTMLCollection'); 1.1474 +test(function () { 1.1475 + var failed = false, elem = makeEl('div',{itemscope:'itemscope'}), realList = elem.properties; 1.1476 + try { 1.1477 + elem.properties = ''; 1.1478 + } catch(e) { 1.1479 + failed = e; 1.1480 + } 1.1481 + assert_equals(elem.properties,realList); 1.1482 + assert_false(failed,'an error was thrown'); 1.1483 +}, 'the properties property must be read-only'); 1.1484 +test(function () { 1.1485 + var testEl = makeEl('div',{}); 1.1486 + assert_equals( testEl.properties, testEl.properties ); 1.1487 +}, 'the properties property must always reference the same object'); 1.1488 +test(function () { 1.1489 + var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>'); 1.1490 + assert_equals( testEl.properties.length, 0, 'length' ); 1.1491 + assert_true( !testEl.properties.item(0), 'item(0)' ); 1.1492 + assert_true( !testEl.properties[0], '[0]' ); 1.1493 + assert_equals( testEl.properties.namedItem('foo').length, 0, 'namedItem' ); 1.1494 + assert_true( !testEl.properties['foo'], '[namedItem]' ); 1.1495 + assert_equals( testEl.properties.namedItem('foo').getValues().length, 0, 'namedItem' ); 1.1496 + assert_equals( testEl.properties.names.length, 0, 'names' ); 1.1497 +}, 'the properties collection must be empty if the element does not have an itemscope property'); 1.1498 +test(function() { 1.1499 + var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>'); 1.1500 + assert_throws( new TypeError(), function() { testEl.properties('foo'); } ); 1.1501 + assert_throws( new TypeError(), function() { testEl.properties(0); } ); 1.1502 +}, 'the properties collection must not support legacycaller'); 1.1503 +test(function () { 1.1504 + var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>'); 1.1505 + testEl.itemScope = true; 1.1506 + assert_equals( testEl.properties.length, 1, 'length' ); 1.1507 + assert_equals( testEl.properties.item(0), testEl.firstChild, 'item(0)' ); 1.1508 + assert_equals( testEl.properties[0], testEl.firstChild, '[0]' ); 1.1509 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'namedItem' ); 1.1510 + assert_equals( testEl.properties['foo'].length, 1, '[namedItem]' ); 1.1511 + assert_equals( testEl.properties.namedItem('foo').getValues().length, 1, 'namedItem' ); 1.1512 + assert_equals( testEl.properties.names.length, 1, 'names' ); 1.1513 +}, 'the properties collection must become populated if the element is given an itemscope property'); 1.1514 +test(function () { 1.1515 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo">bar</div>'); 1.1516 + testEl.itemScope = false; 1.1517 + assert_equals( testEl.properties.length, 0, 'length' ); 1.1518 + assert_true( !testEl.properties.item(0), 'item(0)' ); 1.1519 + assert_true( !testEl.properties[0], '[0]' ); 1.1520 + assert_equals( testEl.properties.namedItem('foo').length, 0, 'namedItem' ); 1.1521 + assert_true( !testEl.properties['foo'], '[namedItem]' ); 1.1522 + assert_equals( testEl.properties.namedItem('foo').getValues().length, 0, 'namedItem' ); 1.1523 + assert_equals( testEl.properties.names.length, 0, 'names' ); 1.1524 +}, 'the properties collection must become empty if the element\'s itemscope property is removed'); 1.1525 +//properties.item and properties.length (part 1) 1.1526 +test(function () { 1.1527 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.1528 + assert_equals( testEl.properties.length, 5 ); 1.1529 +}, 'properties.length must be the total number of properties'); 1.1530 +test(function () { 1.1531 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.1532 + assert_equals( testEl.properties.item(0), testEl.childNodes[0], 'item(0)' ); 1.1533 + assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'item(1)' ); 1.1534 + assert_equals( testEl.properties.item(2), testEl.childNodes[1].childNodes[0], 'item(2)' ); 1.1535 + assert_equals( testEl.properties.item(3), testEl.childNodes[2], 'item(3)' ); 1.1536 +}, 'properties.item must give each property in tree order'); 1.1537 +test(function () { 1.1538 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.1539 + testEl.properties.something = "another"; 1.1540 + var names = Object.getOwnPropertyNames(testEl.properties); 1.1541 + assert_array_equals( names, ["0", "1", "2", "3", "foo", "bar", "baz", "qux", "something"] ); 1.1542 +}, 'properties.item must have the right property names on it when enumerated'); 1.1543 +test(function () { 1.1544 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.1545 + assert_equals( testEl.properties.item(4), null, 'positive index' ); 1.1546 + assert_equals( testEl.properties.item(-1), null, 'negative index' ); 1.1547 +}, 'properties.item must give null for out of range index'); 1.1548 +test(function () { 1.1549 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.1550 + assert_equals( testEl.properties[0], testEl.childNodes[0], '[0]' ); 1.1551 + assert_equals( testEl.properties[1], testEl.childNodes[1], '[1]' ); 1.1552 + assert_equals( testEl.properties[2], testEl.childNodes[1].childNodes[0], '[2]' ); 1.1553 + assert_equals( testEl.properties[3], testEl.childNodes[2], '[3]' ); 1.1554 +}, 'properties[index] must give each property in tree order'); 1.1555 +test(function () { 1.1556 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.1557 + assert_equals( testEl.properties[4], window.undefined, 'positive index' ); 1.1558 + assert_equals( testEl.properties[-1], window.undefined, 'negative index' ); 1.1559 +}, 'properties[index] must give undefined for out of range index'); 1.1560 +test(function () { 1.1561 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemscope itemprop="foo"><div itemprop="bar"></div></div><div><div itemprop="baz"></div></div>'); 1.1562 + assert_equals( testEl.properties.length, 2, 'length' ); 1.1563 + assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0)' ); 1.1564 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0]' ); 1.1565 + assert_equals( testEl.properties.item(1), testEl.childNodes[1].firstChild, 'properties.item(1)' ); 1.1566 + assert_equals( testEl.properties[1], testEl.childNodes[1].firstChild, 'properties[1]' ); 1.1567 +}, 'properties.item and length must ignore properties of nested items'); 1.1568 +test(function () { 1.1569 + //note, itemref ordering is reversed compared with the next test to catch failed sorting algorithms 1.1570 + var parEl = makeEl('div',{},'<div itemprop="foo" id="id1"></div><div itemscope itemref="id2 id1"><div itemprop="bar"></div></div><div itemprop="baz" id="id2"><div itemprop="qux"></div></div>'); 1.1571 + var testEl = parEl.childNodes[1]; 1.1572 + document.body.appendChild(parEl); 1.1573 + var propLength = testEl.properties.length; 1.1574 + var item0 = testEl.properties.item(0); 1.1575 + var square0 = testEl.properties[0]; 1.1576 + var item1 = testEl.properties.item(1); 1.1577 + var square1 = testEl.properties[1]; 1.1578 + var item2 = testEl.properties.item(2); 1.1579 + var square2 = testEl.properties[2]; 1.1580 + var item3 = testEl.properties.item(3); 1.1581 + var square3 = testEl.properties[3]; 1.1582 + document.body.removeChild(parEl); 1.1583 + assert_equals( propLength, 4, 'length' ); 1.1584 + assert_equals( item0, parEl.firstChild, 'properties.item(0)' ); 1.1585 + assert_equals( square0, parEl.firstChild, 'properties[0]' ); 1.1586 + assert_equals( item1, testEl.firstChild, 'properties.item(1)' ); 1.1587 + assert_equals( square1, testEl.firstChild, 'properties[1]' ); 1.1588 + assert_equals( item2, parEl.childNodes[2], 'properties.item(2)' ); 1.1589 + assert_equals( square2, parEl.childNodes[2], 'properties[2]' ); 1.1590 + assert_equals( item3, parEl.childNodes[2].firstChild, 'properties.item(3)' ); 1.1591 + assert_equals( square3, parEl.childNodes[2].firstChild, 'properties[3]' ); 1.1592 +}, 'properties.item and length must see items added with itemref when attached to the document\'s DOM'); 1.1593 +test(function () { 1.1594 + var parEl = makeEl('div',{},'<div itemprop="foo" id="id1"></div><div itemscope itemref="id1 id2"><div itemprop="bar"></div></div><div itemprop="baz" id="id2"><div itemprop="qux"></div></div>'); 1.1595 + var testEl = parEl.childNodes[1]; 1.1596 + assert_equals( testEl.properties.length, 4, 'length' ); 1.1597 + assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0)' ); 1.1598 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0]' ); 1.1599 + assert_equals( testEl.properties.item(1), testEl.firstChild, 'properties.item(1)' ); 1.1600 + assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1]' ); 1.1601 + assert_equals( testEl.properties.item(2), parEl.childNodes[2], 'properties.item(2)' ); 1.1602 + assert_equals( testEl.properties[2], parEl.childNodes[2], 'properties[2]' ); 1.1603 + assert_equals( testEl.properties.item(3), parEl.childNodes[2].firstChild, 'properties.item(3)' ); 1.1604 + assert_equals( testEl.properties[3], parEl.childNodes[2].firstChild, 'properties[3]' ); 1.1605 +}, 'properties.item and length must see items added with itemref'); 1.1606 +test(function () { 1.1607 + var parEl = makeEl('div',{},'<div itemscope itemref="id1"></div><div itemprop="foo" id="id1"><div itemprop="bar"></div></div><div itemprop="baz" id="id1"></div>'); 1.1608 + var testEl = parEl.childNodes[0]; 1.1609 + assert_equals( testEl.properties.length, 2, 'length' ); 1.1610 + assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0)' ); 1.1611 + assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1)' ); 1.1612 + document.body.appendChild(parEl) 1.1613 + var length = testEl.properties.length; 1.1614 + var item0 = testEl.properties.item(0); 1.1615 + var item1 = testEl.properties.item(0); 1.1616 + document.body.removeChild(parEl) 1.1617 + assert_equals( testEl.properties.length, 2, 'length (attached to document)' ); 1.1618 + assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0) (attached to document)' ); 1.1619 + assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1) (attached to document)' ); 1.1620 +}, 'itemref must reference the first element with a given ID'); 1.1621 +test(function () { 1.1622 + var parEl = makeEl('div',{},'<div itemscope itemref="id1 id1"></div><div itemprop="foo" id="id1"><div itemprop="bar"></div></div><div itemprop="baz" id="id1"></div>'); 1.1623 + var testEl = parEl.childNodes[0]; 1.1624 + assert_equals( testEl.properties.length, 2, 'length' ); 1.1625 + assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0)' ); 1.1626 + assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1)' ); 1.1627 + document.body.appendChild(parEl) 1.1628 + var length = testEl.properties.length; 1.1629 + var item0 = testEl.properties.item(0); 1.1630 + var item1 = testEl.properties.item(0); 1.1631 + document.body.removeChild(parEl) 1.1632 + assert_equals( testEl.properties.length, 2, 'length (attached to document)' ); 1.1633 + assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0) (attached to document)' ); 1.1634 + assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1) (attached to document)' ); 1.1635 +}, 'itemref must ignore duplicated IDs'); 1.1636 +test(function () { 1.1637 + var parEl = makeEl('div',{},'<div itemscope itemref="id0 id1"></div><div itemprop="foo" id="id1"><div itemprop="bar"></div></div>'); 1.1638 + var testEl = parEl.childNodes[0]; 1.1639 + assert_equals( testEl.properties.length, 2, 'length' ); 1.1640 + assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0)' ); 1.1641 + assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1)' ); 1.1642 + document.body.appendChild(parEl) 1.1643 + var length = testEl.properties.length; 1.1644 + var item0 = testEl.properties.item(0); 1.1645 + var item1 = testEl.properties.item(0); 1.1646 + document.body.removeChild(parEl) 1.1647 + assert_equals( testEl.properties.length, 2, 'length (attached to document)' ); 1.1648 + assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0) (attached to document)' ); 1.1649 + assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1) (attached to document)' ); 1.1650 +}, 'itemref must ignore non-existent IDs'); 1.1651 +test(function () { 1.1652 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'}); 1.1653 + var dummyEl = makeEl('div',{id:'id1',itemprop:'foo'}); 1.1654 + assert_equals( testEl.properties.length, 0 ); 1.1655 +}, 'itemref in a dislocated tree must not reference elements from another dislocated tree'); 1.1656 +test(function () { 1.1657 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'}); 1.1658 + var dummyEl = makeEl('div',{id:'id1',itemprop:'foo'}); 1.1659 + document.body.appendChild(dummyEl); 1.1660 + var tmp = testEl.properties.length; 1.1661 + document.body.removeChild(dummyEl); 1.1662 + assert_equals( tmp, 0 ); 1.1663 +}, 'itemref in a dislocated tree must not reference elements from the main document'); 1.1664 +test(function () { 1.1665 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'}); 1.1666 + var dummyEl = makeEl('div',{id:'id1',itemprop:'foo'}); 1.1667 + document.body.appendChild(testEl); 1.1668 + var tmp = testEl.properties.length; 1.1669 + document.body.removeChild(testEl); 1.1670 + assert_equals( tmp, 0 ); 1.1671 +}, 'itemref in the main document must not reference elements from a dislocated tree'); 1.1672 +test(function () { 1.1673 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.1674 + assert_equals( testEl.properties.length, 1, 'length (before test)' ); 1.1675 + assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) (before test)' ); 1.1676 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (before test)' ); 1.1677 + testEl.appendChild(makeEl('div',{itemprop:'bar'})); 1.1678 + assert_equals( testEl.properties.length, 2, 'length after adding a child' ); 1.1679 + assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) after adding a child' ); 1.1680 + assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] after adding a child' ); 1.1681 + testEl.lastChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.1682 + assert_equals( testEl.properties.length, 3, 'length after adding a child with duplicated name' ); 1.1683 + assert_equals( testEl.properties.item(2), testEl.childNodes[1].firstChild, 'properties.item(2) after adding a child with duplicated name' ); 1.1684 + assert_equals( testEl.properties[2], testEl.childNodes[1].firstChild, 'properties[2] after adding a child with duplicated name' ); 1.1685 + testEl.lastChild.removeChild(testEl.lastChild.firstChild); 1.1686 + assert_equals( testEl.properties.length, 2, 'length after removing a child' ); 1.1687 + assert_true( !testEl.properties.item(2), 'properties.item(1) after removing a child' ); 1.1688 + assert_true( !testEl.properties[2], 'properties[1] after removing a child' ); 1.1689 +}, 'properties.item and length must update when adding property elements'); 1.1690 +test(function () { 1.1691 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div>'); 1.1692 + assert_equals( testEl.properties.length, 2, 'length (before test)' ); 1.1693 + assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) (before test)' ); 1.1694 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (before test)' ); 1.1695 + assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) (before test)' ); 1.1696 + assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] (before test)' ); 1.1697 + testEl.appendChild(testEl.firstChild); 1.1698 + assert_equals( testEl.properties.length, 2, 'length (after test)' ); 1.1699 + assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) (after test)' ); 1.1700 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (after test)' ); 1.1701 + assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) (after test)' ); 1.1702 + assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] (after test)' ); 1.1703 +}, 'properties.item must update when re-ordering property elements, but length must not'); 1.1704 +test(function () { 1.1705 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div></div>'); 1.1706 + assert_equals( testEl.properties.length, 1, 'length (before test)' ); 1.1707 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (before test)' ); 1.1708 + testEl.lastChild.itemProp.toggle('bar'); 1.1709 + assert_equals( testEl.properties.length, 2, 'length (after test 1)' ); 1.1710 + assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) after adding a token' ); 1.1711 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] after adding a token' ); 1.1712 + assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) after adding a token' ); 1.1713 + assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] after adding a token' ); 1.1714 + testEl.lastChild.removeAttribute('itemprop'); 1.1715 + assert_equals( testEl.properties.length, 1, 'length after removing an attribute' ); 1.1716 + assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) after removing an attribute' ); 1.1717 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] after removing an attribute' ); 1.1718 + assert_true( !testEl.properties.item(1), 'properties.item(1) after removing an attribute' ); 1.1719 + assert_true( !testEl.properties[1], 'properties[1] after removing an attribute' ); 1.1720 +}, 'properties.item and length must update when changing itemProp of children'); 1.1721 +test(function () { 1.1722 + var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div>'); 1.1723 + var testEl = parEl.childNodes[1]; 1.1724 + assert_equals( testEl.properties.length, 0, 'length (before test)' ); 1.1725 + parEl.firstChild.id = 'id1'; 1.1726 + assert_equals( testEl.properties.length, 2, 'length after id is created' ); 1.1727 + assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0) after id is created' ); 1.1728 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after id is created' ); 1.1729 + assert_equals( testEl.properties.item(1), parEl.firstChild.firstChild, 'properties.item(1) after id is created' ); 1.1730 + assert_equals( testEl.properties[1], parEl.firstChild.firstChild, 'properties[1] after id is created' ); 1.1731 + parEl.firstChild.removeAttribute('id'); 1.1732 + assert_equals( testEl.properties.length, 0, 'length after removing an attribute' ); 1.1733 + assert_true( !testEl.properties.item(0), 'properties.item(0) after removing an attribute' ); 1.1734 + assert_true( !testEl.properties[0], 'properties[0] after removing an attribute' ); 1.1735 + document.body.appendChild(parEl); 1.1736 + var beflength = testEl.properties.length; 1.1737 + parEl.firstChild.id = 'id1'; 1.1738 + var length1 = testEl.properties.length, 1.1739 + item0 = testEl.properties.item(0), 1.1740 + prop0 = testEl.properties[0], 1.1741 + item1 = testEl.properties.item(1), 1.1742 + prop1 = testEl.properties[1]; 1.1743 + parEl.firstChild.removeAttribute('id'); 1.1744 + var length2 = testEl.properties.length, 1.1745 + bitem = !testEl.properties.item(0), 1.1746 + bprop = !testEl.properties[0]; 1.1747 + document.body.removeChild(parEl); 1.1748 + assert_equals( beflength, 0, 'length (before test) when appended to document' ); 1.1749 + assert_equals( length1, 2, 'length after id is created when appended to document' ); 1.1750 + assert_equals( item0, parEl.firstChild, 'properties.item(0) after id is created when appended to document' ); 1.1751 + assert_equals( prop0, parEl.firstChild, 'properties[0] after id is created when appended to document' ); 1.1752 + assert_equals( item1, parEl.firstChild.firstChild, 'properties.item(1) after id is created when appended to document' ); 1.1753 + assert_equals( prop1, parEl.firstChild.firstChild, 'properties[1] after id is created when appended to document' ); 1.1754 + assert_equals( length2, 0, 'length after removing an attribute when appended to document' ); 1.1755 + assert_true( bitem, 'properties.item(0) after removing an attribute when appended to document' ); 1.1756 + assert_true( bprop, 'properties[0] after removing an attribute when appended to document' ); 1.1757 +}, 'properties.item and length must update when changing id of referenced sibling'); 1.1758 +test(function () { 1.1759 + var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div><div itemprop="baz" id="id1"></div>'); 1.1760 + var testEl = parEl.childNodes[1]; 1.1761 + assert_equals( testEl.properties.length, 1, 'length (before test)' ); 1.1762 + assert_equals( testEl.properties.item(0), parEl.lastChild, 'properties.item(0) (before test)' ); 1.1763 + assert_equals( testEl.properties[0], parEl.lastChild, 'properties[0] (before test)' ); 1.1764 + parEl.firstChild.id = 'id1'; 1.1765 + assert_equals( testEl.properties.length, 2, 'length after id is created' ); 1.1766 + assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0) after id is created' ); 1.1767 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after id is created' ); 1.1768 + assert_equals( testEl.properties.item(1), parEl.firstChild.firstChild, 'properties.item(1) after id is created' ); 1.1769 + assert_equals( testEl.properties[1], parEl.firstChild.firstChild, 'properties[1] after id is created' ); 1.1770 + parEl.firstChild.removeAttribute('id'); 1.1771 + assert_equals( testEl.properties.length, 1, 'length after removing an attribute' ); 1.1772 + assert_equals( testEl.properties.item(0), parEl.lastChild, 'properties.item(0) after removing an attribute' ); 1.1773 + assert_equals( testEl.properties[0], parEl.lastChild, 'properties[0] after removing an attribute' ); 1.1774 + document.body.appendChild(parEl); 1.1775 + var beflength = testEl.properties.length, 1.1776 + befitem = testEl.properties.item(0), 1.1777 + befprop = testEl.properties[0]; 1.1778 + parEl.firstChild.id = 'id1'; 1.1779 + var length1 = testEl.properties.length, 1.1780 + item0 = testEl.properties.item(0), 1.1781 + prop0 = testEl.properties[0], 1.1782 + item1 = testEl.properties.item(1), 1.1783 + prop1 = testEl.properties[1]; 1.1784 + parEl.firstChild.removeAttribute('id'); 1.1785 + var length2 = testEl.properties.length, 1.1786 + afitem = testEl.properties.item(0), 1.1787 + afprop = testEl.properties[0]; 1.1788 + document.body.removeChild(parEl); 1.1789 + assert_equals( beflength, 1, 'length (before test) when appended to document' ); 1.1790 + assert_equals( befitem, parEl.lastChild, 'properties.item(0) (before test)' ); 1.1791 + assert_equals( befprop, parEl.lastChild, 'properties[0] (before test)' ); 1.1792 + assert_equals( length1, 2, 'length after id is created when appended to document' ); 1.1793 + assert_equals( item0, parEl.firstChild, 'properties.item(0) after id is created when appended to document' ); 1.1794 + assert_equals( prop0, parEl.firstChild, 'properties[0] after id is created when appended to document' ); 1.1795 + assert_equals( item1, parEl.firstChild.firstChild, 'properties.item(1) after id is created when appended to document' ); 1.1796 + assert_equals( prop1, parEl.firstChild.firstChild, 'properties[1] after id is created when appended to document' ); 1.1797 + assert_equals( length2, 1, 'length after removing an attribute when appended to document' ); 1.1798 + assert_equals( afitem, parEl.lastChild, 'properties.item(0) after removing an attribute when appended to document' ); 1.1799 + assert_equals( afprop, parEl.lastChild, 'properties[0] after removing an attribute when appended to document' ); 1.1800 +}, 'properties.item and length must update when changing duplicated id of referenced sibling'); 1.1801 +test(function () { 1.1802 + var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope></div>'); 1.1803 + var testEl = parEl.childNodes[1]; 1.1804 + assert_equals( testEl.properties.length, 0, 'length (before test)' ); 1.1805 + testEl.itemRef.toggle('id1'); 1.1806 + assert_equals( testEl.properties.length, 1, 'length after itemref is changed' ); 1.1807 + assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0) after itemref is changed' ); 1.1808 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after itemref is changed' ); 1.1809 + testEl.removeAttribute('itemref'); 1.1810 + assert_equals( testEl.properties.length, 0, 'length after itemref is removed' ); 1.1811 + assert_true( !testEl.properties.item(0), 'properties.item(0) itemref is removed' ); 1.1812 + assert_true( !testEl.properties[0], 'properties[0] itemref is removed' ); 1.1813 + document.body.appendChild(parEl); 1.1814 + var beflength = testEl.properties.length; 1.1815 + testEl.itemRef.toggle('id1'); 1.1816 + var length1 = testEl.properties.length, 1.1817 + item0 = testEl.properties.item(0), 1.1818 + prop0 = testEl.properties[0]; 1.1819 + testEl.removeAttribute('itemref'); 1.1820 + var length2 = testEl.properties.length, 1.1821 + bitem = !testEl.properties.item(0), 1.1822 + bprop = !testEl.properties[0]; 1.1823 + document.body.removeChild(parEl); 1.1824 + assert_equals( beflength, 0, 'length (before test) when appended to document' ); 1.1825 + assert_equals( length1, 1, 'length after itemref is changed when appended to document' ); 1.1826 + assert_equals( item0, parEl.firstChild, 'properties.item(0) after itemref is changed when appended to document' ); 1.1827 + assert_equals( prop0, parEl.firstChild, 'properties[0] after itemref is changed when appended to document' ); 1.1828 + assert_equals( length2, 0, 'length after itemref is removed when appended to document' ); 1.1829 + assert_true( bitem, 'properties.item(0) after itemref is removed when appended to document' ); 1.1830 + assert_true( bprop, 'properties[0] after itemref is removed when appended to document' ); 1.1831 +}, 'properties.item and length must update when changing itemref to point to an element'); 1.1832 +test(function () { 1.1833 + var parEl = makeEl('div',{},'<div id="id1"><div></div></div><div itemscope itemref="id1"></div>'); 1.1834 + var testEl = parEl.childNodes[1]; 1.1835 + assert_equals( testEl.properties.length, 0, 'length (before test)' ); 1.1836 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.1837 + assert_equals( testEl.properties.length, 1, 'length after a referenced element is added' ); 1.1838 + assert_equals( testEl.properties.item(0), parEl.firstChild.lastChild, 'properties.item(0) after a referenced element is added' ); 1.1839 + assert_equals( testEl.properties[0], parEl.firstChild.lastChild, 'properties[0] after a referenced element is added' ); 1.1840 + parEl.firstChild.firstChild.itemProp.toggle('bar'); 1.1841 + assert_equals( testEl.properties.length, 2, 'length after a referenced itemprop is changed' ); 1.1842 + assert_equals( testEl.properties.item(0), parEl.firstChild.firstChild, 'properties.item(0) after a referenced itemprop is changed' ); 1.1843 + assert_equals( testEl.properties[0], parEl.firstChild.firstChild, 'properties[0] after a referenced itemprop is changed' ); 1.1844 + assert_equals( testEl.properties.item(1), parEl.firstChild.lastChild, 'properties.item(1) after a referenced itemprop is changed' ); 1.1845 + assert_equals( testEl.properties[1], parEl.firstChild.lastChild, 'properties[1] after a referenced itemprop is changed' ); 1.1846 + parEl.firstChild.removeChild(parEl.firstChild.firstChild); 1.1847 + assert_equals( testEl.properties.length, 1, 'length after a referenced element is removed' ); 1.1848 + assert_equals( testEl.properties.item(0), parEl.firstChild.firstChild, 'properties.item(0) after a referenced element is removed' ); 1.1849 + assert_equals( testEl.properties[0], parEl.firstChild.firstChild, 'properties[0] after a referenced element is removed' ); 1.1850 + assert_true( !testEl.properties.item(1), 'properties.item(1) after a referenced element is removed' ); 1.1851 + assert_true( !testEl.properties[1], 'properties[1] after a referenced element is removed' ); 1.1852 + parEl.innerHTML = '<div id="id1"><div></div></div><div itemscope itemref="id1"></div>'; 1.1853 + testEl = parEl.childNodes[1]; 1.1854 + document.body.appendChild(parEl); 1.1855 + var beflength = testEl.properties.length; 1.1856 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.1857 + var length1 = testEl.properties.length, 1.1858 + item0a = testEl.properties.item(0), 1.1859 + prop0a = testEl.properties[0], 1.1860 + targ0a = parEl.firstChild.lastChild; 1.1861 + parEl.firstChild.firstChild.itemProp.toggle('bar'); 1.1862 + var length2 = testEl.properties.length, 1.1863 + item0b = testEl.properties.item(0), 1.1864 + prop0b = testEl.properties[0]; 1.1865 + item1b = testEl.properties.item(1), 1.1866 + prop1b = testEl.properties[1], 1.1867 + targ0b = parEl.firstChild.firstChild, 1.1868 + targ1b = parEl.firstChild.lastChild; 1.1869 + parEl.firstChild.removeChild(parEl.firstChild.firstChild); 1.1870 + var length3 = testEl.properties.length, 1.1871 + item0c = testEl.properties.item(0), 1.1872 + prop0c = testEl.properties[0]; 1.1873 + item1c = testEl.properties.item(1), 1.1874 + prop1c = testEl.properties[1], 1.1875 + targ0c = parEl.firstChild.firstChild; 1.1876 + document.body.removeChild(parEl); 1.1877 + assert_equals( beflength, 0, 'length (before test) when appended to document' ); 1.1878 + assert_equals( length1, 1, 'length after a referenced element is added when appended to document' ); 1.1879 + assert_equals( item0a, targ0a, 'properties.item(0) after a referenced element is added when appended to document' ); 1.1880 + assert_equals( prop0a, targ0a, 'properties[0] after a referenced element is added when appended to document' ); 1.1881 + assert_equals( length2, 2, 'length after a referenced itemprop is changed when appended to document' ); 1.1882 + assert_equals( item0b, targ0b, 'properties.item(0) after a referenced itemprop is changed when appended to document' ); 1.1883 + assert_equals( prop0b, targ0b, 'properties[0] after a referenced itemprop is changed when appended to document' ); 1.1884 + assert_equals( item1b, targ1b, 'properties.item(1) after a referenced itemprop is changed when appended to document' ); 1.1885 + assert_equals( prop1b, targ1b, 'properties[1] after a referenced itemprop is changed when appended to document' ); 1.1886 + assert_equals( length3, 1, 'length after a referenced element is removed when appended to document' ); 1.1887 + assert_equals( item0c, targ0c, 'properties.item(0) after a referenced element is removed when appended to document' ); 1.1888 + assert_equals( prop0c, targ0c, 'properties[0] after a referenced element is removed when appended to document' ); 1.1889 + assert_true( !item1c, 'properties.item(1) after a referenced element is removed when appended to document' ); 1.1890 + assert_true( !prop1c, 'properties[1] after a referenced element is removed when appended to document' ); 1.1891 +}, 'properties.item and length must update when changing children of elements referenced through itemref'); 1.1892 +test(function () { 1.1893 + var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope itemref="id1"><div itemprop="foo"></div></div>'); 1.1894 + var testEl = parEl.childNodes[1]; 1.1895 + assert_equals( testEl.properties.length, 2, 'length (before test)' ); 1.1896 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] (before test)' ); 1.1897 + assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1] (before test)' ); 1.1898 + document.body.appendChild(testEl); 1.1899 + var step1length = testEl.properties.length; 1.1900 + var step1prop0 = testEl.properties[0]; 1.1901 + var step1prop1 = testEl.properties[1]; 1.1902 + parEl.appendChild(testEl); 1.1903 + assert_equals( step1length, 1, 'length after changing parent' ); 1.1904 + assert_equals( step1prop0, testEl.firstChild, 'properties[0] after changing parent' ); 1.1905 + assert_true( !step1prop1, 'properties[1] after changing parent' ); 1.1906 + assert_equals( testEl.properties.length, 2, 'length after re-parenting' ); 1.1907 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after re-parenting' ); 1.1908 + assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1] after re-parenting' ); 1.1909 + document.body.appendChild(parEl); 1.1910 + var step2length = testEl.properties.length; 1.1911 + var step2prop0 = testEl.properties[0]; 1.1912 + var step2prop1 = testEl.properties[1]; 1.1913 + document.createElement('div').appendChild(testEl); 1.1914 + var step3length = testEl.properties.length; 1.1915 + var step3prop0 = testEl.properties[0]; 1.1916 + var step3prop1 = testEl.properties[1]; 1.1917 + parEl.appendChild(testEl); 1.1918 + var step4length = testEl.properties.length; 1.1919 + var step4prop0 = testEl.properties[0]; 1.1920 + var step4prop1 = testEl.properties[1]; 1.1921 + document.body.removeChild(parEl); 1.1922 + assert_equals( step2length, 2, 'length (before test) when appended to document' ); 1.1923 + assert_equals( step2prop0, parEl.firstChild, 'properties[0] (before test) when appended to document' ); 1.1924 + assert_equals( step2prop1, testEl.firstChild, 'properties[1] (before test) when appended to document' ); 1.1925 + assert_equals( step3length, 1, 'length after changing parent when appended to document' ); 1.1926 + assert_equals( step3prop0, testEl.firstChild, 'properties[0] after changing parent when appended to document' ); 1.1927 + assert_true( !step3prop1, 'properties[1] after changing parent when appended to document' ); 1.1928 + assert_equals( step4length, 2, 'length after re-parenting when appended to document' ); 1.1929 + assert_equals( step4prop0, parEl.firstChild, 'properties[0] after re-parenting when appended to document' ); 1.1930 + assert_equals( step4prop1, testEl.firstChild, 'properties[1] after re-parenting when appended to document' ); 1.1931 +}, 'properties.item and length must update when appending elements with itemref to different parents'); 1.1932 +test(function () { 1.1933 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div><div itemprop="foo"></div></div>'); 1.1934 + assert_equals( testEl.properties.length, 1, 'length (before test)' ); 1.1935 + assert_equals( testEl.properties.item(0), testEl.firstChild.firstChild, 'properties.item(0) (before test)' ); 1.1936 + assert_equals( testEl.properties[0], testEl.firstChild.firstChild, 'properties[0] (before test)' ); 1.1937 + testEl.firstChild.itemScope = true; 1.1938 + assert_equals( testEl.properties.length, 0, 'length after setting itemscope' ); 1.1939 + assert_true( !testEl.properties.item(0), 'properties.item(0) after setting itemscope' ); 1.1940 + assert_true( !testEl.properties[0], 'properties[0] after setting itemscope' ); 1.1941 + testEl.firstChild.removeAttribute('itemscope'); 1.1942 + assert_equals( testEl.properties.length, 1, 'length after removing itemscope attribute' ); 1.1943 + assert_equals( testEl.properties.item(0), testEl.firstChild.firstChild, 'properties.item(0) after removing itemscope attribute' ); 1.1944 + assert_equals( testEl.properties[0], testEl.firstChild.firstChild, 'properties[0] after removing itemscope attribute' ); 1.1945 +}, 'properties.item and length must update when changing itemscope of children'); 1.1946 +//properties.namedItem 1.1947 +test(function () { 1.1948 + assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties.namedItem('foo'), 'object' ); 1.1949 +}, 'the namedItem must return an object'); 1.1950 +test(function () { 1.1951 + assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties['foo'], 'object' ); 1.1952 +}, '.properties[] must also act as .properties.namedItem() when there are matching properties'); 1.1953 +test(function () { 1.1954 + assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'').properties.namedItem('foo'), 'object' ); 1.1955 +}, 'the namedItem must return an object even if there are no matching properties'); 1.1956 +test(function () { 1.1957 + assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'').properties['foo'], 'undefined' ); 1.1958 +}, '.properties[] must return undefined when no property exists with the given name'); 1.1959 +test(function () { 1.1960 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.1961 + var PNL = testEl.properties.namedItem('foo'); 1.1962 + assert_equals( PNL, testEl.properties.namedItem('foo'), 'before modification' ); 1.1963 + testEl.innerHTML = ''; 1.1964 + assert_equals( PNL, testEl.properties.namedItem('foo'), 'after modification' ); 1.1965 +}, 'namedItem must return the same object for the same property name'); 1.1966 +test(function () { 1.1967 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.1968 + assert_false( testEl.properties.namedItem('foo') == testEl.properties.namedItem('bar') ); 1.1969 +}, 'namedItem must return a different object for a different property name'); 1.1970 +test(function () { 1.1971 + assert_false( makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties.namedItem('foo') == makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties.namedItem('foo') ); 1.1972 +}, 'namedItem must return a different object for different elements with the same property name'); 1.1973 +test(function () { 1.1974 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.1975 + assert_equals( testEl.properties.namedItem('foo'), testEl.properties['foo'] ); 1.1976 +}, 'namedItem() and properties[] must return the same object for the same property name'); 1.1977 +test(function () { 1.1978 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.1979 + assert_true( testEl.properties.namedItem('foo') instanceof PropertyNodeList, 'instanceof PropertyNodeList' ); 1.1980 + assert_true( testEl.properties.namedItem('foo') instanceof NodeList, 'instanceof NodeList' ); 1.1981 + PropertyNodeList.prototype.customProperty = true; 1.1982 + NodeList.prototype.anotherCustomProperty = true; 1.1983 + assert_true( testEl.properties.namedItem('foo').customProperty, 'inheritance from PropertyNodeList' ); 1.1984 + assert_true( testEl.properties.namedItem('foo').anotherCustomProperty, 'inheritance from NodeList' ); 1.1985 + PropertyNodeList.prototype.anotherCustomProperty = false; 1.1986 + assert_false( testEl.properties.anotherCustomProperty, 'shadowing by PropertyNodeList' ); 1.1987 +}, 'the properties property must implement PropertyNodeList and NodeList'); 1.1988 +test(function () { 1.1989 + var failed = false, elem = makeEl('div',{itemscope:'itemscope'}); 1.1990 + try { 1.1991 + elem.properties.namedItem = 'pass'; 1.1992 + } catch(e) { 1.1993 + failed = e; 1.1994 + } 1.1995 + assert_equals(elem.properties.namedItem,'pass'); 1.1996 + assert_false(failed,'an error was thrown'); 1.1997 +}, 'the namedItem property must be read/write'); 1.1998 +test(function () { 1.1999 + //also tests for sort ordering, which is fairly simple in this case 1.2000 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="baz qux"></div></div><div itemprop="foo"></div>'); 1.2001 + assert_equals( testEl.properties.namedItem('foo').length, 2, 'length of foo' ); 1.2002 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'length of bar' ); 1.2003 + assert_equals( testEl.properties.namedItem('baz').length, 1, 'length of baz' ); 1.2004 + assert_equals( testEl.properties.namedItem('qux').length, 1, 'length of qux' ); 1.2005 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'first foo' ); 1.2006 + assert_equals( testEl.properties.namedItem('foo')[1], testEl.lastChild, 'last foo' ); 1.2007 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.childNodes[1], 'bar' ); 1.2008 + assert_equals( testEl.properties.namedItem('baz')[0], testEl.childNodes[1].firstChild, 'baz' ); 1.2009 + assert_equals( testEl.properties.namedItem('qux')[0], testEl.childNodes[1].firstChild, 'qux' ); 1.2010 +}, 'PropertyNodeList must contain the correct properties'); 1.2011 +test(function () { 1.2012 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="FOO"></div><div itemprop="foo FOO foo"></div></div><div itemprop="baz qux"></div>'); 1.2013 + assert_equals( testEl.properties.namedItem('foo').length, 2, 'length of foo' ); 1.2014 + assert_equals( testEl.properties.namedItem('FOO').length, 2, 'length of FOO' ); 1.2015 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'first foo' ); 1.2016 + assert_equals( testEl.properties.namedItem('foo')[1], testEl.childNodes[1].lastChild, 'last foo' ); 1.2017 + assert_equals( testEl.properties.namedItem('FOO')[0], testEl.childNodes[1].firstChild, 'first FOO' ); 1.2018 + assert_equals( testEl.properties.namedItem('FOO')[1], testEl.childNodes[1].lastChild, 'last FOO' ); 1.2019 +}, 'PropertyNodeList must be case sensitive'); 1.2020 +test(function () { 1.2021 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo bar"></div>'); 1.2022 + assert_equals( testEl.properties.namedItem('foo bar').length, 0, 'space' ); 1.2023 + testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\tbar"></div>'); 1.2024 + assert_equals( testEl.properties.namedItem('foo\tbar').length, 0, 'tab' ); 1.2025 + testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\rbar"></div>'); 1.2026 + assert_equals( testEl.properties.namedItem('foo\rbar').length, 0, 'carriage return' ); 1.2027 + testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\nbar"></div>'); 1.2028 + assert_equals( testEl.properties.namedItem('foo\nbar').length, 0, 'newline' ); 1.2029 + testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\fbar"></div>'); 1.2030 + assert_equals( testEl.properties.namedItem('foo\fbar').length, 0, 'formfeed' ); 1.2031 +}, 'namedItem must not match property names containing whitespace'); 1.2032 +test(function () { 1.2033 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="|§!"#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_<>帿ŨÆ"></div>'); 1.2034 + assert_equals( testEl.properties.namedItem('|§!"#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_<>帿ŨÆ').length, 1 ); 1.2035 +}, 'namedItem must match property names containing other special characters'); 1.2036 +test(function () { 1.2037 + var testEl = makeEl('div',{itemscope:'itemscope'}); 1.2038 + var PNL = testEl.properties.namedItem('foo'); 1.2039 + testEl.innerHTML = '<div itemprop="foo"></div>'; 1.2040 + assert_equals( PNL.length, 1 ); 1.2041 + assert_equals( PNL[0], testEl.firstChild ); 1.2042 +}, 'PropertyNodeList must be live'); 1.2043 +test(function () { 1.2044 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemscope><div itemprop="foo"></div><div itemprop="bar"></div></div>'); 1.2045 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'length of foo' ); 1.2046 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'item 0' ); 1.2047 + assert_equals( testEl.properties.namedItem('bar').length, 0, 'length of bar' ); 1.2048 +}, 'PropertyNodeList must ignore properties of nested items'); 1.2049 +test(function () { 1.2050 + 1.2051 + //note, itemref ordering is reversed compared with the next test to catch failed sorting algorithms - not that that should make much difference here 1.2052 + var parEl = makeEl('div',{},'<div itemprop="foo" id="id1"></div><div itemscope itemref="id2 id1"><div itemprop="foo bar"></div></div><div itemprop="baz" id="id2"><div itemprop="qux"></div></div>'); 1.2053 + var testEl = parEl.childNodes[1]; 1.2054 + document.body.appendChild(parEl); 1.2055 + var fooLength = testEl.properties.namedItem('foo').length; 1.2056 + var barLength = testEl.properties.namedItem('bar').length; 1.2057 + var bazLength = testEl.properties.namedItem('baz').length; 1.2058 + var quxLength = testEl.properties.namedItem('qux').length; 1.2059 + var foo0 = testEl.properties.namedItem('foo')[0]; 1.2060 + var foo1 = testEl.properties.namedItem('foo')[1]; 1.2061 + var bar0 = testEl.properties.namedItem('bar')[0]; 1.2062 + var baz0 = testEl.properties.namedItem('baz')[0]; 1.2063 + var qux0 = testEl.properties.namedItem('qux')[0]; 1.2064 + document.body.removeChild(parEl); 1.2065 + assert_equals( fooLength, 2, 'foo length' ); 1.2066 + assert_equals( barLength, 1, 'bar length' ); 1.2067 + assert_equals( bazLength, 1, 'baz length' ); 1.2068 + assert_equals( quxLength, 1, 'qux length' ); 1.2069 + assert_equals( foo0, parEl.firstChild, 'foo 0' ); 1.2070 + assert_equals( foo1, testEl.firstChild, 'foo 1' ); 1.2071 + assert_equals( bar0, testEl.firstChild, 'bar 0' ); 1.2072 + assert_equals( baz0, parEl.lastChild, 'baz 0' ); 1.2073 + assert_equals( qux0, parEl.lastChild.firstChild, 'qux 0' ); 1.2074 +}, 'PropertyNodeList must see items added with itemref when attached to the document\'s DOM'); 1.2075 +test(function () { 1.2076 + var parEl = makeEl('div',{},'<div itemprop="foo" id="id1"></div><div itemscope itemref="id1 id2"><div itemprop="foo bar"></div></div><div itemprop="baz" id="id2"><div itemprop="qux"></div></div>'); 1.2077 + var testEl = parEl.childNodes[1]; 1.2078 + assert_equals( testEl.properties.namedItem('foo').length, 2, 'foo length' ); 1.2079 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length' ); 1.2080 + assert_equals( testEl.properties.namedItem('baz').length, 1, 'baz length' ); 1.2081 + assert_equals( testEl.properties.namedItem('qux').length, 1, 'qux length' ); 1.2082 + assert_equals( testEl.properties.namedItem('foo')[0], parEl.firstChild, 'foo 0' ); 1.2083 + assert_equals( testEl.properties.namedItem('foo')[1], testEl.firstChild, 'foo 1' ); 1.2084 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar 0' ); 1.2085 + assert_equals( testEl.properties.namedItem('baz')[0], parEl.lastChild, 'baz 0' ); 1.2086 + assert_equals( testEl.properties.namedItem('qux')[0], parEl.lastChild.firstChild, 'qux 0' ); 1.2087 +}, 'PropertyNodeList must see items added with itemref'); 1.2088 +test(function () { 1.2089 + //this one also tests the live object just in case - further ones will not always do this as its live status will already have been well established 1.2090 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.2091 + var PNL = testEl.properties.namedItem('foo'); 1.2092 + testEl.removeAttribute('itemscope'); 1.2093 + assert_equals( testEl.properties.namedItem('foo').length, 0, 'removing attribute' ); 1.2094 + assert_equals( PNL.length, 0, 'removing attribute (live)' ); 1.2095 + assert_true( !testEl.properties['foo'], 'removing attribute []' ); 1.2096 + testEl.itemScope = true; 1.2097 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'setting itemScope' ); 1.2098 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'property 0 after setting itemScope' ); 1.2099 + assert_equals( PNL.length, 1, 'setting itemScope (live)' ); 1.2100 + assert_equals( PNL[0], testEl.firstChild, 'property 0 after setting itemScope (live)' ); 1.2101 + assert_false( !testEl.properties['foo'], 'setting itemScope []' ); 1.2102 +}, 'PropertyNodeList must update when adding itemscope on the root'); 1.2103 +test(function () { 1.2104 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.2105 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo length (before test)' ); 1.2106 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'foo 0 (before test)' ); 1.2107 + assert_equals( testEl.properties.namedItem('bar').length, 0, 'bar length (before test)' ); 1.2108 + testEl.appendChild(makeEl('div',{itemprop:'bar'})); 1.2109 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo length after adding a child' ); 1.2110 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'foo 0 after adding a child' ); 1.2111 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length after adding a child' ); 1.2112 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'bar 0 after adding a child' ); 1.2113 + testEl.lastChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.2114 + assert_equals( testEl.properties.namedItem('foo').length, 2, 'foo length after adding a child with duplicated name' ); 1.2115 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'foo 0 after adding a child with duplicated name' ); 1.2116 + assert_equals( testEl.properties.namedItem('foo')[1], testEl.lastChild.firstChild, 'foo 1 after adding a child with duplicated name' ); 1.2117 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length after adding a child with duplicated name' ); 1.2118 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'bar 0 after adding a child with duplicated name' ); 1.2119 + testEl.lastChild.removeChild(testEl.lastChild.firstChild); 1.2120 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo length after removing a child' ); 1.2121 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length after removing a child' ); 1.2122 +}, 'PropertyNodeList must update when adding property elements'); 1.2123 +test(function () { 1.2124 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="foo"></div>'); 1.2125 + var PNL = testEl.properties.namedItem('foo'); 1.2126 + assert_equals( PNL[0], testEl.firstChild, 'item 0 (before test)' ); 1.2127 + assert_equals( PNL[1], testEl.lastChild, 'item 1 (before test)' ); 1.2128 + testEl.appendChild(testEl.firstChild); 1.2129 + assert_equals( PNL[0], testEl.firstChild, 'item 0 (after test)' ); 1.2130 + assert_equals( PNL[1], testEl.lastChild, 'item 1 (after test)' ); 1.2131 +}, 'PropertyNodeList must update when re-ordering property elements'); 1.2132 +test(function () { 1.2133 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div></div>'); 1.2134 + var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar'); 1.2135 + assert_equals( PNLfoo.length, 1, 'foo length (before test)' ); 1.2136 + assert_equals( PNLbar.length, 0, 'bar length (before test)' ); 1.2137 + assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] (before test)' ); 1.2138 + testEl.lastChild.itemProp.toggle('bar'); 1.2139 + assert_equals( PNLfoo.length, 1, 'foo length after adding a token' ); 1.2140 + assert_equals( PNLbar.length, 1, 'bar length after adding a token' ); 1.2141 + assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] after adding a token' ); 1.2142 + assert_equals( PNLbar[0], testEl.lastChild, 'bar[0] after adding a token' ); 1.2143 + testEl.lastChild.itemProp.add('foo'); 1.2144 + assert_equals( PNLfoo.length, 2, 'foo length after adding a duplicated token' ); 1.2145 + assert_equals( PNLbar.length, 1, 'bar length after adding a duplicated token' ); 1.2146 + assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] after adding a duplicated token' ); 1.2147 + assert_equals( PNLfoo[1], testEl.lastChild, 'foo[1] after adding a duplicated token' ); 1.2148 + assert_equals( PNLbar[0], testEl.lastChild, 'bar[0] after adding a duplicated token' ); 1.2149 + testEl.lastChild.removeAttribute('itemprop'); 1.2150 + assert_equals( PNLfoo.length, 1, 'foo length after removing an attribute' ); 1.2151 + assert_equals( PNLbar.length, 0, 'bar length after removing an attribute' ); 1.2152 + assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] after removing an attribute' ); 1.2153 +}, 'PropertyNodeList must update when changing itemProp of children'); 1.2154 +test(function () { 1.2155 + var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div>'); 1.2156 + var testEl = parEl.childNodes[1]; 1.2157 + var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar'); 1.2158 + assert_equals( PNLfoo.length, 0, 'foo length (before test)' ); 1.2159 + assert_equals( PNLbar.length, 0, 'bar length (before test)' ); 1.2160 + parEl.firstChild.id = 'id1'; 1.2161 + assert_equals( PNLfoo.length, 1, 'foo length after id is created' ); 1.2162 + assert_equals( PNLbar.length, 1, 'bar length after id is created' ); 1.2163 + assert_equals( PNLfoo[0], parEl.firstChild, 'foo[0] after id is created' ); 1.2164 + assert_equals( PNLbar[0], parEl.firstChild.firstChild, 'bar[0] after id is created' ); 1.2165 + parEl.firstChild.removeAttribute('id'); 1.2166 + assert_equals( PNLfoo.length, 0, 'foo length after removing an attribute' ); 1.2167 + assert_equals( PNLbar.length, 0, 'bar length after removing an attribute' ); 1.2168 + document.body.appendChild(parEl); 1.2169 + var fooLength0 = PNLfoo.length; 1.2170 + var barLength0 = PNLbar.length; 1.2171 + parEl.firstChild.id = 'id1'; 1.2172 + var fooLength1 = PNLfoo.length; 1.2173 + var barLength1 = PNLbar.length; 1.2174 + var foo0 = PNLfoo[0]; 1.2175 + var bar0 = PNLbar[0]; 1.2176 + parEl.firstChild.removeAttribute('id'); 1.2177 + var fooLength2 = PNLfoo.length; 1.2178 + var barLength2 = PNLbar.length; 1.2179 + document.body.removeChild(parEl); 1.2180 + assert_equals( fooLength0, 0, 'foo length (before test) when appended to document' ); 1.2181 + assert_equals( barLength0, 0, 'bar length (before test) when appended to document' ); 1.2182 + assert_equals( fooLength1, 1, 'foo length after id is created when appended to document' ); 1.2183 + assert_equals( barLength1, 1, 'bar length after id is created when appended to document' ); 1.2184 + assert_equals( foo0, parEl.firstChild, 'foo[0] after id is created when appended to document' ); 1.2185 + assert_equals( bar0, parEl.firstChild.firstChild, 'bar[0] after id is created when appended to document' ); 1.2186 + assert_equals( fooLength2, 0, 'foo length after removing an attribute when appended to document' ); 1.2187 + assert_equals( barLength2, 0, 'bar length after removing an attribute when appended to document' ); 1.2188 +}, 'PropertyNodeList must update when changing id of referenced sibling'); 1.2189 +test(function () { 1.2190 + var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div><div itemprop="baz" id="id1"></div>'); 1.2191 + var testEl = parEl.childNodes[1]; 1.2192 + var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar'), PNLbaz = testEl.properties.namedItem('baz'); 1.2193 + assert_equals( PNLfoo.length, 0, 'foo length (before test)' ); 1.2194 + assert_equals( PNLbar.length, 0, 'bar length (before test)' ); 1.2195 + assert_equals( PNLbaz.length, 1, 'baz length (before test)' ); 1.2196 + assert_equals( PNLbaz[0], parEl.lastChild, 'baz[0] (before test)' ); 1.2197 + parEl.firstChild.id = 'id1'; 1.2198 + assert_equals( PNLfoo.length, 1, 'foo length after id is created' ); 1.2199 + assert_equals( PNLbar.length, 1, 'bar length after id is created' ); 1.2200 + assert_equals( PNLbaz.length, 0, 'baz length after id is created' ); 1.2201 + assert_equals( PNLfoo[0], parEl.firstChild, 'foo[0] after id is created' ); 1.2202 + assert_equals( PNLbar[0], parEl.firstChild.firstChild, 'bar[0] after id is created' ); 1.2203 + parEl.firstChild.removeAttribute('id'); 1.2204 + assert_equals( PNLfoo.length, 0, 'foo length after removing an attribute' ); 1.2205 + assert_equals( PNLbar.length, 0, 'bar length after removing an attribute' ); 1.2206 + assert_equals( PNLbaz.length, 1, 'baz length after removing an attribute' ); 1.2207 + assert_equals( PNLbaz[0], parEl.lastChild, 'baz[0] after removing an attribute' ); 1.2208 + document.body.appendChild(parEl); 1.2209 + var fooLength0 = PNLfoo.length; 1.2210 + var barLength0 = PNLbar.length; 1.2211 + var bazLength0 = PNLbaz.length; 1.2212 + var baz0 = PNLbaz[0]; 1.2213 + parEl.firstChild.id = 'id1'; 1.2214 + var fooLength1 = PNLfoo.length; 1.2215 + var barLength1 = PNLbar.length; 1.2216 + var bazLength1 = PNLbaz.length; 1.2217 + var foo0 = PNLfoo[0]; 1.2218 + var bar0 = PNLbar[0]; 1.2219 + parEl.firstChild.removeAttribute('id'); 1.2220 + var fooLength2 = PNLfoo.length; 1.2221 + var barLength2 = PNLbar.length; 1.2222 + var bazLength2 = PNLbaz.length; 1.2223 + var baz1 = PNLbaz[0]; 1.2224 + document.body.removeChild(parEl); 1.2225 + assert_equals( fooLength0, 0, 'foo length (before test) when appended to document' ); 1.2226 + assert_equals( barLength0, 0, 'bar length (before test) when appended to document' ); 1.2227 + assert_equals( bazLength0, 1, 'baz length (before test)' ); 1.2228 + assert_equals( baz0, parEl.lastChild, 'baz[0] (before test)' ); 1.2229 + assert_equals( fooLength1, 1, 'foo length after id is created when appended to document' ); 1.2230 + assert_equals( barLength1, 1, 'bar length after id is created when appended to document' ); 1.2231 + assert_equals( bazLength1, 0, 'baz length after id is created' ); 1.2232 + assert_equals( foo0, parEl.firstChild, 'foo[0] after id is created when appended to document' ); 1.2233 + assert_equals( bar0, parEl.firstChild.firstChild, 'bar[0] after id is created when appended to document' ); 1.2234 + assert_equals( fooLength2, 0, 'foo length after removing an attribute when appended to document' ); 1.2235 + assert_equals( barLength2, 0, 'bar length after removing an attribute when appended to document' ); 1.2236 + assert_equals( bazLength2, 1, 'baz length after removing an attribute' ); 1.2237 + assert_equals( baz0, parEl.lastChild, 'baz[0] after removing an attribute' ); 1.2238 +}, 'PropertyNodeList must update when changing duplicated id of referenced sibling'); 1.2239 +test(function () { 1.2240 + var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope></div>'); 1.2241 + var testEl = parEl.childNodes[1]; 1.2242 + var PNL = testEl.properties.namedItem('foo'); 1.2243 + assert_equals( PNL.length, 0, 'length (before test)' ); 1.2244 + testEl.itemRef.toggle('id1'); 1.2245 + assert_equals( PNL.length, 1, 'length after itemref is changed' ); 1.2246 + assert_equals( PNL[0], parEl.firstChild, 'item 0 after itemref is changed' ); 1.2247 + testEl.removeAttribute('itemref'); 1.2248 + assert_equals( PNL.length, 0, 'length after itemref is removed' ); 1.2249 + assert_true( !PNL[0], 'item 0 after itemref is removed' ); 1.2250 + document.body.appendChild(parEl); 1.2251 + var length0 = PNL.length; 1.2252 + testEl.itemRef.toggle('id1'); 1.2253 + var length1 = PNL.length; 1.2254 + var foo0 = PNL[0]; 1.2255 + testEl.removeAttribute('itemref'); 1.2256 + var length2 = PNL.length; 1.2257 + var foo1 = PNL[0]; 1.2258 + document.body.removeChild(parEl); 1.2259 + assert_equals( length0, 0, 'length (before test) when appended to document' ); 1.2260 + assert_equals( length1, 1, 'length after itemref is changed when appended to document' ); 1.2261 + assert_equals( foo0, parEl.firstChild, 'item 0 after itemref is changed when appended to document' ); 1.2262 + assert_equals( length2, 0, 'length after itemref is removed when appended to document' ); 1.2263 + assert_true( !foo1, 'item 0 after itemref is removed when appended to document' ); 1.2264 +}, 'PropertyNodeList must update when changing itemref to point to an element'); 1.2265 +test(function () { 1.2266 + var parEl = makeEl('div',{},'<div id="id1"><div></div></div><div itemscope itemref="id1"></div>'); 1.2267 + var testEl = parEl.childNodes[1]; 1.2268 + var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar'); 1.2269 + assert_equals( PNLfoo.length, 0, 'foo length (before test)' ); 1.2270 + assert_equals( PNLbar.length, 0, 'bar length (before test)' ); 1.2271 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.2272 + assert_equals( PNLfoo.length, 1, 'foo length after a referenced element is added' ); 1.2273 + assert_equals( PNLbar.length, 0, 'bar length after a referenced element is added' ); 1.2274 + assert_equals( PNLfoo.item(0), parEl.firstChild.lastChild, 'foo 0 after a referenced element is added' ); //uses item just for the fun of it 1.2275 + parEl.firstChild.firstChild.itemProp.toggle('bar'); 1.2276 + assert_equals( PNLfoo.length, 1, 'foo length after a referenced itemprop is changed' ); 1.2277 + assert_equals( PNLbar.length, 1, 'bar length after a referenced itemprop is changed' ); 1.2278 + assert_equals( PNLfoo[0], parEl.firstChild.lastChild, 'foo 0 after a referenced element is added' ); 1.2279 + assert_equals( PNLbar[0], parEl.firstChild.firstChild, 'bar 0 after a referenced element is added' ); 1.2280 + parEl.firstChild.removeChild(parEl.firstChild.firstChild); 1.2281 + assert_equals( PNLfoo.length, 1, 'foo length after a referenced element is removed' ); 1.2282 + assert_equals( PNLbar.length, 0, 'bar length after a referenced element is removed' ); 1.2283 + assert_equals( PNLfoo[0], parEl.firstChild.firstChild, 'foo 0 after a referenced element is removed' ); 1.2284 + assert_true( !PNLbar[0], 'bar 0 after a referenced element is removed' ); 1.2285 + parEl.innerHTML = '<div id="id1"><div></div></div><div itemscope itemref="id1"></div>'; 1.2286 + testEl = parEl.childNodes[1]; 1.2287 + PNLfoo = testEl.properties.namedItem('foo'); 1.2288 + PNLbar = testEl.properties.namedItem('bar'); 1.2289 + document.body.appendChild(parEl); 1.2290 + var step1fooLength = PNLfoo.length; 1.2291 + var step1barLength = PNLbar.length; 1.2292 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.2293 + var step2fooLength = PNLfoo.length; 1.2294 + var step2barLength = PNLbar.length; 1.2295 + var step2foo0 = PNLfoo.item(0); //uses item just for the fun of it 1.2296 + var step2fooExpected = parEl.firstChild.lastChild; 1.2297 + parEl.firstChild.firstChild.itemProp.toggle('bar'); 1.2298 + var step3fooLength = PNLfoo.length; 1.2299 + var step3barLength = PNLbar.length; 1.2300 + var step3foo0 = PNLfoo[0]; 1.2301 + var step3bar0 = PNLbar[0]; 1.2302 + var step3fooExpected = parEl.firstChild.lastChild; 1.2303 + var step3barExpected = parEl.firstChild.firstChild; 1.2304 + parEl.firstChild.removeChild(parEl.firstChild.firstChild); 1.2305 + var step4fooLength = PNLfoo.length; 1.2306 + var step4barLength = PNLbar.length; 1.2307 + var step4foo0 = PNLfoo[0]; 1.2308 + var step4bar0 = PNLbar[0]; 1.2309 + var step4fooExpected = parEl.firstChild.firstChild; 1.2310 + document.body.removeChild(parEl); 1.2311 + assert_equals( step1fooLength, 0, 'foo length (before test) when appended to document' ); 1.2312 + assert_equals( step1barLength, 0, 'bar length (before test) when appended to document' ); 1.2313 + assert_equals( step2fooLength, 1, 'foo length after a referenced element is added when appended to document' ); 1.2314 + assert_equals( step2barLength, 0, 'bar length after a referenced element is added when appended to document' ); 1.2315 + assert_equals( step2foo0, step2fooExpected, 'foo 0 after a referenced element is added when appended to document' ); 1.2316 + assert_equals( step3fooLength, 1, 'foo length after a referenced itemprop is changed when appended to document' ); 1.2317 + assert_equals( step3barLength, 1, 'bar length after a referenced itemprop is changed when appended to document' ); 1.2318 + assert_equals( step3foo0, step3fooExpected, 'foo 0 after a referenced element is added when appended to document' ); 1.2319 + assert_equals( step3bar0, step3barExpected, 'bar 0 after a referenced element is added when appended to document' ); 1.2320 + assert_equals( step4fooLength, 1, 'foo length after a referenced element is removed when appended to document' ); 1.2321 + assert_equals( step4barLength, 0, 'bar length after a referenced element is removed when appended to document' ); 1.2322 + assert_equals( step4foo0, step4fooExpected, 'foo 0 after a referenced element is removed when appended to document' ); 1.2323 + assert_true( !step4bar0, 'bar 0 after a referenced element is removed when appended to document' ); 1.2324 +}, 'PropertyNodeList must update when changing children of elements referenced through itemref'); 1.2325 +test(function () { 1.2326 + var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope itemref="id1"><div itemprop="foo"></div></div>'); 1.2327 + var testEl = parEl.childNodes[1]; 1.2328 + var PNL = testEl.properties.namedItem('foo'); 1.2329 + assert_equals( PNL.length, 2, 'length (before test)' ); 1.2330 + assert_equals( PNL[0], parEl.firstChild, 'item 0 (before test)' ); 1.2331 + assert_equals( PNL[1], testEl.firstChild, 'item 1 (before test)' ); 1.2332 + document.body.appendChild(testEl); 1.2333 + var step1length = PNL.length; 1.2334 + var step1prop0 = PNL[0]; 1.2335 + var step1prop1 = PNL[1]; 1.2336 + parEl.appendChild(testEl); 1.2337 + assert_equals( step1length, 1, 'length after changing parent' ); 1.2338 + assert_equals( step1prop0, testEl.firstChild, 'item 0 after changing parent' ); 1.2339 + assert_true( !step1prop1, 'item 1 after changing parent' ); 1.2340 + assert_equals( PNL.length, 2, 'length after re-parenting' ); 1.2341 + assert_equals( PNL[0], parEl.firstChild, 'item 0 after re-parenting' ); 1.2342 + assert_equals( PNL[1], testEl.firstChild, 'item 1 after re-parenting' ); 1.2343 + document.body.appendChild(parEl); 1.2344 + var step2length = PNL.length; 1.2345 + var step2prop0 = PNL[0]; 1.2346 + var step2prop1 = PNL[1]; 1.2347 + document.createElement('div').appendChild(testEl); 1.2348 + var step3length = PNL.length; 1.2349 + var step3prop0 = PNL[0]; 1.2350 + var step3prop1 = PNL[1]; 1.2351 + parEl.appendChild(testEl); 1.2352 + var step4length = PNL.length; 1.2353 + var step4prop0 = PNL[0]; 1.2354 + var step4prop1 = PNL[1]; 1.2355 + document.body.removeChild(parEl); 1.2356 + assert_equals( step2length, 2, 'length (before test) when appended to document' ); 1.2357 + assert_equals( step2prop0, parEl.firstChild, 'item 0 (before test) when appended to document' ); 1.2358 + assert_equals( step2prop1, testEl.firstChild, 'item 1 (before test) when appended to document' ); 1.2359 + assert_equals( step3length, 1, 'length after changing parent when appended to document' ); 1.2360 + assert_equals( step3prop0, testEl.firstChild, 'item 0 after changing parent when appended to document' ); 1.2361 + assert_true( !step3prop1, 'item 1 after changing parent when appended to document' ); 1.2362 + assert_equals( step4length, 2, 'length after re-parenting when appended to document' ); 1.2363 + assert_equals( step4prop0, parEl.firstChild, 'item 0 after re-parenting when appended to document' ); 1.2364 + assert_equals( step4prop1, testEl.firstChild, 'item 1 after re-parenting when appended to document' ); 1.2365 +}, 'PropertyNodeList must update when appending elements with itemref to different parents'); 1.2366 +test(function () { 1.2367 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div><div itemprop="foo"></div></div>'); 1.2368 + var PNL = testEl.properties.namedItem('foo'); 1.2369 + assert_equals( PNL.length, 1, 'length (before test)' ); 1.2370 + assert_equals( PNL[0], testEl.firstChild.firstChild, 'foo 0 (before test)' ); 1.2371 + testEl.firstChild.itemScope = true; 1.2372 + assert_equals( PNL.length, 0, 'length after setting itemscope' ); 1.2373 + assert_true( !PNL[0], 'foo 0 after setting itemscope' ); 1.2374 + testEl.firstChild.removeAttribute('itemscope'); 1.2375 + assert_equals( PNL.length, 1, 'length after removing itemscope attribute' ); 1.2376 + assert_equals( PNL[0], testEl.firstChild.firstChild, 'foo 0 after removing itemscope attribute' ); 1.2377 +}, 'PropertyNodeList must update when changing itemscope of children'); 1.2378 +//PropertyNodeList.getValues 1.2379 +test(function () { 1.2380 + var valuesArray = makeEl('div',{}).properties.namedItem('foo').getValues(); 1.2381 + assert_true( valuesArray instanceof Array, 'instanceof test' ); 1.2382 + Array.prototype.customProp = true; 1.2383 + assert_true( valuesArray.customProp, 'inheritance test' ); 1.2384 +}, 'getValues must return an array'); 1.2385 +test(function () { 1.2386 + var testEl = makeEl('div',{}); 1.2387 + var props = testEl.properties.namedItem('foo'); 1.2388 + assert_not_equals( props.getValues(), props.getValues() ); 1.2389 +}, 'getValues must always return a newly constructed array'); 1.2390 +test(function () { 1.2391 + var parEl = makeEl('div',{},'<div id="id1"></div>'); 1.2392 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1 id2'}); 1.2393 + parEl.appendChild(testEl); 1.2394 + testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'})); 1.2395 + testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2396 + testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'})); 1.2397 + testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2398 + testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'})); 1.2399 + testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'})); 1.2400 + testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'})); 1.2401 + testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2402 + testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text')); 1.2403 + testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'})); 1.2404 + testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'})); 1.2405 + testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text')); 1.2406 + parEl.appendChild(makeEl('time',{itemprop:'foo',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2407 + testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2408 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2409 + testEl.appendChild(makeEl('madeuponthespot',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2410 + var PNL = testEl.properties.namedItem('foo'); 1.2411 + var valuesArray = PNL.getValues(); 1.2412 + for( var i = 0; i < PNL.length; i++ ) { 1.2413 + assert_equals( valuesArray[i], PNL[i].itemValue, 'property index ' + i + ', tag ' + PNL[i].tagName ); 1.2414 + } 1.2415 + assert_equals( valuesArray.length, 20, 'length' ); 1.2416 +}, 'getValues array must contain the same item values as itemValue would return for the given properties'); 1.2417 +test(function () { 1.2418 + var parEl = makeEl('div',{},'<div id="id1"></div>'); 1.2419 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1 id2'}); 1.2420 + parEl.appendChild(testEl); 1.2421 + testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'})); 1.2422 + testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2423 + testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'})); 1.2424 + testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2425 + testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'})); 1.2426 + testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'})); 1.2427 + testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'})); 1.2428 + testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2429 + testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text')); 1.2430 + testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'})); 1.2431 + testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'})); 1.2432 + testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text')); 1.2433 + parEl.appendChild(makeEl('time',{itemprop:'foo',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2434 + testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2435 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2436 + testEl.appendChild(makeEl('madeuponthespot',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2437 + var PNL = testEl.properties.namedItem('foo'); 1.2438 + var valuesArray = PNL.getValues(); 1.2439 + var staticArray = []; 1.2440 + for( var i = 0; i < PNL.length; i++ ) { 1.2441 + staticArray[i] = PNL[i].itemValue; 1.2442 + } 1.2443 + testEl.innerHTML = ''; 1.2444 + parEl.firstChild.firstChild.childNodes[1].itemScope = false; 1.2445 + assert_equals( valuesArray.length, staticArray.length, 'length after modification' ); 1.2446 + for( var j = 0; j < staticArray.length; j++ ) { 1.2447 + assert_equals( valuesArray[j], staticArray[j], 'property index ' + j ); 1.2448 + } 1.2449 + assert_equals( valuesArray[1], parEl.firstChild.firstChild.childNodes[1], 'retaining pointer after modification' ); 1.2450 + staticArray = null; 1.2451 + parEl.firstChild.firstChild.innerHTML = ''; 1.2452 + assert_equals( valuesArray[1] && valuesArray[1].nodeType, 1, 'retaining pointer after removal' ); 1.2453 +}, 'getValues array must not be live'); 1.2454 +//names 1.2455 +test(function () { 1.2456 + assert_equals( typeof makeEl('div',{}).properties.names, 'object' ); 1.2457 +}, 'the names property must be an object'); 1.2458 +test(function () { 1.2459 + var testEl = makeEl('div',{}); 1.2460 + assert_true( testEl.properties.names instanceof DOMStringList, 'instanceof DOMStringList' ); 1.2461 + DOMStringList.prototype.stringCustomProperty = true; 1.2462 + assert_true( testEl.properties.names.stringCustomProperty, 'inheritance from DOMStringList' ); 1.2463 +}, 'the names property must implement DOMStringList'); 1.2464 +test(function () { 1.2465 + var failed = false, elem = makeEl('div',{itemscope:'itemscope'}), realList = elem.properties.names; 1.2466 + try { 1.2467 + elem.properties.names = ''; 1.2468 + } catch(e) { 1.2469 + failed = e; 1.2470 + } 1.2471 + assert_equals(elem.properties.names,realList); 1.2472 + assert_false(failed,'an error was thrown'); 1.2473 +}, 'the names property must be read-only'); 1.2474 +test(function () { 1.2475 + var testEl = makeEl('div',{}); 1.2476 + assert_equals( testEl.properties.names, testEl.properties.names ); 1.2477 +}, 'the names property must always reference the same object'); 1.2478 +test(function () { 1.2479 + var testEl = makeEl('div',{}); 1.2480 + assert_equals( testEl.properties.names.item(0), null, 'item(0)' ); 1.2481 + assert_equals( testEl.properties.names.item(-1), null, 'item(-1)' ); 1.2482 +}, 'names.item() must return null for out of range indexes'); 1.2483 +test(function () { 1.2484 + var testEl = makeEl('div',{}); 1.2485 + assert_equals( testEl.properties.names[0], window.undefined, '[0]' ); 1.2486 + assert_equals( testEl.properties.names[-1], window.undefined, '[-1]' ); 1.2487 +}, 'names[index] must return undefined for out of range indexes'); 1.2488 +test(function () { 1.2489 + var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>'); 1.2490 + assert_equals( testEl.properties.names.length, 0, 'length' ); 1.2491 + assert_true( !testEl.properties.names.item(0), 'item(0)' ); 1.2492 + assert_true( !testEl.properties.names[0], '[0]' ); 1.2493 + assert_false( testEl.properties.names.contains('foo'), 'contains' ); 1.2494 +}, 'the names collection must be empty if the element does not have an itemscope property'); 1.2495 +test(function () { 1.2496 + var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>'); 1.2497 + testEl.itemScope = true; 1.2498 + assert_equals( testEl.properties.names.length, 1, 'length' ); 1.2499 + assert_equals( testEl.properties.names.item(0), 'foo', 'item(0)' ); 1.2500 + assert_equals( testEl.properties.names[0], 'foo', '[0]' ); 1.2501 + assert_true( testEl.properties.names.contains('foo'), 'contains' ); 1.2502 +}, 'the names collection must become populated if the element is given an itemscope property'); 1.2503 +test(function () { 1.2504 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo">bar</div>'); 1.2505 + testEl.itemScope = false; 1.2506 + assert_equals( testEl.properties.names.length, 0, 'length' ); 1.2507 + assert_true( !testEl.properties.names.item(0), 'item(0)' ); 1.2508 + assert_true( !testEl.properties.names[0], '[0]' ); 1.2509 + assert_false( testEl.properties.names.contains('foo'), 'contains' ); 1.2510 +}, 'the names collection must become empty if the element\'s itemscope property is removed'); 1.2511 +test(function () { 1.2512 + var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>'); 1.2513 + testEl.properties.names.item = 'test'; 1.2514 + testEl.properties.names.contains = 'test'; 1.2515 + assert_equals( testEl.properties.names.item, 'test', 'item' ); 1.2516 + assert_equals( testEl.properties.names.contains, 'test', 'contains' ); 1.2517 +}, 'the names.item and names.contains methods should be overwriteable'); 1.2518 +test(function () { 1.2519 + var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>'); 1.2520 + testEl.properties.names.localCustomProperty = 'test'; 1.2521 + assert_equals( testEl.properties.names.localCustomProperty, 'test' ); 1.2522 +}, 'the names.customProperty should be writeable'); 1.2523 +test(function () { 1.2524 + //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter 1.2525 + //ES5 makes [[Put]] fail but not throw 1.2526 + var failed = false; 1.2527 + var elem = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo">bar</div>'); 1.2528 + try { 1.2529 + elem.properties.names.length = 0; 1.2530 + } catch(e) { 1.2531 + failed = e; 1.2532 + } 1.2533 + assert_equals(elem.properties.names.length,1); 1.2534 + assert_false(failed,'an error was thrown'); 1.2535 +}, 'names.length must be read-only'); 1.2536 +test(function () { 1.2537 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.2538 + assert_equals( testEl.properties.names.length, 4 ); 1.2539 +}, 'names.length must be the total number of property names'); 1.2540 +test(function () { 1.2541 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div><div itemprop="foo"></div></div><div itemprop="baz \t\r\n\fqux"></div>'); 1.2542 + assert_equals( testEl.properties.names.item(0), 'foo', 'item(0)' ); 1.2543 + assert_equals( testEl.properties.names.item(1), 'bar', 'item(1)' ); 1.2544 + assert_equals( testEl.properties.names.item(2), 'baz', 'item(2)' ); 1.2545 + assert_equals( testEl.properties.names.item(3), 'qux', 'item(3)' ); 1.2546 + assert_equals( testEl.properties.names[0], 'foo', '[0]' ); 1.2547 + assert_equals( testEl.properties.names[1], 'bar', '[1]' ); 1.2548 + assert_equals( testEl.properties.names[2], 'baz', '[2]' ); 1.2549 + assert_equals( testEl.properties.names[3], 'qux', '[3]' ); 1.2550 +}, 'names.item must give each property name in tree order'); 1.2551 +test(function () { 1.2552 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar BAR bar"><div itemprop="FOO"></div><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.2553 + assert_equals( testEl.properties.names.length, 6, 'length' ); 1.2554 + assert_equals( testEl.properties.names.item(0), 'foo', 'item(0)' ); 1.2555 + assert_equals( testEl.properties.names.item(1), 'bar', 'item(1)' ); 1.2556 + assert_equals( testEl.properties.names.item(2), 'BAR', 'item(2)' ); 1.2557 + assert_equals( testEl.properties.names.item(3), 'FOO', 'item(3)' ); 1.2558 + assert_equals( testEl.properties.names.item(4), 'baz', 'item(4)' ); 1.2559 + assert_equals( testEl.properties.names.item(5), 'qux', 'item(5)' ); 1.2560 + assert_equals( testEl.properties.names[0], 'foo', '[0]' ); 1.2561 + assert_equals( testEl.properties.names[1], 'bar', '[1]' ); 1.2562 + assert_equals( testEl.properties.names[2], 'BAR', '[2]' ); 1.2563 + assert_equals( testEl.properties.names[3], 'FOO', '[3]' ); 1.2564 + assert_equals( testEl.properties.names[4], 'baz', '[4]' ); 1.2565 + assert_equals( testEl.properties.names[5], 'qux', '[5]' ); 1.2566 +}, 'names must be case sensitive'); 1.2567 +test(function () { 1.2568 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="FOO"></div><div itemprop="foo"></div></div><div itemprop="baz qux"></div>'); 1.2569 + assert_true( testEl.properties.names.contains('foo'), 'foo' ); 1.2570 + assert_true( testEl.properties.names.contains('FOO'), 'FOO' ); 1.2571 + assert_true( testEl.properties.names.contains('bar'), 'bar' ); 1.2572 + assert_false( testEl.properties.names.contains('BAR'), 'BAR' ); 1.2573 + assert_true( testEl.properties.names.contains('baz'), 'baz' ); 1.2574 + assert_true( testEl.properties.names.contains('qux'), 'qux' ); 1.2575 + assert_false( testEl.properties.names.contains('madeup'), 'madeup' ); 1.2576 +}, 'names.contains must return boolean if the name exists'); 1.2577 +test(function () { 1.2578 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="1"></div>'); 1.2579 + assert_equals( testEl.properties.names.item('1'), null ); 1.2580 +}, 'names.item must cast to number'); 1.2581 +test(function () { 1.2582 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="1"></div>'); 1.2583 + assert_true( testEl.properties.names.contains({ valueOf: function () { return 2; }, toString: function () { return 'foo'; } }), 'object' ); 1.2584 + assert_true( testEl.properties.names.contains(1), 'number' ); 1.2585 +}, 'names.contains must cast to string'); 1.2586 +test(function () { 1.2587 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div>'); 1.2588 + var namesList = testEl.properties.names; 1.2589 + testEl.innerHTML = '<div itemprop="baz"></div>'; 1.2590 + assert_equals( testEl.properties.names.length, 1, 'length' ); 1.2591 + assert_equals( testEl.properties.names[0], 'baz', '[0]' ); 1.2592 +}, 'the names collection must be live'); 1.2593 +test(function () { 1.2594 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="|§!"#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_<>帿ŨÆ"></div>'); 1.2595 + assert_equals( testEl.properties.names[0], '|§!"#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_<>帿ŨÆ' ); 1.2596 +}, 'names must reflect property names containing special characters'); 1.2597 +test(function () { 1.2598 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemscope><div itemprop="bar"></div></div>'); 1.2599 + assert_equals( testEl.properties.names.length, 1, 'length' ); 1.2600 + assert_equals( testEl.properties.names[0], 'foo', '[0]' ); 1.2601 + assert_true( testEl.properties.names.contains('foo'), 'contains(foo)' ); 1.2602 + assert_false( testEl.properties.names.contains('bar'), 'contains(bar)' ); 1.2603 +}, 'names must ignore properties of nested items'); 1.2604 +test(function () { 1.2605 + //note, itemref ordering is reversed compared with the next test to catch failed sorting algorithms 1.2606 + var parEl = makeEl('div',{},'<div itemprop="foo" id="id1"></div><div itemscope itemref="id2 id1"><div itemprop="bar"></div></div><div itemprop="baz" id="id2"><div itemprop="qux"></div></div>'); 1.2607 + var testEl = parEl.childNodes[1]; 1.2608 + document.body.appendChild(parEl); 1.2609 + var length = testEl.properties.names.length; 1.2610 + var names0 = testEl.properties.names[0]; 1.2611 + var names1 = testEl.properties.names[1]; 1.2612 + var names2 = testEl.properties.names[2]; 1.2613 + var names3 = testEl.properties.names[3]; 1.2614 + document.body.removeChild(parEl); 1.2615 + assert_equals( length, 4, 'length' ); 1.2616 + assert_equals( names0, 'foo', 'names[0]' ); 1.2617 + assert_equals( names1, 'bar', 'names[1]' ); 1.2618 + assert_equals( names2, 'baz', 'names[2]' ); 1.2619 + assert_equals( names3, 'qux', 'names[3]' ); 1.2620 +}, 'names must see items added with itemref when attached to the document\'s DOM'); 1.2621 +test(function () { 1.2622 + var parEl = makeEl('div',{},'<div itemprop="foo" id="id1"></div><div itemscope itemref="id1 id2"><div itemprop="bar"></div></div><div itemprop="baz" id="id2"><div itemprop="qux"></div></div>'); 1.2623 + var testEl = parEl.childNodes[1]; 1.2624 + assert_equals( testEl.properties.names.length, 4, 'length' ); 1.2625 + assert_equals( testEl.properties.names[0], 'foo', 'names[0]' ); 1.2626 + assert_equals( testEl.properties.names[1], 'bar', 'names[1]' ); 1.2627 + assert_equals( testEl.properties.names[2], 'baz', 'names[2]' ); 1.2628 + assert_equals( testEl.properties.names[3], 'qux', 'names[3]' ); 1.2629 +}, 'names must see items added with itemref'); 1.2630 +test(function () { 1.2631 + //this one also tests the live object just in case - further ones will not always do this as its live status will already have been well established 1.2632 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.2633 + var DSL = testEl.properties.names; 1.2634 + testEl.removeAttribute('itemscope'); 1.2635 + assert_equals( testEl.properties.names.length, 0, 'removing attribute' ); 1.2636 + assert_equals( DSL.length, 0, 'removing attribute (live)' ); 1.2637 + assert_true( !testEl.properties.names[0], 'removing attribute [0]' ); 1.2638 + assert_true( !DSL[0], 'removing attribute [0] (live)' ); 1.2639 + testEl.itemScope = true; 1.2640 + assert_equals( testEl.properties.names.length, 1, 'setting itemScope' ); 1.2641 + assert_equals( DSL.length, 1, 'setting itemScope (live)' ); 1.2642 + assert_equals( testEl.properties.names[0], 'foo', 'names[0] after setting itemScope' ); 1.2643 + assert_equals( DSL[0], 'foo', 'names[0] after setting itemScope (live)' ); 1.2644 +}, 'names must update when adding itemscope on the root'); 1.2645 +test(function () { 1.2646 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>'); 1.2647 + assert_equals( testEl.properties.names.length, 1, 'length (before test)' ); 1.2648 + assert_equals( testEl.properties.names[0], 'foo', 'item 0 (before test)' ); 1.2649 + testEl.appendChild(makeEl('div',{itemprop:'bar'})); 1.2650 + assert_equals( testEl.properties.names.length, 2, 'length after adding a child' ); 1.2651 + assert_equals( testEl.properties.names[0], 'foo', 'item 0 after adding a child' ); 1.2652 + assert_equals( testEl.properties.names[1], 'bar', 'item 1 after adding a child' ); 1.2653 + testEl.lastChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.2654 + assert_equals( testEl.properties.names.length, 2, 'foo length after adding a child with duplicated name' ); 1.2655 + assert_equals( testEl.properties.names[0], 'foo', 'item 0 after adding a child with duplicated name' ); 1.2656 + assert_equals( testEl.properties.names[1], 'bar', 'item 1 after adding a child with duplicated name' ); 1.2657 + testEl.removeChild(testEl.lastChild); 1.2658 + assert_equals( testEl.properties.names.length, 1, 'length after removing a child' ); 1.2659 + assert_equals( testEl.properties.names[0], 'foo', 'item 0 after removing a child' ); 1.2660 +}, 'names must update when adding property elements'); 1.2661 +test(function () { 1.2662 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div>'); 1.2663 + var DSL = testEl.properties.names; 1.2664 + assert_equals( DSL[0], 'foo', 'item 0 (before test)' ); 1.2665 + assert_equals( DSL[1], 'bar', 'item 1 (before test)' ); 1.2666 + testEl.appendChild(testEl.firstChild); 1.2667 + assert_equals( DSL[0], 'bar', 'item 0 (after test)' ); 1.2668 + assert_equals( DSL[1], 'foo', 'item 1 (after test)' ); 1.2669 +}, 'names must update when re-ordering property elements'); 1.2670 +test(function () { 1.2671 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div></div>'); 1.2672 + var DSL = testEl.properties.names; 1.2673 + assert_equals( DSL.length, 1, 'length (before test)' ); 1.2674 + assert_equals( DSL[0], 'foo', 'item 0 (before test)' ); 1.2675 + testEl.lastChild.itemProp.toggle('bar'); 1.2676 + assert_equals( DSL.length, 2, 'length after adding a token' ); 1.2677 + assert_equals( DSL[0], 'foo', 'item 0 after adding a token' ); 1.2678 + assert_equals( DSL[1], 'bar', 'item 1 after adding a token' ); 1.2679 + testEl.lastChild.itemProp.add('foo'); 1.2680 + assert_equals( DSL.length, 2, 'length after adding a duplicated token' ); 1.2681 + assert_equals( DSL[0], 'foo', 'item 0 after adding a duplicated token' ); 1.2682 + assert_equals( DSL[1], 'bar', 'item 1 after adding a duplicated token' ); 1.2683 + testEl.lastChild.removeAttribute('itemprop'); 1.2684 + assert_equals( DSL.length, 1, 'length after removing an attribute' ); 1.2685 + assert_equals( DSL[0], 'foo', 'item 0 after removing an attribute' ); 1.2686 + testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div><div itemprop="foo"></div>'); 1.2687 + DSL = testEl.properties.names; 1.2688 + assert_equals( DSL.length, 2, 'length (before second test)' ); 1.2689 + assert_equals( DSL[0], 'foo', 'item 0 (before second test)' ); 1.2690 + assert_equals( DSL[1], 'bar', 'item 1 (before second test)' ); 1.2691 + testEl.firstChild.removeAttribute('itemprop'); 1.2692 + assert_equals( DSL.length, 2, 'length after removing attribute of first item' ); 1.2693 + assert_equals( DSL[0], 'bar', 'item 0 after removing attribute of first item' ); 1.2694 + assert_equals( DSL[1], 'foo', 'item 1 after removing attribute of first item' ); 1.2695 + testEl.firstChild.itemProp.add('foo'); 1.2696 + assert_equals( DSL.length, 2, 'length after adding duplicated token to first item' ); 1.2697 + assert_equals( DSL[0], 'foo', 'item 0 after adding duplicated token to first item' ); 1.2698 + assert_equals( DSL[1], 'bar', 'item 1 after adding duplicated token to first item' ); 1.2699 + testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo bar"></div>'); 1.2700 + DSL = testEl.properties.names; 1.2701 + assert_equals( DSL.length, 2, 'length (before third test)' ); 1.2702 + assert_equals( DSL[0], 'foo', 'item 0 (before third test)' ); 1.2703 + assert_equals( DSL[1], 'bar', 'item 1 (before third test)' ); 1.2704 + testEl.firstChild.itemProp.toggle('foo'); 1.2705 + testEl.firstChild.itemProp.toggle('foo'); 1.2706 + assert_equals( DSL.length, 2, 'length after swapping tokens' ); 1.2707 + assert_equals( DSL[0], 'bar', 'item 0 after swapping tokens' ); 1.2708 + assert_equals( DSL[1], 'foo', 'item 1 after swapping tokens' ); 1.2709 +}, 'names must update when changing itemProp of children'); 1.2710 +test(function () { 1.2711 + var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div>'); 1.2712 + var testEl = parEl.childNodes[1]; 1.2713 + var DSL = testEl.properties.names; 1.2714 + assert_equals( DSL.length, 0, 'length (before test)' ); 1.2715 + parEl.firstChild.id = 'id1'; 1.2716 + assert_equals( DSL.length, 2, 'length after id is created' ); 1.2717 + assert_equals( DSL[0], 'foo', 'item 0 after id is created' ); 1.2718 + assert_equals( DSL[1], 'bar', 'item 1 after id is created' ); 1.2719 + parEl.firstChild.removeAttribute('id'); 1.2720 + assert_equals( DSL.length, 0, 'length after removing an attribute' ); 1.2721 + document.body.appendChild(parEl); 1.2722 + var step1length = DSL.length; 1.2723 + parEl.firstChild.id = 'id1'; 1.2724 + var step2length = DSL.length; 1.2725 + var step2item0 = DSL[0]; 1.2726 + var step2item1 = DSL[1]; 1.2727 + parEl.firstChild.removeAttribute('id'); 1.2728 + var step3length = DSL.length; 1.2729 + document.body.removeChild(parEl); 1.2730 + assert_equals( step1length, 0, 'length (before test) when appended to document' ); 1.2731 + assert_equals( step2length, 2, 'length after id is created when appended to document' ); 1.2732 + assert_equals( step2item0, 'foo', 'item 0 after id is created when appended to document' ); 1.2733 + assert_equals( step2item1, 'bar', 'item 1 after id is created when appended to document' ); 1.2734 + assert_equals( step3length, 0, 'length after removing an attribute when appended to document' ); 1.2735 +}, 'names must update when changing id of referenced sibling when appended to document'); 1.2736 +test(function () { 1.2737 + var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div><div itemprop="baz" id="id1"></div>'); 1.2738 + var testEl = parEl.childNodes[1]; 1.2739 + var DSL = testEl.properties.names; 1.2740 + assert_equals( DSL.length, 1, 'length (before test)' ); 1.2741 + assert_equals( DSL[0], 'baz', 'item 0 (before test)' ); 1.2742 + parEl.firstChild.id = 'id1'; 1.2743 + assert_equals( DSL.length, 2, 'length after id is created' ); 1.2744 + assert_equals( DSL[0], 'foo', 'item 0 after id is created' ); 1.2745 + assert_equals( DSL[1], 'bar', 'item 1 after id is created' ); 1.2746 + parEl.firstChild.removeAttribute('id'); 1.2747 + assert_equals( DSL.length, 1, 'length after removing an attribute' ); 1.2748 + assert_equals( DSL[0], 'baz', 'item 0 after removing an attribute' ); 1.2749 + document.body.appendChild(parEl); 1.2750 + var step1length = DSL.length; 1.2751 + var step1item0 = DSL[0]; 1.2752 + parEl.firstChild.id = 'id1'; 1.2753 + var step2length = DSL.length; 1.2754 + var step2item0 = DSL[0]; 1.2755 + var step2item1 = DSL[1]; 1.2756 + parEl.firstChild.removeAttribute('id'); 1.2757 + var step3length = DSL.length; 1.2758 + var step3item0 = DSL[0]; 1.2759 + document.body.removeChild(parEl); 1.2760 + assert_equals( step1length, 1, 'length (before test)' ); 1.2761 + assert_equals( step1item0, 'baz', 'item 0 (before test)' ); 1.2762 + assert_equals( step2length, 2, 'length after id is created' ); 1.2763 + assert_equals( step2item0, 'foo', 'item 0 after id is created' ); 1.2764 + assert_equals( step2item1, 'bar', 'item 1 after id is created' ); 1.2765 + assert_equals( step3length, 1, 'length after removing an attribute' ); 1.2766 + assert_equals( step3item0, 'baz', 'item 0 after removing an attribute' ); 1.2767 +}, 'names must update when changing duplicated id of referenced sibling'); 1.2768 +test(function () { 1.2769 + var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope></div>'); 1.2770 + var testEl = parEl.childNodes[1]; 1.2771 + var DSL = testEl.properties.names; 1.2772 + assert_equals( DSL.length, 0, 'length (before test)' ); 1.2773 + testEl.itemRef.toggle('id1'); 1.2774 + assert_equals( DSL.length, 1, 'length after itemref is changed' ); 1.2775 + assert_equals( DSL[0], 'foo', 'item 0 after itemref is changed' ); 1.2776 + testEl.removeAttribute('itemref'); 1.2777 + assert_equals( DSL.length, 0, 'length after itemref is removed' ); 1.2778 + assert_true( !DSL[0], 'item 0 after itemref is removed' ); 1.2779 + document.body.appendChild(parEl); 1.2780 + var step1length = DSL.length; 1.2781 + testEl.itemRef.toggle('id1'); 1.2782 + var step2length = DSL.length; 1.2783 + var step2item = DSL[0]; 1.2784 + testEl.removeAttribute('itemref'); 1.2785 + var step3length = DSL.length; 1.2786 + var step3item = DSL[0]; 1.2787 + document.body.removeChild(parEl); 1.2788 + assert_equals( step1length, 0, 'length (before test)' ); 1.2789 + assert_equals( step2length, 1, 'length after itemref is changed' ); 1.2790 + assert_equals( step2item, 'foo', 'item 0 after itemref is changed' ); 1.2791 + assert_equals( step3length, 0, 'length after itemref is removed' ); 1.2792 + assert_true( !step3item, 'item 0 after itemref is removed' ); 1.2793 +}, 'names must update when changing itemref to point to an element'); 1.2794 +test(function () { 1.2795 + var parEl = makeEl('div',{},'<div id="id1"><div></div></div><div itemscope itemref="id1"></div>'); 1.2796 + var testEl = parEl.childNodes[1]; 1.2797 + var DSL = testEl.properties.names; 1.2798 + assert_equals( DSL.length, 0, 'length (before test)' ); 1.2799 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.2800 + assert_equals( DSL.length, 1, 'length after a referenced element is added' ); 1.2801 + assert_equals( DSL.item(0), 'foo', 'item 0 after a referenced element is added' ); //uses item just for the fun of it 1.2802 + parEl.firstChild.firstChild.itemProp.toggle('bar'); 1.2803 + assert_equals( DSL.length, 2, 'length after a referenced itemprop is changed' ); 1.2804 + assert_equals( DSL[0], 'bar', 'item 0 after a referenced element is added' ); 1.2805 + assert_equals( DSL[1], 'foo', 'item 1 after a referenced element is added' ); 1.2806 + parEl.firstChild.removeChild(parEl.firstChild.firstChild); 1.2807 + assert_equals( DSL.length, 1, 'length after a referenced element is removed' ); 1.2808 + assert_equals( DSL[0], 'foo', 'item 0 after a referenced element is removed' ); 1.2809 + parEl.innerHTML = '<div id="id1"><div></div></div><div itemscope itemref="id1"></div>'; 1.2810 + testEl = parEl.childNodes[1]; 1.2811 + DSL = testEl.properties.names; 1.2812 + document.body.appendChild(parEl); 1.2813 + var step1length = DSL.length; 1.2814 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.2815 + var step2length = DSL.length; 1.2816 + var step2item0 = DSL.item(0); //uses item just for the fun of it 1.2817 + parEl.firstChild.firstChild.itemProp.toggle('bar'); 1.2818 + var step3length = DSL.length; 1.2819 + var step3item0 = DSL[0]; 1.2820 + var step3item1 = DSL[1]; 1.2821 + parEl.firstChild.removeChild(parEl.firstChild.firstChild); 1.2822 + var step4length = DSL.length; 1.2823 + var step4item0 = DSL[0]; 1.2824 + document.body.removeChild(parEl); 1.2825 + assert_equals( step1length, 0, 'length (before test)' ); 1.2826 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'})); 1.2827 + assert_equals( step2length, 1, 'length after a referenced element is added' ); 1.2828 + assert_equals( step2item0, 'foo', 'item 0 after a referenced element is added' ); //uses item just for the fun of it 1.2829 + parEl.firstChild.firstChild.itemProp.toggle('bar'); 1.2830 + assert_equals( step3length, 2, 'length after a referenced itemprop is changed' ); 1.2831 + assert_equals( step3item0, 'bar', 'item 0 after a referenced element is added' ); 1.2832 + assert_equals( step3item1, 'foo', 'item 1 after a referenced element is added' ); 1.2833 + parEl.firstChild.removeChild(parEl.firstChild.firstChild); 1.2834 + assert_equals( step4length, 1, 'length after a referenced element is removed' ); 1.2835 + assert_equals( step4item0, 'foo', 'item 0 after a referenced element is removed' ); 1.2836 +}, 'names must update when changing children of elements referenced through itemref'); 1.2837 +test(function () { 1.2838 + var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope itemref="id1"><div itemprop="bar"></div></div>'); 1.2839 + var testEl = parEl.childNodes[1]; 1.2840 + var DSL = testEl.properties.names; 1.2841 + assert_equals( DSL.length, 2, 'length (before test)' ); 1.2842 + assert_equals( DSL[0], 'foo', 'item 0 (before test)' ); 1.2843 + assert_equals( DSL[1], 'bar', 'item 1 (before test)' ); 1.2844 + document.body.appendChild(testEl); 1.2845 + var step1length = DSL.length; 1.2846 + var step1prop0 = DSL[0]; 1.2847 + var step1prop1 = DSL[1]; 1.2848 + parEl.appendChild(testEl); 1.2849 + assert_equals( step1length, 1, 'length after changing parent' ); 1.2850 + assert_equals( step1prop0, 'bar', 'item 0 after changing parent' ); 1.2851 + assert_true( !step1prop1, 'item 1 after changing parent' ); 1.2852 + assert_equals( DSL.length, 2, 'length after re-parenting' ); 1.2853 + assert_equals( DSL[0], 'foo', 'item 0 after re-parenting' ); 1.2854 + assert_equals( DSL[1], 'bar', 'item 1 after re-parenting' ); 1.2855 + document.body.appendChild(parEl); 1.2856 + var step2length = DSL.length; 1.2857 + var step2prop0 = DSL[0]; 1.2858 + var step2prop1 = DSL[1]; 1.2859 + document.createElement('div').appendChild(testEl); 1.2860 + var step3length = DSL.length; 1.2861 + var step3prop0 = DSL[0]; 1.2862 + var step3prop1 = DSL[1]; 1.2863 + parEl.appendChild(testEl); 1.2864 + var step4length = DSL.length; 1.2865 + var step4prop0 = DSL[0]; 1.2866 + var step4prop1 = DSL[1]; 1.2867 + document.body.removeChild(parEl); 1.2868 + assert_equals( step2length, 2, 'length (before test) when appended to document' ); 1.2869 + assert_equals( step2prop0, 'foo', 'item 0 (before test) when appended to document' ); 1.2870 + assert_equals( step2prop1, 'bar', 'item 1 (before test) when appended to document' ); 1.2871 + assert_equals( step3length, 1, 'length after changing parent when appended to document' ); 1.2872 + assert_equals( step3prop0, 'bar', 'item 0 after changing parent when appended to document' ); 1.2873 + assert_true( !step3prop1, 'item 1 after changing parent when appended to document' ); 1.2874 + assert_equals( step4length, 2, 'length after re-parenting when appended to document' ); 1.2875 + assert_equals( step4prop0, 'foo', 'item 0 after re-parenting when appended to document' ); 1.2876 + assert_equals( step4prop1, 'bar', 'item 1 after re-parenting when appended to document' ); 1.2877 +}, 'names must update when appending elements with itemref to different parents'); 1.2878 +test(function () { 1.2879 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div><div itemprop="foo"></div></div>'); 1.2880 + var DSL = testEl.properties.names; 1.2881 + assert_equals( DSL.length, 1, 'length (before test)' ); 1.2882 + assert_equals( DSL[0], 'foo', 'item 0 (before test)' ); 1.2883 + testEl.firstChild.itemScope = true; 1.2884 + assert_equals( DSL.length, 0, 'length after setting itemscope' ); 1.2885 + assert_true( !DSL[0], 'item 0 after setting itemscope' ); 1.2886 + testEl.firstChild.removeAttribute('itemscope'); 1.2887 + assert_equals( DSL.length, 1, 'length after removing itemscope attribute' ); 1.2888 + assert_equals( DSL[0], 'foo', 'item 0 after removing itemscope attribute' ); 1.2889 +}, 'names must update when changing itemscope of children'); 1.2890 + 1.2891 +/* potential bugs */ 1.2892 +test(function () { 1.2893 + var parEl = makeEl('div',{},'<div id="id1"></div>'); 1.2894 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1 id2'}); 1.2895 + parEl.appendChild(testEl); 1.2896 + testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'})); 1.2897 + testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2898 + testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'})); 1.2899 + testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2900 + testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'})); 1.2901 + testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'})); 1.2902 + testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'})); 1.2903 + testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2904 + testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text')); 1.2905 + testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'})); 1.2906 + testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'})); 1.2907 + testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text')); 1.2908 + parEl.appendChild(makeEl('time',{itemprop:'bar',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2909 + testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2910 + parEl.firstChild.appendChild(makeEl('div',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2911 + testEl.appendChild(makeEl('madeuponthespot',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2912 + var properties, PNLfoo, PNLbar, PNLbaz, fooValues, barValues, bazValues, allArrays, snapshot = []; 1.2913 + document.body.appendChild(parEl); 1.2914 + try { 1.2915 + properties = testEl.properties; 1.2916 + PNLfoo = properties.namedItem('foo'); 1.2917 + PNLbar = properties.namedItem('bar'); 1.2918 + PNLbaz = properties.namedItem('baz'); 1.2919 + fooValues = PNLfoo.getValues(); 1.2920 + barValues = PNLbar.getValues(); 1.2921 + bazValues = PNLbaz.getValues(); 1.2922 + allArrays = [properties,PNLfoo,PNLbar,PNLbaz,fooValues,barValues,bazValues]; 1.2923 + for( var a = 0; a < allArrays.length; a++ ) { 1.2924 + snapshot[a] = []; 1.2925 + for( var b = 0; b < allArrays[a].length; b++ ) { 1.2926 + snapshot[a][b] = allArrays[a][b]; 1.2927 + } 1.2928 + } 1.2929 + } catch(e) { /* need to clean up */ } 1.2930 + document.body.removeChild(parEl); 1.2931 + var c, d; 1.2932 + for( c = 0; c < allArrays.length; c++ ) { 1.2933 + for( d = 0; d < allArrays[c].length; d++ ) { 1.2934 + assert_equals( snapshot[c][d], allArrays[c][d], 'allArrays['+c+']['+d+']' ); 1.2935 + } 1.2936 + } 1.2937 + var newArrays = [testEl.properties,testEl.properties.namedItem('foo'),testEl.properties.namedItem('bar'),testEl.properties.namedItem('baz'),testEl.properties.namedItem('foo').getValues(),testEl.properties.namedItem('bar').getValues(),testEl.properties.namedItem('baz').getValues()]; 1.2938 + for( c = 0; c < newArrays.length; c++ ) { 1.2939 + for( d = 0; d < newArrays[c].length; d++ ) { 1.2940 + assert_equals( snapshot[c][d], newArrays[c][d], 'newArrays['+c+']['+d+']' ); 1.2941 + } 1.2942 + } 1.2943 +}, 'collections must survive the parent\'s removal from the document'); 1.2944 +test(function () { 1.2945 + var testEl = makeEl('div',{itemscope:'itemscope'}); 1.2946 + testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'})); 1.2947 + testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2948 + testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'})); 1.2949 + testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2950 + testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'})); 1.2951 + testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'})); 1.2952 + testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'})); 1.2953 + testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text')); 1.2954 + testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text')); 1.2955 + testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'})); 1.2956 + testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'})); 1.2957 + testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text')); 1.2958 + testEl.appendChild(makeEl('time',{itemprop:'bar',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2959 + testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2960 + testEl.appendChild(makeEl('div',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2961 + testEl.appendChild(makeEl('madeuponthespot',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing')); 1.2962 + var properties, PNLfoo, PNLbar, PNLbaz, fooValues, barValues, bazValues, allArrays, snapshot = []; 1.2963 + document.body.appendChild(testEl); 1.2964 + try { 1.2965 + properties = testEl.properties; 1.2966 + PNLfoo = properties.namedItem('foo'); 1.2967 + PNLbar = properties.namedItem('bar'); 1.2968 + PNLbaz = properties.namedItem('baz'); 1.2969 + fooValues = PNLfoo.getValues(); 1.2970 + barValues = PNLbar.getValues(); 1.2971 + bazValues = PNLbaz.getValues(); 1.2972 + allArrays = [properties,PNLfoo,PNLbar,PNLbaz,fooValues,barValues,bazValues]; 1.2973 + for( var a = 0; a < allArrays.length; a++ ) { 1.2974 + snapshot[a] = []; 1.2975 + for( var b = 0; b < allArrays[a].length; b++ ) { 1.2976 + snapshot[a][b] = allArrays[a][b]; 1.2977 + } 1.2978 + } 1.2979 + } catch(e) { /* need to clean up */ } 1.2980 + document.body.removeChild(testEl); 1.2981 + var c, d; 1.2982 + for( c = 0; c < allArrays.length; c++ ) { 1.2983 + for( d = 0; d < allArrays[c].length; d++ ) { 1.2984 + assert_equals( snapshot[c][d], allArrays[c][d], 'allArrays['+c+']['+d+']' ); 1.2985 + } 1.2986 + } 1.2987 + var newArrays = [testEl.properties,testEl.properties.namedItem('foo'),testEl.properties.namedItem('bar'),testEl.properties.namedItem('baz'),testEl.properties.namedItem('foo').getValues(),testEl.properties.namedItem('bar').getValues(),testEl.properties.namedItem('baz').getValues()]; 1.2988 + for( c = 0; c < newArrays.length; c++ ) { 1.2989 + for( d = 0; d < newArrays[c].length; d++ ) { 1.2990 + assert_equals( snapshot[c][d], newArrays[c][d], 'newArrays['+c+']['+d+']' ); 1.2991 + } 1.2992 + } 1.2993 +}, 'collections must survive the item\'s removal from the document'); 1.2994 + 1.2995 +/* override_builtins */ 1.2996 +test(function () { 1.2997 + //http://dev.w3.org/2006/webapi/WebIDL/#named-properties 1.2998 + //[OverrideBuiltins] is not declared for any of the properties, hence no overriding is allowed 1.2999 + var testEl = makeEl('div',{itemscope:'itemscope'}); 1.3000 + var namedItem = testEl.properties.namedItem; 1.3001 + var item = testEl.properties.item; 1.3002 + var names = testEl.properties.names; 1.3003 + testEl.innerHTML = '<div itemprop="namedItem length item names"></div>'; 1.3004 + assert_equals( testEl.properties['namedItem'], namedItem, 'namedItem' ); 1.3005 + assert_equals( testEl.properties['length'], 1, 'length' ); 1.3006 + assert_equals( testEl.properties['item'], item, 'item' ); 1.3007 + assert_equals( testEl.properties['names'], names, 'names' ); 1.3008 +}, 'itemprop names must not override builtin properties'); 1.3009 + 1.3010 +/* casting */ 1.3011 +//when calling object[other_object], ECMAScript treats other_object as a named property so it casts it to a string using toString 1.3012 +//when looking up a named property, ECMAScript and WebIDL <http://dev.w3.org/2006/webapi/WebIDL/#named-properties> will prefer an array index property name 1.3013 +test(function () { 1.3014 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="2"></div><div itemprop="0"></div>'); 1.3015 + assert_equals( testEl.properties.item('0'), testEl.properties.item(0), '0' ); 1.3016 + assert_equals( testEl.properties.item('2'), testEl.properties.item(2), '2' ); 1.3017 +}, 'properties.item(integerString) should cast to a number'); 1.3018 +test(function () { 1.3019 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="2"></div><div itemprop="0"></div>'); 1.3020 + assert_equals( testEl.properties['0'], testEl.properties.item(0), '0' ); 1.3021 + assert_equals( testEl.properties['2'], window.undefined, '2' ); 1.3022 +}, 'properties[integerString] should act as a numeric index'); 1.3023 +test(function () { 1.3024 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="0"></div>'); 1.3025 + assert_equals( testEl.properties.namedItem(0), testEl.properties.namedItem('0'), '0' ); 1.3026 + assert_true( testEl.properties.namedItem(0) instanceof PropertyNodeList , 'instanceof' ); 1.3027 +}, 'properties.namedItem(integer) should cast to a string'); 1.3028 +test(function () { 1.3029 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="2 foo"></div><div itemprop="0"></div>'); 1.3030 + assert_equals( testEl.properties[{ toString: function(){return 'foo';}, valueOf: function(){return 1;} }][0], testEl.firstChild, 'foo' ); 1.3031 + assert_equals( testEl.properties[{ toString: function(){return '0';}, valueOf: function(){return 1;} }], testEl.firstChild, '0' ); 1.3032 + assert_equals( testEl.properties[{ toString: function(){return '2';}, valueOf: function(){return 0;} }], window.undefined, '2' ); 1.3033 +}, 'properties[someObject] should cast toString before using whichever casting applies'); 1.3034 + 1.3035 +/* loops and evil itemref */ 1.3036 +test(function () { 1.3037 + //This should have 1 property on each itemscope, pointing only to its direct child 1.3038 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemscope itemprop="foo"><div itemprop="bar"></div></div>'); 1.3039 + assert_equals( testEl.properties.length, 1, 'outer length' ); 1.3040 + assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' ); 1.3041 + assert_true( !testEl.properties[1], 'outer properties[1]' ); 1.3042 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' ); 1.3043 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' ); 1.3044 + assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' ); 1.3045 + assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length' ); 1.3046 + assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0]' ); 1.3047 + assert_equals( testEl.properties.names.length, 1, 'outer names.length' ); 1.3048 + assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' ); 1.3049 + assert_true( !testEl.properties.names[1], 'outer names[1]' ); 1.3050 + assert_equals( testEl.firstChild.properties.length, 1, 'inner length' ); 1.3051 + assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' ); 1.3052 + assert_true( !testEl.firstChild.properties[1], 'inner properties[1]' ); 1.3053 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' ); 1.3054 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' ); 1.3055 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' ); 1.3056 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' ); 1.3057 + assert_true( !testEl.firstChild.properties.namedItem('foo')[1], 'inner foo[1]' ); 1.3058 + assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length' ); 1.3059 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' ); 1.3060 + assert_true( !testEl.firstChild.properties.names[1], 'inner names[1]' ); 1.3061 +}, 'simple nested itemscope'); 1.3062 +test(function () { 1.3063 + //This should have 1 property on each itemscope, pointing only to its direct child 1.3064 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'},'<div itemscope itemprop="foo" id="id1" itemref="id2"><div itemprop="bar" id="id2"></div></div>'); 1.3065 + assert_equals( testEl.properties.length, 1, 'outer length' ); 1.3066 + assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' ); 1.3067 + assert_true( !testEl.properties[1], 'outer properties[1]' ); 1.3068 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' ); 1.3069 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' ); 1.3070 + assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' ); 1.3071 + assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length' ); 1.3072 + assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0]' ); 1.3073 + assert_equals( testEl.properties.names.length, 1, 'outer names.length' ); 1.3074 + assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' ); 1.3075 + assert_true( !testEl.properties.names[1], 'outer names[1]' ); 1.3076 + assert_equals( testEl.firstChild.properties.length, 1, 'inner length' ); 1.3077 + assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' ); 1.3078 + assert_true( !testEl.firstChild.properties[1], 'inner properties[1]' ); 1.3079 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' ); 1.3080 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' ); 1.3081 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' ); 1.3082 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' ); 1.3083 + assert_true( !testEl.firstChild.properties.namedItem('foo')[1], 'inner foo[1]' ); 1.3084 + assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length' ); 1.3085 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' ); 1.3086 + assert_true( !testEl.firstChild.properties.names[1], 'inner names[1]' ); 1.3087 + document.body.appendChild(testEl); 1.3088 + try { 1.3089 + assert_equals( testEl.properties.length, 1, 'outer length when appended to document' ); 1.3090 + assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0] when appended to document' ); 1.3091 + assert_true( !testEl.properties[1], 'outer properties[1] when appended to document' ); 1.3092 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length when appended to document' ); 1.3093 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0] when appended to document' ); 1.3094 + assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1] when appended to document' ); 1.3095 + assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length when appended to document' ); 1.3096 + assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0] when appended to document' ); 1.3097 + assert_equals( testEl.properties.names.length, 1, 'outer names.length when appended to document' ); 1.3098 + assert_equals( testEl.properties.names[0], 'foo', 'outer names[0] when appended to document' ); 1.3099 + assert_true( !testEl.properties.names[1], 'outer names[1] when appended to document' ); 1.3100 + assert_equals( testEl.firstChild.properties.length, 1, 'inner length when appended to document' ); 1.3101 + assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0] when appended to document' ); 1.3102 + assert_true( !testEl.firstChild.properties[1], 'inner properties[1] when appended to document' ); 1.3103 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length when appended to document' ); 1.3104 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0] when appended to document' ); 1.3105 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length when appended to document' ); 1.3106 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0] when appended to document' ); 1.3107 + assert_true( !testEl.firstChild.properties.namedItem('foo')[1], 'inner foo[1] when appended to document' ); 1.3108 + assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length when appended to document' ); 1.3109 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0] when appended to document' ); 1.3110 + assert_true( !testEl.firstChild.properties.names[1], 'inner names[1] when appended to document' ); 1.3111 + } catch(e) { 1.3112 + document.body.removeChild(testEl); 1.3113 + throw (e); 1.3114 + } 1.3115 + document.body.removeChild(testEl); 1.3116 +}, 'simple nested itemscope with itemref'); 1.3117 +test(function () { 1.3118 + //This should have 3 properties on the item; foo, bar and baz 1.3119 + var parEl = makeEl('div',{},'<div itemprop="foo" id="id2"></div><div itemscope itemref="id1 id2"><div itemprop="bar"></div></div><div itemprop="baz" id="id1"></div>'); 1.3120 + var testEl = parEl.childNodes[1]; 1.3121 + assert_equals( testEl.properties.length, 3, 'length' ); 1.3122 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0]' ); 1.3123 + assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1]' ); 1.3124 + assert_equals( testEl.properties[2], parEl.lastChild, 'properties[2]' ); 1.3125 + assert_true( !testEl.properties[3], 'properties[3]' ); 1.3126 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo.length' ); 1.3127 + assert_equals( testEl.properties.namedItem('foo')[0], parEl.firstChild, 'foo[0]' ); 1.3128 + assert_true( !testEl.properties.namedItem('foo')[1], 'foo[1]' ); 1.3129 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length' ); 1.3130 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0]' ); 1.3131 + assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1]' ); 1.3132 + assert_equals( testEl.properties.namedItem('baz').length, 1, 'baz.length' ); 1.3133 + assert_equals( testEl.properties.namedItem('baz')[0], parEl.lastChild, 'baz[0]' ); 1.3134 + assert_true( !testEl.properties.namedItem('baz')[1], 'baz[1]' ); 1.3135 + assert_equals( testEl.properties.names.length, 3, 'names.length' ); 1.3136 + assert_equals( testEl.properties.names[0], 'foo', 'names[0]' ); 1.3137 + assert_equals( testEl.properties.names[1], 'bar', 'names[1]' ); 1.3138 + assert_equals( testEl.properties.names[2], 'baz', 'names[2]' ); 1.3139 + assert_true( !testEl.properties.names[3], 'names[3]' ); 1.3140 + document.body.appendChild(parEl); 1.3141 + try { 1.3142 + assert_equals( testEl.properties.length, 3, 'length when appended to document' ); 1.3143 + assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] when appended to document' ); 1.3144 + assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1] when appended to document' ); 1.3145 + assert_equals( testEl.properties[2], parEl.lastChild, 'properties[2] when appended to document' ); 1.3146 + assert_true( !testEl.properties[3], 'properties[3] when appended to document' ); 1.3147 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo.length when appended to document' ); 1.3148 + assert_equals( testEl.properties.namedItem('foo')[0], parEl.firstChild, 'foo[0] when appended to document' ); 1.3149 + assert_true( !testEl.properties.namedItem('foo')[1], 'foo[1] when appended to document' ); 1.3150 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length when appended to document' ); 1.3151 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0] when appended to document' ); 1.3152 + assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1] when appended to document' ); 1.3153 + assert_equals( testEl.properties.namedItem('baz').length, 1, 'baz.length when appended to document' ); 1.3154 + assert_equals( testEl.properties.namedItem('baz')[0], parEl.lastChild, 'baz[0] when appended to document' ); 1.3155 + assert_true( !testEl.properties.namedItem('baz')[1], 'baz[1] when appended to document' ); 1.3156 + assert_equals( testEl.properties.names.length, 3, 'names.length when appended to document' ); 1.3157 + assert_equals( testEl.properties.names[0], 'foo', 'names[0] when appended to document' ); 1.3158 + assert_equals( testEl.properties.names[1], 'bar', 'names[1] when appended to document' ); 1.3159 + assert_equals( testEl.properties.names[2], 'baz', 'names[2] when appended to document' ); 1.3160 + assert_true( !testEl.properties.names[3], 'names[3] when appended to document' ); 1.3161 + } catch(e) { 1.3162 + document.body.removeChild(parEl); 1.3163 + throw (e); 1.3164 + } 1.3165 + document.body.removeChild(parEl); 1.3166 +}, 'simple sibling itemref'); 1.3167 +test(function () { 1.3168 + //This should have no properties 1.3169 + var testEl = makeEl('div',{itemscope:'itemscope',id:'id1',itemref:'id1',itemprop:'foo'}); 1.3170 + assert_equals( testEl.properties.length, 0, 'length' ); 1.3171 + assert_true( !testEl.properties[0], 'properties[0]' ); 1.3172 + assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length' ); 1.3173 + assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0]' ); 1.3174 + assert_equals( testEl.properties.names.length, 0, 'names.length' ); 1.3175 + assert_true( !testEl.properties.names[0], 'names[0]' ); 1.3176 + document.body.appendChild(testEl); 1.3177 + try { 1.3178 + assert_equals( testEl.properties.length, 0, 'length when appended to document' ); 1.3179 + assert_true( !testEl.properties[0], 'properties[0] when appended to document' ); 1.3180 + assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length when appended to document' ); 1.3181 + assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0] when appended to document' ); 1.3182 + assert_equals( testEl.properties.names.length, 0, 'names.length when appended to document' ); 1.3183 + assert_true( !testEl.properties.names[0], 'names[0] when appended to document' ); 1.3184 + } catch(e) { 1.3185 + document.body.removeChild(testEl); 1.3186 + throw (e); 1.3187 + } 1.3188 + document.body.removeChild(testEl); 1.3189 +}, 'itemref pointing to itself'); 1.3190 +test(function () { 1.3191 + //This should have 1 property, pointing to the child 1.3192 + var testEl = makeEl('div',{itemscope:'itemscope',id:'id1',itemref:'id1',itemprop:'foo'},'<div itemprop="bar"></div>'); 1.3193 + assert_equals( testEl.properties.length, 1, 'length' ); 1.3194 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0]' ); 1.3195 + assert_true( !testEl.properties[1], 'properties[1]' ); 1.3196 + assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length' ); 1.3197 + assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0]' ); 1.3198 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length' ); 1.3199 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0]' ); 1.3200 + assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1]' ); 1.3201 + assert_equals( testEl.properties.names.length, 1, 'names.length' ); 1.3202 + assert_equals( testEl.properties.names[0], 'bar', 'names[0]' ); 1.3203 + assert_true( !testEl.properties.names[1], 'names[1]' ); 1.3204 + document.body.appendChild(testEl); 1.3205 + try { 1.3206 + assert_equals( testEl.properties.length, 1, 'length when appended to document' ); 1.3207 + assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] when appended to document' ); 1.3208 + assert_true( !testEl.properties[1], 'properties[1] when appended to document' ); 1.3209 + assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length when appended to document' ); 1.3210 + assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0] when appended to document' ); 1.3211 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length when appended to document' ); 1.3212 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0] when appended to document' ); 1.3213 + assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1] when appended to document' ); 1.3214 + assert_equals( testEl.properties.names.length, 1, 'names.length when appended to document' ); 1.3215 + assert_equals( testEl.properties.names[0], 'bar', 'names[0] when appended to document' ); 1.3216 + assert_true( !testEl.properties.names[1], 'names[1] when appended to document' ); 1.3217 + } catch(e) { 1.3218 + document.body.removeChild(testEl); 1.3219 + throw (e); 1.3220 + } 1.3221 + document.body.removeChild(testEl); 1.3222 +}, 'itemref pointing to itself with child'); 1.3223 +test(function () { 1.3224 + //This should have 1 property on each itemscope, pointing only to its direct child 1.3225 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemscope itemprop="foo" id="id1" itemref="id1"><div itemprop="bar"></div></div>'); 1.3226 + assert_equals( testEl.properties.length, 1, 'outer length' ); 1.3227 + assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' ); 1.3228 + assert_true( !testEl.properties[1], 'outer properties[1]' ); 1.3229 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' ); 1.3230 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' ); 1.3231 + assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' ); 1.3232 + assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length' ); 1.3233 + assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0]' ); 1.3234 + assert_equals( testEl.properties.names.length, 1, 'outer names.length' ); 1.3235 + assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' ); 1.3236 + assert_true( !testEl.properties.names[1], 'outer names[1]' ); 1.3237 + assert_equals( testEl.firstChild.properties.length, 1, 'inner length' ); 1.3238 + assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' ); 1.3239 + assert_true( !testEl.firstChild.properties[1], 'inner properties[1]' ); 1.3240 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' ); 1.3241 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' ); 1.3242 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' ); 1.3243 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' ); 1.3244 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1]' ); 1.3245 + assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length' ); 1.3246 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' ); 1.3247 + assert_true( !testEl.firstChild.properties.names[1], 'inner names[1]' ); 1.3248 + document.body.appendChild(testEl); 1.3249 + try { 1.3250 + assert_equals( testEl.properties.length, 1, 'outer length when appended to document' ); 1.3251 + assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0] when appended to document' ); 1.3252 + assert_true( !testEl.properties[1], 'outer properties[1] when appended to document' ); 1.3253 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length when appended to document' ); 1.3254 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0] when appended to document' ); 1.3255 + assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1] when appended to document' ); 1.3256 + assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length when appended to document' ); 1.3257 + assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0] when appended to document' ); 1.3258 + assert_equals( testEl.properties.names.length, 1, 'outer names.length when appended to document' ); 1.3259 + assert_equals( testEl.properties.names[0], 'foo', 'outer names[0] when appended to document' ); 1.3260 + assert_true( !testEl.properties.names[1], 'outer names[1] when appended to document' ); 1.3261 + assert_equals( testEl.firstChild.properties.length, 1, 'inner length when appended to document' ); 1.3262 + assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0] when appended to document' ); 1.3263 + assert_true( !testEl.firstChild.properties[1], 'inner properties[1] when appended to document' ); 1.3264 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length when appended to document' ); 1.3265 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0] when appended to document' ); 1.3266 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length when appended to document' ); 1.3267 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0] when appended to document' ); 1.3268 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1] when appended to document' ); 1.3269 + assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length when appended to document' ); 1.3270 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0] when appended to document' ); 1.3271 + assert_true( !testEl.firstChild.properties.names[1], 'inner names[1] when appended to document' ); 1.3272 + } catch(e) { 1.3273 + document.body.removeChild(testEl); 1.3274 + throw (e); 1.3275 + } 1.3276 + document.body.removeChild(testEl); 1.3277 +}, 'nested itemref pointing to itself with child'); 1.3278 +test(function () { 1.3279 + //Each itemscope has one property, pointing to the other one 1.3280 + var testEl = makeEl('div',{},'<div id="id1" itemprop="foo" itemscope itemref="id2"></div><div id="id2" itemprop="bar" itemscope itemref="id1"></div>'); 1.3281 + assert_equals( testEl.firstChild.properties.length, 1, 'id1 length' ); 1.3282 + assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0]' ); 1.3283 + assert_true( !testEl.firstChild.properties[1], 'id1 properties[1]' ); 1.3284 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length' ); 1.3285 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0]' ); 1.3286 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length' ); 1.3287 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0]' ); 1.3288 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1]' ); 1.3289 + assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length' ); 1.3290 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0]' ); 1.3291 + assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1]' ); 1.3292 + assert_equals( testEl.lastChild.properties.length, 1, 'id2 length' ); 1.3293 + assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0]' ); 1.3294 + assert_true( !testEl.lastChild.properties[1], 'id2 properties[1]' ); 1.3295 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length' ); 1.3296 + assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0]' ); 1.3297 + assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1]' ); 1.3298 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length' ); 1.3299 + assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0]' ); 1.3300 + assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length' ); 1.3301 + assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0]' ); 1.3302 + assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1]' ); 1.3303 + document.body.appendChild(testEl); 1.3304 + try { 1.3305 + assert_equals( testEl.firstChild.properties.length, 1, 'id1 length when appended to document' ); 1.3306 + assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0] when appended to document' ); 1.3307 + assert_true( !testEl.firstChild.properties[1], 'id1 properties[1] when appended to document' ); 1.3308 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length when appended to document' ); 1.3309 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0] when appended to document' ); 1.3310 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length when appended to document' ); 1.3311 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0] when appended to document' ); 1.3312 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1] when appended to document' ); 1.3313 + assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length when appended to document' ); 1.3314 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0] when appended to document' ); 1.3315 + assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1] when appended to document' ); 1.3316 + assert_equals( testEl.lastChild.properties.length, 1, 'id2 length when appended to document' ); 1.3317 + assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0] when appended to document' ); 1.3318 + assert_true( !testEl.lastChild.properties[1], 'id2 properties[1] when appended to document' ); 1.3319 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length when appended to document' ); 1.3320 + assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0] when appended to document' ); 1.3321 + assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1] when appended to document' ); 1.3322 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length when appended to document' ); 1.3323 + assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0] when appended to document' ); 1.3324 + assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length when appended to document' ); 1.3325 + assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0] when appended to document' ); 1.3326 + assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1] when appended to document' ); 1.3327 + } catch(e) { 1.3328 + document.body.removeChild(testEl); 1.3329 + throw (e); 1.3330 + } 1.3331 + document.body.removeChild(testEl); 1.3332 +}, 'mutually referencing siblings'); 1.3333 +test(function () { 1.3334 + //Root has 2 properties, foo and bar 1.3335 + //Each itemscope has one property, pointing to the other one 1.3336 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div id="id1" itemprop="foo" itemscope itemref="id2"></div><div id="id2" itemprop="bar" itemscope itemref="id1"></div>'); 1.3337 + assert_equals( testEl.properties.length, 2, 'root length' ); 1.3338 + assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0]' ); 1.3339 + assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1]' ); 1.3340 + assert_true( !testEl.properties[2], 'root properties[2]' ); 1.3341 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length' ); 1.3342 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0]' ); 1.3343 + assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1]' ); 1.3344 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length' ); 1.3345 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0]' ); 1.3346 + assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1]' ); 1.3347 + assert_equals( testEl.properties.names.length, 2, 'root names.length' ); 1.3348 + assert_equals( testEl.properties.names[0], 'foo', 'root names[0]' ); 1.3349 + assert_equals( testEl.properties.names[1], 'bar', 'root names[1]' ); 1.3350 + assert_true( !testEl.properties.names[2], 'root names[2]' ); 1.3351 + assert_equals( testEl.firstChild.properties.length, 1, 'id1 length' ); 1.3352 + assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0]' ); 1.3353 + assert_true( !testEl.firstChild.properties[1], 'id1 properties[1]' ); 1.3354 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length' ); 1.3355 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0]' ); 1.3356 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length' ); 1.3357 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0]' ); 1.3358 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1]' ); 1.3359 + assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length' ); 1.3360 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0]' ); 1.3361 + assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1]' ); 1.3362 + assert_equals( testEl.lastChild.properties.length, 1, 'id2 length' ); 1.3363 + assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0]' ); 1.3364 + assert_true( !testEl.lastChild.properties[1], 'id2 properties[1]' ); 1.3365 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length' ); 1.3366 + assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0]' ); 1.3367 + assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1]' ); 1.3368 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length' ); 1.3369 + assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0]' ); 1.3370 + assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length' ); 1.3371 + assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0]' ); 1.3372 + assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1]' ); 1.3373 + document.body.appendChild(testEl); 1.3374 + try { 1.3375 + assert_equals( testEl.properties.length, 2, 'root length when appended to document' ); 1.3376 + assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0] when appended to document' ); 1.3377 + assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1] when appended to document' ); 1.3378 + assert_true( !testEl.properties[2], 'root properties[2] when appended to document' ); 1.3379 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length when appended to document' ); 1.3380 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0] when appended to document' ); 1.3381 + assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1] when appended to document' ); 1.3382 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length when appended to document' ); 1.3383 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0] when appended to document' ); 1.3384 + assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1] when appended to document' ); 1.3385 + assert_equals( testEl.properties.names.length, 2, 'root names.length when appended to document' ); 1.3386 + assert_equals( testEl.properties.names[0], 'foo', 'root names[0] when appended to document' ); 1.3387 + assert_equals( testEl.properties.names[1], 'bar', 'root names[1] when appended to document' ); 1.3388 + assert_true( !testEl.properties.names[2], 'root names[2] when appended to document' ); 1.3389 + assert_equals( testEl.firstChild.properties.length, 1, 'id1 length when appended to document' ); 1.3390 + assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0] when appended to document' ); 1.3391 + assert_true( !testEl.firstChild.properties[1], 'id1 properties[1] when appended to document' ); 1.3392 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length when appended to document' ); 1.3393 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0] when appended to document' ); 1.3394 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length when appended to document' ); 1.3395 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0] when appended to document' ); 1.3396 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1] when appended to document' ); 1.3397 + assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length when appended to document' ); 1.3398 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0] when appended to document' ); 1.3399 + assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1] when appended to document' ); 1.3400 + assert_equals( testEl.lastChild.properties.length, 1, 'id2 length when appended to document' ); 1.3401 + assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0] when appended to document' ); 1.3402 + assert_true( !testEl.lastChild.properties[1], 'id2 properties[1] when appended to document' ); 1.3403 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length when appended to document' ); 1.3404 + assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0] when appended to document' ); 1.3405 + assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1] when appended to document' ); 1.3406 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length when appended to document' ); 1.3407 + assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0] when appended to document' ); 1.3408 + assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length when appended to document' ); 1.3409 + assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0] when appended to document' ); 1.3410 + assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1] when appended to document' ); 1.3411 + } catch(e) { 1.3412 + document.body.removeChild(testEl); 1.3413 + throw (e); 1.3414 + } 1.3415 + document.body.removeChild(testEl); 1.3416 +}, 'mutually referencing siblings with item parent'); 1.3417 +test(function () { 1.3418 + //Root has two properties, foo and bar 1.3419 + //Bar has two properties, baz and qux 1.3420 + //Qux has one property, bar 1.3421 + var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div id="id1" itemprop="bar" itemscope><div itemprop="baz"></div><div itemprop="qux" itemscope itemref="id1"></div></div>'); 1.3422 + assert_equals( testEl.properties.length, 2, 'root length' ); 1.3423 + assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0]' ); 1.3424 + assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1]' ); 1.3425 + assert_true( !testEl.properties[2], 'root properties[2]' ); 1.3426 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length' ); 1.3427 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0]' ); 1.3428 + assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1]' ); 1.3429 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length' ); 1.3430 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0]' ); 1.3431 + assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1]' ); 1.3432 + assert_equals( testEl.properties.namedItem('baz').length, 0, 'root baz.length' ); 1.3433 + assert_true( !testEl.properties.namedItem('baz')[0], 'root baz[0]' ); 1.3434 + assert_equals( testEl.properties.namedItem('qux').length, 0, 'root qux.length' ); 1.3435 + assert_true( !testEl.properties.namedItem('qux')[0], 'root qux[0]' ); 1.3436 + assert_equals( testEl.properties.names.length, 2, 'root names.length' ); 1.3437 + assert_equals( testEl.properties.names[0], 'foo', 'root names[0]' ); 1.3438 + assert_equals( testEl.properties.names[1], 'bar', 'root names[1]' ); 1.3439 + assert_true( !testEl.properties.names[2], 'root names[2]' ); 1.3440 + assert_equals( testEl.lastChild.properties.length, 2, 'bar length' ); 1.3441 + assert_equals( testEl.lastChild.properties[0], testEl.lastChild.firstChild, 'bar properties[0]' ); 1.3442 + assert_equals( testEl.lastChild.properties[1], testEl.lastChild.lastChild, 'bar properties[1]' ); 1.3443 + assert_true( !testEl.lastChild.properties[2], 'bar properties[2]' ); 1.3444 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'bar foo.length' ); 1.3445 + assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'bar foo[0]' ); 1.3446 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'bar bar.length' ); 1.3447 + assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'bar bar[0]' ); 1.3448 + assert_equals( testEl.lastChild.properties.namedItem('baz').length, 1, 'bar baz.length' ); 1.3449 + assert_equals( testEl.lastChild.properties.namedItem('baz')[0], testEl.lastChild.firstChild, 'bar baz[0]' ); 1.3450 + assert_true( !testEl.lastChild.properties.namedItem('baz')[1], 'bar baz[1]' ); 1.3451 + assert_equals( testEl.lastChild.properties.namedItem('qux').length, 1, 'bar qux.length' ); 1.3452 + assert_equals( testEl.lastChild.properties.namedItem('qux')[0], testEl.lastChild.lastChild, 'bar qux[0]' ); 1.3453 + assert_true( !testEl.lastChild.properties.namedItem('qux')[1], 'bar qux[1]' ); 1.3454 + assert_equals( testEl.lastChild.properties.names.length, 2, 'bar names.length' ); 1.3455 + assert_equals( testEl.lastChild.properties.names[0], 'baz', 'bar names[0]' ); 1.3456 + assert_equals( testEl.lastChild.properties.names[1], 'qux', 'bar names[1]' ); 1.3457 + assert_true( !testEl.lastChild.properties.names[2], 'bar names[2]' ); 1.3458 + assert_equals( testEl.lastChild.lastChild.properties.length, 1, 'qux length' ); 1.3459 + assert_equals( testEl.lastChild.lastChild.properties[0], testEl.lastChild, 'qux properties[0]' ); 1.3460 + assert_true( !testEl.lastChild.lastChild.properties[1], 'qux properties[1]' ); 1.3461 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('foo').length, 0, 'qux foo.length' ); 1.3462 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('foo')[0], 'qux foo[0]' ); 1.3463 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar').length, 1, 'qux bar.length' ); 1.3464 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar')[0], testEl.lastChild, 'qux bar[0]' ); 1.3465 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('bar')[1], 'qux bar[1]' ); 1.3466 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('baz').length, 0, 'qux baz.length' ); 1.3467 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('baz')[0], 'qux baz[0]' ); 1.3468 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('qux').length, 0, 'qux qux.length' ); 1.3469 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('qux')[0], 'qux qux[0]' ); 1.3470 + assert_equals( testEl.lastChild.lastChild.properties.names.length, 1, 'qux names.length' ); 1.3471 + assert_equals( testEl.lastChild.lastChild.properties.names[0], 'bar', 'qux names[0]' ); 1.3472 + assert_true( !testEl.lastChild.lastChild.properties.names[1], 'qux names[1]' ); 1.3473 + document.body.appendChild(testEl); 1.3474 + try { 1.3475 + assert_equals( testEl.properties.length, 2, 'root length when appended to document' ); 1.3476 + assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0] when appended to document' ); 1.3477 + assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1] when appended to document' ); 1.3478 + assert_true( !testEl.properties[2], 'root properties[2] when appended to document' ); 1.3479 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length when appended to document' ); 1.3480 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0] when appended to document' ); 1.3481 + assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1] when appended to document' ); 1.3482 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length when appended to document' ); 1.3483 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0] when appended to document' ); 1.3484 + assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1] when appended to document' ); 1.3485 + assert_equals( testEl.properties.namedItem('baz').length, 0, 'root baz.length when appended to document' ); 1.3486 + assert_true( !testEl.properties.namedItem('baz')[0], 'root baz[0] when appended to document' ); 1.3487 + assert_equals( testEl.properties.namedItem('qux').length, 0, 'root qux.length when appended to document' ); 1.3488 + assert_true( !testEl.properties.namedItem('qux')[0], 'root qux[0] when appended to document' ); 1.3489 + assert_equals( testEl.properties.names.length, 2, 'root names.length when appended to document' ); 1.3490 + assert_equals( testEl.properties.names[0], 'foo', 'root names[0] when appended to document' ); 1.3491 + assert_equals( testEl.properties.names[1], 'bar', 'root names[1] when appended to document' ); 1.3492 + assert_true( !testEl.properties.names[2], 'root names[2] when appended to document' ); 1.3493 + assert_equals( testEl.lastChild.properties.length, 2, 'bar length when appended to document' ); 1.3494 + assert_equals( testEl.lastChild.properties[0], testEl.lastChild.firstChild, 'bar properties[0] when appended to document' ); 1.3495 + assert_equals( testEl.lastChild.properties[1], testEl.lastChild.lastChild, 'bar properties[1] when appended to document' ); 1.3496 + assert_true( !testEl.lastChild.properties[2], 'bar properties[2] when appended to document' ); 1.3497 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'bar foo.length when appended to document' ); 1.3498 + assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'bar foo[0] when appended to document' ); 1.3499 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'bar bar.length when appended to document' ); 1.3500 + assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'bar bar[0] when appended to document' ); 1.3501 + assert_equals( testEl.lastChild.properties.namedItem('baz').length, 1, 'bar baz.length when appended to document' ); 1.3502 + assert_equals( testEl.lastChild.properties.namedItem('baz')[0], testEl.lastChild.firstChild, 'bar baz[0] when appended to document' ); 1.3503 + assert_true( !testEl.lastChild.properties.namedItem('baz')[1], 'bar baz[1] when appended to document' ); 1.3504 + assert_equals( testEl.lastChild.properties.namedItem('qux').length, 1, 'bar qux.length when appended to document' ); 1.3505 + assert_equals( testEl.lastChild.properties.namedItem('qux')[0], testEl.lastChild.lastChild, 'bar qux[0] when appended to document' ); 1.3506 + assert_true( !testEl.lastChild.properties.namedItem('qux')[1], 'bar qux[1] when appended to document' ); 1.3507 + assert_equals( testEl.lastChild.properties.names.length, 2, 'bar names.length when appended to document' ); 1.3508 + assert_equals( testEl.lastChild.properties.names[0], 'baz', 'bar names[0] when appended to document' ); 1.3509 + assert_equals( testEl.lastChild.properties.names[1], 'qux', 'bar names[1] when appended to document' ); 1.3510 + assert_true( !testEl.lastChild.properties.names[2], 'bar names[2] when appended to document' ); 1.3511 + assert_equals( testEl.lastChild.lastChild.properties.length, 1, 'qux length when appended to document' ); 1.3512 + assert_equals( testEl.lastChild.lastChild.properties[0], testEl.lastChild, 'qux properties[0] when appended to document' ); 1.3513 + assert_true( !testEl.lastChild.lastChild.properties[1], 'qux properties[1] when appended to document' ); 1.3514 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('foo').length, 0, 'qux foo.length when appended to document' ); 1.3515 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('foo')[0], 'qux foo[0] when appended to document' ); 1.3516 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar').length, 1, 'qux bar.length when appended to document' ); 1.3517 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar')[0], testEl.lastChild, 'qux bar[0] when appended to document' ); 1.3518 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('bar')[1], 'qux bar[1] when appended to document' ); 1.3519 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('baz').length, 0, 'qux baz.length when appended to document' ); 1.3520 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('baz')[0], 'qux baz[0] when appended to document' ); 1.3521 + assert_equals( testEl.lastChild.lastChild.properties.namedItem('qux').length, 0, 'qux qux.length when appended to document' ); 1.3522 + assert_true( !testEl.lastChild.lastChild.properties.namedItem('qux')[0], 'qux qux[0] when appended to document' ); 1.3523 + assert_equals( testEl.lastChild.lastChild.properties.names.length, 1, 'qux names.length when appended to document' ); 1.3524 + assert_equals( testEl.lastChild.lastChild.properties.names[0], 'bar', 'qux names[0] when appended to document' ); 1.3525 + assert_true( !testEl.lastChild.lastChild.properties.names[1], 'qux names[1] when appended to document' ); 1.3526 + } catch(e) { 1.3527 + document.body.removeChild(testEl); 1.3528 + throw (e); 1.3529 + } 1.3530 + document.body.removeChild(testEl); 1.3531 +}, 'itemref referencing parent item'); 1.3532 +test(function () { 1.3533 + //foo has one property, bar 1.3534 + var testEl = makeEl('div',{id:'id1'},'<div itemprop="bar"></div><div itemscope itemref="id1" itemprop="foo"></div>'); 1.3535 + assert_equals( testEl.lastChild.properties.length, 1, 'length' ); 1.3536 + assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'properties[0]' ); 1.3537 + assert_true( !testEl.lastChild.properties[1], 'properties[1]' ); 1.3538 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'foo.length' ); 1.3539 + assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'foo[0]' ); 1.3540 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 1, 'bar.length' ); 1.3541 + assert_equals( testEl.lastChild.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0]' ); 1.3542 + assert_true( !testEl.lastChild.properties.namedItem('bar')[1], 'bar[1]' ); 1.3543 + assert_equals( testEl.lastChild.properties.names.length, 1, 'names.length' ); 1.3544 + assert_equals( testEl.lastChild.properties.names[0], 'bar', 'names[0]' ); 1.3545 + assert_true( !testEl.lastChild.properties.names[1], 'names[1]' ); 1.3546 + document.body.appendChild(testEl); 1.3547 + try { 1.3548 + assert_equals( testEl.lastChild.properties.length, 1, 'length when appended to document' ); 1.3549 + assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'properties[0] when appended to document' ); 1.3550 + assert_true( !testEl.lastChild.properties[1], 'properties[1] when appended to document' ); 1.3551 + assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'foo.length when appended to document' ); 1.3552 + assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'foo[0] when appended to document' ); 1.3553 + assert_equals( testEl.lastChild.properties.namedItem('bar').length, 1, 'bar.length when appended to document' ); 1.3554 + assert_equals( testEl.lastChild.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0] when appended to document' ); 1.3555 + assert_true( !testEl.lastChild.properties.namedItem('bar')[1], 'bar[1] when appended to document' ); 1.3556 + assert_equals( testEl.lastChild.properties.names.length, 1, 'names.length when appended to document' ); 1.3557 + assert_equals( testEl.lastChild.properties.names[0], 'bar', 'names[0] when appended to document' ); 1.3558 + assert_true( !testEl.lastChild.properties.names[1], 'names[1] when appended to document' ); 1.3559 + } catch(e) { 1.3560 + document.body.removeChild(testEl); 1.3561 + throw (e); 1.3562 + } 1.3563 + document.body.removeChild(testEl); 1.3564 +}, 'itemref referencing parent without itemscope'); 1.3565 +test(function () { 1.3566 + var testDiv = makeEl('div', {itemprop:'bar', id:'foo'}, ''); 1.3567 + var testSpan = makeEl('span', {itemscope:'itemscope', itemref: 'foo', id: 'foo'}, ''); 1.3568 + document.body.appendChild(testDiv); 1.3569 + document.body.appendChild(testSpan); 1.3570 + assert_equals(testSpan.properties.length, 1, 'has one property'); 1.3571 + assert_equals(testSpan.properties[0], testDiv, 'has first property'); 1.3572 + assert_equals(testSpan.properties.item(0), testDiv, 'has first property'); 1.3573 + assert_equals(testSpan.properties.namedItem('bar').length, 1, 'has 1 foo property'); 1.3574 + assert_equals(testSpan.properties.namedItem('bar').item(0), testDiv, 'div is foo property'); 1.3575 + assert_equals(testSpan.properties.names.length, 1, 'only has one property'); 1.3576 + document.body.removeChild(testDiv); 1.3577 + document.body.removeChild(testSpan); 1.3578 +}, 'itemref referencing element with same id'); 1.3579 +test(function () { 1.3580 + //Root has three properties, foo, bar and baz 1.3581 + //Foo has two properties, bar and baz 1.3582 + var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'},'<div itemscope itemprop="foo"><div itemprop="bar" id="id1"><div itemprop="baz"></div></div></div>'); 1.3583 + assert_equals( testEl.properties.length, 3, 'outer length' ); 1.3584 + assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' ); 1.3585 + assert_equals( testEl.properties[1], testEl.firstChild.firstChild, 'outer properties[1]' ); 1.3586 + assert_equals( testEl.properties[2], testEl.firstChild.firstChild.firstChild, 'outer properties[2]' ); 1.3587 + assert_true( !testEl.properties[3], 'outer properties[3]' ); 1.3588 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' ); 1.3589 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' ); 1.3590 + assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' ); 1.3591 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'outer bar.length' ); 1.3592 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'outer bar[0]' ); 1.3593 + assert_true( !testEl.properties.namedItem('bar')[1], 'outer bar[1]' ); 1.3594 + assert_equals( testEl.properties.namedItem('baz').length, 1, 'outer baz.length' ); 1.3595 + assert_equals( testEl.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'outer baz[0]' ); 1.3596 + assert_true( !testEl.properties.namedItem('baz')[1], 'outer baz[1]' ); 1.3597 + assert_equals( testEl.properties.names.length, 3, 'outer names.length' ); 1.3598 + assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' ); 1.3599 + assert_equals( testEl.properties.names[1], 'bar', 'outer names[1]' ); 1.3600 + assert_equals( testEl.properties.names[2], 'baz', 'outer names[2]' ); 1.3601 + assert_true( !testEl.properties.names[3], 'outer names[3]' ); 1.3602 + assert_equals( testEl.firstChild.properties.length, 2, 'inner length' ); 1.3603 + assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' ); 1.3604 + assert_equals( testEl.firstChild.properties[1], testEl.firstChild.firstChild.firstChild, 'inner properties[1]' ); 1.3605 + assert_true( !testEl.firstChild.properties[2], 'inner properties[2]' ); 1.3606 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' ); 1.3607 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' ); 1.3608 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' ); 1.3609 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' ); 1.3610 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1]' ); 1.3611 + assert_equals( testEl.firstChild.properties.namedItem('baz').length, 1, 'inner baz.length' ); 1.3612 + assert_equals( testEl.firstChild.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'inner baz[0]' ); 1.3613 + assert_true( !testEl.firstChild.properties.namedItem('baz')[1], 'inner baz[1]' ); 1.3614 + assert_equals( testEl.firstChild.properties.names.length, 2, 'inner names.length' ); 1.3615 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' ); 1.3616 + assert_equals( testEl.firstChild.properties.names[1], 'baz', 'inner names[1]' ); 1.3617 + assert_true( !testEl.firstChild.properties.names[2], 'inner names[2]' ); 1.3618 + document.body.appendChild(testEl); 1.3619 + try { 1.3620 + assert_equals( testEl.properties.length, 3, 'outer length when appended to document' ); 1.3621 + assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0] when appended to document' ); 1.3622 + assert_equals( testEl.properties[1], testEl.firstChild.firstChild, 'outer properties[1] when appended to document' ); 1.3623 + assert_equals( testEl.properties[2], testEl.firstChild.firstChild.firstChild, 'outer properties[2] when appended to document' ); 1.3624 + assert_true( !testEl.properties[3], 'outer properties[3] when appended to document' ); 1.3625 + assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length when appended to document' ); 1.3626 + assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0] when appended to document' ); 1.3627 + assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1] when appended to document' ); 1.3628 + assert_equals( testEl.properties.namedItem('bar').length, 1, 'outer bar.length when appended to document' ); 1.3629 + assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'outer bar[0] when appended to document' ); 1.3630 + assert_true( !testEl.properties.namedItem('bar')[1], 'outer bar[1] when appended to document' ); 1.3631 + assert_equals( testEl.properties.namedItem('baz').length, 1, 'outer baz.length when appended to document' ); 1.3632 + assert_equals( testEl.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'outer baz[0] when appended to document' ); 1.3633 + assert_true( !testEl.properties.namedItem('baz')[1], 'outer baz[1] when appended to document' ); 1.3634 + assert_equals( testEl.properties.names.length, 3, 'outer names.length when appended to document' ); 1.3635 + assert_equals( testEl.properties.names[0], 'foo', 'outer names[0] when appended to document' ); 1.3636 + assert_equals( testEl.properties.names[1], 'bar', 'outer names[1] when appended to document' ); 1.3637 + assert_equals( testEl.properties.names[2], 'baz', 'outer names[2] when appended to document' ); 1.3638 + assert_true( !testEl.properties.names[3], 'outer names[3] when appended to document' ); 1.3639 + assert_equals( testEl.firstChild.properties.length, 2, 'inner length when appended to document' ); 1.3640 + assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0] when appended to document' ); 1.3641 + assert_equals( testEl.firstChild.properties[1], testEl.firstChild.firstChild.firstChild, 'inner properties[1] when appended to document' ); 1.3642 + assert_true( !testEl.firstChild.properties[2], 'inner properties[2] when appended to document' ); 1.3643 + assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length when appended to document' ); 1.3644 + assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0] when appended to document' ); 1.3645 + assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length when appended to document' ); 1.3646 + assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0] when appended to document' ); 1.3647 + assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1] when appended to document' ); 1.3648 + assert_equals( testEl.firstChild.properties.namedItem('baz').length, 1, 'inner baz.length when appended to document' ); 1.3649 + assert_equals( testEl.firstChild.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'inner baz[0] when appended to document' ); 1.3650 + assert_true( !testEl.firstChild.properties.namedItem('baz')[1], 'inner baz[1] when appended to document' ); 1.3651 + assert_equals( testEl.firstChild.properties.names.length, 2, 'inner names.length when appended to document' ); 1.3652 + assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0] when appended to document' ); 1.3653 + assert_equals( testEl.firstChild.properties.names[1], 'baz', 'inner names[1] when appended to document' ); 1.3654 + assert_true( !testEl.firstChild.properties.names[2], 'inner names[2] when appended to document' ); 1.3655 + } catch(e) { 1.3656 + document.body.removeChild(testEl); 1.3657 + throw (e); 1.3658 + } 1.3659 + document.body.removeChild(testEl); 1.3660 +}, 'itemref pointing to child of nested itemscope'); 1.3661 + 1.3662 + </script> 1.3663 + </body> 1.3664 +</html>