dom/imptests/html/microdata/microdata-dom-api/test_001.html

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 <!doctype html>
michael@0 2 <html>
michael@0 3 <head>
michael@0 4 <meta charset="UTF-8">
michael@0 5 <title>Microdata tests</title>
michael@0 6 <script type="text/javascript" src="/resources/testharness.js"></script>
michael@0 7 <script type="text/javascript" src="/resources/testharnessreport.js"></script>
michael@0 8 <link rel="help" href="http://dev.w3.org/html5/md/#microdata-dom-api">
michael@0 9 <link rel="help" href="http://dev.w3.org/html5/md/#encoding-microdata">
michael@0 10 </head>
michael@0 11 <body>
michael@0 12 <noscript><p>Enable JavaScript and reload</p></noscript>
michael@0 13 <div id="log">Running test...</div>
michael@0 14 <div itemscope itemtype="http://example.com/bar data:text/plain, http://example.com/foo" id="one"></div>
michael@0 15 <div itemscope itemtype="http://example.com/bar" id="two"></div>
michael@0 16 <div itemscope itemtype="http://example.com/foo http://example.com/bar" id="three">
michael@0 17 <div itemscope itemtype="http://example.com/bar data:text/plain," id="four"></div>
michael@0 18 </div>
michael@0 19 <div itemscope id="five"></div>
michael@0 20 <script type="text/javascript">
michael@0 21 /* All tests are stand-alone.
michael@0 22 To reduce this testsuite to show only a single desired test,
michael@0 23 simply remove all test(...) blocks before and after it. */
michael@0 24
michael@0 25 function makeEl(eltype,props,contents) {
michael@0 26 var elem = document.createElement(eltype);
michael@0 27 for( var i in props ) {
michael@0 28 //just in case the framework extends object...
michael@0 29 if( props.hasOwnProperty(i) ) {
michael@0 30 elem.setAttribute(i,props[i]);
michael@0 31 }
michael@0 32 }
michael@0 33 if( contents ) {
michael@0 34 elem.innerHTML = contents;
michael@0 35 }
michael@0 36 return elem;
michael@0 37 }
michael@0 38
michael@0 39 /* getItem tests */
michael@0 40 test(function () {
michael@0 41 assert_true( !!document.getItems );
michael@0 42 }, 'document.getItems must exist');
michael@0 43 test(function () {
michael@0 44 assert_true( document.getItems() instanceof NodeList, 'instanceof test' );
michael@0 45 NodeList.prototype.customProperty = true;
michael@0 46 assert_true( document.getItems().customProperty, 'inheritance test' );
michael@0 47 }, 'document.getItems must return a NodeList');
michael@0 48 test(function () {
michael@0 49 assert_equals( document.getItems().length, 5 );
michael@0 50 }, 'document.getItems must locate the correct number of items');
michael@0 51 test(function () {
michael@0 52 var nlist = document.getItems();
michael@0 53 var foo = makeEl('div',{itemscope:'itemscope'});
michael@0 54 document.body.appendChild(foo);
michael@0 55 var templength = nlist.length;
michael@0 56 document.body.removeChild(foo);
michael@0 57 assert_equals( templength, 6 );
michael@0 58 assert_equals( nlist.length, 5 );
michael@0 59 }, 'document.getItems must return a live NodeList');
michael@0 60 test(function () {
michael@0 61 var nlist = document.getItems();
michael@0 62 document.getElementById('one').removeAttribute('itemscope');
michael@0 63 var templength = nlist.length;
michael@0 64 document.getElementById('one').setAttribute('itemscope','itemscope');
michael@0 65 assert_equals( templength, 4 );
michael@0 66 assert_equals( nlist.length, 5 );
michael@0 67 }, 'live NodeList must notice when itemscope changes');
michael@0 68 test(function () {
michael@0 69 document.getElementById('one').removeAttribute('itemscope');
michael@0 70 var templength = document.getItems().length;
michael@0 71 document.getElementById('one').setAttribute('itemscope','itemscope');
michael@0 72 assert_equals( templength, 4 );
michael@0 73 assert_equals( document.getItems().length, 5 );
michael@0 74 }, 'next request must notice when itemscope changes');
michael@0 75 test(function () {
michael@0 76 assert_equals( document.getItems('http://example.com/').length, 0, 'http://example.com/' );
michael@0 77 assert_equals( document.getItems('example').length, 0, 'example' );
michael@0 78 assert_equals( document.getItems('http://example.com/foo').length, 2, 'http://example.com/foo' );
michael@0 79 assert_equals( document.getItems('http://example.com/bar').length, 4, 'http://example.com/bar' );
michael@0 80 assert_equals( document.getItems('data:text/plain,').length, 2, 'data:text/plain,' );
michael@0 81 }, 'document.getItems must locate the right number of items for each itemtype');
michael@0 82 test(function () {
michael@0 83 assert_equals( document.getItems('http://example.com/Foo').length, 0, 'http://example.com/Foo' );
michael@0 84 assert_equals( document.getItems('HTTP://example.com/foo').length, 0, 'HTTP://example.com/foo' );
michael@0 85 }, 'document.getItems must be case sensitive');
michael@0 86 test(function () {
michael@0 87 var nlist = document.getItems('http://example.com/foo');
michael@0 88 var foo = makeEl('div',{itemscope:'itemscope',itemtype:'http://example.com/foo'});
michael@0 89 document.body.appendChild(foo);
michael@0 90 var templength = nlist.length;
michael@0 91 document.body.removeChild(foo);
michael@0 92 assert_equals( templength, 3 );
michael@0 93 assert_equals( nlist.length, 2 );
michael@0 94 }, 'document.getItems must return a live NodeList when using URLs');
michael@0 95 test(function () {
michael@0 96 var nlist = document.getItems('http://example.com/foo');
michael@0 97 document.getElementById('one').removeAttribute('itemtype');
michael@0 98 var templength = nlist.length;
michael@0 99 document.getElementById('one').setAttribute('itemtype','http://example.com/bar data:text/plain, http://example.com/foo');
michael@0 100 assert_equals( templength, 1 );
michael@0 101 assert_equals( nlist.length, 2 );
michael@0 102 }, 'live NodeList must notice when itemtype changes');
michael@0 103 test(function () {
michael@0 104 document.getElementById('one').removeAttribute('itemtype');
michael@0 105 var templength = document.getItems('http://example.com/foo').length;
michael@0 106 document.getElementById('one').setAttribute('itemtype','http://example.com/bar data:text/plain, http://example.com/foo');
michael@0 107 assert_equals( templength, 1 );
michael@0 108 assert_equals( document.getItems('http://example.com/foo').length, 2 );
michael@0 109 }, 'next request must notice when itemtype changes');
michael@0 110 test(function () {
michael@0 111 assert_equals( document.getItems('http://example.com/foo data:text/plain,').length, 1, 'basic spaces' );
michael@0 112 assert_equals( document.getItems(' http://example.com/foo data:text/plain, ').length, 1, 'extraneous spaces' );
michael@0 113 }, 'document.getItems must locate items when parameters are separated by spaces');
michael@0 114 test(function () {
michael@0 115 assert_equals( document.getItems('http://example.com/foo data:text/plain, http://example.com/foo').length, 1 );
michael@0 116 }, 'document.getItems must ignore duplicated tokens');
michael@0 117 test(function () {
michael@0 118 var testitems = document.getItems('http://example.com/bar');
michael@0 119 assert_equals( testitems[0].id, 'one' );
michael@0 120 assert_equals( testitems[1].id, 'two' );
michael@0 121 assert_equals( testitems[2].id, 'three' );
michael@0 122 assert_equals( testitems[3].id, 'four' );
michael@0 123 }, 'document.getItems NodeList must be in source tree order');
michael@0 124 test(function () {
michael@0 125 assert_true( document.getItems('http://example.com/abc') != document.getItems('http://example.com/def'), 'different tokens' );
michael@0 126 assert_true( document.getItems() != document.getItems(' '), 'no tokens' );
michael@0 127 }, 'document.getItems must not return the same NodeList for different parameters');
michael@0 128 test(function () {
michael@0 129 assert_equals( document.getItems('').length, 5, 'empty string' );
michael@0 130 assert_equals( document.getItems(' ').length, 5, 'string with spaces' );
michael@0 131 }, 'document.getItems must treat no tokens as no parameter');
michael@0 132 //removed due to disputed Web compatibility of casting null with DOM methods
michael@0 133 /*
michael@0 134 test(function () {
michael@0 135 assert_equals( document.getItems(null).length, 0, 'null' );
michael@0 136 assert_equals( document.getItems(window.undefined).length, 0, 'undefined' );
michael@0 137 }, 'document.getItems must cast null and undefined to strings');
michael@0 138 */
michael@0 139 test(function () {
michael@0 140 var foo = makeEl('div',{itemtype:'http://example.com/foo'});
michael@0 141 document.body.appendChild(foo);
michael@0 142 var templength = document.getItems('http://example.com/foo').length;
michael@0 143 document.body.removeChild(foo);
michael@0 144 assert_equals( templength, 2 );
michael@0 145 }, 'document.getItems must not find items with itemtype but not itemscope');
michael@0 146 test(function () {
michael@0 147 var foo = makeEl('div',{itemscope:'itemscope',itemtype:'baz'}),
michael@0 148 bar = makeEl('div',{itemscope:'itemscope',itemtype:location.href.replace(/\/[^\/]*$/,'/baz')});
michael@0 149 document.body.appendChild(foo);
michael@0 150 document.body.appendChild(bar);
michael@0 151 var unrezlength = document.getItems('baz').length;
michael@0 152 var rezlength = document.getItems(location.href.replace(/\/[^\/]*$/,'/baz')).length;
michael@0 153 document.body.removeChild(foo);
michael@0 154 document.body.removeChild(bar);
michael@0 155 assert_equals( unrezlength, 1, 'unresolved URL' );
michael@0 156 assert_equals( rezlength, 1, 'resolved URL' );
michael@0 157 }, 'document.getItems and itemtype must not resolve URLs');
michael@0 158 test(function () {
michael@0 159 document.getElementById('one').setAttribute('itemprop','test');
michael@0 160 document.getElementById('four').setAttribute('itemprop','test');
michael@0 161 var templength = document.getItems().length;
michael@0 162 document.getElementById('one').removeAttribute('itemprop');
michael@0 163 document.getElementById('four').removeAttribute('itemprop');
michael@0 164 assert_equals( templength, 3 );
michael@0 165 }, 'document.getItems must not see items that have the itemprop attribute set');
michael@0 166
michael@0 167 /* itemScope property tests */
michael@0 168 test(function () {
michael@0 169 assert_true(makeEl('div',{itemscope:'itemscope'}).itemScope);
michael@0 170 assert_false(makeEl('div',{}).itemScope);
michael@0 171 }, 'the itemscope attribute must be reflected by the .itemScope property');
michael@0 172 test(function () {
michael@0 173 assert_equals( typeof makeEl('div',{itemscope:'itemscope'}).itemScope, 'boolean', 'attribute exists' );
michael@0 174 assert_equals( typeof makeEl('div',{}).itemScope, 'boolean', 'attribute does not exist' );
michael@0 175 }, 'the itemScope property must be boolean');
michael@0 176 test(function () {
michael@0 177 var testEl = makeEl('div',{});
michael@0 178 testEl.itemScope = true;
michael@0 179 assert_true(testEl.itemScope,'writing true');
michael@0 180 testEl.itemScope = false;
michael@0 181 assert_false(testEl.itemScope,'writing false');
michael@0 182 }, 'the itemScope property must be read/write');
michael@0 183 test(function () {
michael@0 184 var testEl = makeEl('div',{});
michael@0 185 testEl.itemScope = true;
michael@0 186 assert_true(testEl.hasAttribute('itemscope'),'writing true');
michael@0 187 testEl.itemScope = false;
michael@0 188 assert_false(testEl.hasAttribute('itemscope'),'writing false');
michael@0 189 }, 'writing to the itemScope property must toggle existence of the itemscope content attribute');
michael@0 190 test(function () {
michael@0 191 var testEl = makeEl('div',{});
michael@0 192 document.body.appendChild(testEl);
michael@0 193 var numAppend = document.getItems().length;
michael@0 194 testEl.itemScope = true;
michael@0 195 var numTrue = document.getItems().length;
michael@0 196 testEl.itemScope = false;
michael@0 197 var numFalse = document.getItems().length;
michael@0 198 document.body.removeChild(testEl);
michael@0 199 assert_equals(numAppend,5,'after appending the new item');
michael@0 200 assert_equals(numTrue,6,'after setting the property to true');
michael@0 201 assert_equals(numFalse,5,'after setting the property to false');
michael@0 202 }, 'writing to the itemScope property must affect whether the element is returned by getItems');
michael@0 203 test(function () {
michael@0 204 var testEl = makeEl('div',{}), nlist = document.getItems();
michael@0 205 document.body.appendChild(testEl);
michael@0 206 var numAppend = nlist.length;
michael@0 207 testEl.itemScope = true;
michael@0 208 var numTrue = nlist.length;
michael@0 209 testEl.itemScope = false;
michael@0 210 var numFalse = nlist.length;
michael@0 211 document.body.removeChild(testEl);
michael@0 212 assert_equals(numAppend,5,'after appending the new item');
michael@0 213 assert_equals(numTrue,6,'after setting the property to true');
michael@0 214 assert_equals(numFalse,5,'after setting the property to false');
michael@0 215 }, 'writing to the itemScope property must affect membership of live NodeLists');
michael@0 216
michael@0 217 /* itemType property tests (properties collection tests are done later) */
michael@0 218 test(function () {
michael@0 219 assert_equals(makeEl('div',{}).itemType.toString(),'','no attribute');
michael@0 220 assert_equals(makeEl('div',{itemtype:' foo bar '}).itemType.toString(),' foo bar ','with simple tokens');
michael@0 221 var testEl = makeEl('div',{itemtype:'foo'});
michael@0 222 testEl.removeAttribute('itemtype');
michael@0 223 assert_equals(testEl.itemType.toString(),'','removed attribute');
michael@0 224 }, 'the itemType attribute must be reflected by the .itemRef property');
michael@0 225 test(function () {
michael@0 226 assert_equals( typeof makeEl('div',{}).itemType, 'object' );
michael@0 227 }, 'the itemType property must be an object');
michael@0 228 test(function () {
michael@0 229 assert_true( makeEl('div',{}).itemType instanceof DOMTokenList, 'instanceof test' );
michael@0 230 DOMTokenList.prototype.customProperty = true;
michael@0 231 assert_true( makeEl('div',{}).itemType.customProperty, 'inheritance test' );
michael@0 232 }, 'the itemType property must implement DOMTokenList');
michael@0 233 test(function () {
michael@0 234 var testEl = makeEl('div',{});
michael@0 235 assert_equals( testEl.itemType, testEl.itemType );
michael@0 236 }, 'the itemType property must always reference the same object');
michael@0 237 test(function () {
michael@0 238 assert_equals( makeEl('div',{itemtype:'test test'}).itemType.length, 2, 'duplicates in initial string should be preserved' );
michael@0 239 assert_equals( makeEl('div',{itemtype:'test test'}).itemType.item(0), 'test' );
michael@0 240 assert_true( makeEl('div',{itemtype:'test test'}).itemType.contains('test') );
michael@0 241 }, 'itemType must be correct for an element that has itemtype tokens');
michael@0 242 test(function () {
michael@0 243 assert_equals( makeEl('div',{itemtype:' '}).itemType.length, 0 );
michael@0 244 }, 'itemType.length must be 0 for an element that has no tokens');
michael@0 245 test(function () {
michael@0 246 assert_false( makeEl('div',{itemtype:' '}).itemType.contains('foo') );
michael@0 247 }, 'itemType must not contain an undefined class');
michael@0 248 test(function () {
michael@0 249 assert_equals( makeEl('div',{itemtype:' '}).itemType.item(0), null );
michael@0 250 }, 'itemType.item() must return null for out-of-range index');
michael@0 251 test(function () {
michael@0 252 assert_equals( makeEl('div',{itemtype:' '}).itemType.item(-1), null );
michael@0 253 }, 'itemType.item() must return null for negative index');
michael@0 254 test(function () {
michael@0 255 /* the normative part of the spec states that:
michael@0 256 "unless the length is zero, in which case there are no supported property indices"
michael@0 257 ...
michael@0 258 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 259 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 260 assert_equals( makeEl('div',{itemtype:' '}).itemType[0], window.undefined );
michael@0 261 }, 'itemType[index] must be undefined for out-of-range index');
michael@0 262 test(function () {
michael@0 263 assert_equals( makeEl('div',{itemtype:' '}).itemType[-1], window.undefined );
michael@0 264 }, 'itemType[index] must be undefined for negative index');
michael@0 265 test(function () {
michael@0 266 assert_equals( makeEl('div',{itemType:' '}).itemType.toString(), ' ' );
michael@0 267 }, 'empty itemType should stringify to contain the attribute\'s whitespace');
michael@0 268 test(function () {
michael@0 269 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.contains(''); } );
michael@0 270 }, 'itemType.contains(empty_string) must throw a SYNTAX_ERR');
michael@0 271 test(function () {
michael@0 272 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.add(''); } );
michael@0 273 }, 'itemType.add(empty_string) must throw a SYNTAX_ERR');
michael@0 274 test(function () {
michael@0 275 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.remove(''); } );
michael@0 276 }, 'itemType.remove(empty_string) must throw a SYNTAX_ERR');
michael@0 277 test(function () {
michael@0 278 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemtype:' '}).itemType.toggle(''); } );
michael@0 279 }, 'itemType.toggle(empty_string) must throw a SYNTAX_ERR');
michael@0 280 test(function () {
michael@0 281 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.contains('a b'); } );
michael@0 282 }, 'itemType.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 283 test(function () {
michael@0 284 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.add('a b'); } );
michael@0 285 }, 'itemType.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 286 test(function () {
michael@0 287 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.remove('a b'); } );
michael@0 288 }, 'itemType.remove(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 289 test(function () {
michael@0 290 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemtype:' '}).itemType.toggle('a b'); } );
michael@0 291 }, 'itemType.toggle(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 292 test(function () {
michael@0 293 var testEl = makeEl('div',{itemtype:'foo'});
michael@0 294 assert_true( testEl.itemType.contains('foo'), 'before change' );
michael@0 295 testEl.setAttribute('itemtype','bar');
michael@0 296 assert_true( testEl.itemType.contains('bar'), 'after change' );
michael@0 297 assert_false( testEl.itemType.contains('foo'), 'after change' );
michael@0 298 }, 'itemType.contains must update when the underlying attribute is changed');
michael@0 299 test(function () {
michael@0 300 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('FOO') );
michael@0 301 }, 'itemType.contains must be case sensitive');
michael@0 302 test(function () {
michael@0 303 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo.') );
michael@0 304 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo)') );
michael@0 305 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo\'') );
michael@0 306 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo$') );
michael@0 307 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo~') );
michael@0 308 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo?') );
michael@0 309 assert_false( makeEl('div',{itemtype:'foo'}).itemType.contains('foo\\') );
michael@0 310 }, 'itemType.contains must not match when punctuation characters are added');
michael@0 311 test(function () {
michael@0 312 var elem = makeEl('div',{itemtype:'foo'});
michael@0 313 elem.itemType.add('FOO');
michael@0 314 assert_true( elem.itemType.contains('foo') );
michael@0 315 }, 'itemType.add must not remove existing tokens');
michael@0 316 test(function () {
michael@0 317 assert_true( makeEl('div',{itemtype:'foo FOO'}).itemType.contains('FOO') );
michael@0 318 }, 'itemType.contains case sensitivity must match a case-specific string');
michael@0 319 test(function () {
michael@0 320 assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType.length, 2 );
michael@0 321 }, 'itemType.length must correctly reflect the number of tokens');
michael@0 322 test(function () {
michael@0 323 assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType.item(0), 'foo' );
michael@0 324 }, 'itemType.item(0) must return the first token');
michael@0 325 test(function () {
michael@0 326 var elem = makeEl('div',{itemtype:'foo'});
michael@0 327 elem.itemType.add('FOO');
michael@0 328 assert_equals( elem.itemType.item(1), 'FOO' );
michael@0 329 }, 'itemType.item must return case-sensitive strings and preserve token order');
michael@0 330 test(function () {
michael@0 331 assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType[0], 'foo' );
michael@0 332 }, 'itemType[0] must return the first token');
michael@0 333 test(function () {
michael@0 334 assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType[1], 'FOO' );
michael@0 335 }, 'itemType[index] must return case-sensitive strings and preserve token order');
michael@0 336 test(function () {
michael@0 337 /* the normative part of the spec states that:
michael@0 338 "unless the length is zero, in which case there are no supported property indices"
michael@0 339 ...
michael@0 340 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 341 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 342 assert_equals( makeEl('div',{itemtype:'foo FOO'}).itemType[2], window.undefined );
michael@0 343 }, 'itemType[index] must still be undefined for out-of-range index when earlier indexes exist');
michael@0 344 test(function () {
michael@0 345 var elem = makeEl('div',{});
michael@0 346 elem.itemType.add('foo');
michael@0 347 elem.itemType.add('FOO');
michael@0 348 assert_equals( elem.getAttribute('itemtype'), 'foo FOO' );
michael@0 349 }, 'itemtype attribute must update correctly when items have been added through itemType');
michael@0 350 test(function () {
michael@0 351 var elem = makeEl('div',{});
michael@0 352 elem.itemType.add('foo');
michael@0 353 elem.itemType.add('FOO');
michael@0 354 assert_equals( elem.itemType + '', 'foo FOO' );
michael@0 355 }, 'itemType must stringify correctly when items have been added');
michael@0 356 test(function () {
michael@0 357 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 358 elem.itemType.add('foo');
michael@0 359 assert_equals( elem.itemType.length, 2 );
michael@0 360 assert_equals( elem.itemType + '', 'foo FOO' );
michael@0 361 }, 'itemType.add must not make any changes if an existing token is added');
michael@0 362 test(function () {
michael@0 363 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 364 elem.itemType.remove('bar');
michael@0 365 assert_equals( elem.itemType.length, 2 );
michael@0 366 assert_equals( elem.itemType + '', 'foo FOO' );
michael@0 367 }, 'itemType.remove must not make any changes if a non-existing token is removed');
michael@0 368 test(function () {
michael@0 369 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 370 elem.itemType.remove('foo');
michael@0 371 assert_equals( elem.itemType.length, 1 );
michael@0 372 assert_equals( elem.itemType.toString(), 'FOO' );
michael@0 373 assert_false( elem.itemType.contains('foo') );
michael@0 374 assert_true( elem.itemType.contains('FOO') );
michael@0 375 }, 'itemType.remove must remove existing tokens');
michael@0 376 test(function () {
michael@0 377 var elem = makeEl('div',{itemtype:'test test'});
michael@0 378 elem.itemType.remove('test');
michael@0 379 assert_equals( elem.itemType.length, 0 );
michael@0 380 assert_false( elem.itemType.contains('test') );
michael@0 381 }, 'itemType.remove must remove duplicated tokens');
michael@0 382 test(function () {
michael@0 383 var elem = makeEl('div',{itemtype:'token1 token2 token3'});
michael@0 384 elem.itemType.remove('token2');
michael@0 385 assert_equals( elem.itemType.toString(), 'token1 token3' );
michael@0 386 }, 'itemType.remove must collapse whitespace around removed tokens');
michael@0 387 test(function () {
michael@0 388 var elem = makeEl('div',{itemtype:' token1 token2 '});
michael@0 389 elem.itemType.remove('token2');
michael@0 390 assert_equals( elem.itemType.toString(), 'token1' );
michael@0 391 }, 'itemType.remove must remove all useless whitespace');
michael@0 392 test(function () {
michael@0 393 var elem = makeEl('div',{itemtype:' token1 token2 token3 '});
michael@0 394 elem.itemType.remove('token2');
michael@0 395 assert_equals( elem.itemType.toString(), 'token1 token3' );
michael@0 396 }, 'itemType.remove must collapse multiple whitespace around removed tokens');
michael@0 397 test(function () {
michael@0 398 var elem = makeEl('div',{itemtype:' token1 token2 token1 '});
michael@0 399 elem.itemType.remove('token2');
michael@0 400 assert_equals( elem.itemType.toString(), 'token1' );
michael@0 401 }, 'itemType.remove must remove duplicates when removing tokens');
michael@0 402 test(function () {
michael@0 403 var elem = makeEl('div',{itemtype:' token1 token2 token3 '});
michael@0 404 elem.itemType.remove('token1', 'token3');
michael@0 405 assert_equals( elem.itemType.toString(), 'token2' );
michael@0 406 }, 'itemType.remove must collapse whitespace when removing multiple tokens');
michael@0 407 test(function () {
michael@0 408 var elem = makeEl('div',{itemtype:' token1 token2 '});
michael@0 409 elem.itemType.add('token1');
michael@0 410 assert_equals( elem.itemType.toString(), 'token1 token2' );
michael@0 411 }, 'itemType.add must remove unused whitespace when the token already exists');
michael@0 412 test(function () {
michael@0 413 var elem = makeEl('div',{itemtype:'FOO'});
michael@0 414 assert_true(elem.itemType.toggle('foo'));
michael@0 415 assert_equals( elem.itemType.length, 2 );
michael@0 416 assert_true( elem.itemType.contains('foo') );
michael@0 417 assert_true( elem.itemType.contains('FOO') );
michael@0 418 }, 'itemType.toggle must toggle tokens case-sensitively when adding');
michael@0 419 test(function () {
michael@0 420 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 421 assert_false(elem.itemType.toggle('foo'));
michael@0 422 assert_false(elem.itemType.toggle('FOO'));
michael@0 423 assert_false( elem.itemType.contains('foo') );
michael@0 424 assert_false( elem.itemType.contains('FOO') );
michael@0 425 }, 'itemType.toggle must be able to remove tokens case-sensitively');
michael@0 426 test(function () {
michael@0 427 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 428 elem.itemType.toggle('foo');
michael@0 429 elem.itemType.toggle('FOO');
michael@0 430 assert_equals( elem.getAttribute('itemtype'), '' );
michael@0 431 }, 'itemtype attribute must be empty when all classes have been removed');
michael@0 432 test(function () {
michael@0 433 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 434 elem.itemType.toggle('foo');
michael@0 435 elem.itemType.toggle('FOO');
michael@0 436 assert_equals( elem.itemType.toString(), '' );
michael@0 437 }, 'itemType must stringify to an empty string when all classes have been removed');
michael@0 438 test(function () {
michael@0 439 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 440 elem.itemType.toggle('foo');
michael@0 441 elem.itemType.toggle('FOO');
michael@0 442 assert_equals( elem.itemType.item(0), null );
michael@0 443 }, 'itemType.item(0) must return null when all classes have been removed');
michael@0 444 test(function () {
michael@0 445 /* the normative part of the spec states that:
michael@0 446 "unless the length is zero, in which case there are no supported property indices"
michael@0 447 ...
michael@0 448 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 449 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 450 var elem = makeEl('div',{itemtype:'foo FOO'});
michael@0 451 elem.itemType.toggle('foo');
michael@0 452 elem.itemType.toggle('FOO');
michael@0 453 assert_equals( elem.itemType[0], window.undefined );
michael@0 454 }, 'itemType[0] must be undefined when all classes have been removed');
michael@0 455 //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"
michael@0 456 test(function () {
michael@0 457 var elem = makeEl('div',{itemtype:'a '});
michael@0 458 elem.itemType.add('b');
michael@0 459 assert_equals(elem.itemType.toString(),'a b');
michael@0 460 }, 'itemType.add should treat " " as a space');
michael@0 461 test(function () {
michael@0 462 var elem = makeEl('div',{itemtype:'a\t'});
michael@0 463 elem.itemType.add('b');
michael@0 464 assert_equals(elem.itemType.toString(),'a b');
michael@0 465 }, 'itemType.add should normalize \\t as a space');
michael@0 466 test(function () {
michael@0 467 var elem = makeEl('div',{itemtype:'a\r'});
michael@0 468 elem.itemType.add('b');
michael@0 469 assert_equals(elem.itemType.toString(),'a b');
michael@0 470 }, 'itemType.add should normalize \\r as a space');
michael@0 471 test(function () {
michael@0 472 var elem = makeEl('div',{itemtype:'a\n'});
michael@0 473 elem.itemType.add('b');
michael@0 474 assert_equals(elem.itemType.toString(),'a b');
michael@0 475 }, 'itemType.add should normalize \\n as a space');
michael@0 476 test(function () {
michael@0 477 var elem = makeEl('div',{itemtype:'a\f'});
michael@0 478 elem.itemType.add('b');
michael@0 479 assert_equals(elem.itemType.toString(),'a b');
michael@0 480 }, 'itemType.add should normalize \\f as a space');
michael@0 481 test(function () {
michael@0 482 var elem = makeEl('div',{itemtype:'foo'});
michael@0 483 elem.itemType.remove('foo');
michael@0 484 elem.removeAttribute('itemtype');
michael@0 485 assert_true( elem.itemType.toggle('foo') );
michael@0 486 }, 'itemType.toggle must work after removing the itemtype attribute');
michael@0 487 test(function () {
michael@0 488 //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter
michael@0 489 //ES5 makes [[Put]] fail but not throw
michael@0 490 var failed = false;
michael@0 491 var elem = makeEl('div',{itemtype:'token1'});
michael@0 492 try {
michael@0 493 elem.itemType.length = 0;
michael@0 494 } catch(e) {
michael@0 495 failed = e;
michael@0 496 }
michael@0 497 assert_equals(elem.itemType.length,1);
michael@0 498 assert_false(failed,'an error was thrown');
michael@0 499 }, 'itemType.length must be read-only');
michael@0 500 test(function () {
michael@0 501 var failed = false, elem = makeEl('div',{itemtype:'test'}), realList = elem.itemType;
michael@0 502 try {
michael@0 503 elem.itemType = 'dummy';
michael@0 504 } catch(e) {
michael@0 505 failed = e;
michael@0 506 }
michael@0 507 assert_equals(elem.itemType,realList);
michael@0 508 assert_equals(elem.itemType.toString(),'dummy','attempting to write should modify the underlying string');
michael@0 509 assert_false(failed,'an error was thrown');
michael@0 510 }, 'itemType must be read-only');
michael@0 511
michael@0 512 /* itemProp property tests (properties collection tests are done later) */
michael@0 513 test(function () {
michael@0 514 assert_equals(makeEl('div',{}).itemProp.toString(),'','no attribute');
michael@0 515 assert_equals(makeEl('div',{itemprop:' http://example.com/foo#bar test '}).itemProp.toString(),' http://example.com/foo#bar test ','with URL and simple tokens');
michael@0 516 var testEl = makeEl('div',{itemprop:'http://example.com/foo#bar'});
michael@0 517 testEl.removeAttribute('itemprop');
michael@0 518 assert_equals(testEl.itemProp.toString(),'','removed attribute');
michael@0 519 }, 'the itemprop attribute must be reflected by the .itemProp property');
michael@0 520 test(function () {
michael@0 521 assert_equals( typeof makeEl('div',{}).itemProp, 'object' );
michael@0 522 }, 'the itemProp property must be an object');
michael@0 523 test(function () {
michael@0 524 assert_true( makeEl('div',{}).itemProp instanceof DOMTokenList, 'instanceof test' );
michael@0 525 DOMTokenList.prototype.customProperty = true;
michael@0 526 assert_true( makeEl('div',{}).itemProp.customProperty, 'inheritance test' );
michael@0 527 }, 'the itemProp property must implement DOMTokenList');
michael@0 528 test(function () {
michael@0 529 var testEl = makeEl('div',{});
michael@0 530 assert_equals( testEl.itemProp, testEl.itemProp );
michael@0 531 }, 'the itemProp property must always reference the same object');
michael@0 532 test(function () {
michael@0 533 assert_equals( makeEl('div',{itemprop:'test test'}).itemProp.length, 2, 'duplicates in initial string should be preserved' );
michael@0 534 assert_equals( makeEl('div',{itemprop:'test test'}).itemProp.item(0), 'test' );
michael@0 535 assert_true( makeEl('div',{itemprop:'test test'}).itemProp.contains('test') );
michael@0 536 }, 'itemProp must be correct for an element that has itemprop tokens');
michael@0 537 test(function () {
michael@0 538 assert_equals( makeEl('div',{itemprop:' '}).itemProp.length, 0 );
michael@0 539 }, 'itemProp.length must be 0 for an element that has no tokens');
michael@0 540 test(function () {
michael@0 541 assert_false( makeEl('div',{itemprop:' '}).itemProp.contains('foo') );
michael@0 542 }, 'itemProp must not contain an undefined class');
michael@0 543 test(function () {
michael@0 544 assert_equals( makeEl('div',{itemprop:' '}).itemProp.item(0), null );
michael@0 545 }, 'itemProp.item() must return null for out-of-range index');
michael@0 546 test(function () {
michael@0 547 assert_equals( makeEl('div',{itemprop:' '}).itemProp.item(-1), null );
michael@0 548 }, 'itemProp.item() must return null for negative index');
michael@0 549 test(function () {
michael@0 550 /* the normative part of the spec states that:
michael@0 551 "unless the length is zero, in which case there are no supported property indices"
michael@0 552 ...
michael@0 553 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 554 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 555 assert_equals( makeEl('div',{itemprop:' '}).itemProp[0], window.undefined );
michael@0 556 }, 'itemProp[index] must be undefined for out-of-range index');
michael@0 557 test(function () {
michael@0 558 assert_equals( makeEl('div',{itemprop:' '}).itemProp[-1], window.undefined );
michael@0 559 }, 'itemProp[index] must be undefined for negative index');
michael@0 560 test(function () {
michael@0 561 assert_equals( makeEl('div',{itemprop:' '}).itemProp.toString(), ' ' );
michael@0 562 }, 'empty itemProp should stringify to contain the attribute\'s whitespace');
michael@0 563 test(function () {
michael@0 564 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.contains(''); } );
michael@0 565 }, 'itemProp.contains(empty_string) must throw a SYNTAX_ERR');
michael@0 566 test(function () {
michael@0 567 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.add(''); } );
michael@0 568 }, 'itemProp.add(empty_string) must throw a SYNTAX_ERR');
michael@0 569 test(function () {
michael@0 570 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.remove(''); } );
michael@0 571 }, 'itemProp.remove(empty_string) must throw a SYNTAX_ERR');
michael@0 572 test(function () {
michael@0 573 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.toggle(''); } );
michael@0 574 }, 'itemProp.toggle(empty_string) must throw a SYNTAX_ERR');
michael@0 575 test(function () {
michael@0 576 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.contains('a b'); } );
michael@0 577 }, '.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 578 test(function () {
michael@0 579 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.add('a b'); } );
michael@0 580 }, 'itemProp.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 581 test(function () {
michael@0 582 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.remove('a b'); } );
michael@0 583 }, 'itemProp.remove(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 584 test(function () {
michael@0 585 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemprop:' '}).itemProp.toggle('a b'); } );
michael@0 586 }, 'itemProp.toggle(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 587 test(function () {
michael@0 588 var testEl = makeEl('div',{itemprop:'foo'});
michael@0 589 assert_true( testEl.itemProp.contains('foo'), 'before change' );
michael@0 590 testEl.setAttribute('itemprop','bar');
michael@0 591 assert_true( testEl.itemProp.contains('bar'), 'after change' );
michael@0 592 assert_false( testEl.itemProp.contains('foo'), 'after change' );
michael@0 593 }, 'itemProp.contains must update when the underlying attribute is changed');
michael@0 594 test(function () {
michael@0 595 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('FOO') );
michael@0 596 }, 'itemProp.contains must be case sensitive');
michael@0 597 test(function () {
michael@0 598 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo.') );
michael@0 599 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo)') );
michael@0 600 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo\'') );
michael@0 601 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo$') );
michael@0 602 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo~') );
michael@0 603 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo?') );
michael@0 604 assert_false( makeEl('div',{itemprop:'foo'}).itemProp.contains('foo\\') );
michael@0 605 }, 'itemProp.contains must not match when punctuation characters are added');
michael@0 606 test(function () {
michael@0 607 var elem = makeEl('div',{itemprop:'foo'});
michael@0 608 elem.itemProp.add('FOO');
michael@0 609 assert_true( elem.itemProp.contains('foo') );
michael@0 610 }, 'itemProp.add must not remove existing tokens');
michael@0 611 test(function () {
michael@0 612 assert_true( makeEl('div',{itemprop:'foo FOO'}).itemProp.contains('FOO') );
michael@0 613 }, 'itemProp.contains case sensitivity must match a case-specific string');
michael@0 614 test(function () {
michael@0 615 assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp.length, 2 );
michael@0 616 }, 'itemProp.length must correctly reflect the number of tokens');
michael@0 617 test(function () {
michael@0 618 assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp.item(0), 'foo' );
michael@0 619 }, 'itemProp.item(0) must return the first token');
michael@0 620 test(function () {
michael@0 621 var elem = makeEl('div',{itemprop:'foo'});
michael@0 622 elem.itemProp.add('FOO');
michael@0 623 assert_equals( elem.itemProp.item(1), 'FOO' );
michael@0 624 }, 'itemProp.item must return case-sensitive strings and preserve token order');
michael@0 625 test(function () {
michael@0 626 assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp[0], 'foo' );
michael@0 627 }, 'itemProp[0] must return the first token');
michael@0 628 test(function () {
michael@0 629 assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp[1], 'FOO' );
michael@0 630 }, 'itemProp[index] must return case-sensitive strings and preserve token order');
michael@0 631 test(function () {
michael@0 632 /* the normative part of the spec states that:
michael@0 633 "unless the length is zero, in which case there are no supported property indices"
michael@0 634 ...
michael@0 635 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 636 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 637 assert_equals( makeEl('div',{itemprop:'foo FOO'}).itemProp[2], window.undefined );
michael@0 638 }, 'itemProp[index] must still be undefined for out-of-range index when earlier indexes exist');
michael@0 639 test(function () {
michael@0 640 var elem = makeEl('div',{});
michael@0 641 elem.itemProp.add('foo');
michael@0 642 elem.itemProp.add('FOO');
michael@0 643 assert_equals( elem.getAttribute('itemprop'), 'foo FOO' );
michael@0 644 }, 'itemprop attribute must update correctly when items have been added through itemProp');
michael@0 645 test(function () {
michael@0 646 var elem = makeEl('div',{});
michael@0 647 elem.itemProp.add('foo');
michael@0 648 elem.itemProp.add('FOO');
michael@0 649 assert_equals( elem.itemProp + '', 'foo FOO' );
michael@0 650 }, 'itemProp must stringify correctly when items have been added');
michael@0 651 test(function () {
michael@0 652 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 653 elem.itemProp.add('foo');
michael@0 654 assert_equals( elem.itemProp.length, 2 );
michael@0 655 assert_equals( elem.itemProp + '', 'foo FOO' );
michael@0 656 }, 'itemProp.add must not make any changes if an existing token is added');
michael@0 657 test(function () {
michael@0 658 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 659 elem.itemProp.remove('bar');
michael@0 660 assert_equals( elem.itemProp.length, 2 );
michael@0 661 assert_equals( elem.itemProp + '', 'foo FOO' );
michael@0 662 }, 'itemProp.remove must not make any changes if a non-existing token is removed');
michael@0 663 test(function () {
michael@0 664 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 665 elem.itemProp.remove('foo');
michael@0 666 assert_equals( elem.itemProp.length, 1 );
michael@0 667 assert_equals( elem.itemProp.toString(), 'FOO' );
michael@0 668 assert_false( elem.itemProp.contains('foo') );
michael@0 669 assert_true( elem.itemProp.contains('FOO') );
michael@0 670 }, 'itemProp.remove must remove existing tokens');
michael@0 671 test(function () {
michael@0 672 var elem = makeEl('div',{itemprop:'test test'});
michael@0 673 elem.itemProp.remove('test');
michael@0 674 assert_equals( elem.itemProp.length, 0 );
michael@0 675 assert_false( elem.itemProp.contains('test') );
michael@0 676 }, 'itemProp.remove must remove duplicated tokens');
michael@0 677 test(function () {
michael@0 678 var elem = makeEl('div',{itemprop:'token1 token2 token3'});
michael@0 679 elem.itemProp.remove('token2');
michael@0 680 assert_equals( elem.itemProp.toString(), 'token1 token3' );
michael@0 681 }, 'itemProp.remove must collapse whitespace around removed tokens');
michael@0 682 test(function () {
michael@0 683 var elem = makeEl('div',{itemprop:' token1 token2 token3 '});
michael@0 684 elem.itemProp.remove('token2');
michael@0 685 assert_equals( elem.itemProp.toString(), 'token1 token3' );
michael@0 686 }, 'itemProp.remove must remove all useless whitespace');
michael@0 687 test(function () {
michael@0 688 var elem = makeEl('div',{itemprop:' token1 token2 token3 '});
michael@0 689 elem.itemProp.remove('token1', 'token3');
michael@0 690 assert_equals( elem.itemProp.toString(), 'token2' );
michael@0 691 }, 'itemProp.remove must remove useless whitespace when removing multiple tokens');
michael@0 692 test(function () {
michael@0 693 var elem = makeEl('div',{itemprop:' token1 token1 '});
michael@0 694 elem.itemProp.add('token1');
michael@0 695 assert_equals( elem.itemProp.toString(), 'token1' );
michael@0 696 }, 'itemProp.add must remove useless whitespace and duplicates when the token already exists');
michael@0 697 test(function () {
michael@0 698 var elem = makeEl('div',{itemprop:'FOO'});
michael@0 699 assert_true(elem.itemProp.toggle('foo'));
michael@0 700 assert_equals( elem.itemProp.length, 2 );
michael@0 701 assert_true( elem.itemProp.contains('foo') );
michael@0 702 assert_true( elem.itemProp.contains('FOO') );
michael@0 703 }, 'itemProp.toggle must toggle tokens case-sensitively when adding');
michael@0 704 test(function () {
michael@0 705 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 706 assert_false(elem.itemProp.toggle('foo'));
michael@0 707 assert_false(elem.itemProp.toggle('FOO'));
michael@0 708 assert_false( elem.itemProp.contains('foo') );
michael@0 709 assert_false( elem.itemProp.contains('FOO') );
michael@0 710 }, 'itemProp.toggle must be able to remove tokens case-sensitively');
michael@0 711 test(function () {
michael@0 712 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 713 elem.itemProp.toggle('foo');
michael@0 714 elem.itemProp.toggle('FOO');
michael@0 715 assert_equals( elem.getAttribute('itemprop'), '' );
michael@0 716 }, 'itemprop attribute must be empty when all classes have been removed');
michael@0 717 test(function () {
michael@0 718 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 719 elem.itemProp.toggle('foo');
michael@0 720 elem.itemProp.toggle('FOO');
michael@0 721 assert_equals( elem.itemProp.toString(), '' );
michael@0 722 }, 'itemProp must stringify to an empty string when all classes have been removed');
michael@0 723 test(function () {
michael@0 724 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 725 elem.itemProp.toggle('foo');
michael@0 726 elem.itemProp.toggle('FOO');
michael@0 727 assert_equals( elem.itemProp.item(0), null );
michael@0 728 }, 'itemProp.item(0) must return null when all classes have been removed');
michael@0 729 test(function () {
michael@0 730 /* the normative part of the spec states that:
michael@0 731 "unless the length is zero, in which case there are no supported property indices"
michael@0 732 ...
michael@0 733 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 734 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 735 var elem = makeEl('div',{itemprop:'foo FOO'});
michael@0 736 elem.itemProp.toggle('foo');
michael@0 737 elem.itemProp.toggle('FOO');
michael@0 738 assert_equals( elem.itemProp[0], window.undefined );
michael@0 739 }, 'itemProp[0] must be undefined when all classes have been removed');
michael@0 740 //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"
michael@0 741 test(function () {
michael@0 742 var elem = makeEl('div',{itemprop:'a '});
michael@0 743 elem.itemProp.add('b');
michael@0 744 assert_equals(elem.itemProp.toString(),'a b');
michael@0 745 }, 'itemProp.add should treat " " as a space');
michael@0 746 test(function () {
michael@0 747 var elem = makeEl('div',{itemprop:'a\t'});
michael@0 748 elem.itemProp.add('b');
michael@0 749 assert_equals(elem.itemProp.toString(),'a b');
michael@0 750 }, 'itemProp.add should normalize \\t as a space');
michael@0 751 test(function () {
michael@0 752 var elem = makeEl('div',{itemprop:'a\r'});
michael@0 753 elem.itemProp.add('b');
michael@0 754 assert_equals(elem.itemProp.toString(),'a b');
michael@0 755 }, 'itemProp.add should normalize \\r as a space');
michael@0 756 test(function () {
michael@0 757 var elem = makeEl('div',{itemprop:'a\n'});
michael@0 758 elem.itemProp.add('b');
michael@0 759 assert_equals(elem.itemProp.toString(),'a b');
michael@0 760 }, 'itemProp.add should normalize \\n as a space');
michael@0 761 test(function () {
michael@0 762 var elem = makeEl('div',{itemprop:'a\f'});
michael@0 763 elem.itemProp.add('b');
michael@0 764 assert_equals(elem.itemProp.toString(),'a b');
michael@0 765 }, 'itemProp.add should normalize \\f as a space');
michael@0 766 test(function () {
michael@0 767 var elem = makeEl('div',{itemprop:'foo'});
michael@0 768 elem.itemProp.remove('foo');
michael@0 769 elem.removeAttribute('itemprop');
michael@0 770 assert_true( elem.itemProp.toggle('foo') );
michael@0 771 }, 'itemProp.toggle must work after removing the itemprop attribute');
michael@0 772 test(function () {
michael@0 773 //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter
michael@0 774 //ES5 makes [[Put]] fail but not throw
michael@0 775 var failed = false;
michael@0 776 var elem = makeEl('div',{itemprop:'token1'});
michael@0 777 try {
michael@0 778 elem.itemProp.length = 0;
michael@0 779 } catch(e) {
michael@0 780 failed = e;
michael@0 781 }
michael@0 782 assert_equals(elem.itemProp.length,1);
michael@0 783 assert_false(failed,'an error was thrown');
michael@0 784 }, 'itemProp.length must be read-only');
michael@0 785 test(function () {
michael@0 786 var failed = false, elem = makeEl('div',{itemprop:'test'}), realList = elem.itemProp;
michael@0 787 try {
michael@0 788 elem.itemProp = 'dummy';
michael@0 789 } catch(e) {
michael@0 790 failed = e;
michael@0 791 }
michael@0 792 assert_equals(elem.itemProp,realList);
michael@0 793 assert_equals(elem.itemProp.toString(),'dummy','attempting to write should modify the underlying string');
michael@0 794 assert_false(failed,'an error was thrown');
michael@0 795 }, 'itemProp must be read-only');
michael@0 796
michael@0 797 /* itemId property tests */
michael@0 798 test(function () {
michael@0 799 assert_equals( makeEl('div',{itemid:'http://example.com/foo'}).itemId, 'http://example.com/foo' );
michael@0 800 assert_equals( makeEl('div',{itemid:'http://example.com/FOO'}).itemId, 'http://example.com/FOO', 'case-sensitive' );
michael@0 801 assert_equals( makeEl('div',{itemid:' http://example.com/foo '}).itemId, 'http://example.com/foo', 'whitespace' );
michael@0 802 assert_equals( makeEl('div',{itemid:'data:text/plain,'}).itemId, 'data:text/plain,' );
michael@0 803 assert_equals( makeEl('div',{itemid:'madeup:onthespot'}).itemId, 'madeup:onthespot' );
michael@0 804 assert_equals( makeEl('div',{}).itemId, '' );
michael@0 805 }, 'the itemid attribute must be reflected by the .itemId property');
michael@0 806 test(function () {
michael@0 807 var testEl = makeEl('div',{});
michael@0 808 testEl.itemId = 'http://example.com/foo';
michael@0 809 assert_equals(testEl.itemId,'http://example.com/foo','writing a URL');
michael@0 810 testEl.itemId = '';
michael@0 811 assert_equals(testEl.itemId,location.href,'writing an empty string');
michael@0 812 }, 'the itemId property must be read/write');
michael@0 813 test(function () {
michael@0 814 var testEl = makeEl('div',{});
michael@0 815 testEl.itemId = 'http://example.com/foo';
michael@0 816 assert_true(testEl.hasAttribute('itemid'),'writing a URL');
michael@0 817 assert_equals(testEl.getAttribute('itemid'),'http://example.com/foo','writing a URL');
michael@0 818 testEl = makeEl('div',{})
michael@0 819 testEl.itemId = '';
michael@0 820 assert_true(testEl.hasAttribute('itemid'),'writing an empty string');
michael@0 821 assert_equals(testEl.getAttribute('itemid'),'','writing an empty string');
michael@0 822 }, 'writing to the itemId property must create the itemid content attribute');
michael@0 823 test(function () {
michael@0 824 assert_equals( makeEl('div',{itemid:'foo'}).itemId, location.href.replace(/\/[^\/]*$/,'\/foo'),'foo' );
michael@0 825 assert_equals( makeEl('div',{itemid:'foo bar'}).itemId, location.href.replace(/\/[^\/]*$/,'\/foo%20bar'),'foo bar' );
michael@0 826 assert_equals( makeEl('div',{itemid:'foo\u0129 bar'}).itemId, location.href.replace(/\/[^\/]*$/,'\/foo%C4%A9%20bar'),'foo\u0129 bar' );
michael@0 827 }, 'the itemId property must see the resolved itemid URL');
michael@0 828 test(function () {
michael@0 829 var testEl = makeEl('div',{});
michael@0 830 testEl.itemId = 'foo';
michael@0 831 assert_equals( testEl.itemId, location.href.replace(/\/[^\/]*$/,'\/foo') );
michael@0 832 }, 'the itemId property must see the resolved itemId property URL on setting');
michael@0 833 test(function () {
michael@0 834 var testEl = makeEl('div',{});
michael@0 835 testEl.itemId = 'foo';
michael@0 836 assert_equals( testEl.getAttribute('itemid'), 'foo' );
michael@0 837 }, 'the itemid attribute must see the resolved itemId URL');
michael@0 838
michael@0 839 /* itemRef property tests (properties collection tests are done later) */
michael@0 840 test(function () {
michael@0 841 assert_equals(makeEl('div',{}).itemRef.toString(),'','no attribute');
michael@0 842 assert_equals(makeEl('div',{itemref:' foo bar '}).itemRef.toString(),' foo bar ','with simple tokens');
michael@0 843 var testEl = makeEl('div',{itemref:'foo'});
michael@0 844 testEl.removeAttribute('itemref');
michael@0 845 assert_equals(testEl.itemRef.toString(),'','removed attribute');
michael@0 846 }, 'the itemref attribute must be reflected by the .itemRef property');
michael@0 847 test(function () {
michael@0 848 assert_equals( typeof makeEl('div',{}).itemRef, 'object' );
michael@0 849 }, 'the itemRef property must be an object');
michael@0 850 test(function () {
michael@0 851 assert_true( makeEl('div',{}).itemRef instanceof DOMTokenList, 'instanceof test' );
michael@0 852 DOMTokenList.prototype.customProperty = true;
michael@0 853 assert_true( makeEl('div',{}).itemRef.customProperty, 'inheritance test' );
michael@0 854 }, 'the itemRef property must implement DOMTokenList');
michael@0 855 test(function () {
michael@0 856 var testEl = makeEl('div',{});
michael@0 857 assert_equals( testEl.itemRef, testEl.itemRef );
michael@0 858 }, 'the itemRef property must always reference the same object');
michael@0 859 test(function () {
michael@0 860 assert_equals( makeEl('div',{itemref:'test test'}).itemRef.length, 2, 'duplicates in initial string should be preserved' );
michael@0 861 assert_equals( makeEl('div',{itemref:'test test'}).itemRef.item(0), 'test' );
michael@0 862 assert_true( makeEl('div',{itemref:'test test'}).itemRef.contains('test') );
michael@0 863 }, 'itemRef must be correct for an element that has itemref tokens');
michael@0 864 test(function () {
michael@0 865 assert_equals( makeEl('div',{itemref:' '}).itemRef.length, 0 );
michael@0 866 }, 'itemRef.length must be 0 for an element that has no tokens');
michael@0 867 test(function () {
michael@0 868 assert_false( makeEl('div',{itemref:' '}).itemRef.contains('foo') );
michael@0 869 }, 'itemRef must not contain an undefined class');
michael@0 870 test(function () {
michael@0 871 assert_equals( makeEl('div',{itemref:' '}).itemRef.item(0), null );
michael@0 872 }, 'itemRef.item() must return null for out-of-range index');
michael@0 873 test(function () {
michael@0 874 assert_equals( makeEl('div',{itemref:' '}).itemRef.item(-1), null );
michael@0 875 }, 'itemRef.item() must return null for negative index');
michael@0 876 test(function () {
michael@0 877 /* the normative part of the spec states that:
michael@0 878 "unless the length is zero, in which case there are no supported property indices"
michael@0 879 ...
michael@0 880 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 881 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 882 assert_equals( makeEl('div',{itemref:' '}).itemRef[0], window.undefined );
michael@0 883 }, 'itemRef[index] must be undefined for out-of-range index');
michael@0 884 test(function () {
michael@0 885 assert_equals( makeEl('div',{itemref:' '}).itemRef[-1], window.undefined );
michael@0 886 }, 'itemRef[index] must be undefined for negative index');
michael@0 887 test(function () {
michael@0 888 assert_equals( makeEl('div',{itemref:' '}).itemRef.toString(), ' ' );
michael@0 889 }, 'empty itemRef should stringify to contain the attribute\'s whitespace');
michael@0 890 test(function () {
michael@0 891 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.contains(''); } );
michael@0 892 }, 'itemRef.contains(empty_string) must throw a SYNTAX_ERR');
michael@0 893 test(function () {
michael@0 894 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.add(''); } );
michael@0 895 }, 'itemRef.add(empty_string) must throw a SYNTAX_ERR');
michael@0 896 test(function () {
michael@0 897 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.remove(''); } );
michael@0 898 }, 'itemRef.remove(empty_string) must throw a SYNTAX_ERR');
michael@0 899 test(function () {
michael@0 900 assert_throws( 'SYNTAX_ERR', function () { makeEl('div',{itemref:' '}).itemRef.toggle(''); } );
michael@0 901 }, 'itemRef.toggle(empty_string) must throw a SYNTAX_ERR');
michael@0 902 test(function () {
michael@0 903 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.contains('a b'); } );
michael@0 904 }, 'itemRef.contains(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 905 test(function () {
michael@0 906 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.add('a b'); } );
michael@0 907 }, 'itemRef.add(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 908 test(function () {
michael@0 909 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.remove('a b'); } );
michael@0 910 }, 'itemRef.remove(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 911 test(function () {
michael@0 912 assert_throws( 'INVALID_CHARACTER_ERR', function () { makeEl('div',{itemref:' '}).itemRef.toggle('a b'); } );
michael@0 913 }, 'itemRef.toggle(string_with_spaces) must throw an INVALID_CHARACTER_ERR');
michael@0 914 test(function () {
michael@0 915 var testEl = makeEl('div',{itemref:'foo'});
michael@0 916 assert_true( testEl.itemRef.contains('foo'), 'before change' );
michael@0 917 testEl.setAttribute('itemref','bar');
michael@0 918 assert_true( testEl.itemRef.contains('bar'), 'after change' );
michael@0 919 assert_false( testEl.itemRef.contains('foo'), 'after change' );
michael@0 920 }, 'itemRef.contains must update when the underlying attribute is changed');
michael@0 921 test(function () {
michael@0 922 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('FOO') );
michael@0 923 }, 'itemRef.contains must be case sensitive');
michael@0 924 test(function () {
michael@0 925 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo.') );
michael@0 926 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo)') );
michael@0 927 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo\'') );
michael@0 928 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo$') );
michael@0 929 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo~') );
michael@0 930 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo?') );
michael@0 931 assert_false( makeEl('div',{itemref:'foo'}).itemRef.contains('foo\\') );
michael@0 932 }, 'itemRef.contains must not match when punctuation characters are added');
michael@0 933 test(function () {
michael@0 934 var elem = makeEl('div',{itemref:'foo'});
michael@0 935 elem.itemRef.add('FOO');
michael@0 936 assert_true( elem.itemRef.contains('foo') );
michael@0 937 }, 'itemRef.add must not remove existing tokens');
michael@0 938 test(function () {
michael@0 939 assert_true( makeEl('div',{itemref:'foo FOO'}).itemRef.contains('FOO') );
michael@0 940 }, 'itemRef.contains case sensitivity must match a case-specific string');
michael@0 941 test(function () {
michael@0 942 assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef.length, 2 );
michael@0 943 }, 'itemRef.length must correctly reflect the number of tokens');
michael@0 944 test(function () {
michael@0 945 assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef.item(0), 'foo' );
michael@0 946 }, 'itemRef.item(0) must return the first token');
michael@0 947 test(function () {
michael@0 948 var elem = makeEl('div',{itemref:'foo'});
michael@0 949 elem.itemRef.add('FOO');
michael@0 950 assert_equals( elem.itemRef.item(1), 'FOO' );
michael@0 951 }, 'itemRef.item must return case-sensitive strings and preserve token order');
michael@0 952 test(function () {
michael@0 953 assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef[0], 'foo' );
michael@0 954 }, 'itemRef[0] must return the first token');
michael@0 955 test(function () {
michael@0 956 assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef[1], 'FOO' );
michael@0 957 }, 'itemRef[index] must return case-sensitive strings and preserve token order');
michael@0 958 test(function () {
michael@0 959 /* the normative part of the spec states that:
michael@0 960 "unless the length is zero, in which case there are no supported property indices"
michael@0 961 ...
michael@0 962 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 963 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 964 assert_equals( makeEl('div',{itemref:'foo FOO'}).itemRef[2], window.undefined );
michael@0 965 }, 'itemRef[index] must still be undefined for out-of-range index when earlier indexes exist');
michael@0 966 test(function () {
michael@0 967 var elem = makeEl('div',{});
michael@0 968 elem.itemRef.add('foo');
michael@0 969 elem.itemRef.add('FOO');
michael@0 970 assert_equals( elem.getAttribute('itemref'), 'foo FOO' );
michael@0 971 }, 'itemref attribute must update correctly when items have been added through itemRef');
michael@0 972 test(function () {
michael@0 973 var elem = makeEl('div',{});
michael@0 974 elem.itemRef.add('foo');
michael@0 975 elem.itemRef.add('FOO');
michael@0 976 assert_equals( elem.itemRef + '', 'foo FOO' );
michael@0 977 }, 'itemRef must stringify correctly when items have been added');
michael@0 978 test(function () {
michael@0 979 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 980 elem.itemRef.add('foo');
michael@0 981 assert_equals( elem.itemRef.length, 2 );
michael@0 982 assert_equals( elem.itemRef + '', 'foo FOO' );
michael@0 983 }, 'itemRef.add must not make any changes if an existing token is added');
michael@0 984 test(function () {
michael@0 985 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 986 elem.itemRef.remove('bar');
michael@0 987 assert_equals( elem.itemRef.length, 2 );
michael@0 988 assert_equals( elem.itemRef + '', 'foo FOO' );
michael@0 989 }, 'itemRef.remove must not make any changes if a non-existing token is removed');
michael@0 990 test(function () {
michael@0 991 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 992 elem.itemRef.remove('foo');
michael@0 993 assert_equals( elem.itemRef.length, 1 );
michael@0 994 assert_equals( elem.itemRef.toString(), 'FOO' );
michael@0 995 assert_false( elem.itemRef.contains('foo') );
michael@0 996 assert_true( elem.itemRef.contains('FOO') );
michael@0 997 }, 'itemRef.remove must remove existing tokens');
michael@0 998 test(function () {
michael@0 999 var elem = makeEl('div',{itemref:'test test'});
michael@0 1000 elem.itemRef.remove('test');
michael@0 1001 assert_equals( elem.itemRef.length, 0 );
michael@0 1002 assert_false( elem.itemRef.contains('test') );
michael@0 1003 }, 'itemRef.remove must remove duplicated tokens');
michael@0 1004 test(function () {
michael@0 1005 var elem = makeEl('div',{itemref:'token1 token2 token3'});
michael@0 1006 elem.itemRef.remove('token2');
michael@0 1007 assert_equals( elem.itemRef.toString(), 'token1 token3' );
michael@0 1008 }, 'itemRef.remove must collapse whitespace around removed tokens');
michael@0 1009 test(function () {
michael@0 1010 var elem = makeEl('div',{itemref:' token1 token2 '});
michael@0 1011 elem.itemRef.remove('token2');
michael@0 1012 assert_equals( elem.itemRef.toString(), 'token1' );
michael@0 1013 }, 'itemRef.remove must remove useless whitespace when removing tokens');
michael@0 1014 test(function () {
michael@0 1015 var elem = makeEl('div',{itemref:' token1 token2 token3 '});
michael@0 1016 elem.itemRef.remove('token2');
michael@0 1017 assert_equals( elem.itemRef.toString(), 'token1 token3' );
michael@0 1018 }, 'itemRef.remove must remove useless whitespace when removing tokens');
michael@0 1019 test(function () {
michael@0 1020 var elem = makeEl('div',{itemref:' token1 token2 token3 '});
michael@0 1021 elem.itemRef.remove('token1', 'token3');
michael@0 1022 assert_equals( elem.itemRef.toString(), 'token2' );
michael@0 1023 }, 'itemRef.remove must collapse whitespace when removing multiple tokens');
michael@0 1024 test(function () {
michael@0 1025 var elem = makeEl('div',{itemref:' token1 token1 '});
michael@0 1026 elem.itemRef.add('token1');
michael@0 1027 assert_equals( elem.itemRef.toString(), 'token1' );
michael@0 1028 }, 'itemRef.add must remove whitespace and duplicate when the token already exists');
michael@0 1029 test(function () {
michael@0 1030 var elem = makeEl('div',{itemref:'FOO'});
michael@0 1031 assert_true(elem.itemRef.toggle('foo'));
michael@0 1032 assert_equals( elem.itemRef.length, 2 );
michael@0 1033 assert_true( elem.itemRef.contains('foo') );
michael@0 1034 assert_true( elem.itemRef.contains('FOO') );
michael@0 1035 }, 'itemRef.toggle must toggle tokens case-sensitively when adding');
michael@0 1036 test(function () {
michael@0 1037 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 1038 assert_false(elem.itemRef.toggle('foo'));
michael@0 1039 assert_false(elem.itemRef.toggle('FOO'));
michael@0 1040 assert_false( elem.itemRef.contains('foo') );
michael@0 1041 assert_false( elem.itemRef.contains('FOO') );
michael@0 1042 }, 'itemRef.toggle must be able to remove tokens case-sensitively');
michael@0 1043 test(function () {
michael@0 1044 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 1045 elem.itemRef.toggle('foo');
michael@0 1046 elem.itemRef.toggle('FOO');
michael@0 1047 assert_equals( elem.getAttribute('itemref'), '' );
michael@0 1048 }, 'itemref attribute must be empty when all classes have been removed');
michael@0 1049 test(function () {
michael@0 1050 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 1051 elem.itemRef.toggle('foo');
michael@0 1052 elem.itemRef.toggle('FOO');
michael@0 1053 assert_equals( elem.itemRef.toString(), '' );
michael@0 1054 }, 'itemRef must stringify to an empty string when all classes have been removed');
michael@0 1055 test(function () {
michael@0 1056 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 1057 elem.itemRef.toggle('foo');
michael@0 1058 elem.itemRef.toggle('FOO');
michael@0 1059 assert_equals( elem.itemRef.item(0), null );
michael@0 1060 }, 'itemRef.item(0) must return null when all classes have been removed');
michael@0 1061 test(function () {
michael@0 1062 /* the normative part of the spec states that:
michael@0 1063 "unless the length is zero, in which case there are no supported property indices"
michael@0 1064 ...
michael@0 1065 "The term[...] supported property indices [is] used as defined in the WebIDL specification."
michael@0 1066 WebIDL creates actual OwnProperties and then [] just acts as a normal property lookup */
michael@0 1067 var elem = makeEl('div',{itemref:'foo FOO'});
michael@0 1068 elem.itemRef.toggle('foo');
michael@0 1069 elem.itemRef.toggle('FOO');
michael@0 1070 assert_equals( elem.itemRef[0], window.undefined );
michael@0 1071 }, 'itemRef[0] must be undefined when all classes have been removed');
michael@0 1072 //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"
michael@0 1073 test(function () {
michael@0 1074 var elem = makeEl('div',{itemref:'a '});
michael@0 1075 elem.itemRef.add('b');
michael@0 1076 assert_equals(elem.itemRef.toString(),'a b');
michael@0 1077 }, 'itemRef.add should treat " " as a space');
michael@0 1078 test(function () {
michael@0 1079 var elem = makeEl('div',{itemref:'a\t'});
michael@0 1080 elem.itemRef.add('b');
michael@0 1081 assert_equals(elem.itemRef.toString(),'a b');
michael@0 1082 }, 'itemRef.add should normalize \\t as a space');
michael@0 1083 test(function () {
michael@0 1084 var elem = makeEl('div',{itemref:'a\r'});
michael@0 1085 elem.itemRef.add('b');
michael@0 1086 assert_equals(elem.itemRef.toString(),'a b');
michael@0 1087 }, 'itemRef.add should normalize \\r as a space');
michael@0 1088 test(function () {
michael@0 1089 var elem = makeEl('div',{itemref:'a\n'});
michael@0 1090 elem.itemRef.add('b');
michael@0 1091 assert_equals(elem.itemRef.toString(),'a b');
michael@0 1092 }, 'itemRef.add should normalize \\n as a space');
michael@0 1093 test(function () {
michael@0 1094 var elem = makeEl('div',{itemref:'a\f'});
michael@0 1095 elem.itemRef.add('b');
michael@0 1096 assert_equals(elem.itemRef.toString(),'a b');
michael@0 1097 }, 'itemRef.add should normalize \\f as a space');
michael@0 1098 test(function () {
michael@0 1099 var elem = makeEl('div',{itemref:'foo'});
michael@0 1100 elem.itemRef.remove('foo');
michael@0 1101 elem.removeAttribute('itemref');
michael@0 1102 assert_true( elem.itemRef.toggle('foo') );
michael@0 1103 }, 'itemRef.toggle must work after removing the itemref attribute');
michael@0 1104 test(function () {
michael@0 1105 //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter
michael@0 1106 //ES5 makes [[Put]] fail but not throw
michael@0 1107 var failed = false;
michael@0 1108 var elem = makeEl('div',{itemref:'token1'});
michael@0 1109 try {
michael@0 1110 elem.itemRef.length = 0;
michael@0 1111 } catch(e) {
michael@0 1112 failed = e;
michael@0 1113 }
michael@0 1114 assert_equals(elem.itemRef.length,1);
michael@0 1115 assert_false(failed,'an error was thrown');
michael@0 1116 }, 'itemRef.length must be read-only');
michael@0 1117 test(function () {
michael@0 1118 var failed = false, elem = makeEl('div',{itemref:'test'}), realList = elem.itemRef;
michael@0 1119 try {
michael@0 1120 elem.itemRef = 'dummy';
michael@0 1121 } catch(e) {
michael@0 1122 failed = e;
michael@0 1123 }
michael@0 1124 assert_equals(elem.itemRef,realList);
michael@0 1125 assert_equals(elem.itemRef.toString(),'dummy','attempting to write should modify the underlying string');
michael@0 1126 assert_false(failed,'an error was thrown');
michael@0 1127 }, 'itemRef must be read-only');
michael@0 1128
michael@0 1129 /* itemValue property tests */
michael@0 1130 test(function () {
michael@0 1131 assert_equals( makeEl('meta',{content:'test'}).itemValue, null, 'meta' );
michael@0 1132 assert_equals( makeEl('audio',{src:'test'}).itemValue, null, 'audio' );
michael@0 1133 assert_equals( makeEl('embed',{src:'test'}).itemValue, null, 'embed' );
michael@0 1134 assert_equals( makeEl('iframe',{src:'test'}).itemValue, null, 'iframe' );
michael@0 1135 assert_equals( makeEl('img',{src:'test'}).itemValue, null, 'img' );
michael@0 1136 assert_equals( makeEl('source',{src:'test'}).itemValue, null, 'source' );
michael@0 1137 assert_equals( makeEl('track',{src:'test'}).itemValue, null, 'track' );
michael@0 1138 assert_equals( makeEl('video',{src:'test'}).itemValue, null, 'video' );
michael@0 1139 assert_equals( makeEl('a',{href:'test'}).itemValue, null, 'a' );
michael@0 1140 assert_equals( makeEl('area',{href:'test'}).itemValue, null, 'area' );
michael@0 1141 assert_equals( makeEl('link',{href:'test'}).itemValue, null, 'link' );
michael@0 1142 assert_equals( makeEl('object',{data:'test'}).itemValue, null, 'object' );
michael@0 1143 assert_equals( makeEl('time',{}).itemValue, null, 'time without datetime' );
michael@0 1144 assert_equals( makeEl('time',{datetime:'test'}).itemValue, null, 'time with datetime' );
michael@0 1145 assert_equals( makeEl('div',{},'test').itemValue, null, 'otherwise' );
michael@0 1146 assert_equals( makeEl('madeuponthespot',{},'test').itemValue, null, 'unknown element' );
michael@0 1147 }, 'itemValue must be null if the element does not have an itemprop attribute');
michael@0 1148 test(function () {
michael@0 1149 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('meta',{content:'test'}); testEl.itemValue = 'test2'; }, 'meta' );
michael@0 1150 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('audio',{content:'test'}); testEl.itemValue = 'test2'; }, 'audio' );
michael@0 1151 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('embed',{content:'test'}); testEl.itemValue = 'test2'; }, 'embed' );
michael@0 1152 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('iframe',{content:'test'}); testEl.itemValue = 'test2'; }, 'iframe' );
michael@0 1153 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('img',{content:'test'}); testEl.itemValue = 'test2'; }, 'img' );
michael@0 1154 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('source',{content:'test'}); testEl.itemValue = 'test2'; }, 'source' );
michael@0 1155 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('track',{content:'test'}); testEl.itemValue = 'test2'; }, 'track' );
michael@0 1156 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('video',{content:'test'}); testEl.itemValue = 'test2'; }, 'video' );
michael@0 1157 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('a',{href:'test'}); testEl.itemValue = 'test2'; }, 'a' );
michael@0 1158 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('area',{href:'test'}); testEl.itemValue = 'test2'; }, 'area' );
michael@0 1159 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('link',{href:'test'}); testEl.itemValue = 'test2'; }, 'link' );
michael@0 1160 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('object',{data:'test'}); testEl.itemValue = 'test2'; }, 'object' );
michael@0 1161 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('time',{}); testEl.itemValue = 'test2'; }, 'time without datetime' );
michael@0 1162 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('time',{datetime:'test'}); testEl.itemValue = 'test2'; }, 'time with datetime' );
michael@0 1163 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('div',{},'test'); testEl.itemValue = 'test2'; }, 'otherwise' );
michael@0 1164 assert_throws( 'INVALID_ACCESS_ERR', function () { var testEl = makeEl('madeuponthespot',{},'test'); testEl.itemValue = 'test2'; }, 'unknown element' );
michael@0 1165 }, 'writing to itemValue must throw an INVALID_ACCESS_ERR error if the element does not have an itemprop attribute');
michael@0 1166 test(function () {
michael@0 1167 var testEl;
michael@0 1168 testEl = makeEl('meta',{itemscope:'itemscope',itemprop:'foo',content:'test'});
michael@0 1169 assert_equals( testEl.itemValue, testEl, 'meta' );
michael@0 1170 testEl = makeEl('audio',{itemscope:'itemscope',itemprop:'foo',src:'test'},'fail');
michael@0 1171 assert_equals( testEl.itemValue, testEl, 'audio' );
michael@0 1172 testEl = makeEl('embed',{itemscope:'itemscope',itemprop:'foo',src:'test'});
michael@0 1173 assert_equals( testEl.itemValue, testEl, 'embed' );
michael@0 1174 testEl = makeEl('iframe',{itemscope:'itemscope',itemprop:'foo',src:'test'},'fail');
michael@0 1175 assert_equals( testEl.itemValue, testEl, 'iframe' );
michael@0 1176 testEl = makeEl('img',{itemscope:'itemscope',itemprop:'foo',src:'test'});
michael@0 1177 assert_equals( testEl.itemValue, testEl, 'img' );
michael@0 1178 testEl = makeEl('source',{itemscope:'itemscope',itemprop:'foo',src:'test'});
michael@0 1179 assert_equals( testEl.itemValue, testEl, 'source' );
michael@0 1180 testEl = makeEl('track',{itemscope:'itemscope',itemprop:'foo',src:'test'});
michael@0 1181 assert_equals( testEl.itemValue, testEl, 'track' );
michael@0 1182 testEl = makeEl('video',{itemscope:'itemscope',itemprop:'foo',src:'test'},'fail');
michael@0 1183 assert_equals( testEl.itemValue, testEl, 'video' );
michael@0 1184 testEl = makeEl('a',{itemscope:'itemscope',itemprop:'foo',href:'test'},'fail');
michael@0 1185 assert_equals( testEl.itemValue, testEl, 'a' );
michael@0 1186 testEl = makeEl('area',{itemscope:'itemscope',itemprop:'foo',href:'test'});
michael@0 1187 assert_equals( testEl.itemValue, testEl, 'area' );
michael@0 1188 testEl = makeEl('link',{itemscope:'itemscope',itemprop:'foo',href:'test'});
michael@0 1189 assert_equals( testEl.itemValue, testEl, 'link' );
michael@0 1190 testEl = makeEl('object',{itemscope:'itemscope',itemprop:'foo',data:'test'},'fail');
michael@0 1191 assert_equals( testEl.itemValue, testEl, 'object' );
michael@0 1192 testEl = makeEl('time',{itemscope:'itemscope',itemprop:'foo'},'fail');
michael@0 1193 assert_equals( testEl.itemValue, testEl, 'time without datetime' );
michael@0 1194 testEl = makeEl('time',{itemscope:'itemscope',itemprop:'foo',datetime:'test'},'fail');
michael@0 1195 assert_equals( testEl.itemValue, testEl, 'time with datetime' );
michael@0 1196 testEl = makeEl('div',{itemscope:'itemscope',itemprop:'foo'},'test');
michael@0 1197 assert_equals( testEl.itemValue, testEl, 'otherwise' );
michael@0 1198 testEl = makeEl('madeuponthespot',{itemscope:'itemscope',itemprop:'foo'},'test');
michael@0 1199 assert_equals( testEl.itemValue, testEl, 'unknown element' );
michael@0 1200 testEl = makeEl('madeuponthespot',{itemscope:'itemscope',itemprop:'foo',content:'test',src:'test',href:'test',data:'test',datetime:'test',value:'test'},'test');
michael@0 1201 assert_equals( testEl.itemValue, testEl, 'unknown element with known attributes' );
michael@0 1202 testEl = makeEl('input',{itemscope:'itemscope',itemprop:'foo',value:'test'},'test');
michael@0 1203 assert_equals( testEl.itemValue, testEl, 'input' );
michael@0 1204 }, 'itemValue must return the element if the element has an itemscope attribute');
michael@0 1205 test(function () {
michael@0 1206 var testEl = makeEl('meta',{itemprop:'foo',content:'test'});
michael@0 1207 assert_equals( testEl.itemValue, 'test', 'reading' );
michael@0 1208 testEl.content = 'retest';
michael@0 1209 assert_equals( testEl.itemValue, 'retest', 'reading after change' );
michael@0 1210 testEl.itemValue = 'bar';
michael@0 1211 assert_equals( testEl.content, 'bar', 'writing (checking content)' );
michael@0 1212 assert_equals( testEl.textContent, '', 'writing (checking textContent)' );
michael@0 1213 }, 'itemValue must reflect the content attribute on meta elements');
michael@0 1214 test(function () {
michael@0 1215 var testEl = makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text');
michael@0 1216 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1217 testEl.src = 'http://example.net/';
michael@0 1218 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1219 testEl.itemValue = 'http://example.com/';
michael@0 1220 assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' );
michael@0 1221 assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' );
michael@0 1222 assert_equals( makeEl('audio',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' );
michael@0 1223 testEl.src = 'bar';
michael@0 1224 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1225 }, 'itemValue must reflect the src attribute on audio elements');
michael@0 1226 test(function () {
michael@0 1227 var testEl = makeEl('embed',{itemprop:'foo',src:'http://example.org/'});
michael@0 1228 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1229 testEl.src = 'http://example.net/';
michael@0 1230 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1231 testEl.itemValue = 'http://example.com/';
michael@0 1232 assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' );
michael@0 1233 assert_equals( testEl.textContent, '', 'writing (checking textContent)' );
michael@0 1234 testEl.src = 'bar';
michael@0 1235 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1236 }, 'itemValue must reflect the src attribute on embed elements');
michael@0 1237 test(function () {
michael@0 1238 var testEl = makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text');
michael@0 1239 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1240 testEl.src = 'http://example.net/';
michael@0 1241 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1242 testEl.itemValue = 'http://example.com/';
michael@0 1243 assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' );
michael@0 1244 assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' );
michael@0 1245 assert_equals( makeEl('iframe',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' );
michael@0 1246 testEl.src = 'bar';
michael@0 1247 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1248 }, 'itemValue must reflect the src attribute on iframe elements');
michael@0 1249 test(function () {
michael@0 1250 var testEl = makeEl('img',{itemprop:'foo',src:'http://example.org/'});
michael@0 1251 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1252 testEl.src = 'http://example.net/';
michael@0 1253 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1254 testEl.itemValue = 'http://example.com/';
michael@0 1255 assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' );
michael@0 1256 assert_equals( testEl.textContent, '', 'writing (checking textContent)' );
michael@0 1257 testEl.src = 'bar';
michael@0 1258 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1259 }, 'itemValue must reflect the src attribute on img elements');
michael@0 1260 test(function () {
michael@0 1261 var testEl = makeEl('source',{itemprop:'foo',src:'http://example.org/'});
michael@0 1262 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1263 testEl.src = 'http://example.net/';
michael@0 1264 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1265 testEl.itemValue = 'http://example.com/';
michael@0 1266 assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' );
michael@0 1267 assert_equals( testEl.textContent, '', 'writing (checking textContent)' );
michael@0 1268 testEl.src = 'bar';
michael@0 1269 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1270 }, 'itemValue must reflect the src attribute on source elements');
michael@0 1271 test(function () {
michael@0 1272 var testEl = makeEl('track',{itemprop:'foo',src:'http://example.org/'});
michael@0 1273 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1274 testEl.src = 'http://example.net/';
michael@0 1275 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1276 testEl.itemValue = 'http://example.com/';
michael@0 1277 assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' );
michael@0 1278 assert_equals( testEl.textContent, '', 'writing (checking textContent)' );
michael@0 1279 testEl.src = 'bar';
michael@0 1280 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1281 }, 'itemValue must reflect the src attribute on track elements');
michael@0 1282 test(function () {
michael@0 1283 var testEl = makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text');
michael@0 1284 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1285 testEl.src = 'http://example.net/';
michael@0 1286 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1287 testEl.itemValue = 'http://example.com/';
michael@0 1288 assert_equals( testEl.src, 'http://example.com/', 'writing (checking src)' );
michael@0 1289 assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' );
michael@0 1290 assert_equals( makeEl('video',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' );
michael@0 1291 testEl.src = 'bar';
michael@0 1292 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1293 }, 'itemValue must reflect the src attribute on video elements');
michael@0 1294 test(function () {
michael@0 1295 var testEl = makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text');
michael@0 1296 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1297 testEl.href = 'http://example.net/';
michael@0 1298 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1299 testEl.itemValue = 'http://example.com/';
michael@0 1300 assert_equals( testEl.href, 'http://example.com/', 'writing (checking href)' );
michael@0 1301 assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' );
michael@0 1302 assert_equals( makeEl('a',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' );
michael@0 1303 testEl.href = 'bar';
michael@0 1304 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1305 }, 'itemValue must reflect the src attribute on anchor elements');
michael@0 1306 test(function () {
michael@0 1307 var testEl = makeEl('area',{itemprop:'foo',href:'http://example.org/'});
michael@0 1308 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1309 testEl.href = 'http://example.net/';
michael@0 1310 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1311 testEl.itemValue = 'http://example.com/';
michael@0 1312 assert_equals( testEl.href, 'http://example.com/', 'writing (checking href)' );
michael@0 1313 assert_equals( testEl.textContent, '', 'writing (checking textContent)' );
michael@0 1314 testEl.href = 'bar';
michael@0 1315 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1316 }, 'itemValue must reflect the src attribute on area elements');
michael@0 1317 test(function () {
michael@0 1318 var testEl = makeEl('link',{itemprop:'foo',href:'http://example.org/'});
michael@0 1319 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1320 testEl.href = 'http://example.net/';
michael@0 1321 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1322 testEl.itemValue = 'http://example.com/';
michael@0 1323 assert_equals( testEl.href, 'http://example.com/', 'writing (checking href)' );
michael@0 1324 assert_equals( testEl.textContent, '', 'writing (checking textContent)' );
michael@0 1325 testEl.href = 'bar';
michael@0 1326 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1327 }, 'itemValue must reflect the src attribute on link elements');
michael@0 1328 test(function () {
michael@0 1329 var testEl = makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text');
michael@0 1330 assert_equals( testEl.itemValue, 'http://example.org/', 'reading' );
michael@0 1331 testEl.data = 'http://example.net/';
michael@0 1332 assert_equals( testEl.itemValue, 'http://example.net/', 'reading after change' );
michael@0 1333 testEl.itemValue = 'http://example.com/';
michael@0 1334 assert_equals( testEl.data, 'http://example.com/', 'writing (checking data)' );
michael@0 1335 assert_equals( testEl.textContent, 'contained text', 'writing (checking textContent)' );
michael@0 1336 assert_equals( makeEl('object',{itemprop:'foo'},'contained text').itemValue, '', 'reading with missing attribute' );
michael@0 1337 testEl.data = 'bar';
michael@0 1338 assert_equals( testEl.itemValue, location.href.replace(/\/[^\/]*$/,'/bar'), 'resolving URLs' );
michael@0 1339 }, 'itemValue must reflect the src attribute on object elements');
michael@0 1340 test(function () {
michael@0 1341 var testEl = makeEl('time',{itemprop:'foo'},'te <span itemprop="bar" itemscope>st</span> ing');
michael@0 1342 assert_equals( testEl.itemValue, 'te st ing', 'reading' );
michael@0 1343 testEl.innerHTML = 'retest';
michael@0 1344 assert_equals( testEl.itemValue, 'retest', 'reading after change' );
michael@0 1345 testEl.itemValue = '2001-02-03T04:05:06Z';
michael@0 1346 assert_equals( testEl.dateTime, '2001-02-03T04:05:06Z', 'writing (checking dateTime)' );
michael@0 1347 assert_equals( testEl.textContent, 'retest', 'writing (checking textContent)' );
michael@0 1348 assert_equals( testEl.itemValue, '2001-02-03T04:05:06Z', 'writing (checking itemValue)' );
michael@0 1349 }, 'itemValue must reflect the dateTime attribute of time elements with no datetime attribute');
michael@0 1350 test(function () {
michael@0 1351 var testEl = makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="bar" itemscope>st</span> ing');
michael@0 1352 assert_equals( testEl.itemValue, 'test', 'reading' );
michael@0 1353 testEl.dateTime = 'retest';
michael@0 1354 assert_equals( testEl.itemValue, 'retest', 'reading after change' );
michael@0 1355 testEl.itemValue = '2001-02-03T04:05:06Z';
michael@0 1356 assert_equals( testEl.dateTime, '2001-02-03T04:05:06Z', 'writing (checking dateTime)' );
michael@0 1357 assert_equals( testEl.textContent, 'te st ing', 'writing (checking textContent)' );
michael@0 1358 }, 'itemValue must reflect the datetime attribute of time elements with a datetime attribute');
michael@0 1359 test(function () {
michael@0 1360 var testEl = makeEl('div',{itemprop:'foo'},'te <span itemprop="bar" itemscope>st</span> ing');
michael@0 1361 assert_equals( testEl.itemValue, 'te st ing', 'reading' );
michael@0 1362 testEl.innerHTML = 're<strong>te</strong>st';
michael@0 1363 assert_equals( testEl.itemValue, 'retest', 'reading after change' );
michael@0 1364 testEl.itemValue = 'test';
michael@0 1365 assert_equals( testEl.textContent, 'test', 'writing' );
michael@0 1366 }, 'itemValue must reflect the textContent of other elements');
michael@0 1367 test(function () {
michael@0 1368 var testEl = makeEl('madeuponthespot',{itemprop:'foo'},'te <span itemprop="bar" itemscope>st</span> ing');
michael@0 1369 assert_equals( testEl.itemValue, 'te st ing', 'reading' );
michael@0 1370 testEl.innerHTML = 're<strong>te</strong>st';
michael@0 1371 assert_equals( testEl.itemValue, 'retest', 'reading after change' );
michael@0 1372 testEl.itemValue = 'test';
michael@0 1373 assert_equals( testEl.textContent, 'test', 'writing' );
michael@0 1374 }, 'itemValue must reflect the textContent of unknown elements');
michael@0 1375 test(function () {
michael@0 1376 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');
michael@0 1377 assert_equals( testEl.itemValue, 'te st ing', 'reading' );
michael@0 1378 testEl.innerHTML = 're<strong>te</strong>st';
michael@0 1379 assert_equals( testEl.itemValue, 'retest', 'reading after change' );
michael@0 1380 testEl.itemValue = 'test';
michael@0 1381 assert_equals( testEl.textContent, 'test', 'writing' );
michael@0 1382 }, 'itemValue must reflect the textContent of unknown elements with known attributes');
michael@0 1383 test(function () {
michael@0 1384 var testEl = makeEl('input',{itemprop:'foo',value:'test'});
michael@0 1385 assert_equals( testEl.itemValue, '', 'reading' );
michael@0 1386 testEl.value = 'retest';
michael@0 1387 assert_equals( testEl.itemValue, '', 'reading after change' );
michael@0 1388 }, 'itemValue must not reflect the value of input elements');
michael@0 1389 test(function () {
michael@0 1390 var testEl, eltypes = [
michael@0 1391 makeEl('meta',{itemprop:'foo',content:'test'}),
michael@0 1392 makeEl('audio',{itemprop:'foo',src:'test'},'fail'),
michael@0 1393 makeEl('embed',{itemprop:'foo',src:'test'}),
michael@0 1394 makeEl('iframe',{itemprop:'foo',src:'test'},'fail'),
michael@0 1395 makeEl('img',{itemprop:'foo',src:'test'}),
michael@0 1396 makeEl('source',{itemprop:'foo',src:'test'}),
michael@0 1397 makeEl('track',{itemprop:'foo',src:'test'}),
michael@0 1398 makeEl('video',{itemprop:'foo',src:'test'},'fail'),
michael@0 1399 makeEl('a',{itemprop:'foo',href:'test'},'fail'),
michael@0 1400 makeEl('area',{itemprop:'foo',href:'test'}),
michael@0 1401 makeEl('link',{itemprop:'foo',href:'test'}),
michael@0 1402 makeEl('object',{itemprop:'foo',data:'test'},'fail'),
michael@0 1403 makeEl('time',{itemprop:'foo'},'fail'),
michael@0 1404 makeEl('time',{itemprop:'foo',datetime:'test'},'fail'),
michael@0 1405 makeEl('div',{itemprop:'foo'},'test'),
michael@0 1406 makeEl('madeuponthespot',{itemprop:'foo'},'test'),
michael@0 1407 makeEl('madeuponthespot',{itemprop:'foo',content:'test',src:'test',href:'test',data:'test',datetime:'test',value:'test'},'test'),
michael@0 1408 makeEl('input',{itemprop:'foo',value:'test'},'test')
michael@0 1409 ], beforeValues, i;
michael@0 1410 for( i = 0; i < eltypes.length; i++ ) {
michael@0 1411 testEl = eltypes[i];
michael@0 1412 beforeValues = testEl.itemValue;
michael@0 1413 testEl.itemScope = true;
michael@0 1414 assert_equals( testEl.itemValue, testEl, 'itemscope enabled on '+testEl.tagName+' index '+i );
michael@0 1415 testEl.itemScope = false;
michael@0 1416 assert_equals( testEl.itemValue, beforeValues, 'itemscope disabled on '+testEl.tagName+' index '+i );
michael@0 1417 testEl.itemScope = true;
michael@0 1418 testEl.removeAttribute('itemscope');
michael@0 1419 assert_equals( testEl.itemValue, beforeValues, 'itemscope attribute removed on '+testEl.tagName+' index '+i );
michael@0 1420 }
michael@0 1421 }, 'dynamic changes of itemscope should change the value exposed through itemValue');
michael@0 1422
michael@0 1423 test(function () {
michael@0 1424 var testEl, eltypes = [
michael@0 1425 makeEl('meta',{itemprop:'foo',content:'test'}),
michael@0 1426 makeEl('audio',{itemprop:'foo',src:'test'},'fail'),
michael@0 1427 makeEl('embed',{itemprop:'foo',src:'test'}),
michael@0 1428 makeEl('iframe',{itemprop:'foo',src:'test'},'fail'),
michael@0 1429 makeEl('img',{itemprop:'foo',src:'test'}),
michael@0 1430 makeEl('source',{itemprop:'foo',src:'test'}),
michael@0 1431 makeEl('track',{itemprop:'foo',src:'test'}),
michael@0 1432 makeEl('video',{itemprop:'foo',src:'test'},'fail'),
michael@0 1433 makeEl('a',{itemprop:'foo',href:'test'},'fail'),
michael@0 1434 makeEl('area',{itemprop:'foo',href:'test'}),
michael@0 1435 makeEl('link',{itemprop:'foo',href:'test'}),
michael@0 1436 makeEl('object',{itemprop:'foo',data:'test'},'fail'),
michael@0 1437 makeEl('time',{itemprop:'foo'},'fail'),
michael@0 1438 makeEl('time',{itemprop:'foo',datetime:'test'},'fail'),
michael@0 1439 makeEl('div',{itemprop:'foo'},'test'),
michael@0 1440 makeEl('madeuponthespot',{itemprop:'foo'},'test'),
michael@0 1441 makeEl('madeuponthespot',{itemprop:'foo',content:'test',src:'test',href:'test',data:'test',datetime:'test',value:'test'},'test'),
michael@0 1442 makeEl('input',{itemprop:'foo',value:'test'},'test')
michael@0 1443 ], beforeValues, i;
michael@0 1444 for( i = 0; i < eltypes.length; i++ ) {
michael@0 1445 testEl = eltypes[i];
michael@0 1446 beforeValues = testEl.itemValue;
michael@0 1447 testEl.itemProp.remove('foo');
michael@0 1448 assert_equals( testEl.itemValue, beforeValues, 'itemprop tokens removed on '+testEl.tagName+' index '+i );
michael@0 1449 testEl.removeAttribute('itemprop');
michael@0 1450 assert_equals( testEl.itemValue, null, 'itemprop attribute removed on '+testEl.tagName+' index '+i );
michael@0 1451 testEl.itemProp.toggle('foo');
michael@0 1452 assert_equals( testEl.itemValue, beforeValues, 'itemprop tokens added on '+testEl.tagName+' index '+i );
michael@0 1453 }
michael@0 1454 }, 'dynamic changes of itemprop should change the value exposed through itemValue');
michael@0 1455
michael@0 1456 /* properties */
michael@0 1457 test(function () {
michael@0 1458 assert_equals( typeof makeEl('div',{}).properties, 'object' );
michael@0 1459 }, 'the properties property must be an object');
michael@0 1460 test(function () {
michael@0 1461 var testEl = makeEl('div',{});
michael@0 1462 assert_true( testEl.properties instanceof HTMLPropertiesCollection, 'instanceof HTMLPropertiesCollection' );
michael@0 1463 assert_true( testEl.properties instanceof HTMLCollection, 'instanceof HTMLCollection' );
michael@0 1464 HTMLPropertiesCollection.prototype.customProperty = true;
michael@0 1465 HTMLCollection.prototype.anotherCustomProperty = true;
michael@0 1466 assert_true( testEl.properties.customProperty, 'inheritance from HTMLPropertiesCollection' );
michael@0 1467 assert_true( testEl.properties.anotherCustomProperty, 'inheritance from HTMLCollection' );
michael@0 1468 HTMLPropertiesCollection.prototype.anotherCustomProperty = false;
michael@0 1469 assert_false( testEl.properties.anotherCustomProperty, 'shadowing by HTMLPropertiesCollection' );
michael@0 1470 }, 'the properties property must implement HTMLPropertiesCollection and HTMLCollection');
michael@0 1471 test(function () {
michael@0 1472 var failed = false, elem = makeEl('div',{itemscope:'itemscope'}), realList = elem.properties;
michael@0 1473 try {
michael@0 1474 elem.properties = '';
michael@0 1475 } catch(e) {
michael@0 1476 failed = e;
michael@0 1477 }
michael@0 1478 assert_equals(elem.properties,realList);
michael@0 1479 assert_false(failed,'an error was thrown');
michael@0 1480 }, 'the properties property must be read-only');
michael@0 1481 test(function () {
michael@0 1482 var testEl = makeEl('div',{});
michael@0 1483 assert_equals( testEl.properties, testEl.properties );
michael@0 1484 }, 'the properties property must always reference the same object');
michael@0 1485 test(function () {
michael@0 1486 var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>');
michael@0 1487 assert_equals( testEl.properties.length, 0, 'length' );
michael@0 1488 assert_true( !testEl.properties.item(0), 'item(0)' );
michael@0 1489 assert_true( !testEl.properties[0], '[0]' );
michael@0 1490 assert_equals( testEl.properties.namedItem('foo').length, 0, 'namedItem' );
michael@0 1491 assert_true( !testEl.properties['foo'], '[namedItem]' );
michael@0 1492 assert_equals( testEl.properties.namedItem('foo').getValues().length, 0, 'namedItem' );
michael@0 1493 assert_equals( testEl.properties.names.length, 0, 'names' );
michael@0 1494 }, 'the properties collection must be empty if the element does not have an itemscope property');
michael@0 1495 test(function() {
michael@0 1496 var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>');
michael@0 1497 assert_throws( new TypeError(), function() { testEl.properties('foo'); } );
michael@0 1498 assert_throws( new TypeError(), function() { testEl.properties(0); } );
michael@0 1499 }, 'the properties collection must not support legacycaller');
michael@0 1500 test(function () {
michael@0 1501 var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>');
michael@0 1502 testEl.itemScope = true;
michael@0 1503 assert_equals( testEl.properties.length, 1, 'length' );
michael@0 1504 assert_equals( testEl.properties.item(0), testEl.firstChild, 'item(0)' );
michael@0 1505 assert_equals( testEl.properties[0], testEl.firstChild, '[0]' );
michael@0 1506 assert_equals( testEl.properties.namedItem('foo').length, 1, 'namedItem' );
michael@0 1507 assert_equals( testEl.properties['foo'].length, 1, '[namedItem]' );
michael@0 1508 assert_equals( testEl.properties.namedItem('foo').getValues().length, 1, 'namedItem' );
michael@0 1509 assert_equals( testEl.properties.names.length, 1, 'names' );
michael@0 1510 }, 'the properties collection must become populated if the element is given an itemscope property');
michael@0 1511 test(function () {
michael@0 1512 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo">bar</div>');
michael@0 1513 testEl.itemScope = false;
michael@0 1514 assert_equals( testEl.properties.length, 0, 'length' );
michael@0 1515 assert_true( !testEl.properties.item(0), 'item(0)' );
michael@0 1516 assert_true( !testEl.properties[0], '[0]' );
michael@0 1517 assert_equals( testEl.properties.namedItem('foo').length, 0, 'namedItem' );
michael@0 1518 assert_true( !testEl.properties['foo'], '[namedItem]' );
michael@0 1519 assert_equals( testEl.properties.namedItem('foo').getValues().length, 0, 'namedItem' );
michael@0 1520 assert_equals( testEl.properties.names.length, 0, 'names' );
michael@0 1521 }, 'the properties collection must become empty if the element\'s itemscope property is removed');
michael@0 1522 //properties.item and properties.length (part 1)
michael@0 1523 test(function () {
michael@0 1524 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>');
michael@0 1525 assert_equals( testEl.properties.length, 5 );
michael@0 1526 }, 'properties.length must be the total number of properties');
michael@0 1527 test(function () {
michael@0 1528 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>');
michael@0 1529 assert_equals( testEl.properties.item(0), testEl.childNodes[0], 'item(0)' );
michael@0 1530 assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'item(1)' );
michael@0 1531 assert_equals( testEl.properties.item(2), testEl.childNodes[1].childNodes[0], 'item(2)' );
michael@0 1532 assert_equals( testEl.properties.item(3), testEl.childNodes[2], 'item(3)' );
michael@0 1533 }, 'properties.item must give each property in tree order');
michael@0 1534 test(function () {
michael@0 1535 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>');
michael@0 1536 testEl.properties.something = "another";
michael@0 1537 var names = Object.getOwnPropertyNames(testEl.properties);
michael@0 1538 assert_array_equals( names, ["0", "1", "2", "3", "foo", "bar", "baz", "qux", "something"] );
michael@0 1539 }, 'properties.item must have the right property names on it when enumerated');
michael@0 1540 test(function () {
michael@0 1541 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>');
michael@0 1542 assert_equals( testEl.properties.item(4), null, 'positive index' );
michael@0 1543 assert_equals( testEl.properties.item(-1), null, 'negative index' );
michael@0 1544 }, 'properties.item must give null for out of range index');
michael@0 1545 test(function () {
michael@0 1546 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>');
michael@0 1547 assert_equals( testEl.properties[0], testEl.childNodes[0], '[0]' );
michael@0 1548 assert_equals( testEl.properties[1], testEl.childNodes[1], '[1]' );
michael@0 1549 assert_equals( testEl.properties[2], testEl.childNodes[1].childNodes[0], '[2]' );
michael@0 1550 assert_equals( testEl.properties[3], testEl.childNodes[2], '[3]' );
michael@0 1551 }, 'properties[index] must give each property in tree order');
michael@0 1552 test(function () {
michael@0 1553 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="foo"></div></div><div itemprop="baz qux"></div>');
michael@0 1554 assert_equals( testEl.properties[4], window.undefined, 'positive index' );
michael@0 1555 assert_equals( testEl.properties[-1], window.undefined, 'negative index' );
michael@0 1556 }, 'properties[index] must give undefined for out of range index');
michael@0 1557 test(function () {
michael@0 1558 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemscope itemprop="foo"><div itemprop="bar"></div></div><div><div itemprop="baz"></div></div>');
michael@0 1559 assert_equals( testEl.properties.length, 2, 'length' );
michael@0 1560 assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0)' );
michael@0 1561 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0]' );
michael@0 1562 assert_equals( testEl.properties.item(1), testEl.childNodes[1].firstChild, 'properties.item(1)' );
michael@0 1563 assert_equals( testEl.properties[1], testEl.childNodes[1].firstChild, 'properties[1]' );
michael@0 1564 }, 'properties.item and length must ignore properties of nested items');
michael@0 1565 test(function () {
michael@0 1566 //note, itemref ordering is reversed compared with the next test to catch failed sorting algorithms
michael@0 1567 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>');
michael@0 1568 var testEl = parEl.childNodes[1];
michael@0 1569 document.body.appendChild(parEl);
michael@0 1570 var propLength = testEl.properties.length;
michael@0 1571 var item0 = testEl.properties.item(0);
michael@0 1572 var square0 = testEl.properties[0];
michael@0 1573 var item1 = testEl.properties.item(1);
michael@0 1574 var square1 = testEl.properties[1];
michael@0 1575 var item2 = testEl.properties.item(2);
michael@0 1576 var square2 = testEl.properties[2];
michael@0 1577 var item3 = testEl.properties.item(3);
michael@0 1578 var square3 = testEl.properties[3];
michael@0 1579 document.body.removeChild(parEl);
michael@0 1580 assert_equals( propLength, 4, 'length' );
michael@0 1581 assert_equals( item0, parEl.firstChild, 'properties.item(0)' );
michael@0 1582 assert_equals( square0, parEl.firstChild, 'properties[0]' );
michael@0 1583 assert_equals( item1, testEl.firstChild, 'properties.item(1)' );
michael@0 1584 assert_equals( square1, testEl.firstChild, 'properties[1]' );
michael@0 1585 assert_equals( item2, parEl.childNodes[2], 'properties.item(2)' );
michael@0 1586 assert_equals( square2, parEl.childNodes[2], 'properties[2]' );
michael@0 1587 assert_equals( item3, parEl.childNodes[2].firstChild, 'properties.item(3)' );
michael@0 1588 assert_equals( square3, parEl.childNodes[2].firstChild, 'properties[3]' );
michael@0 1589 }, 'properties.item and length must see items added with itemref when attached to the document\'s DOM');
michael@0 1590 test(function () {
michael@0 1591 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>');
michael@0 1592 var testEl = parEl.childNodes[1];
michael@0 1593 assert_equals( testEl.properties.length, 4, 'length' );
michael@0 1594 assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0)' );
michael@0 1595 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0]' );
michael@0 1596 assert_equals( testEl.properties.item(1), testEl.firstChild, 'properties.item(1)' );
michael@0 1597 assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1]' );
michael@0 1598 assert_equals( testEl.properties.item(2), parEl.childNodes[2], 'properties.item(2)' );
michael@0 1599 assert_equals( testEl.properties[2], parEl.childNodes[2], 'properties[2]' );
michael@0 1600 assert_equals( testEl.properties.item(3), parEl.childNodes[2].firstChild, 'properties.item(3)' );
michael@0 1601 assert_equals( testEl.properties[3], parEl.childNodes[2].firstChild, 'properties[3]' );
michael@0 1602 }, 'properties.item and length must see items added with itemref');
michael@0 1603 test(function () {
michael@0 1604 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>');
michael@0 1605 var testEl = parEl.childNodes[0];
michael@0 1606 assert_equals( testEl.properties.length, 2, 'length' );
michael@0 1607 assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0)' );
michael@0 1608 assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1)' );
michael@0 1609 document.body.appendChild(parEl)
michael@0 1610 var length = testEl.properties.length;
michael@0 1611 var item0 = testEl.properties.item(0);
michael@0 1612 var item1 = testEl.properties.item(0);
michael@0 1613 document.body.removeChild(parEl)
michael@0 1614 assert_equals( testEl.properties.length, 2, 'length (attached to document)' );
michael@0 1615 assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0) (attached to document)' );
michael@0 1616 assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1) (attached to document)' );
michael@0 1617 }, 'itemref must reference the first element with a given ID');
michael@0 1618 test(function () {
michael@0 1619 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>');
michael@0 1620 var testEl = parEl.childNodes[0];
michael@0 1621 assert_equals( testEl.properties.length, 2, 'length' );
michael@0 1622 assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0)' );
michael@0 1623 assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1)' );
michael@0 1624 document.body.appendChild(parEl)
michael@0 1625 var length = testEl.properties.length;
michael@0 1626 var item0 = testEl.properties.item(0);
michael@0 1627 var item1 = testEl.properties.item(0);
michael@0 1628 document.body.removeChild(parEl)
michael@0 1629 assert_equals( testEl.properties.length, 2, 'length (attached to document)' );
michael@0 1630 assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0) (attached to document)' );
michael@0 1631 assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1) (attached to document)' );
michael@0 1632 }, 'itemref must ignore duplicated IDs');
michael@0 1633 test(function () {
michael@0 1634 var parEl = makeEl('div',{},'<div itemscope itemref="id0 id1"></div><div itemprop="foo" id="id1"><div itemprop="bar"></div></div>');
michael@0 1635 var testEl = parEl.childNodes[0];
michael@0 1636 assert_equals( testEl.properties.length, 2, 'length' );
michael@0 1637 assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0)' );
michael@0 1638 assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1)' );
michael@0 1639 document.body.appendChild(parEl)
michael@0 1640 var length = testEl.properties.length;
michael@0 1641 var item0 = testEl.properties.item(0);
michael@0 1642 var item1 = testEl.properties.item(0);
michael@0 1643 document.body.removeChild(parEl)
michael@0 1644 assert_equals( testEl.properties.length, 2, 'length (attached to document)' );
michael@0 1645 assert_equals( testEl.properties.item(0), parEl.childNodes[1], 'properties.item(0) (attached to document)' );
michael@0 1646 assert_equals( testEl.properties.item(1), parEl.childNodes[1].firstChild, 'properties.item(1) (attached to document)' );
michael@0 1647 }, 'itemref must ignore non-existent IDs');
michael@0 1648 test(function () {
michael@0 1649 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'});
michael@0 1650 var dummyEl = makeEl('div',{id:'id1',itemprop:'foo'});
michael@0 1651 assert_equals( testEl.properties.length, 0 );
michael@0 1652 }, 'itemref in a dislocated tree must not reference elements from another dislocated tree');
michael@0 1653 test(function () {
michael@0 1654 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'});
michael@0 1655 var dummyEl = makeEl('div',{id:'id1',itemprop:'foo'});
michael@0 1656 document.body.appendChild(dummyEl);
michael@0 1657 var tmp = testEl.properties.length;
michael@0 1658 document.body.removeChild(dummyEl);
michael@0 1659 assert_equals( tmp, 0 );
michael@0 1660 }, 'itemref in a dislocated tree must not reference elements from the main document');
michael@0 1661 test(function () {
michael@0 1662 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'});
michael@0 1663 var dummyEl = makeEl('div',{id:'id1',itemprop:'foo'});
michael@0 1664 document.body.appendChild(testEl);
michael@0 1665 var tmp = testEl.properties.length;
michael@0 1666 document.body.removeChild(testEl);
michael@0 1667 assert_equals( tmp, 0 );
michael@0 1668 }, 'itemref in the main document must not reference elements from a dislocated tree');
michael@0 1669 test(function () {
michael@0 1670 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 1671 assert_equals( testEl.properties.length, 1, 'length (before test)' );
michael@0 1672 assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) (before test)' );
michael@0 1673 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (before test)' );
michael@0 1674 testEl.appendChild(makeEl('div',{itemprop:'bar'}));
michael@0 1675 assert_equals( testEl.properties.length, 2, 'length after adding a child' );
michael@0 1676 assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) after adding a child' );
michael@0 1677 assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] after adding a child' );
michael@0 1678 testEl.lastChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 1679 assert_equals( testEl.properties.length, 3, 'length after adding a child with duplicated name' );
michael@0 1680 assert_equals( testEl.properties.item(2), testEl.childNodes[1].firstChild, 'properties.item(2) after adding a child with duplicated name' );
michael@0 1681 assert_equals( testEl.properties[2], testEl.childNodes[1].firstChild, 'properties[2] after adding a child with duplicated name' );
michael@0 1682 testEl.lastChild.removeChild(testEl.lastChild.firstChild);
michael@0 1683 assert_equals( testEl.properties.length, 2, 'length after removing a child' );
michael@0 1684 assert_true( !testEl.properties.item(2), 'properties.item(1) after removing a child' );
michael@0 1685 assert_true( !testEl.properties[2], 'properties[1] after removing a child' );
michael@0 1686 }, 'properties.item and length must update when adding property elements');
michael@0 1687 test(function () {
michael@0 1688 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div>');
michael@0 1689 assert_equals( testEl.properties.length, 2, 'length (before test)' );
michael@0 1690 assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) (before test)' );
michael@0 1691 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (before test)' );
michael@0 1692 assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) (before test)' );
michael@0 1693 assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] (before test)' );
michael@0 1694 testEl.appendChild(testEl.firstChild);
michael@0 1695 assert_equals( testEl.properties.length, 2, 'length (after test)' );
michael@0 1696 assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) (after test)' );
michael@0 1697 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (after test)' );
michael@0 1698 assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) (after test)' );
michael@0 1699 assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] (after test)' );
michael@0 1700 }, 'properties.item must update when re-ordering property elements, but length must not');
michael@0 1701 test(function () {
michael@0 1702 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div></div>');
michael@0 1703 assert_equals( testEl.properties.length, 1, 'length (before test)' );
michael@0 1704 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] (before test)' );
michael@0 1705 testEl.lastChild.itemProp.toggle('bar');
michael@0 1706 assert_equals( testEl.properties.length, 2, 'length (after test 1)' );
michael@0 1707 assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) after adding a token' );
michael@0 1708 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] after adding a token' );
michael@0 1709 assert_equals( testEl.properties.item(1), testEl.childNodes[1], 'properties.item(1) after adding a token' );
michael@0 1710 assert_equals( testEl.properties[1], testEl.childNodes[1], 'properties[1] after adding a token' );
michael@0 1711 testEl.lastChild.removeAttribute('itemprop');
michael@0 1712 assert_equals( testEl.properties.length, 1, 'length after removing an attribute' );
michael@0 1713 assert_equals( testEl.properties.item(0), testEl.firstChild, 'properties.item(0) after removing an attribute' );
michael@0 1714 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] after removing an attribute' );
michael@0 1715 assert_true( !testEl.properties.item(1), 'properties.item(1) after removing an attribute' );
michael@0 1716 assert_true( !testEl.properties[1], 'properties[1] after removing an attribute' );
michael@0 1717 }, 'properties.item and length must update when changing itemProp of children');
michael@0 1718 test(function () {
michael@0 1719 var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div>');
michael@0 1720 var testEl = parEl.childNodes[1];
michael@0 1721 assert_equals( testEl.properties.length, 0, 'length (before test)' );
michael@0 1722 parEl.firstChild.id = 'id1';
michael@0 1723 assert_equals( testEl.properties.length, 2, 'length after id is created' );
michael@0 1724 assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0) after id is created' );
michael@0 1725 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after id is created' );
michael@0 1726 assert_equals( testEl.properties.item(1), parEl.firstChild.firstChild, 'properties.item(1) after id is created' );
michael@0 1727 assert_equals( testEl.properties[1], parEl.firstChild.firstChild, 'properties[1] after id is created' );
michael@0 1728 parEl.firstChild.removeAttribute('id');
michael@0 1729 assert_equals( testEl.properties.length, 0, 'length after removing an attribute' );
michael@0 1730 assert_true( !testEl.properties.item(0), 'properties.item(0) after removing an attribute' );
michael@0 1731 assert_true( !testEl.properties[0], 'properties[0] after removing an attribute' );
michael@0 1732 document.body.appendChild(parEl);
michael@0 1733 var beflength = testEl.properties.length;
michael@0 1734 parEl.firstChild.id = 'id1';
michael@0 1735 var length1 = testEl.properties.length,
michael@0 1736 item0 = testEl.properties.item(0),
michael@0 1737 prop0 = testEl.properties[0],
michael@0 1738 item1 = testEl.properties.item(1),
michael@0 1739 prop1 = testEl.properties[1];
michael@0 1740 parEl.firstChild.removeAttribute('id');
michael@0 1741 var length2 = testEl.properties.length,
michael@0 1742 bitem = !testEl.properties.item(0),
michael@0 1743 bprop = !testEl.properties[0];
michael@0 1744 document.body.removeChild(parEl);
michael@0 1745 assert_equals( beflength, 0, 'length (before test) when appended to document' );
michael@0 1746 assert_equals( length1, 2, 'length after id is created when appended to document' );
michael@0 1747 assert_equals( item0, parEl.firstChild, 'properties.item(0) after id is created when appended to document' );
michael@0 1748 assert_equals( prop0, parEl.firstChild, 'properties[0] after id is created when appended to document' );
michael@0 1749 assert_equals( item1, parEl.firstChild.firstChild, 'properties.item(1) after id is created when appended to document' );
michael@0 1750 assert_equals( prop1, parEl.firstChild.firstChild, 'properties[1] after id is created when appended to document' );
michael@0 1751 assert_equals( length2, 0, 'length after removing an attribute when appended to document' );
michael@0 1752 assert_true( bitem, 'properties.item(0) after removing an attribute when appended to document' );
michael@0 1753 assert_true( bprop, 'properties[0] after removing an attribute when appended to document' );
michael@0 1754 }, 'properties.item and length must update when changing id of referenced sibling');
michael@0 1755 test(function () {
michael@0 1756 var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div><div itemprop="baz" id="id1"></div>');
michael@0 1757 var testEl = parEl.childNodes[1];
michael@0 1758 assert_equals( testEl.properties.length, 1, 'length (before test)' );
michael@0 1759 assert_equals( testEl.properties.item(0), parEl.lastChild, 'properties.item(0) (before test)' );
michael@0 1760 assert_equals( testEl.properties[0], parEl.lastChild, 'properties[0] (before test)' );
michael@0 1761 parEl.firstChild.id = 'id1';
michael@0 1762 assert_equals( testEl.properties.length, 2, 'length after id is created' );
michael@0 1763 assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0) after id is created' );
michael@0 1764 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after id is created' );
michael@0 1765 assert_equals( testEl.properties.item(1), parEl.firstChild.firstChild, 'properties.item(1) after id is created' );
michael@0 1766 assert_equals( testEl.properties[1], parEl.firstChild.firstChild, 'properties[1] after id is created' );
michael@0 1767 parEl.firstChild.removeAttribute('id');
michael@0 1768 assert_equals( testEl.properties.length, 1, 'length after removing an attribute' );
michael@0 1769 assert_equals( testEl.properties.item(0), parEl.lastChild, 'properties.item(0) after removing an attribute' );
michael@0 1770 assert_equals( testEl.properties[0], parEl.lastChild, 'properties[0] after removing an attribute' );
michael@0 1771 document.body.appendChild(parEl);
michael@0 1772 var beflength = testEl.properties.length,
michael@0 1773 befitem = testEl.properties.item(0),
michael@0 1774 befprop = testEl.properties[0];
michael@0 1775 parEl.firstChild.id = 'id1';
michael@0 1776 var length1 = testEl.properties.length,
michael@0 1777 item0 = testEl.properties.item(0),
michael@0 1778 prop0 = testEl.properties[0],
michael@0 1779 item1 = testEl.properties.item(1),
michael@0 1780 prop1 = testEl.properties[1];
michael@0 1781 parEl.firstChild.removeAttribute('id');
michael@0 1782 var length2 = testEl.properties.length,
michael@0 1783 afitem = testEl.properties.item(0),
michael@0 1784 afprop = testEl.properties[0];
michael@0 1785 document.body.removeChild(parEl);
michael@0 1786 assert_equals( beflength, 1, 'length (before test) when appended to document' );
michael@0 1787 assert_equals( befitem, parEl.lastChild, 'properties.item(0) (before test)' );
michael@0 1788 assert_equals( befprop, parEl.lastChild, 'properties[0] (before test)' );
michael@0 1789 assert_equals( length1, 2, 'length after id is created when appended to document' );
michael@0 1790 assert_equals( item0, parEl.firstChild, 'properties.item(0) after id is created when appended to document' );
michael@0 1791 assert_equals( prop0, parEl.firstChild, 'properties[0] after id is created when appended to document' );
michael@0 1792 assert_equals( item1, parEl.firstChild.firstChild, 'properties.item(1) after id is created when appended to document' );
michael@0 1793 assert_equals( prop1, parEl.firstChild.firstChild, 'properties[1] after id is created when appended to document' );
michael@0 1794 assert_equals( length2, 1, 'length after removing an attribute when appended to document' );
michael@0 1795 assert_equals( afitem, parEl.lastChild, 'properties.item(0) after removing an attribute when appended to document' );
michael@0 1796 assert_equals( afprop, parEl.lastChild, 'properties[0] after removing an attribute when appended to document' );
michael@0 1797 }, 'properties.item and length must update when changing duplicated id of referenced sibling');
michael@0 1798 test(function () {
michael@0 1799 var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope></div>');
michael@0 1800 var testEl = parEl.childNodes[1];
michael@0 1801 assert_equals( testEl.properties.length, 0, 'length (before test)' );
michael@0 1802 testEl.itemRef.toggle('id1');
michael@0 1803 assert_equals( testEl.properties.length, 1, 'length after itemref is changed' );
michael@0 1804 assert_equals( testEl.properties.item(0), parEl.firstChild, 'properties.item(0) after itemref is changed' );
michael@0 1805 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after itemref is changed' );
michael@0 1806 testEl.removeAttribute('itemref');
michael@0 1807 assert_equals( testEl.properties.length, 0, 'length after itemref is removed' );
michael@0 1808 assert_true( !testEl.properties.item(0), 'properties.item(0) itemref is removed' );
michael@0 1809 assert_true( !testEl.properties[0], 'properties[0] itemref is removed' );
michael@0 1810 document.body.appendChild(parEl);
michael@0 1811 var beflength = testEl.properties.length;
michael@0 1812 testEl.itemRef.toggle('id1');
michael@0 1813 var length1 = testEl.properties.length,
michael@0 1814 item0 = testEl.properties.item(0),
michael@0 1815 prop0 = testEl.properties[0];
michael@0 1816 testEl.removeAttribute('itemref');
michael@0 1817 var length2 = testEl.properties.length,
michael@0 1818 bitem = !testEl.properties.item(0),
michael@0 1819 bprop = !testEl.properties[0];
michael@0 1820 document.body.removeChild(parEl);
michael@0 1821 assert_equals( beflength, 0, 'length (before test) when appended to document' );
michael@0 1822 assert_equals( length1, 1, 'length after itemref is changed when appended to document' );
michael@0 1823 assert_equals( item0, parEl.firstChild, 'properties.item(0) after itemref is changed when appended to document' );
michael@0 1824 assert_equals( prop0, parEl.firstChild, 'properties[0] after itemref is changed when appended to document' );
michael@0 1825 assert_equals( length2, 0, 'length after itemref is removed when appended to document' );
michael@0 1826 assert_true( bitem, 'properties.item(0) after itemref is removed when appended to document' );
michael@0 1827 assert_true( bprop, 'properties[0] after itemref is removed when appended to document' );
michael@0 1828 }, 'properties.item and length must update when changing itemref to point to an element');
michael@0 1829 test(function () {
michael@0 1830 var parEl = makeEl('div',{},'<div id="id1"><div></div></div><div itemscope itemref="id1"></div>');
michael@0 1831 var testEl = parEl.childNodes[1];
michael@0 1832 assert_equals( testEl.properties.length, 0, 'length (before test)' );
michael@0 1833 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 1834 assert_equals( testEl.properties.length, 1, 'length after a referenced element is added' );
michael@0 1835 assert_equals( testEl.properties.item(0), parEl.firstChild.lastChild, 'properties.item(0) after a referenced element is added' );
michael@0 1836 assert_equals( testEl.properties[0], parEl.firstChild.lastChild, 'properties[0] after a referenced element is added' );
michael@0 1837 parEl.firstChild.firstChild.itemProp.toggle('bar');
michael@0 1838 assert_equals( testEl.properties.length, 2, 'length after a referenced itemprop is changed' );
michael@0 1839 assert_equals( testEl.properties.item(0), parEl.firstChild.firstChild, 'properties.item(0) after a referenced itemprop is changed' );
michael@0 1840 assert_equals( testEl.properties[0], parEl.firstChild.firstChild, 'properties[0] after a referenced itemprop is changed' );
michael@0 1841 assert_equals( testEl.properties.item(1), parEl.firstChild.lastChild, 'properties.item(1) after a referenced itemprop is changed' );
michael@0 1842 assert_equals( testEl.properties[1], parEl.firstChild.lastChild, 'properties[1] after a referenced itemprop is changed' );
michael@0 1843 parEl.firstChild.removeChild(parEl.firstChild.firstChild);
michael@0 1844 assert_equals( testEl.properties.length, 1, 'length after a referenced element is removed' );
michael@0 1845 assert_equals( testEl.properties.item(0), parEl.firstChild.firstChild, 'properties.item(0) after a referenced element is removed' );
michael@0 1846 assert_equals( testEl.properties[0], parEl.firstChild.firstChild, 'properties[0] after a referenced element is removed' );
michael@0 1847 assert_true( !testEl.properties.item(1), 'properties.item(1) after a referenced element is removed' );
michael@0 1848 assert_true( !testEl.properties[1], 'properties[1] after a referenced element is removed' );
michael@0 1849 parEl.innerHTML = '<div id="id1"><div></div></div><div itemscope itemref="id1"></div>';
michael@0 1850 testEl = parEl.childNodes[1];
michael@0 1851 document.body.appendChild(parEl);
michael@0 1852 var beflength = testEl.properties.length;
michael@0 1853 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 1854 var length1 = testEl.properties.length,
michael@0 1855 item0a = testEl.properties.item(0),
michael@0 1856 prop0a = testEl.properties[0],
michael@0 1857 targ0a = parEl.firstChild.lastChild;
michael@0 1858 parEl.firstChild.firstChild.itemProp.toggle('bar');
michael@0 1859 var length2 = testEl.properties.length,
michael@0 1860 item0b = testEl.properties.item(0),
michael@0 1861 prop0b = testEl.properties[0];
michael@0 1862 item1b = testEl.properties.item(1),
michael@0 1863 prop1b = testEl.properties[1],
michael@0 1864 targ0b = parEl.firstChild.firstChild,
michael@0 1865 targ1b = parEl.firstChild.lastChild;
michael@0 1866 parEl.firstChild.removeChild(parEl.firstChild.firstChild);
michael@0 1867 var length3 = testEl.properties.length,
michael@0 1868 item0c = testEl.properties.item(0),
michael@0 1869 prop0c = testEl.properties[0];
michael@0 1870 item1c = testEl.properties.item(1),
michael@0 1871 prop1c = testEl.properties[1],
michael@0 1872 targ0c = parEl.firstChild.firstChild;
michael@0 1873 document.body.removeChild(parEl);
michael@0 1874 assert_equals( beflength, 0, 'length (before test) when appended to document' );
michael@0 1875 assert_equals( length1, 1, 'length after a referenced element is added when appended to document' );
michael@0 1876 assert_equals( item0a, targ0a, 'properties.item(0) after a referenced element is added when appended to document' );
michael@0 1877 assert_equals( prop0a, targ0a, 'properties[0] after a referenced element is added when appended to document' );
michael@0 1878 assert_equals( length2, 2, 'length after a referenced itemprop is changed when appended to document' );
michael@0 1879 assert_equals( item0b, targ0b, 'properties.item(0) after a referenced itemprop is changed when appended to document' );
michael@0 1880 assert_equals( prop0b, targ0b, 'properties[0] after a referenced itemprop is changed when appended to document' );
michael@0 1881 assert_equals( item1b, targ1b, 'properties.item(1) after a referenced itemprop is changed when appended to document' );
michael@0 1882 assert_equals( prop1b, targ1b, 'properties[1] after a referenced itemprop is changed when appended to document' );
michael@0 1883 assert_equals( length3, 1, 'length after a referenced element is removed when appended to document' );
michael@0 1884 assert_equals( item0c, targ0c, 'properties.item(0) after a referenced element is removed when appended to document' );
michael@0 1885 assert_equals( prop0c, targ0c, 'properties[0] after a referenced element is removed when appended to document' );
michael@0 1886 assert_true( !item1c, 'properties.item(1) after a referenced element is removed when appended to document' );
michael@0 1887 assert_true( !prop1c, 'properties[1] after a referenced element is removed when appended to document' );
michael@0 1888 }, 'properties.item and length must update when changing children of elements referenced through itemref');
michael@0 1889 test(function () {
michael@0 1890 var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope itemref="id1"><div itemprop="foo"></div></div>');
michael@0 1891 var testEl = parEl.childNodes[1];
michael@0 1892 assert_equals( testEl.properties.length, 2, 'length (before test)' );
michael@0 1893 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] (before test)' );
michael@0 1894 assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1] (before test)' );
michael@0 1895 document.body.appendChild(testEl);
michael@0 1896 var step1length = testEl.properties.length;
michael@0 1897 var step1prop0 = testEl.properties[0];
michael@0 1898 var step1prop1 = testEl.properties[1];
michael@0 1899 parEl.appendChild(testEl);
michael@0 1900 assert_equals( step1length, 1, 'length after changing parent' );
michael@0 1901 assert_equals( step1prop0, testEl.firstChild, 'properties[0] after changing parent' );
michael@0 1902 assert_true( !step1prop1, 'properties[1] after changing parent' );
michael@0 1903 assert_equals( testEl.properties.length, 2, 'length after re-parenting' );
michael@0 1904 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] after re-parenting' );
michael@0 1905 assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1] after re-parenting' );
michael@0 1906 document.body.appendChild(parEl);
michael@0 1907 var step2length = testEl.properties.length;
michael@0 1908 var step2prop0 = testEl.properties[0];
michael@0 1909 var step2prop1 = testEl.properties[1];
michael@0 1910 document.createElement('div').appendChild(testEl);
michael@0 1911 var step3length = testEl.properties.length;
michael@0 1912 var step3prop0 = testEl.properties[0];
michael@0 1913 var step3prop1 = testEl.properties[1];
michael@0 1914 parEl.appendChild(testEl);
michael@0 1915 var step4length = testEl.properties.length;
michael@0 1916 var step4prop0 = testEl.properties[0];
michael@0 1917 var step4prop1 = testEl.properties[1];
michael@0 1918 document.body.removeChild(parEl);
michael@0 1919 assert_equals( step2length, 2, 'length (before test) when appended to document' );
michael@0 1920 assert_equals( step2prop0, parEl.firstChild, 'properties[0] (before test) when appended to document' );
michael@0 1921 assert_equals( step2prop1, testEl.firstChild, 'properties[1] (before test) when appended to document' );
michael@0 1922 assert_equals( step3length, 1, 'length after changing parent when appended to document' );
michael@0 1923 assert_equals( step3prop0, testEl.firstChild, 'properties[0] after changing parent when appended to document' );
michael@0 1924 assert_true( !step3prop1, 'properties[1] after changing parent when appended to document' );
michael@0 1925 assert_equals( step4length, 2, 'length after re-parenting when appended to document' );
michael@0 1926 assert_equals( step4prop0, parEl.firstChild, 'properties[0] after re-parenting when appended to document' );
michael@0 1927 assert_equals( step4prop1, testEl.firstChild, 'properties[1] after re-parenting when appended to document' );
michael@0 1928 }, 'properties.item and length must update when appending elements with itemref to different parents');
michael@0 1929 test(function () {
michael@0 1930 var testEl = makeEl('div',{itemscope:'itemscope'},'<div><div itemprop="foo"></div></div>');
michael@0 1931 assert_equals( testEl.properties.length, 1, 'length (before test)' );
michael@0 1932 assert_equals( testEl.properties.item(0), testEl.firstChild.firstChild, 'properties.item(0) (before test)' );
michael@0 1933 assert_equals( testEl.properties[0], testEl.firstChild.firstChild, 'properties[0] (before test)' );
michael@0 1934 testEl.firstChild.itemScope = true;
michael@0 1935 assert_equals( testEl.properties.length, 0, 'length after setting itemscope' );
michael@0 1936 assert_true( !testEl.properties.item(0), 'properties.item(0) after setting itemscope' );
michael@0 1937 assert_true( !testEl.properties[0], 'properties[0] after setting itemscope' );
michael@0 1938 testEl.firstChild.removeAttribute('itemscope');
michael@0 1939 assert_equals( testEl.properties.length, 1, 'length after removing itemscope attribute' );
michael@0 1940 assert_equals( testEl.properties.item(0), testEl.firstChild.firstChild, 'properties.item(0) after removing itemscope attribute' );
michael@0 1941 assert_equals( testEl.properties[0], testEl.firstChild.firstChild, 'properties[0] after removing itemscope attribute' );
michael@0 1942 }, 'properties.item and length must update when changing itemscope of children');
michael@0 1943 //properties.namedItem
michael@0 1944 test(function () {
michael@0 1945 assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties.namedItem('foo'), 'object' );
michael@0 1946 }, 'the namedItem must return an object');
michael@0 1947 test(function () {
michael@0 1948 assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties['foo'], 'object' );
michael@0 1949 }, '.properties[] must also act as .properties.namedItem() when there are matching properties');
michael@0 1950 test(function () {
michael@0 1951 assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'').properties.namedItem('foo'), 'object' );
michael@0 1952 }, 'the namedItem must return an object even if there are no matching properties');
michael@0 1953 test(function () {
michael@0 1954 assert_equals( typeof makeEl('div',{itemscope:'itemscope'},'').properties['foo'], 'undefined' );
michael@0 1955 }, '.properties[] must return undefined when no property exists with the given name');
michael@0 1956 test(function () {
michael@0 1957 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 1958 var PNL = testEl.properties.namedItem('foo');
michael@0 1959 assert_equals( PNL, testEl.properties.namedItem('foo'), 'before modification' );
michael@0 1960 testEl.innerHTML = '';
michael@0 1961 assert_equals( PNL, testEl.properties.namedItem('foo'), 'after modification' );
michael@0 1962 }, 'namedItem must return the same object for the same property name');
michael@0 1963 test(function () {
michael@0 1964 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 1965 assert_false( testEl.properties.namedItem('foo') == testEl.properties.namedItem('bar') );
michael@0 1966 }, 'namedItem must return a different object for a different property name');
michael@0 1967 test(function () {
michael@0 1968 assert_false( makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties.namedItem('foo') == makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>').properties.namedItem('foo') );
michael@0 1969 }, 'namedItem must return a different object for different elements with the same property name');
michael@0 1970 test(function () {
michael@0 1971 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 1972 assert_equals( testEl.properties.namedItem('foo'), testEl.properties['foo'] );
michael@0 1973 }, 'namedItem() and properties[] must return the same object for the same property name');
michael@0 1974 test(function () {
michael@0 1975 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 1976 assert_true( testEl.properties.namedItem('foo') instanceof PropertyNodeList, 'instanceof PropertyNodeList' );
michael@0 1977 assert_true( testEl.properties.namedItem('foo') instanceof NodeList, 'instanceof NodeList' );
michael@0 1978 PropertyNodeList.prototype.customProperty = true;
michael@0 1979 NodeList.prototype.anotherCustomProperty = true;
michael@0 1980 assert_true( testEl.properties.namedItem('foo').customProperty, 'inheritance from PropertyNodeList' );
michael@0 1981 assert_true( testEl.properties.namedItem('foo').anotherCustomProperty, 'inheritance from NodeList' );
michael@0 1982 PropertyNodeList.prototype.anotherCustomProperty = false;
michael@0 1983 assert_false( testEl.properties.anotherCustomProperty, 'shadowing by PropertyNodeList' );
michael@0 1984 }, 'the properties property must implement PropertyNodeList and NodeList');
michael@0 1985 test(function () {
michael@0 1986 var failed = false, elem = makeEl('div',{itemscope:'itemscope'});
michael@0 1987 try {
michael@0 1988 elem.properties.namedItem = 'pass';
michael@0 1989 } catch(e) {
michael@0 1990 failed = e;
michael@0 1991 }
michael@0 1992 assert_equals(elem.properties.namedItem,'pass');
michael@0 1993 assert_false(failed,'an error was thrown');
michael@0 1994 }, 'the namedItem property must be read/write');
michael@0 1995 test(function () {
michael@0 1996 //also tests for sort ordering, which is fairly simple in this case
michael@0 1997 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"><div itemprop="baz qux"></div></div><div itemprop="foo"></div>');
michael@0 1998 assert_equals( testEl.properties.namedItem('foo').length, 2, 'length of foo' );
michael@0 1999 assert_equals( testEl.properties.namedItem('bar').length, 1, 'length of bar' );
michael@0 2000 assert_equals( testEl.properties.namedItem('baz').length, 1, 'length of baz' );
michael@0 2001 assert_equals( testEl.properties.namedItem('qux').length, 1, 'length of qux' );
michael@0 2002 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'first foo' );
michael@0 2003 assert_equals( testEl.properties.namedItem('foo')[1], testEl.lastChild, 'last foo' );
michael@0 2004 assert_equals( testEl.properties.namedItem('bar')[0], testEl.childNodes[1], 'bar' );
michael@0 2005 assert_equals( testEl.properties.namedItem('baz')[0], testEl.childNodes[1].firstChild, 'baz' );
michael@0 2006 assert_equals( testEl.properties.namedItem('qux')[0], testEl.childNodes[1].firstChild, 'qux' );
michael@0 2007 }, 'PropertyNodeList must contain the correct properties');
michael@0 2008 test(function () {
michael@0 2009 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>');
michael@0 2010 assert_equals( testEl.properties.namedItem('foo').length, 2, 'length of foo' );
michael@0 2011 assert_equals( testEl.properties.namedItem('FOO').length, 2, 'length of FOO' );
michael@0 2012 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'first foo' );
michael@0 2013 assert_equals( testEl.properties.namedItem('foo')[1], testEl.childNodes[1].lastChild, 'last foo' );
michael@0 2014 assert_equals( testEl.properties.namedItem('FOO')[0], testEl.childNodes[1].firstChild, 'first FOO' );
michael@0 2015 assert_equals( testEl.properties.namedItem('FOO')[1], testEl.childNodes[1].lastChild, 'last FOO' );
michael@0 2016 }, 'PropertyNodeList must be case sensitive');
michael@0 2017 test(function () {
michael@0 2018 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo bar"></div>');
michael@0 2019 assert_equals( testEl.properties.namedItem('foo bar').length, 0, 'space' );
michael@0 2020 testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\tbar"></div>');
michael@0 2021 assert_equals( testEl.properties.namedItem('foo\tbar').length, 0, 'tab' );
michael@0 2022 testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\rbar"></div>');
michael@0 2023 assert_equals( testEl.properties.namedItem('foo\rbar').length, 0, 'carriage return' );
michael@0 2024 testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\nbar"></div>');
michael@0 2025 assert_equals( testEl.properties.namedItem('foo\nbar').length, 0, 'newline' );
michael@0 2026 testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo\fbar"></div>');
michael@0 2027 assert_equals( testEl.properties.namedItem('foo\fbar').length, 0, 'formfeed' );
michael@0 2028 }, 'namedItem must not match property names containing whitespace');
michael@0 2029 test(function () {
michael@0 2030 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="|§!&quot;#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_&lt;&gt;帿ŨÆ"></div>');
michael@0 2031 assert_equals( testEl.properties.namedItem('|§!"#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_<>帿ŨÆ').length, 1 );
michael@0 2032 }, 'namedItem must match property names containing other special characters');
michael@0 2033 test(function () {
michael@0 2034 var testEl = makeEl('div',{itemscope:'itemscope'});
michael@0 2035 var PNL = testEl.properties.namedItem('foo');
michael@0 2036 testEl.innerHTML = '<div itemprop="foo"></div>';
michael@0 2037 assert_equals( PNL.length, 1 );
michael@0 2038 assert_equals( PNL[0], testEl.firstChild );
michael@0 2039 }, 'PropertyNodeList must be live');
michael@0 2040 test(function () {
michael@0 2041 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemscope><div itemprop="foo"></div><div itemprop="bar"></div></div>');
michael@0 2042 assert_equals( testEl.properties.namedItem('foo').length, 1, 'length of foo' );
michael@0 2043 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'item 0' );
michael@0 2044 assert_equals( testEl.properties.namedItem('bar').length, 0, 'length of bar' );
michael@0 2045 }, 'PropertyNodeList must ignore properties of nested items');
michael@0 2046 test(function () {
michael@0 2047
michael@0 2048 //note, itemref ordering is reversed compared with the next test to catch failed sorting algorithms - not that that should make much difference here
michael@0 2049 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>');
michael@0 2050 var testEl = parEl.childNodes[1];
michael@0 2051 document.body.appendChild(parEl);
michael@0 2052 var fooLength = testEl.properties.namedItem('foo').length;
michael@0 2053 var barLength = testEl.properties.namedItem('bar').length;
michael@0 2054 var bazLength = testEl.properties.namedItem('baz').length;
michael@0 2055 var quxLength = testEl.properties.namedItem('qux').length;
michael@0 2056 var foo0 = testEl.properties.namedItem('foo')[0];
michael@0 2057 var foo1 = testEl.properties.namedItem('foo')[1];
michael@0 2058 var bar0 = testEl.properties.namedItem('bar')[0];
michael@0 2059 var baz0 = testEl.properties.namedItem('baz')[0];
michael@0 2060 var qux0 = testEl.properties.namedItem('qux')[0];
michael@0 2061 document.body.removeChild(parEl);
michael@0 2062 assert_equals( fooLength, 2, 'foo length' );
michael@0 2063 assert_equals( barLength, 1, 'bar length' );
michael@0 2064 assert_equals( bazLength, 1, 'baz length' );
michael@0 2065 assert_equals( quxLength, 1, 'qux length' );
michael@0 2066 assert_equals( foo0, parEl.firstChild, 'foo 0' );
michael@0 2067 assert_equals( foo1, testEl.firstChild, 'foo 1' );
michael@0 2068 assert_equals( bar0, testEl.firstChild, 'bar 0' );
michael@0 2069 assert_equals( baz0, parEl.lastChild, 'baz 0' );
michael@0 2070 assert_equals( qux0, parEl.lastChild.firstChild, 'qux 0' );
michael@0 2071 }, 'PropertyNodeList must see items added with itemref when attached to the document\'s DOM');
michael@0 2072 test(function () {
michael@0 2073 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>');
michael@0 2074 var testEl = parEl.childNodes[1];
michael@0 2075 assert_equals( testEl.properties.namedItem('foo').length, 2, 'foo length' );
michael@0 2076 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length' );
michael@0 2077 assert_equals( testEl.properties.namedItem('baz').length, 1, 'baz length' );
michael@0 2078 assert_equals( testEl.properties.namedItem('qux').length, 1, 'qux length' );
michael@0 2079 assert_equals( testEl.properties.namedItem('foo')[0], parEl.firstChild, 'foo 0' );
michael@0 2080 assert_equals( testEl.properties.namedItem('foo')[1], testEl.firstChild, 'foo 1' );
michael@0 2081 assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar 0' );
michael@0 2082 assert_equals( testEl.properties.namedItem('baz')[0], parEl.lastChild, 'baz 0' );
michael@0 2083 assert_equals( testEl.properties.namedItem('qux')[0], parEl.lastChild.firstChild, 'qux 0' );
michael@0 2084 }, 'PropertyNodeList must see items added with itemref');
michael@0 2085 test(function () {
michael@0 2086 //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
michael@0 2087 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 2088 var PNL = testEl.properties.namedItem('foo');
michael@0 2089 testEl.removeAttribute('itemscope');
michael@0 2090 assert_equals( testEl.properties.namedItem('foo').length, 0, 'removing attribute' );
michael@0 2091 assert_equals( PNL.length, 0, 'removing attribute (live)' );
michael@0 2092 assert_true( !testEl.properties['foo'], 'removing attribute []' );
michael@0 2093 testEl.itemScope = true;
michael@0 2094 assert_equals( testEl.properties.namedItem('foo').length, 1, 'setting itemScope' );
michael@0 2095 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'property 0 after setting itemScope' );
michael@0 2096 assert_equals( PNL.length, 1, 'setting itemScope (live)' );
michael@0 2097 assert_equals( PNL[0], testEl.firstChild, 'property 0 after setting itemScope (live)' );
michael@0 2098 assert_false( !testEl.properties['foo'], 'setting itemScope []' );
michael@0 2099 }, 'PropertyNodeList must update when adding itemscope on the root');
michael@0 2100 test(function () {
michael@0 2101 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 2102 assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo length (before test)' );
michael@0 2103 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'foo 0 (before test)' );
michael@0 2104 assert_equals( testEl.properties.namedItem('bar').length, 0, 'bar length (before test)' );
michael@0 2105 testEl.appendChild(makeEl('div',{itemprop:'bar'}));
michael@0 2106 assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo length after adding a child' );
michael@0 2107 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'foo 0 after adding a child' );
michael@0 2108 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length after adding a child' );
michael@0 2109 assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'bar 0 after adding a child' );
michael@0 2110 testEl.lastChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 2111 assert_equals( testEl.properties.namedItem('foo').length, 2, 'foo length after adding a child with duplicated name' );
michael@0 2112 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'foo 0 after adding a child with duplicated name' );
michael@0 2113 assert_equals( testEl.properties.namedItem('foo')[1], testEl.lastChild.firstChild, 'foo 1 after adding a child with duplicated name' );
michael@0 2114 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length after adding a child with duplicated name' );
michael@0 2115 assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'bar 0 after adding a child with duplicated name' );
michael@0 2116 testEl.lastChild.removeChild(testEl.lastChild.firstChild);
michael@0 2117 assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo length after removing a child' );
michael@0 2118 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar length after removing a child' );
michael@0 2119 }, 'PropertyNodeList must update when adding property elements');
michael@0 2120 test(function () {
michael@0 2121 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="foo"></div>');
michael@0 2122 var PNL = testEl.properties.namedItem('foo');
michael@0 2123 assert_equals( PNL[0], testEl.firstChild, 'item 0 (before test)' );
michael@0 2124 assert_equals( PNL[1], testEl.lastChild, 'item 1 (before test)' );
michael@0 2125 testEl.appendChild(testEl.firstChild);
michael@0 2126 assert_equals( PNL[0], testEl.firstChild, 'item 0 (after test)' );
michael@0 2127 assert_equals( PNL[1], testEl.lastChild, 'item 1 (after test)' );
michael@0 2128 }, 'PropertyNodeList must update when re-ordering property elements');
michael@0 2129 test(function () {
michael@0 2130 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div></div>');
michael@0 2131 var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar');
michael@0 2132 assert_equals( PNLfoo.length, 1, 'foo length (before test)' );
michael@0 2133 assert_equals( PNLbar.length, 0, 'bar length (before test)' );
michael@0 2134 assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] (before test)' );
michael@0 2135 testEl.lastChild.itemProp.toggle('bar');
michael@0 2136 assert_equals( PNLfoo.length, 1, 'foo length after adding a token' );
michael@0 2137 assert_equals( PNLbar.length, 1, 'bar length after adding a token' );
michael@0 2138 assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] after adding a token' );
michael@0 2139 assert_equals( PNLbar[0], testEl.lastChild, 'bar[0] after adding a token' );
michael@0 2140 testEl.lastChild.itemProp.add('foo');
michael@0 2141 assert_equals( PNLfoo.length, 2, 'foo length after adding a duplicated token' );
michael@0 2142 assert_equals( PNLbar.length, 1, 'bar length after adding a duplicated token' );
michael@0 2143 assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] after adding a duplicated token' );
michael@0 2144 assert_equals( PNLfoo[1], testEl.lastChild, 'foo[1] after adding a duplicated token' );
michael@0 2145 assert_equals( PNLbar[0], testEl.lastChild, 'bar[0] after adding a duplicated token' );
michael@0 2146 testEl.lastChild.removeAttribute('itemprop');
michael@0 2147 assert_equals( PNLfoo.length, 1, 'foo length after removing an attribute' );
michael@0 2148 assert_equals( PNLbar.length, 0, 'bar length after removing an attribute' );
michael@0 2149 assert_equals( PNLfoo[0], testEl.firstChild, 'foo[0] after removing an attribute' );
michael@0 2150 }, 'PropertyNodeList must update when changing itemProp of children');
michael@0 2151 test(function () {
michael@0 2152 var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div>');
michael@0 2153 var testEl = parEl.childNodes[1];
michael@0 2154 var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar');
michael@0 2155 assert_equals( PNLfoo.length, 0, 'foo length (before test)' );
michael@0 2156 assert_equals( PNLbar.length, 0, 'bar length (before test)' );
michael@0 2157 parEl.firstChild.id = 'id1';
michael@0 2158 assert_equals( PNLfoo.length, 1, 'foo length after id is created' );
michael@0 2159 assert_equals( PNLbar.length, 1, 'bar length after id is created' );
michael@0 2160 assert_equals( PNLfoo[0], parEl.firstChild, 'foo[0] after id is created' );
michael@0 2161 assert_equals( PNLbar[0], parEl.firstChild.firstChild, 'bar[0] after id is created' );
michael@0 2162 parEl.firstChild.removeAttribute('id');
michael@0 2163 assert_equals( PNLfoo.length, 0, 'foo length after removing an attribute' );
michael@0 2164 assert_equals( PNLbar.length, 0, 'bar length after removing an attribute' );
michael@0 2165 document.body.appendChild(parEl);
michael@0 2166 var fooLength0 = PNLfoo.length;
michael@0 2167 var barLength0 = PNLbar.length;
michael@0 2168 parEl.firstChild.id = 'id1';
michael@0 2169 var fooLength1 = PNLfoo.length;
michael@0 2170 var barLength1 = PNLbar.length;
michael@0 2171 var foo0 = PNLfoo[0];
michael@0 2172 var bar0 = PNLbar[0];
michael@0 2173 parEl.firstChild.removeAttribute('id');
michael@0 2174 var fooLength2 = PNLfoo.length;
michael@0 2175 var barLength2 = PNLbar.length;
michael@0 2176 document.body.removeChild(parEl);
michael@0 2177 assert_equals( fooLength0, 0, 'foo length (before test) when appended to document' );
michael@0 2178 assert_equals( barLength0, 0, 'bar length (before test) when appended to document' );
michael@0 2179 assert_equals( fooLength1, 1, 'foo length after id is created when appended to document' );
michael@0 2180 assert_equals( barLength1, 1, 'bar length after id is created when appended to document' );
michael@0 2181 assert_equals( foo0, parEl.firstChild, 'foo[0] after id is created when appended to document' );
michael@0 2182 assert_equals( bar0, parEl.firstChild.firstChild, 'bar[0] after id is created when appended to document' );
michael@0 2183 assert_equals( fooLength2, 0, 'foo length after removing an attribute when appended to document' );
michael@0 2184 assert_equals( barLength2, 0, 'bar length after removing an attribute when appended to document' );
michael@0 2185 }, 'PropertyNodeList must update when changing id of referenced sibling');
michael@0 2186 test(function () {
michael@0 2187 var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div><div itemprop="baz" id="id1"></div>');
michael@0 2188 var testEl = parEl.childNodes[1];
michael@0 2189 var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar'), PNLbaz = testEl.properties.namedItem('baz');
michael@0 2190 assert_equals( PNLfoo.length, 0, 'foo length (before test)' );
michael@0 2191 assert_equals( PNLbar.length, 0, 'bar length (before test)' );
michael@0 2192 assert_equals( PNLbaz.length, 1, 'baz length (before test)' );
michael@0 2193 assert_equals( PNLbaz[0], parEl.lastChild, 'baz[0] (before test)' );
michael@0 2194 parEl.firstChild.id = 'id1';
michael@0 2195 assert_equals( PNLfoo.length, 1, 'foo length after id is created' );
michael@0 2196 assert_equals( PNLbar.length, 1, 'bar length after id is created' );
michael@0 2197 assert_equals( PNLbaz.length, 0, 'baz length after id is created' );
michael@0 2198 assert_equals( PNLfoo[0], parEl.firstChild, 'foo[0] after id is created' );
michael@0 2199 assert_equals( PNLbar[0], parEl.firstChild.firstChild, 'bar[0] after id is created' );
michael@0 2200 parEl.firstChild.removeAttribute('id');
michael@0 2201 assert_equals( PNLfoo.length, 0, 'foo length after removing an attribute' );
michael@0 2202 assert_equals( PNLbar.length, 0, 'bar length after removing an attribute' );
michael@0 2203 assert_equals( PNLbaz.length, 1, 'baz length after removing an attribute' );
michael@0 2204 assert_equals( PNLbaz[0], parEl.lastChild, 'baz[0] after removing an attribute' );
michael@0 2205 document.body.appendChild(parEl);
michael@0 2206 var fooLength0 = PNLfoo.length;
michael@0 2207 var barLength0 = PNLbar.length;
michael@0 2208 var bazLength0 = PNLbaz.length;
michael@0 2209 var baz0 = PNLbaz[0];
michael@0 2210 parEl.firstChild.id = 'id1';
michael@0 2211 var fooLength1 = PNLfoo.length;
michael@0 2212 var barLength1 = PNLbar.length;
michael@0 2213 var bazLength1 = PNLbaz.length;
michael@0 2214 var foo0 = PNLfoo[0];
michael@0 2215 var bar0 = PNLbar[0];
michael@0 2216 parEl.firstChild.removeAttribute('id');
michael@0 2217 var fooLength2 = PNLfoo.length;
michael@0 2218 var barLength2 = PNLbar.length;
michael@0 2219 var bazLength2 = PNLbaz.length;
michael@0 2220 var baz1 = PNLbaz[0];
michael@0 2221 document.body.removeChild(parEl);
michael@0 2222 assert_equals( fooLength0, 0, 'foo length (before test) when appended to document' );
michael@0 2223 assert_equals( barLength0, 0, 'bar length (before test) when appended to document' );
michael@0 2224 assert_equals( bazLength0, 1, 'baz length (before test)' );
michael@0 2225 assert_equals( baz0, parEl.lastChild, 'baz[0] (before test)' );
michael@0 2226 assert_equals( fooLength1, 1, 'foo length after id is created when appended to document' );
michael@0 2227 assert_equals( barLength1, 1, 'bar length after id is created when appended to document' );
michael@0 2228 assert_equals( bazLength1, 0, 'baz length after id is created' );
michael@0 2229 assert_equals( foo0, parEl.firstChild, 'foo[0] after id is created when appended to document' );
michael@0 2230 assert_equals( bar0, parEl.firstChild.firstChild, 'bar[0] after id is created when appended to document' );
michael@0 2231 assert_equals( fooLength2, 0, 'foo length after removing an attribute when appended to document' );
michael@0 2232 assert_equals( barLength2, 0, 'bar length after removing an attribute when appended to document' );
michael@0 2233 assert_equals( bazLength2, 1, 'baz length after removing an attribute' );
michael@0 2234 assert_equals( baz0, parEl.lastChild, 'baz[0] after removing an attribute' );
michael@0 2235 }, 'PropertyNodeList must update when changing duplicated id of referenced sibling');
michael@0 2236 test(function () {
michael@0 2237 var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope></div>');
michael@0 2238 var testEl = parEl.childNodes[1];
michael@0 2239 var PNL = testEl.properties.namedItem('foo');
michael@0 2240 assert_equals( PNL.length, 0, 'length (before test)' );
michael@0 2241 testEl.itemRef.toggle('id1');
michael@0 2242 assert_equals( PNL.length, 1, 'length after itemref is changed' );
michael@0 2243 assert_equals( PNL[0], parEl.firstChild, 'item 0 after itemref is changed' );
michael@0 2244 testEl.removeAttribute('itemref');
michael@0 2245 assert_equals( PNL.length, 0, 'length after itemref is removed' );
michael@0 2246 assert_true( !PNL[0], 'item 0 after itemref is removed' );
michael@0 2247 document.body.appendChild(parEl);
michael@0 2248 var length0 = PNL.length;
michael@0 2249 testEl.itemRef.toggle('id1');
michael@0 2250 var length1 = PNL.length;
michael@0 2251 var foo0 = PNL[0];
michael@0 2252 testEl.removeAttribute('itemref');
michael@0 2253 var length2 = PNL.length;
michael@0 2254 var foo1 = PNL[0];
michael@0 2255 document.body.removeChild(parEl);
michael@0 2256 assert_equals( length0, 0, 'length (before test) when appended to document' );
michael@0 2257 assert_equals( length1, 1, 'length after itemref is changed when appended to document' );
michael@0 2258 assert_equals( foo0, parEl.firstChild, 'item 0 after itemref is changed when appended to document' );
michael@0 2259 assert_equals( length2, 0, 'length after itemref is removed when appended to document' );
michael@0 2260 assert_true( !foo1, 'item 0 after itemref is removed when appended to document' );
michael@0 2261 }, 'PropertyNodeList must update when changing itemref to point to an element');
michael@0 2262 test(function () {
michael@0 2263 var parEl = makeEl('div',{},'<div id="id1"><div></div></div><div itemscope itemref="id1"></div>');
michael@0 2264 var testEl = parEl.childNodes[1];
michael@0 2265 var PNLfoo = testEl.properties.namedItem('foo'), PNLbar = testEl.properties.namedItem('bar');
michael@0 2266 assert_equals( PNLfoo.length, 0, 'foo length (before test)' );
michael@0 2267 assert_equals( PNLbar.length, 0, 'bar length (before test)' );
michael@0 2268 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 2269 assert_equals( PNLfoo.length, 1, 'foo length after a referenced element is added' );
michael@0 2270 assert_equals( PNLbar.length, 0, 'bar length after a referenced element is added' );
michael@0 2271 assert_equals( PNLfoo.item(0), parEl.firstChild.lastChild, 'foo 0 after a referenced element is added' ); //uses item just for the fun of it
michael@0 2272 parEl.firstChild.firstChild.itemProp.toggle('bar');
michael@0 2273 assert_equals( PNLfoo.length, 1, 'foo length after a referenced itemprop is changed' );
michael@0 2274 assert_equals( PNLbar.length, 1, 'bar length after a referenced itemprop is changed' );
michael@0 2275 assert_equals( PNLfoo[0], parEl.firstChild.lastChild, 'foo 0 after a referenced element is added' );
michael@0 2276 assert_equals( PNLbar[0], parEl.firstChild.firstChild, 'bar 0 after a referenced element is added' );
michael@0 2277 parEl.firstChild.removeChild(parEl.firstChild.firstChild);
michael@0 2278 assert_equals( PNLfoo.length, 1, 'foo length after a referenced element is removed' );
michael@0 2279 assert_equals( PNLbar.length, 0, 'bar length after a referenced element is removed' );
michael@0 2280 assert_equals( PNLfoo[0], parEl.firstChild.firstChild, 'foo 0 after a referenced element is removed' );
michael@0 2281 assert_true( !PNLbar[0], 'bar 0 after a referenced element is removed' );
michael@0 2282 parEl.innerHTML = '<div id="id1"><div></div></div><div itemscope itemref="id1"></div>';
michael@0 2283 testEl = parEl.childNodes[1];
michael@0 2284 PNLfoo = testEl.properties.namedItem('foo');
michael@0 2285 PNLbar = testEl.properties.namedItem('bar');
michael@0 2286 document.body.appendChild(parEl);
michael@0 2287 var step1fooLength = PNLfoo.length;
michael@0 2288 var step1barLength = PNLbar.length;
michael@0 2289 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 2290 var step2fooLength = PNLfoo.length;
michael@0 2291 var step2barLength = PNLbar.length;
michael@0 2292 var step2foo0 = PNLfoo.item(0); //uses item just for the fun of it
michael@0 2293 var step2fooExpected = parEl.firstChild.lastChild;
michael@0 2294 parEl.firstChild.firstChild.itemProp.toggle('bar');
michael@0 2295 var step3fooLength = PNLfoo.length;
michael@0 2296 var step3barLength = PNLbar.length;
michael@0 2297 var step3foo0 = PNLfoo[0];
michael@0 2298 var step3bar0 = PNLbar[0];
michael@0 2299 var step3fooExpected = parEl.firstChild.lastChild;
michael@0 2300 var step3barExpected = parEl.firstChild.firstChild;
michael@0 2301 parEl.firstChild.removeChild(parEl.firstChild.firstChild);
michael@0 2302 var step4fooLength = PNLfoo.length;
michael@0 2303 var step4barLength = PNLbar.length;
michael@0 2304 var step4foo0 = PNLfoo[0];
michael@0 2305 var step4bar0 = PNLbar[0];
michael@0 2306 var step4fooExpected = parEl.firstChild.firstChild;
michael@0 2307 document.body.removeChild(parEl);
michael@0 2308 assert_equals( step1fooLength, 0, 'foo length (before test) when appended to document' );
michael@0 2309 assert_equals( step1barLength, 0, 'bar length (before test) when appended to document' );
michael@0 2310 assert_equals( step2fooLength, 1, 'foo length after a referenced element is added when appended to document' );
michael@0 2311 assert_equals( step2barLength, 0, 'bar length after a referenced element is added when appended to document' );
michael@0 2312 assert_equals( step2foo0, step2fooExpected, 'foo 0 after a referenced element is added when appended to document' );
michael@0 2313 assert_equals( step3fooLength, 1, 'foo length after a referenced itemprop is changed when appended to document' );
michael@0 2314 assert_equals( step3barLength, 1, 'bar length after a referenced itemprop is changed when appended to document' );
michael@0 2315 assert_equals( step3foo0, step3fooExpected, 'foo 0 after a referenced element is added when appended to document' );
michael@0 2316 assert_equals( step3bar0, step3barExpected, 'bar 0 after a referenced element is added when appended to document' );
michael@0 2317 assert_equals( step4fooLength, 1, 'foo length after a referenced element is removed when appended to document' );
michael@0 2318 assert_equals( step4barLength, 0, 'bar length after a referenced element is removed when appended to document' );
michael@0 2319 assert_equals( step4foo0, step4fooExpected, 'foo 0 after a referenced element is removed when appended to document' );
michael@0 2320 assert_true( !step4bar0, 'bar 0 after a referenced element is removed when appended to document' );
michael@0 2321 }, 'PropertyNodeList must update when changing children of elements referenced through itemref');
michael@0 2322 test(function () {
michael@0 2323 var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope itemref="id1"><div itemprop="foo"></div></div>');
michael@0 2324 var testEl = parEl.childNodes[1];
michael@0 2325 var PNL = testEl.properties.namedItem('foo');
michael@0 2326 assert_equals( PNL.length, 2, 'length (before test)' );
michael@0 2327 assert_equals( PNL[0], parEl.firstChild, 'item 0 (before test)' );
michael@0 2328 assert_equals( PNL[1], testEl.firstChild, 'item 1 (before test)' );
michael@0 2329 document.body.appendChild(testEl);
michael@0 2330 var step1length = PNL.length;
michael@0 2331 var step1prop0 = PNL[0];
michael@0 2332 var step1prop1 = PNL[1];
michael@0 2333 parEl.appendChild(testEl);
michael@0 2334 assert_equals( step1length, 1, 'length after changing parent' );
michael@0 2335 assert_equals( step1prop0, testEl.firstChild, 'item 0 after changing parent' );
michael@0 2336 assert_true( !step1prop1, 'item 1 after changing parent' );
michael@0 2337 assert_equals( PNL.length, 2, 'length after re-parenting' );
michael@0 2338 assert_equals( PNL[0], parEl.firstChild, 'item 0 after re-parenting' );
michael@0 2339 assert_equals( PNL[1], testEl.firstChild, 'item 1 after re-parenting' );
michael@0 2340 document.body.appendChild(parEl);
michael@0 2341 var step2length = PNL.length;
michael@0 2342 var step2prop0 = PNL[0];
michael@0 2343 var step2prop1 = PNL[1];
michael@0 2344 document.createElement('div').appendChild(testEl);
michael@0 2345 var step3length = PNL.length;
michael@0 2346 var step3prop0 = PNL[0];
michael@0 2347 var step3prop1 = PNL[1];
michael@0 2348 parEl.appendChild(testEl);
michael@0 2349 var step4length = PNL.length;
michael@0 2350 var step4prop0 = PNL[0];
michael@0 2351 var step4prop1 = PNL[1];
michael@0 2352 document.body.removeChild(parEl);
michael@0 2353 assert_equals( step2length, 2, 'length (before test) when appended to document' );
michael@0 2354 assert_equals( step2prop0, parEl.firstChild, 'item 0 (before test) when appended to document' );
michael@0 2355 assert_equals( step2prop1, testEl.firstChild, 'item 1 (before test) when appended to document' );
michael@0 2356 assert_equals( step3length, 1, 'length after changing parent when appended to document' );
michael@0 2357 assert_equals( step3prop0, testEl.firstChild, 'item 0 after changing parent when appended to document' );
michael@0 2358 assert_true( !step3prop1, 'item 1 after changing parent when appended to document' );
michael@0 2359 assert_equals( step4length, 2, 'length after re-parenting when appended to document' );
michael@0 2360 assert_equals( step4prop0, parEl.firstChild, 'item 0 after re-parenting when appended to document' );
michael@0 2361 assert_equals( step4prop1, testEl.firstChild, 'item 1 after re-parenting when appended to document' );
michael@0 2362 }, 'PropertyNodeList must update when appending elements with itemref to different parents');
michael@0 2363 test(function () {
michael@0 2364 var testEl = makeEl('div',{itemscope:'itemscope'},'<div><div itemprop="foo"></div></div>');
michael@0 2365 var PNL = testEl.properties.namedItem('foo');
michael@0 2366 assert_equals( PNL.length, 1, 'length (before test)' );
michael@0 2367 assert_equals( PNL[0], testEl.firstChild.firstChild, 'foo 0 (before test)' );
michael@0 2368 testEl.firstChild.itemScope = true;
michael@0 2369 assert_equals( PNL.length, 0, 'length after setting itemscope' );
michael@0 2370 assert_true( !PNL[0], 'foo 0 after setting itemscope' );
michael@0 2371 testEl.firstChild.removeAttribute('itemscope');
michael@0 2372 assert_equals( PNL.length, 1, 'length after removing itemscope attribute' );
michael@0 2373 assert_equals( PNL[0], testEl.firstChild.firstChild, 'foo 0 after removing itemscope attribute' );
michael@0 2374 }, 'PropertyNodeList must update when changing itemscope of children');
michael@0 2375 //PropertyNodeList.getValues
michael@0 2376 test(function () {
michael@0 2377 var valuesArray = makeEl('div',{}).properties.namedItem('foo').getValues();
michael@0 2378 assert_true( valuesArray instanceof Array, 'instanceof test' );
michael@0 2379 Array.prototype.customProp = true;
michael@0 2380 assert_true( valuesArray.customProp, 'inheritance test' );
michael@0 2381 }, 'getValues must return an array');
michael@0 2382 test(function () {
michael@0 2383 var testEl = makeEl('div',{});
michael@0 2384 var props = testEl.properties.namedItem('foo');
michael@0 2385 assert_not_equals( props.getValues(), props.getValues() );
michael@0 2386 }, 'getValues must always return a newly constructed array');
michael@0 2387 test(function () {
michael@0 2388 var parEl = makeEl('div',{},'<div id="id1"></div>');
michael@0 2389 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1 id2'});
michael@0 2390 parEl.appendChild(testEl);
michael@0 2391 testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'}));
michael@0 2392 testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2393 testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2394 testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2395 testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2396 testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2397 testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2398 testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2399 testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text'));
michael@0 2400 testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2401 testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2402 testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text'));
michael@0 2403 parEl.appendChild(makeEl('time',{itemprop:'foo',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2404 testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2405 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2406 testEl.appendChild(makeEl('madeuponthespot',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2407 var PNL = testEl.properties.namedItem('foo');
michael@0 2408 var valuesArray = PNL.getValues();
michael@0 2409 for( var i = 0; i < PNL.length; i++ ) {
michael@0 2410 assert_equals( valuesArray[i], PNL[i].itemValue, 'property index ' + i + ', tag ' + PNL[i].tagName );
michael@0 2411 }
michael@0 2412 assert_equals( valuesArray.length, 20, 'length' );
michael@0 2413 }, 'getValues array must contain the same item values as itemValue would return for the given properties');
michael@0 2414 test(function () {
michael@0 2415 var parEl = makeEl('div',{},'<div id="id1"></div>');
michael@0 2416 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1 id2'});
michael@0 2417 parEl.appendChild(testEl);
michael@0 2418 testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'}));
michael@0 2419 testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2420 testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2421 testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2422 testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2423 testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2424 testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2425 testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2426 testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text'));
michael@0 2427 testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2428 testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2429 testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text'));
michael@0 2430 parEl.appendChild(makeEl('time',{itemprop:'foo',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2431 testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2432 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2433 testEl.appendChild(makeEl('madeuponthespot',{itemprop:'foo'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2434 var PNL = testEl.properties.namedItem('foo');
michael@0 2435 var valuesArray = PNL.getValues();
michael@0 2436 var staticArray = [];
michael@0 2437 for( var i = 0; i < PNL.length; i++ ) {
michael@0 2438 staticArray[i] = PNL[i].itemValue;
michael@0 2439 }
michael@0 2440 testEl.innerHTML = '';
michael@0 2441 parEl.firstChild.firstChild.childNodes[1].itemScope = false;
michael@0 2442 assert_equals( valuesArray.length, staticArray.length, 'length after modification' );
michael@0 2443 for( var j = 0; j < staticArray.length; j++ ) {
michael@0 2444 assert_equals( valuesArray[j], staticArray[j], 'property index ' + j );
michael@0 2445 }
michael@0 2446 assert_equals( valuesArray[1], parEl.firstChild.firstChild.childNodes[1], 'retaining pointer after modification' );
michael@0 2447 staticArray = null;
michael@0 2448 parEl.firstChild.firstChild.innerHTML = '';
michael@0 2449 assert_equals( valuesArray[1] && valuesArray[1].nodeType, 1, 'retaining pointer after removal' );
michael@0 2450 }, 'getValues array must not be live');
michael@0 2451 //names
michael@0 2452 test(function () {
michael@0 2453 assert_equals( typeof makeEl('div',{}).properties.names, 'object' );
michael@0 2454 }, 'the names property must be an object');
michael@0 2455 test(function () {
michael@0 2456 var testEl = makeEl('div',{});
michael@0 2457 assert_true( testEl.properties.names instanceof DOMStringList, 'instanceof DOMStringList' );
michael@0 2458 DOMStringList.prototype.stringCustomProperty = true;
michael@0 2459 assert_true( testEl.properties.names.stringCustomProperty, 'inheritance from DOMStringList' );
michael@0 2460 }, 'the names property must implement DOMStringList');
michael@0 2461 test(function () {
michael@0 2462 var failed = false, elem = makeEl('div',{itemscope:'itemscope'}), realList = elem.properties.names;
michael@0 2463 try {
michael@0 2464 elem.properties.names = '';
michael@0 2465 } catch(e) {
michael@0 2466 failed = e;
michael@0 2467 }
michael@0 2468 assert_equals(elem.properties.names,realList);
michael@0 2469 assert_false(failed,'an error was thrown');
michael@0 2470 }, 'the names property must be read-only');
michael@0 2471 test(function () {
michael@0 2472 var testEl = makeEl('div',{});
michael@0 2473 assert_equals( testEl.properties.names, testEl.properties.names );
michael@0 2474 }, 'the names property must always reference the same object');
michael@0 2475 test(function () {
michael@0 2476 var testEl = makeEl('div',{});
michael@0 2477 assert_equals( testEl.properties.names.item(0), null, 'item(0)' );
michael@0 2478 assert_equals( testEl.properties.names.item(-1), null, 'item(-1)' );
michael@0 2479 }, 'names.item() must return null for out of range indexes');
michael@0 2480 test(function () {
michael@0 2481 var testEl = makeEl('div',{});
michael@0 2482 assert_equals( testEl.properties.names[0], window.undefined, '[0]' );
michael@0 2483 assert_equals( testEl.properties.names[-1], window.undefined, '[-1]' );
michael@0 2484 }, 'names[index] must return undefined for out of range indexes');
michael@0 2485 test(function () {
michael@0 2486 var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>');
michael@0 2487 assert_equals( testEl.properties.names.length, 0, 'length' );
michael@0 2488 assert_true( !testEl.properties.names.item(0), 'item(0)' );
michael@0 2489 assert_true( !testEl.properties.names[0], '[0]' );
michael@0 2490 assert_false( testEl.properties.names.contains('foo'), 'contains' );
michael@0 2491 }, 'the names collection must be empty if the element does not have an itemscope property');
michael@0 2492 test(function () {
michael@0 2493 var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>');
michael@0 2494 testEl.itemScope = true;
michael@0 2495 assert_equals( testEl.properties.names.length, 1, 'length' );
michael@0 2496 assert_equals( testEl.properties.names.item(0), 'foo', 'item(0)' );
michael@0 2497 assert_equals( testEl.properties.names[0], 'foo', '[0]' );
michael@0 2498 assert_true( testEl.properties.names.contains('foo'), 'contains' );
michael@0 2499 }, 'the names collection must become populated if the element is given an itemscope property');
michael@0 2500 test(function () {
michael@0 2501 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo">bar</div>');
michael@0 2502 testEl.itemScope = false;
michael@0 2503 assert_equals( testEl.properties.names.length, 0, 'length' );
michael@0 2504 assert_true( !testEl.properties.names.item(0), 'item(0)' );
michael@0 2505 assert_true( !testEl.properties.names[0], '[0]' );
michael@0 2506 assert_false( testEl.properties.names.contains('foo'), 'contains' );
michael@0 2507 }, 'the names collection must become empty if the element\'s itemscope property is removed');
michael@0 2508 test(function () {
michael@0 2509 var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>');
michael@0 2510 testEl.properties.names.item = 'test';
michael@0 2511 testEl.properties.names.contains = 'test';
michael@0 2512 assert_equals( testEl.properties.names.item, 'test', 'item' );
michael@0 2513 assert_equals( testEl.properties.names.contains, 'test', 'contains' );
michael@0 2514 }, 'the names.item and names.contains methods should be overwriteable');
michael@0 2515 test(function () {
michael@0 2516 var testEl = makeEl('div',{},'<div itemprop="foo">bar</div>');
michael@0 2517 testEl.properties.names.localCustomProperty = 'test';
michael@0 2518 assert_equals( testEl.properties.names.localCustomProperty, 'test' );
michael@0 2519 }, 'the names.customProperty should be writeable');
michael@0 2520 test(function () {
michael@0 2521 //WebIDL and ECMAScript 5 - a readonly property has a getter but not a setter
michael@0 2522 //ES5 makes [[Put]] fail but not throw
michael@0 2523 var failed = false;
michael@0 2524 var elem = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo">bar</div>');
michael@0 2525 try {
michael@0 2526 elem.properties.names.length = 0;
michael@0 2527 } catch(e) {
michael@0 2528 failed = e;
michael@0 2529 }
michael@0 2530 assert_equals(elem.properties.names.length,1);
michael@0 2531 assert_false(failed,'an error was thrown');
michael@0 2532 }, 'names.length must be read-only');
michael@0 2533 test(function () {
michael@0 2534 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>');
michael@0 2535 assert_equals( testEl.properties.names.length, 4 );
michael@0 2536 }, 'names.length must be the total number of property names');
michael@0 2537 test(function () {
michael@0 2538 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>');
michael@0 2539 assert_equals( testEl.properties.names.item(0), 'foo', 'item(0)' );
michael@0 2540 assert_equals( testEl.properties.names.item(1), 'bar', 'item(1)' );
michael@0 2541 assert_equals( testEl.properties.names.item(2), 'baz', 'item(2)' );
michael@0 2542 assert_equals( testEl.properties.names.item(3), 'qux', 'item(3)' );
michael@0 2543 assert_equals( testEl.properties.names[0], 'foo', '[0]' );
michael@0 2544 assert_equals( testEl.properties.names[1], 'bar', '[1]' );
michael@0 2545 assert_equals( testEl.properties.names[2], 'baz', '[2]' );
michael@0 2546 assert_equals( testEl.properties.names[3], 'qux', '[3]' );
michael@0 2547 }, 'names.item must give each property name in tree order');
michael@0 2548 test(function () {
michael@0 2549 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>');
michael@0 2550 assert_equals( testEl.properties.names.length, 6, 'length' );
michael@0 2551 assert_equals( testEl.properties.names.item(0), 'foo', 'item(0)' );
michael@0 2552 assert_equals( testEl.properties.names.item(1), 'bar', 'item(1)' );
michael@0 2553 assert_equals( testEl.properties.names.item(2), 'BAR', 'item(2)' );
michael@0 2554 assert_equals( testEl.properties.names.item(3), 'FOO', 'item(3)' );
michael@0 2555 assert_equals( testEl.properties.names.item(4), 'baz', 'item(4)' );
michael@0 2556 assert_equals( testEl.properties.names.item(5), 'qux', 'item(5)' );
michael@0 2557 assert_equals( testEl.properties.names[0], 'foo', '[0]' );
michael@0 2558 assert_equals( testEl.properties.names[1], 'bar', '[1]' );
michael@0 2559 assert_equals( testEl.properties.names[2], 'BAR', '[2]' );
michael@0 2560 assert_equals( testEl.properties.names[3], 'FOO', '[3]' );
michael@0 2561 assert_equals( testEl.properties.names[4], 'baz', '[4]' );
michael@0 2562 assert_equals( testEl.properties.names[5], 'qux', '[5]' );
michael@0 2563 }, 'names must be case sensitive');
michael@0 2564 test(function () {
michael@0 2565 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>');
michael@0 2566 assert_true( testEl.properties.names.contains('foo'), 'foo' );
michael@0 2567 assert_true( testEl.properties.names.contains('FOO'), 'FOO' );
michael@0 2568 assert_true( testEl.properties.names.contains('bar'), 'bar' );
michael@0 2569 assert_false( testEl.properties.names.contains('BAR'), 'BAR' );
michael@0 2570 assert_true( testEl.properties.names.contains('baz'), 'baz' );
michael@0 2571 assert_true( testEl.properties.names.contains('qux'), 'qux' );
michael@0 2572 assert_false( testEl.properties.names.contains('madeup'), 'madeup' );
michael@0 2573 }, 'names.contains must return boolean if the name exists');
michael@0 2574 test(function () {
michael@0 2575 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="1"></div>');
michael@0 2576 assert_equals( testEl.properties.names.item('1'), null );
michael@0 2577 }, 'names.item must cast to number');
michael@0 2578 test(function () {
michael@0 2579 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="1"></div>');
michael@0 2580 assert_true( testEl.properties.names.contains({ valueOf: function () { return 2; }, toString: function () { return 'foo'; } }), 'object' );
michael@0 2581 assert_true( testEl.properties.names.contains(1), 'number' );
michael@0 2582 }, 'names.contains must cast to string');
michael@0 2583 test(function () {
michael@0 2584 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div>');
michael@0 2585 var namesList = testEl.properties.names;
michael@0 2586 testEl.innerHTML = '<div itemprop="baz"></div>';
michael@0 2587 assert_equals( testEl.properties.names.length, 1, 'length' );
michael@0 2588 assert_equals( testEl.properties.names[0], 'baz', '[0]' );
michael@0 2589 }, 'the names collection must be live');
michael@0 2590 test(function () {
michael@0 2591 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="|§!&quot;#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_&lt;&gt;帿ŨÆ"></div>');
michael@0 2592 assert_equals( testEl.properties.names[0], '|§!"#¤%&/()=?`\\@£${[]}´€^¨~\'*,;.:-_<>帿ŨÆ' );
michael@0 2593 }, 'names must reflect property names containing special characters');
michael@0 2594 test(function () {
michael@0 2595 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemscope><div itemprop="bar"></div></div>');
michael@0 2596 assert_equals( testEl.properties.names.length, 1, 'length' );
michael@0 2597 assert_equals( testEl.properties.names[0], 'foo', '[0]' );
michael@0 2598 assert_true( testEl.properties.names.contains('foo'), 'contains(foo)' );
michael@0 2599 assert_false( testEl.properties.names.contains('bar'), 'contains(bar)' );
michael@0 2600 }, 'names must ignore properties of nested items');
michael@0 2601 test(function () {
michael@0 2602 //note, itemref ordering is reversed compared with the next test to catch failed sorting algorithms
michael@0 2603 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>');
michael@0 2604 var testEl = parEl.childNodes[1];
michael@0 2605 document.body.appendChild(parEl);
michael@0 2606 var length = testEl.properties.names.length;
michael@0 2607 var names0 = testEl.properties.names[0];
michael@0 2608 var names1 = testEl.properties.names[1];
michael@0 2609 var names2 = testEl.properties.names[2];
michael@0 2610 var names3 = testEl.properties.names[3];
michael@0 2611 document.body.removeChild(parEl);
michael@0 2612 assert_equals( length, 4, 'length' );
michael@0 2613 assert_equals( names0, 'foo', 'names[0]' );
michael@0 2614 assert_equals( names1, 'bar', 'names[1]' );
michael@0 2615 assert_equals( names2, 'baz', 'names[2]' );
michael@0 2616 assert_equals( names3, 'qux', 'names[3]' );
michael@0 2617 }, 'names must see items added with itemref when attached to the document\'s DOM');
michael@0 2618 test(function () {
michael@0 2619 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>');
michael@0 2620 var testEl = parEl.childNodes[1];
michael@0 2621 assert_equals( testEl.properties.names.length, 4, 'length' );
michael@0 2622 assert_equals( testEl.properties.names[0], 'foo', 'names[0]' );
michael@0 2623 assert_equals( testEl.properties.names[1], 'bar', 'names[1]' );
michael@0 2624 assert_equals( testEl.properties.names[2], 'baz', 'names[2]' );
michael@0 2625 assert_equals( testEl.properties.names[3], 'qux', 'names[3]' );
michael@0 2626 }, 'names must see items added with itemref');
michael@0 2627 test(function () {
michael@0 2628 //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
michael@0 2629 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 2630 var DSL = testEl.properties.names;
michael@0 2631 testEl.removeAttribute('itemscope');
michael@0 2632 assert_equals( testEl.properties.names.length, 0, 'removing attribute' );
michael@0 2633 assert_equals( DSL.length, 0, 'removing attribute (live)' );
michael@0 2634 assert_true( !testEl.properties.names[0], 'removing attribute [0]' );
michael@0 2635 assert_true( !DSL[0], 'removing attribute [0] (live)' );
michael@0 2636 testEl.itemScope = true;
michael@0 2637 assert_equals( testEl.properties.names.length, 1, 'setting itemScope' );
michael@0 2638 assert_equals( DSL.length, 1, 'setting itemScope (live)' );
michael@0 2639 assert_equals( testEl.properties.names[0], 'foo', 'names[0] after setting itemScope' );
michael@0 2640 assert_equals( DSL[0], 'foo', 'names[0] after setting itemScope (live)' );
michael@0 2641 }, 'names must update when adding itemscope on the root');
michael@0 2642 test(function () {
michael@0 2643 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div>');
michael@0 2644 assert_equals( testEl.properties.names.length, 1, 'length (before test)' );
michael@0 2645 assert_equals( testEl.properties.names[0], 'foo', 'item 0 (before test)' );
michael@0 2646 testEl.appendChild(makeEl('div',{itemprop:'bar'}));
michael@0 2647 assert_equals( testEl.properties.names.length, 2, 'length after adding a child' );
michael@0 2648 assert_equals( testEl.properties.names[0], 'foo', 'item 0 after adding a child' );
michael@0 2649 assert_equals( testEl.properties.names[1], 'bar', 'item 1 after adding a child' );
michael@0 2650 testEl.lastChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 2651 assert_equals( testEl.properties.names.length, 2, 'foo length after adding a child with duplicated name' );
michael@0 2652 assert_equals( testEl.properties.names[0], 'foo', 'item 0 after adding a child with duplicated name' );
michael@0 2653 assert_equals( testEl.properties.names[1], 'bar', 'item 1 after adding a child with duplicated name' );
michael@0 2654 testEl.removeChild(testEl.lastChild);
michael@0 2655 assert_equals( testEl.properties.names.length, 1, 'length after removing a child' );
michael@0 2656 assert_equals( testEl.properties.names[0], 'foo', 'item 0 after removing a child' );
michael@0 2657 }, 'names must update when adding property elements');
michael@0 2658 test(function () {
michael@0 2659 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div>');
michael@0 2660 var DSL = testEl.properties.names;
michael@0 2661 assert_equals( DSL[0], 'foo', 'item 0 (before test)' );
michael@0 2662 assert_equals( DSL[1], 'bar', 'item 1 (before test)' );
michael@0 2663 testEl.appendChild(testEl.firstChild);
michael@0 2664 assert_equals( DSL[0], 'bar', 'item 0 (after test)' );
michael@0 2665 assert_equals( DSL[1], 'foo', 'item 1 (after test)' );
michael@0 2666 }, 'names must update when re-ordering property elements');
michael@0 2667 test(function () {
michael@0 2668 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div></div>');
michael@0 2669 var DSL = testEl.properties.names;
michael@0 2670 assert_equals( DSL.length, 1, 'length (before test)' );
michael@0 2671 assert_equals( DSL[0], 'foo', 'item 0 (before test)' );
michael@0 2672 testEl.lastChild.itemProp.toggle('bar');
michael@0 2673 assert_equals( DSL.length, 2, 'length after adding a token' );
michael@0 2674 assert_equals( DSL[0], 'foo', 'item 0 after adding a token' );
michael@0 2675 assert_equals( DSL[1], 'bar', 'item 1 after adding a token' );
michael@0 2676 testEl.lastChild.itemProp.add('foo');
michael@0 2677 assert_equals( DSL.length, 2, 'length after adding a duplicated token' );
michael@0 2678 assert_equals( DSL[0], 'foo', 'item 0 after adding a duplicated token' );
michael@0 2679 assert_equals( DSL[1], 'bar', 'item 1 after adding a duplicated token' );
michael@0 2680 testEl.lastChild.removeAttribute('itemprop');
michael@0 2681 assert_equals( DSL.length, 1, 'length after removing an attribute' );
michael@0 2682 assert_equals( DSL[0], 'foo', 'item 0 after removing an attribute' );
michael@0 2683 testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo"></div><div itemprop="bar"></div><div itemprop="foo"></div>');
michael@0 2684 DSL = testEl.properties.names;
michael@0 2685 assert_equals( DSL.length, 2, 'length (before second test)' );
michael@0 2686 assert_equals( DSL[0], 'foo', 'item 0 (before second test)' );
michael@0 2687 assert_equals( DSL[1], 'bar', 'item 1 (before second test)' );
michael@0 2688 testEl.firstChild.removeAttribute('itemprop');
michael@0 2689 assert_equals( DSL.length, 2, 'length after removing attribute of first item' );
michael@0 2690 assert_equals( DSL[0], 'bar', 'item 0 after removing attribute of first item' );
michael@0 2691 assert_equals( DSL[1], 'foo', 'item 1 after removing attribute of first item' );
michael@0 2692 testEl.firstChild.itemProp.add('foo');
michael@0 2693 assert_equals( DSL.length, 2, 'length after adding duplicated token to first item' );
michael@0 2694 assert_equals( DSL[0], 'foo', 'item 0 after adding duplicated token to first item' );
michael@0 2695 assert_equals( DSL[1], 'bar', 'item 1 after adding duplicated token to first item' );
michael@0 2696 testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="foo bar"></div>');
michael@0 2697 DSL = testEl.properties.names;
michael@0 2698 assert_equals( DSL.length, 2, 'length (before third test)' );
michael@0 2699 assert_equals( DSL[0], 'foo', 'item 0 (before third test)' );
michael@0 2700 assert_equals( DSL[1], 'bar', 'item 1 (before third test)' );
michael@0 2701 testEl.firstChild.itemProp.toggle('foo');
michael@0 2702 testEl.firstChild.itemProp.toggle('foo');
michael@0 2703 assert_equals( DSL.length, 2, 'length after swapping tokens' );
michael@0 2704 assert_equals( DSL[0], 'bar', 'item 0 after swapping tokens' );
michael@0 2705 assert_equals( DSL[1], 'foo', 'item 1 after swapping tokens' );
michael@0 2706 }, 'names must update when changing itemProp of children');
michael@0 2707 test(function () {
michael@0 2708 var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div>');
michael@0 2709 var testEl = parEl.childNodes[1];
michael@0 2710 var DSL = testEl.properties.names;
michael@0 2711 assert_equals( DSL.length, 0, 'length (before test)' );
michael@0 2712 parEl.firstChild.id = 'id1';
michael@0 2713 assert_equals( DSL.length, 2, 'length after id is created' );
michael@0 2714 assert_equals( DSL[0], 'foo', 'item 0 after id is created' );
michael@0 2715 assert_equals( DSL[1], 'bar', 'item 1 after id is created' );
michael@0 2716 parEl.firstChild.removeAttribute('id');
michael@0 2717 assert_equals( DSL.length, 0, 'length after removing an attribute' );
michael@0 2718 document.body.appendChild(parEl);
michael@0 2719 var step1length = DSL.length;
michael@0 2720 parEl.firstChild.id = 'id1';
michael@0 2721 var step2length = DSL.length;
michael@0 2722 var step2item0 = DSL[0];
michael@0 2723 var step2item1 = DSL[1];
michael@0 2724 parEl.firstChild.removeAttribute('id');
michael@0 2725 var step3length = DSL.length;
michael@0 2726 document.body.removeChild(parEl);
michael@0 2727 assert_equals( step1length, 0, 'length (before test) when appended to document' );
michael@0 2728 assert_equals( step2length, 2, 'length after id is created when appended to document' );
michael@0 2729 assert_equals( step2item0, 'foo', 'item 0 after id is created when appended to document' );
michael@0 2730 assert_equals( step2item1, 'bar', 'item 1 after id is created when appended to document' );
michael@0 2731 assert_equals( step3length, 0, 'length after removing an attribute when appended to document' );
michael@0 2732 }, 'names must update when changing id of referenced sibling when appended to document');
michael@0 2733 test(function () {
michael@0 2734 var parEl = makeEl('div',{},'<div itemprop="foo"><div itemprop="bar"></div></div><div itemscope itemref="id1"></div><div itemprop="baz" id="id1"></div>');
michael@0 2735 var testEl = parEl.childNodes[1];
michael@0 2736 var DSL = testEl.properties.names;
michael@0 2737 assert_equals( DSL.length, 1, 'length (before test)' );
michael@0 2738 assert_equals( DSL[0], 'baz', 'item 0 (before test)' );
michael@0 2739 parEl.firstChild.id = 'id1';
michael@0 2740 assert_equals( DSL.length, 2, 'length after id is created' );
michael@0 2741 assert_equals( DSL[0], 'foo', 'item 0 after id is created' );
michael@0 2742 assert_equals( DSL[1], 'bar', 'item 1 after id is created' );
michael@0 2743 parEl.firstChild.removeAttribute('id');
michael@0 2744 assert_equals( DSL.length, 1, 'length after removing an attribute' );
michael@0 2745 assert_equals( DSL[0], 'baz', 'item 0 after removing an attribute' );
michael@0 2746 document.body.appendChild(parEl);
michael@0 2747 var step1length = DSL.length;
michael@0 2748 var step1item0 = DSL[0];
michael@0 2749 parEl.firstChild.id = 'id1';
michael@0 2750 var step2length = DSL.length;
michael@0 2751 var step2item0 = DSL[0];
michael@0 2752 var step2item1 = DSL[1];
michael@0 2753 parEl.firstChild.removeAttribute('id');
michael@0 2754 var step3length = DSL.length;
michael@0 2755 var step3item0 = DSL[0];
michael@0 2756 document.body.removeChild(parEl);
michael@0 2757 assert_equals( step1length, 1, 'length (before test)' );
michael@0 2758 assert_equals( step1item0, 'baz', 'item 0 (before test)' );
michael@0 2759 assert_equals( step2length, 2, 'length after id is created' );
michael@0 2760 assert_equals( step2item0, 'foo', 'item 0 after id is created' );
michael@0 2761 assert_equals( step2item1, 'bar', 'item 1 after id is created' );
michael@0 2762 assert_equals( step3length, 1, 'length after removing an attribute' );
michael@0 2763 assert_equals( step3item0, 'baz', 'item 0 after removing an attribute' );
michael@0 2764 }, 'names must update when changing duplicated id of referenced sibling');
michael@0 2765 test(function () {
michael@0 2766 var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope></div>');
michael@0 2767 var testEl = parEl.childNodes[1];
michael@0 2768 var DSL = testEl.properties.names;
michael@0 2769 assert_equals( DSL.length, 0, 'length (before test)' );
michael@0 2770 testEl.itemRef.toggle('id1');
michael@0 2771 assert_equals( DSL.length, 1, 'length after itemref is changed' );
michael@0 2772 assert_equals( DSL[0], 'foo', 'item 0 after itemref is changed' );
michael@0 2773 testEl.removeAttribute('itemref');
michael@0 2774 assert_equals( DSL.length, 0, 'length after itemref is removed' );
michael@0 2775 assert_true( !DSL[0], 'item 0 after itemref is removed' );
michael@0 2776 document.body.appendChild(parEl);
michael@0 2777 var step1length = DSL.length;
michael@0 2778 testEl.itemRef.toggle('id1');
michael@0 2779 var step2length = DSL.length;
michael@0 2780 var step2item = DSL[0];
michael@0 2781 testEl.removeAttribute('itemref');
michael@0 2782 var step3length = DSL.length;
michael@0 2783 var step3item = DSL[0];
michael@0 2784 document.body.removeChild(parEl);
michael@0 2785 assert_equals( step1length, 0, 'length (before test)' );
michael@0 2786 assert_equals( step2length, 1, 'length after itemref is changed' );
michael@0 2787 assert_equals( step2item, 'foo', 'item 0 after itemref is changed' );
michael@0 2788 assert_equals( step3length, 0, 'length after itemref is removed' );
michael@0 2789 assert_true( !step3item, 'item 0 after itemref is removed' );
michael@0 2790 }, 'names must update when changing itemref to point to an element');
michael@0 2791 test(function () {
michael@0 2792 var parEl = makeEl('div',{},'<div id="id1"><div></div></div><div itemscope itemref="id1"></div>');
michael@0 2793 var testEl = parEl.childNodes[1];
michael@0 2794 var DSL = testEl.properties.names;
michael@0 2795 assert_equals( DSL.length, 0, 'length (before test)' );
michael@0 2796 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 2797 assert_equals( DSL.length, 1, 'length after a referenced element is added' );
michael@0 2798 assert_equals( DSL.item(0), 'foo', 'item 0 after a referenced element is added' ); //uses item just for the fun of it
michael@0 2799 parEl.firstChild.firstChild.itemProp.toggle('bar');
michael@0 2800 assert_equals( DSL.length, 2, 'length after a referenced itemprop is changed' );
michael@0 2801 assert_equals( DSL[0], 'bar', 'item 0 after a referenced element is added' );
michael@0 2802 assert_equals( DSL[1], 'foo', 'item 1 after a referenced element is added' );
michael@0 2803 parEl.firstChild.removeChild(parEl.firstChild.firstChild);
michael@0 2804 assert_equals( DSL.length, 1, 'length after a referenced element is removed' );
michael@0 2805 assert_equals( DSL[0], 'foo', 'item 0 after a referenced element is removed' );
michael@0 2806 parEl.innerHTML = '<div id="id1"><div></div></div><div itemscope itemref="id1"></div>';
michael@0 2807 testEl = parEl.childNodes[1];
michael@0 2808 DSL = testEl.properties.names;
michael@0 2809 document.body.appendChild(parEl);
michael@0 2810 var step1length = DSL.length;
michael@0 2811 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 2812 var step2length = DSL.length;
michael@0 2813 var step2item0 = DSL.item(0); //uses item just for the fun of it
michael@0 2814 parEl.firstChild.firstChild.itemProp.toggle('bar');
michael@0 2815 var step3length = DSL.length;
michael@0 2816 var step3item0 = DSL[0];
michael@0 2817 var step3item1 = DSL[1];
michael@0 2818 parEl.firstChild.removeChild(parEl.firstChild.firstChild);
michael@0 2819 var step4length = DSL.length;
michael@0 2820 var step4item0 = DSL[0];
michael@0 2821 document.body.removeChild(parEl);
michael@0 2822 assert_equals( step1length, 0, 'length (before test)' );
michael@0 2823 parEl.firstChild.appendChild(makeEl('div',{itemprop:'foo'}));
michael@0 2824 assert_equals( step2length, 1, 'length after a referenced element is added' );
michael@0 2825 assert_equals( step2item0, 'foo', 'item 0 after a referenced element is added' ); //uses item just for the fun of it
michael@0 2826 parEl.firstChild.firstChild.itemProp.toggle('bar');
michael@0 2827 assert_equals( step3length, 2, 'length after a referenced itemprop is changed' );
michael@0 2828 assert_equals( step3item0, 'bar', 'item 0 after a referenced element is added' );
michael@0 2829 assert_equals( step3item1, 'foo', 'item 1 after a referenced element is added' );
michael@0 2830 parEl.firstChild.removeChild(parEl.firstChild.firstChild);
michael@0 2831 assert_equals( step4length, 1, 'length after a referenced element is removed' );
michael@0 2832 assert_equals( step4item0, 'foo', 'item 0 after a referenced element is removed' );
michael@0 2833 }, 'names must update when changing children of elements referenced through itemref');
michael@0 2834 test(function () {
michael@0 2835 var parEl = makeEl('div',{},'<div id="id1" itemprop="foo"></div><div itemscope itemref="id1"><div itemprop="bar"></div></div>');
michael@0 2836 var testEl = parEl.childNodes[1];
michael@0 2837 var DSL = testEl.properties.names;
michael@0 2838 assert_equals( DSL.length, 2, 'length (before test)' );
michael@0 2839 assert_equals( DSL[0], 'foo', 'item 0 (before test)' );
michael@0 2840 assert_equals( DSL[1], 'bar', 'item 1 (before test)' );
michael@0 2841 document.body.appendChild(testEl);
michael@0 2842 var step1length = DSL.length;
michael@0 2843 var step1prop0 = DSL[0];
michael@0 2844 var step1prop1 = DSL[1];
michael@0 2845 parEl.appendChild(testEl);
michael@0 2846 assert_equals( step1length, 1, 'length after changing parent' );
michael@0 2847 assert_equals( step1prop0, 'bar', 'item 0 after changing parent' );
michael@0 2848 assert_true( !step1prop1, 'item 1 after changing parent' );
michael@0 2849 assert_equals( DSL.length, 2, 'length after re-parenting' );
michael@0 2850 assert_equals( DSL[0], 'foo', 'item 0 after re-parenting' );
michael@0 2851 assert_equals( DSL[1], 'bar', 'item 1 after re-parenting' );
michael@0 2852 document.body.appendChild(parEl);
michael@0 2853 var step2length = DSL.length;
michael@0 2854 var step2prop0 = DSL[0];
michael@0 2855 var step2prop1 = DSL[1];
michael@0 2856 document.createElement('div').appendChild(testEl);
michael@0 2857 var step3length = DSL.length;
michael@0 2858 var step3prop0 = DSL[0];
michael@0 2859 var step3prop1 = DSL[1];
michael@0 2860 parEl.appendChild(testEl);
michael@0 2861 var step4length = DSL.length;
michael@0 2862 var step4prop0 = DSL[0];
michael@0 2863 var step4prop1 = DSL[1];
michael@0 2864 document.body.removeChild(parEl);
michael@0 2865 assert_equals( step2length, 2, 'length (before test) when appended to document' );
michael@0 2866 assert_equals( step2prop0, 'foo', 'item 0 (before test) when appended to document' );
michael@0 2867 assert_equals( step2prop1, 'bar', 'item 1 (before test) when appended to document' );
michael@0 2868 assert_equals( step3length, 1, 'length after changing parent when appended to document' );
michael@0 2869 assert_equals( step3prop0, 'bar', 'item 0 after changing parent when appended to document' );
michael@0 2870 assert_true( !step3prop1, 'item 1 after changing parent when appended to document' );
michael@0 2871 assert_equals( step4length, 2, 'length after re-parenting when appended to document' );
michael@0 2872 assert_equals( step4prop0, 'foo', 'item 0 after re-parenting when appended to document' );
michael@0 2873 assert_equals( step4prop1, 'bar', 'item 1 after re-parenting when appended to document' );
michael@0 2874 }, 'names must update when appending elements with itemref to different parents');
michael@0 2875 test(function () {
michael@0 2876 var testEl = makeEl('div',{itemscope:'itemscope'},'<div><div itemprop="foo"></div></div>');
michael@0 2877 var DSL = testEl.properties.names;
michael@0 2878 assert_equals( DSL.length, 1, 'length (before test)' );
michael@0 2879 assert_equals( DSL[0], 'foo', 'item 0 (before test)' );
michael@0 2880 testEl.firstChild.itemScope = true;
michael@0 2881 assert_equals( DSL.length, 0, 'length after setting itemscope' );
michael@0 2882 assert_true( !DSL[0], 'item 0 after setting itemscope' );
michael@0 2883 testEl.firstChild.removeAttribute('itemscope');
michael@0 2884 assert_equals( DSL.length, 1, 'length after removing itemscope attribute' );
michael@0 2885 assert_equals( DSL[0], 'foo', 'item 0 after removing itemscope attribute' );
michael@0 2886 }, 'names must update when changing itemscope of children');
michael@0 2887
michael@0 2888 /* potential bugs */
michael@0 2889 test(function () {
michael@0 2890 var parEl = makeEl('div',{},'<div id="id1"></div>');
michael@0 2891 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1 id2'});
michael@0 2892 parEl.appendChild(testEl);
michael@0 2893 testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'}));
michael@0 2894 testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2895 testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2896 testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2897 testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2898 testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2899 testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2900 testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2901 testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text'));
michael@0 2902 testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2903 testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2904 testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text'));
michael@0 2905 parEl.appendChild(makeEl('time',{itemprop:'bar',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2906 testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2907 parEl.firstChild.appendChild(makeEl('div',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2908 testEl.appendChild(makeEl('madeuponthespot',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2909 var properties, PNLfoo, PNLbar, PNLbaz, fooValues, barValues, bazValues, allArrays, snapshot = [];
michael@0 2910 document.body.appendChild(parEl);
michael@0 2911 try {
michael@0 2912 properties = testEl.properties;
michael@0 2913 PNLfoo = properties.namedItem('foo');
michael@0 2914 PNLbar = properties.namedItem('bar');
michael@0 2915 PNLbaz = properties.namedItem('baz');
michael@0 2916 fooValues = PNLfoo.getValues();
michael@0 2917 barValues = PNLbar.getValues();
michael@0 2918 bazValues = PNLbaz.getValues();
michael@0 2919 allArrays = [properties,PNLfoo,PNLbar,PNLbaz,fooValues,barValues,bazValues];
michael@0 2920 for( var a = 0; a < allArrays.length; a++ ) {
michael@0 2921 snapshot[a] = [];
michael@0 2922 for( var b = 0; b < allArrays[a].length; b++ ) {
michael@0 2923 snapshot[a][b] = allArrays[a][b];
michael@0 2924 }
michael@0 2925 }
michael@0 2926 } catch(e) { /* need to clean up */ }
michael@0 2927 document.body.removeChild(parEl);
michael@0 2928 var c, d;
michael@0 2929 for( c = 0; c < allArrays.length; c++ ) {
michael@0 2930 for( d = 0; d < allArrays[c].length; d++ ) {
michael@0 2931 assert_equals( snapshot[c][d], allArrays[c][d], 'allArrays['+c+']['+d+']' );
michael@0 2932 }
michael@0 2933 }
michael@0 2934 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()];
michael@0 2935 for( c = 0; c < newArrays.length; c++ ) {
michael@0 2936 for( d = 0; d < newArrays[c].length; d++ ) {
michael@0 2937 assert_equals( snapshot[c][d], newArrays[c][d], 'newArrays['+c+']['+d+']' );
michael@0 2938 }
michael@0 2939 }
michael@0 2940 }, 'collections must survive the parent\'s removal from the document');
michael@0 2941 test(function () {
michael@0 2942 var testEl = makeEl('div',{itemscope:'itemscope'});
michael@0 2943 testEl.appendChild(makeEl('meta',{itemprop:'foo',content:'test'}));
michael@0 2944 testEl.appendChild(makeEl('audio',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2945 testEl.appendChild(makeEl('embed',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2946 testEl.appendChild(makeEl('iframe',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2947 testEl.appendChild(makeEl('img',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2948 testEl.appendChild(makeEl('source',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2949 testEl.appendChild(makeEl('track',{itemprop:'foo',src:'http://example.org/'}));
michael@0 2950 testEl.appendChild(makeEl('video',{itemprop:'foo',src:'http://example.org/'},'contained text'));
michael@0 2951 testEl.appendChild(makeEl('a',{itemprop:'foo',href:'http://example.org/'},'contained text'));
michael@0 2952 testEl.appendChild(makeEl('area',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2953 testEl.appendChild(makeEl('link',{itemprop:'foo',href:'http://example.org/'}));
michael@0 2954 testEl.appendChild(makeEl('object',{itemprop:'foo',data:'http://example.org/'},'contained text'));
michael@0 2955 testEl.appendChild(makeEl('time',{itemprop:'bar',id:'id2'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2956 testEl.appendChild(makeEl('time',{itemprop:'foo',datetime:'test'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2957 testEl.appendChild(makeEl('div',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2958 testEl.appendChild(makeEl('madeuponthespot',{itemprop:'baz'},'te <span itemprop="foo" itemscope>st</span> ing'));
michael@0 2959 var properties, PNLfoo, PNLbar, PNLbaz, fooValues, barValues, bazValues, allArrays, snapshot = [];
michael@0 2960 document.body.appendChild(testEl);
michael@0 2961 try {
michael@0 2962 properties = testEl.properties;
michael@0 2963 PNLfoo = properties.namedItem('foo');
michael@0 2964 PNLbar = properties.namedItem('bar');
michael@0 2965 PNLbaz = properties.namedItem('baz');
michael@0 2966 fooValues = PNLfoo.getValues();
michael@0 2967 barValues = PNLbar.getValues();
michael@0 2968 bazValues = PNLbaz.getValues();
michael@0 2969 allArrays = [properties,PNLfoo,PNLbar,PNLbaz,fooValues,barValues,bazValues];
michael@0 2970 for( var a = 0; a < allArrays.length; a++ ) {
michael@0 2971 snapshot[a] = [];
michael@0 2972 for( var b = 0; b < allArrays[a].length; b++ ) {
michael@0 2973 snapshot[a][b] = allArrays[a][b];
michael@0 2974 }
michael@0 2975 }
michael@0 2976 } catch(e) { /* need to clean up */ }
michael@0 2977 document.body.removeChild(testEl);
michael@0 2978 var c, d;
michael@0 2979 for( c = 0; c < allArrays.length; c++ ) {
michael@0 2980 for( d = 0; d < allArrays[c].length; d++ ) {
michael@0 2981 assert_equals( snapshot[c][d], allArrays[c][d], 'allArrays['+c+']['+d+']' );
michael@0 2982 }
michael@0 2983 }
michael@0 2984 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()];
michael@0 2985 for( c = 0; c < newArrays.length; c++ ) {
michael@0 2986 for( d = 0; d < newArrays[c].length; d++ ) {
michael@0 2987 assert_equals( snapshot[c][d], newArrays[c][d], 'newArrays['+c+']['+d+']' );
michael@0 2988 }
michael@0 2989 }
michael@0 2990 }, 'collections must survive the item\'s removal from the document');
michael@0 2991
michael@0 2992 /* override_builtins */
michael@0 2993 test(function () {
michael@0 2994 //http://dev.w3.org/2006/webapi/WebIDL/#named-properties
michael@0 2995 //[OverrideBuiltins] is not declared for any of the properties, hence no overriding is allowed
michael@0 2996 var testEl = makeEl('div',{itemscope:'itemscope'});
michael@0 2997 var namedItem = testEl.properties.namedItem;
michael@0 2998 var item = testEl.properties.item;
michael@0 2999 var names = testEl.properties.names;
michael@0 3000 testEl.innerHTML = '<div itemprop="namedItem length item names"></div>';
michael@0 3001 assert_equals( testEl.properties['namedItem'], namedItem, 'namedItem' );
michael@0 3002 assert_equals( testEl.properties['length'], 1, 'length' );
michael@0 3003 assert_equals( testEl.properties['item'], item, 'item' );
michael@0 3004 assert_equals( testEl.properties['names'], names, 'names' );
michael@0 3005 }, 'itemprop names must not override builtin properties');
michael@0 3006
michael@0 3007 /* casting */
michael@0 3008 //when calling object[other_object], ECMAScript treats other_object as a named property so it casts it to a string using toString
michael@0 3009 //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
michael@0 3010 test(function () {
michael@0 3011 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="2"></div><div itemprop="0"></div>');
michael@0 3012 assert_equals( testEl.properties.item('0'), testEl.properties.item(0), '0' );
michael@0 3013 assert_equals( testEl.properties.item('2'), testEl.properties.item(2), '2' );
michael@0 3014 }, 'properties.item(integerString) should cast to a number');
michael@0 3015 test(function () {
michael@0 3016 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="2"></div><div itemprop="0"></div>');
michael@0 3017 assert_equals( testEl.properties['0'], testEl.properties.item(0), '0' );
michael@0 3018 assert_equals( testEl.properties['2'], window.undefined, '2' );
michael@0 3019 }, 'properties[integerString] should act as a numeric index');
michael@0 3020 test(function () {
michael@0 3021 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="0"></div>');
michael@0 3022 assert_equals( testEl.properties.namedItem(0), testEl.properties.namedItem('0'), '0' );
michael@0 3023 assert_true( testEl.properties.namedItem(0) instanceof PropertyNodeList , 'instanceof' );
michael@0 3024 }, 'properties.namedItem(integer) should cast to a string');
michael@0 3025 test(function () {
michael@0 3026 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemprop="2 foo"></div><div itemprop="0"></div>');
michael@0 3027 assert_equals( testEl.properties[{ toString: function(){return 'foo';}, valueOf: function(){return 1;} }][0], testEl.firstChild, 'foo' );
michael@0 3028 assert_equals( testEl.properties[{ toString: function(){return '0';}, valueOf: function(){return 1;} }], testEl.firstChild, '0' );
michael@0 3029 assert_equals( testEl.properties[{ toString: function(){return '2';}, valueOf: function(){return 0;} }], window.undefined, '2' );
michael@0 3030 }, 'properties[someObject] should cast toString before using whichever casting applies');
michael@0 3031
michael@0 3032 /* loops and evil itemref */
michael@0 3033 test(function () {
michael@0 3034 //This should have 1 property on each itemscope, pointing only to its direct child
michael@0 3035 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemscope itemprop="foo"><div itemprop="bar"></div></div>');
michael@0 3036 assert_equals( testEl.properties.length, 1, 'outer length' );
michael@0 3037 assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' );
michael@0 3038 assert_true( !testEl.properties[1], 'outer properties[1]' );
michael@0 3039 assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' );
michael@0 3040 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' );
michael@0 3041 assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' );
michael@0 3042 assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length' );
michael@0 3043 assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0]' );
michael@0 3044 assert_equals( testEl.properties.names.length, 1, 'outer names.length' );
michael@0 3045 assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' );
michael@0 3046 assert_true( !testEl.properties.names[1], 'outer names[1]' );
michael@0 3047 assert_equals( testEl.firstChild.properties.length, 1, 'inner length' );
michael@0 3048 assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' );
michael@0 3049 assert_true( !testEl.firstChild.properties[1], 'inner properties[1]' );
michael@0 3050 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' );
michael@0 3051 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' );
michael@0 3052 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' );
michael@0 3053 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' );
michael@0 3054 assert_true( !testEl.firstChild.properties.namedItem('foo')[1], 'inner foo[1]' );
michael@0 3055 assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length' );
michael@0 3056 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' );
michael@0 3057 assert_true( !testEl.firstChild.properties.names[1], 'inner names[1]' );
michael@0 3058 }, 'simple nested itemscope');
michael@0 3059 test(function () {
michael@0 3060 //This should have 1 property on each itemscope, pointing only to its direct child
michael@0 3061 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'},'<div itemscope itemprop="foo" id="id1" itemref="id2"><div itemprop="bar" id="id2"></div></div>');
michael@0 3062 assert_equals( testEl.properties.length, 1, 'outer length' );
michael@0 3063 assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' );
michael@0 3064 assert_true( !testEl.properties[1], 'outer properties[1]' );
michael@0 3065 assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' );
michael@0 3066 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' );
michael@0 3067 assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' );
michael@0 3068 assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length' );
michael@0 3069 assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0]' );
michael@0 3070 assert_equals( testEl.properties.names.length, 1, 'outer names.length' );
michael@0 3071 assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' );
michael@0 3072 assert_true( !testEl.properties.names[1], 'outer names[1]' );
michael@0 3073 assert_equals( testEl.firstChild.properties.length, 1, 'inner length' );
michael@0 3074 assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' );
michael@0 3075 assert_true( !testEl.firstChild.properties[1], 'inner properties[1]' );
michael@0 3076 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' );
michael@0 3077 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' );
michael@0 3078 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' );
michael@0 3079 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' );
michael@0 3080 assert_true( !testEl.firstChild.properties.namedItem('foo')[1], 'inner foo[1]' );
michael@0 3081 assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length' );
michael@0 3082 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' );
michael@0 3083 assert_true( !testEl.firstChild.properties.names[1], 'inner names[1]' );
michael@0 3084 document.body.appendChild(testEl);
michael@0 3085 try {
michael@0 3086 assert_equals( testEl.properties.length, 1, 'outer length when appended to document' );
michael@0 3087 assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0] when appended to document' );
michael@0 3088 assert_true( !testEl.properties[1], 'outer properties[1] when appended to document' );
michael@0 3089 assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length when appended to document' );
michael@0 3090 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0] when appended to document' );
michael@0 3091 assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1] when appended to document' );
michael@0 3092 assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length when appended to document' );
michael@0 3093 assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0] when appended to document' );
michael@0 3094 assert_equals( testEl.properties.names.length, 1, 'outer names.length when appended to document' );
michael@0 3095 assert_equals( testEl.properties.names[0], 'foo', 'outer names[0] when appended to document' );
michael@0 3096 assert_true( !testEl.properties.names[1], 'outer names[1] when appended to document' );
michael@0 3097 assert_equals( testEl.firstChild.properties.length, 1, 'inner length when appended to document' );
michael@0 3098 assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0] when appended to document' );
michael@0 3099 assert_true( !testEl.firstChild.properties[1], 'inner properties[1] when appended to document' );
michael@0 3100 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length when appended to document' );
michael@0 3101 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0] when appended to document' );
michael@0 3102 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length when appended to document' );
michael@0 3103 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0] when appended to document' );
michael@0 3104 assert_true( !testEl.firstChild.properties.namedItem('foo')[1], 'inner foo[1] when appended to document' );
michael@0 3105 assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length when appended to document' );
michael@0 3106 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0] when appended to document' );
michael@0 3107 assert_true( !testEl.firstChild.properties.names[1], 'inner names[1] when appended to document' );
michael@0 3108 } catch(e) {
michael@0 3109 document.body.removeChild(testEl);
michael@0 3110 throw (e);
michael@0 3111 }
michael@0 3112 document.body.removeChild(testEl);
michael@0 3113 }, 'simple nested itemscope with itemref');
michael@0 3114 test(function () {
michael@0 3115 //This should have 3 properties on the item; foo, bar and baz
michael@0 3116 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>');
michael@0 3117 var testEl = parEl.childNodes[1];
michael@0 3118 assert_equals( testEl.properties.length, 3, 'length' );
michael@0 3119 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0]' );
michael@0 3120 assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1]' );
michael@0 3121 assert_equals( testEl.properties[2], parEl.lastChild, 'properties[2]' );
michael@0 3122 assert_true( !testEl.properties[3], 'properties[3]' );
michael@0 3123 assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo.length' );
michael@0 3124 assert_equals( testEl.properties.namedItem('foo')[0], parEl.firstChild, 'foo[0]' );
michael@0 3125 assert_true( !testEl.properties.namedItem('foo')[1], 'foo[1]' );
michael@0 3126 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length' );
michael@0 3127 assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0]' );
michael@0 3128 assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1]' );
michael@0 3129 assert_equals( testEl.properties.namedItem('baz').length, 1, 'baz.length' );
michael@0 3130 assert_equals( testEl.properties.namedItem('baz')[0], parEl.lastChild, 'baz[0]' );
michael@0 3131 assert_true( !testEl.properties.namedItem('baz')[1], 'baz[1]' );
michael@0 3132 assert_equals( testEl.properties.names.length, 3, 'names.length' );
michael@0 3133 assert_equals( testEl.properties.names[0], 'foo', 'names[0]' );
michael@0 3134 assert_equals( testEl.properties.names[1], 'bar', 'names[1]' );
michael@0 3135 assert_equals( testEl.properties.names[2], 'baz', 'names[2]' );
michael@0 3136 assert_true( !testEl.properties.names[3], 'names[3]' );
michael@0 3137 document.body.appendChild(parEl);
michael@0 3138 try {
michael@0 3139 assert_equals( testEl.properties.length, 3, 'length when appended to document' );
michael@0 3140 assert_equals( testEl.properties[0], parEl.firstChild, 'properties[0] when appended to document' );
michael@0 3141 assert_equals( testEl.properties[1], testEl.firstChild, 'properties[1] when appended to document' );
michael@0 3142 assert_equals( testEl.properties[2], parEl.lastChild, 'properties[2] when appended to document' );
michael@0 3143 assert_true( !testEl.properties[3], 'properties[3] when appended to document' );
michael@0 3144 assert_equals( testEl.properties.namedItem('foo').length, 1, 'foo.length when appended to document' );
michael@0 3145 assert_equals( testEl.properties.namedItem('foo')[0], parEl.firstChild, 'foo[0] when appended to document' );
michael@0 3146 assert_true( !testEl.properties.namedItem('foo')[1], 'foo[1] when appended to document' );
michael@0 3147 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length when appended to document' );
michael@0 3148 assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0] when appended to document' );
michael@0 3149 assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1] when appended to document' );
michael@0 3150 assert_equals( testEl.properties.namedItem('baz').length, 1, 'baz.length when appended to document' );
michael@0 3151 assert_equals( testEl.properties.namedItem('baz')[0], parEl.lastChild, 'baz[0] when appended to document' );
michael@0 3152 assert_true( !testEl.properties.namedItem('baz')[1], 'baz[1] when appended to document' );
michael@0 3153 assert_equals( testEl.properties.names.length, 3, 'names.length when appended to document' );
michael@0 3154 assert_equals( testEl.properties.names[0], 'foo', 'names[0] when appended to document' );
michael@0 3155 assert_equals( testEl.properties.names[1], 'bar', 'names[1] when appended to document' );
michael@0 3156 assert_equals( testEl.properties.names[2], 'baz', 'names[2] when appended to document' );
michael@0 3157 assert_true( !testEl.properties.names[3], 'names[3] when appended to document' );
michael@0 3158 } catch(e) {
michael@0 3159 document.body.removeChild(parEl);
michael@0 3160 throw (e);
michael@0 3161 }
michael@0 3162 document.body.removeChild(parEl);
michael@0 3163 }, 'simple sibling itemref');
michael@0 3164 test(function () {
michael@0 3165 //This should have no properties
michael@0 3166 var testEl = makeEl('div',{itemscope:'itemscope',id:'id1',itemref:'id1',itemprop:'foo'});
michael@0 3167 assert_equals( testEl.properties.length, 0, 'length' );
michael@0 3168 assert_true( !testEl.properties[0], 'properties[0]' );
michael@0 3169 assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length' );
michael@0 3170 assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0]' );
michael@0 3171 assert_equals( testEl.properties.names.length, 0, 'names.length' );
michael@0 3172 assert_true( !testEl.properties.names[0], 'names[0]' );
michael@0 3173 document.body.appendChild(testEl);
michael@0 3174 try {
michael@0 3175 assert_equals( testEl.properties.length, 0, 'length when appended to document' );
michael@0 3176 assert_true( !testEl.properties[0], 'properties[0] when appended to document' );
michael@0 3177 assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length when appended to document' );
michael@0 3178 assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0] when appended to document' );
michael@0 3179 assert_equals( testEl.properties.names.length, 0, 'names.length when appended to document' );
michael@0 3180 assert_true( !testEl.properties.names[0], 'names[0] when appended to document' );
michael@0 3181 } catch(e) {
michael@0 3182 document.body.removeChild(testEl);
michael@0 3183 throw (e);
michael@0 3184 }
michael@0 3185 document.body.removeChild(testEl);
michael@0 3186 }, 'itemref pointing to itself');
michael@0 3187 test(function () {
michael@0 3188 //This should have 1 property, pointing to the child
michael@0 3189 var testEl = makeEl('div',{itemscope:'itemscope',id:'id1',itemref:'id1',itemprop:'foo'},'<div itemprop="bar"></div>');
michael@0 3190 assert_equals( testEl.properties.length, 1, 'length' );
michael@0 3191 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0]' );
michael@0 3192 assert_true( !testEl.properties[1], 'properties[1]' );
michael@0 3193 assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length' );
michael@0 3194 assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0]' );
michael@0 3195 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length' );
michael@0 3196 assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0]' );
michael@0 3197 assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1]' );
michael@0 3198 assert_equals( testEl.properties.names.length, 1, 'names.length' );
michael@0 3199 assert_equals( testEl.properties.names[0], 'bar', 'names[0]' );
michael@0 3200 assert_true( !testEl.properties.names[1], 'names[1]' );
michael@0 3201 document.body.appendChild(testEl);
michael@0 3202 try {
michael@0 3203 assert_equals( testEl.properties.length, 1, 'length when appended to document' );
michael@0 3204 assert_equals( testEl.properties[0], testEl.firstChild, 'properties[0] when appended to document' );
michael@0 3205 assert_true( !testEl.properties[1], 'properties[1] when appended to document' );
michael@0 3206 assert_equals( testEl.properties.namedItem('foo').length, 0, 'foo.length when appended to document' );
michael@0 3207 assert_true( !testEl.properties.namedItem('foo')[0], 'foo[0] when appended to document' );
michael@0 3208 assert_equals( testEl.properties.namedItem('bar').length, 1, 'bar.length when appended to document' );
michael@0 3209 assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0] when appended to document' );
michael@0 3210 assert_true( !testEl.properties.namedItem('bar')[1], 'bar[1] when appended to document' );
michael@0 3211 assert_equals( testEl.properties.names.length, 1, 'names.length when appended to document' );
michael@0 3212 assert_equals( testEl.properties.names[0], 'bar', 'names[0] when appended to document' );
michael@0 3213 assert_true( !testEl.properties.names[1], 'names[1] when appended to document' );
michael@0 3214 } catch(e) {
michael@0 3215 document.body.removeChild(testEl);
michael@0 3216 throw (e);
michael@0 3217 }
michael@0 3218 document.body.removeChild(testEl);
michael@0 3219 }, 'itemref pointing to itself with child');
michael@0 3220 test(function () {
michael@0 3221 //This should have 1 property on each itemscope, pointing only to its direct child
michael@0 3222 var testEl = makeEl('div',{itemscope:'itemscope'},'<div itemscope itemprop="foo" id="id1" itemref="id1"><div itemprop="bar"></div></div>');
michael@0 3223 assert_equals( testEl.properties.length, 1, 'outer length' );
michael@0 3224 assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' );
michael@0 3225 assert_true( !testEl.properties[1], 'outer properties[1]' );
michael@0 3226 assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' );
michael@0 3227 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' );
michael@0 3228 assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' );
michael@0 3229 assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length' );
michael@0 3230 assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0]' );
michael@0 3231 assert_equals( testEl.properties.names.length, 1, 'outer names.length' );
michael@0 3232 assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' );
michael@0 3233 assert_true( !testEl.properties.names[1], 'outer names[1]' );
michael@0 3234 assert_equals( testEl.firstChild.properties.length, 1, 'inner length' );
michael@0 3235 assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' );
michael@0 3236 assert_true( !testEl.firstChild.properties[1], 'inner properties[1]' );
michael@0 3237 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' );
michael@0 3238 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' );
michael@0 3239 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' );
michael@0 3240 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' );
michael@0 3241 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1]' );
michael@0 3242 assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length' );
michael@0 3243 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' );
michael@0 3244 assert_true( !testEl.firstChild.properties.names[1], 'inner names[1]' );
michael@0 3245 document.body.appendChild(testEl);
michael@0 3246 try {
michael@0 3247 assert_equals( testEl.properties.length, 1, 'outer length when appended to document' );
michael@0 3248 assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0] when appended to document' );
michael@0 3249 assert_true( !testEl.properties[1], 'outer properties[1] when appended to document' );
michael@0 3250 assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length when appended to document' );
michael@0 3251 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0] when appended to document' );
michael@0 3252 assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1] when appended to document' );
michael@0 3253 assert_equals( testEl.properties.namedItem('bar').length, 0, 'outer bar.length when appended to document' );
michael@0 3254 assert_true( !testEl.properties.namedItem('bar')[0], 'outer bar[0] when appended to document' );
michael@0 3255 assert_equals( testEl.properties.names.length, 1, 'outer names.length when appended to document' );
michael@0 3256 assert_equals( testEl.properties.names[0], 'foo', 'outer names[0] when appended to document' );
michael@0 3257 assert_true( !testEl.properties.names[1], 'outer names[1] when appended to document' );
michael@0 3258 assert_equals( testEl.firstChild.properties.length, 1, 'inner length when appended to document' );
michael@0 3259 assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0] when appended to document' );
michael@0 3260 assert_true( !testEl.firstChild.properties[1], 'inner properties[1] when appended to document' );
michael@0 3261 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length when appended to document' );
michael@0 3262 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0] when appended to document' );
michael@0 3263 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length when appended to document' );
michael@0 3264 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0] when appended to document' );
michael@0 3265 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1] when appended to document' );
michael@0 3266 assert_equals( testEl.firstChild.properties.names.length, 1, 'inner names.length when appended to document' );
michael@0 3267 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0] when appended to document' );
michael@0 3268 assert_true( !testEl.firstChild.properties.names[1], 'inner names[1] when appended to document' );
michael@0 3269 } catch(e) {
michael@0 3270 document.body.removeChild(testEl);
michael@0 3271 throw (e);
michael@0 3272 }
michael@0 3273 document.body.removeChild(testEl);
michael@0 3274 }, 'nested itemref pointing to itself with child');
michael@0 3275 test(function () {
michael@0 3276 //Each itemscope has one property, pointing to the other one
michael@0 3277 var testEl = makeEl('div',{},'<div id="id1" itemprop="foo" itemscope itemref="id2"></div><div id="id2" itemprop="bar" itemscope itemref="id1"></div>');
michael@0 3278 assert_equals( testEl.firstChild.properties.length, 1, 'id1 length' );
michael@0 3279 assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0]' );
michael@0 3280 assert_true( !testEl.firstChild.properties[1], 'id1 properties[1]' );
michael@0 3281 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length' );
michael@0 3282 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0]' );
michael@0 3283 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length' );
michael@0 3284 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0]' );
michael@0 3285 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1]' );
michael@0 3286 assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length' );
michael@0 3287 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0]' );
michael@0 3288 assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1]' );
michael@0 3289 assert_equals( testEl.lastChild.properties.length, 1, 'id2 length' );
michael@0 3290 assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0]' );
michael@0 3291 assert_true( !testEl.lastChild.properties[1], 'id2 properties[1]' );
michael@0 3292 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length' );
michael@0 3293 assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0]' );
michael@0 3294 assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1]' );
michael@0 3295 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length' );
michael@0 3296 assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0]' );
michael@0 3297 assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length' );
michael@0 3298 assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0]' );
michael@0 3299 assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1]' );
michael@0 3300 document.body.appendChild(testEl);
michael@0 3301 try {
michael@0 3302 assert_equals( testEl.firstChild.properties.length, 1, 'id1 length when appended to document' );
michael@0 3303 assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0] when appended to document' );
michael@0 3304 assert_true( !testEl.firstChild.properties[1], 'id1 properties[1] when appended to document' );
michael@0 3305 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length when appended to document' );
michael@0 3306 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0] when appended to document' );
michael@0 3307 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length when appended to document' );
michael@0 3308 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0] when appended to document' );
michael@0 3309 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1] when appended to document' );
michael@0 3310 assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length when appended to document' );
michael@0 3311 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0] when appended to document' );
michael@0 3312 assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1] when appended to document' );
michael@0 3313 assert_equals( testEl.lastChild.properties.length, 1, 'id2 length when appended to document' );
michael@0 3314 assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0] when appended to document' );
michael@0 3315 assert_true( !testEl.lastChild.properties[1], 'id2 properties[1] when appended to document' );
michael@0 3316 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length when appended to document' );
michael@0 3317 assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0] when appended to document' );
michael@0 3318 assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1] when appended to document' );
michael@0 3319 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length when appended to document' );
michael@0 3320 assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0] when appended to document' );
michael@0 3321 assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length when appended to document' );
michael@0 3322 assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0] when appended to document' );
michael@0 3323 assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1] when appended to document' );
michael@0 3324 } catch(e) {
michael@0 3325 document.body.removeChild(testEl);
michael@0 3326 throw (e);
michael@0 3327 }
michael@0 3328 document.body.removeChild(testEl);
michael@0 3329 }, 'mutually referencing siblings');
michael@0 3330 test(function () {
michael@0 3331 //Root has 2 properties, foo and bar
michael@0 3332 //Each itemscope has one property, pointing to the other one
michael@0 3333 var testEl = makeEl('div',{itemscope:'itemscope'},'<div id="id1" itemprop="foo" itemscope itemref="id2"></div><div id="id2" itemprop="bar" itemscope itemref="id1"></div>');
michael@0 3334 assert_equals( testEl.properties.length, 2, 'root length' );
michael@0 3335 assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0]' );
michael@0 3336 assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1]' );
michael@0 3337 assert_true( !testEl.properties[2], 'root properties[2]' );
michael@0 3338 assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length' );
michael@0 3339 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0]' );
michael@0 3340 assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1]' );
michael@0 3341 assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length' );
michael@0 3342 assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0]' );
michael@0 3343 assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1]' );
michael@0 3344 assert_equals( testEl.properties.names.length, 2, 'root names.length' );
michael@0 3345 assert_equals( testEl.properties.names[0], 'foo', 'root names[0]' );
michael@0 3346 assert_equals( testEl.properties.names[1], 'bar', 'root names[1]' );
michael@0 3347 assert_true( !testEl.properties.names[2], 'root names[2]' );
michael@0 3348 assert_equals( testEl.firstChild.properties.length, 1, 'id1 length' );
michael@0 3349 assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0]' );
michael@0 3350 assert_true( !testEl.firstChild.properties[1], 'id1 properties[1]' );
michael@0 3351 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length' );
michael@0 3352 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0]' );
michael@0 3353 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length' );
michael@0 3354 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0]' );
michael@0 3355 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1]' );
michael@0 3356 assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length' );
michael@0 3357 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0]' );
michael@0 3358 assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1]' );
michael@0 3359 assert_equals( testEl.lastChild.properties.length, 1, 'id2 length' );
michael@0 3360 assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0]' );
michael@0 3361 assert_true( !testEl.lastChild.properties[1], 'id2 properties[1]' );
michael@0 3362 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length' );
michael@0 3363 assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0]' );
michael@0 3364 assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1]' );
michael@0 3365 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length' );
michael@0 3366 assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0]' );
michael@0 3367 assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length' );
michael@0 3368 assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0]' );
michael@0 3369 assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1]' );
michael@0 3370 document.body.appendChild(testEl);
michael@0 3371 try {
michael@0 3372 assert_equals( testEl.properties.length, 2, 'root length when appended to document' );
michael@0 3373 assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0] when appended to document' );
michael@0 3374 assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1] when appended to document' );
michael@0 3375 assert_true( !testEl.properties[2], 'root properties[2] when appended to document' );
michael@0 3376 assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length when appended to document' );
michael@0 3377 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0] when appended to document' );
michael@0 3378 assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1] when appended to document' );
michael@0 3379 assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length when appended to document' );
michael@0 3380 assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0] when appended to document' );
michael@0 3381 assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1] when appended to document' );
michael@0 3382 assert_equals( testEl.properties.names.length, 2, 'root names.length when appended to document' );
michael@0 3383 assert_equals( testEl.properties.names[0], 'foo', 'root names[0] when appended to document' );
michael@0 3384 assert_equals( testEl.properties.names[1], 'bar', 'root names[1] when appended to document' );
michael@0 3385 assert_true( !testEl.properties.names[2], 'root names[2] when appended to document' );
michael@0 3386 assert_equals( testEl.firstChild.properties.length, 1, 'id1 length when appended to document' );
michael@0 3387 assert_equals( testEl.firstChild.properties[0], testEl.lastChild, 'id1 properties[0] when appended to document' );
michael@0 3388 assert_true( !testEl.firstChild.properties[1], 'id1 properties[1] when appended to document' );
michael@0 3389 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'id1 foo.length when appended to document' );
michael@0 3390 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'id1 foo[0] when appended to document' );
michael@0 3391 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'id1 bar.length when appended to document' );
michael@0 3392 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.lastChild, 'id1 bar[0] when appended to document' );
michael@0 3393 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'id1 bar[1] when appended to document' );
michael@0 3394 assert_equals( testEl.firstChild.properties.names.length, 1, 'id1 names.length when appended to document' );
michael@0 3395 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'id1 names[0] when appended to document' );
michael@0 3396 assert_true( !testEl.firstChild.properties.names[1], 'id1 names[1] when appended to document' );
michael@0 3397 assert_equals( testEl.lastChild.properties.length, 1, 'id2 length when appended to document' );
michael@0 3398 assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'id2 properties[0] when appended to document' );
michael@0 3399 assert_true( !testEl.lastChild.properties[1], 'id2 properties[1] when appended to document' );
michael@0 3400 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 1, 'id2 foo.length when appended to document' );
michael@0 3401 assert_equals( testEl.lastChild.properties.namedItem('foo')[0], testEl.firstChild, 'id2 foo[0] when appended to document' );
michael@0 3402 assert_true( !testEl.lastChild.properties.namedItem('foo')[1], 'id2 foo[1] when appended to document' );
michael@0 3403 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'id2 bar.length when appended to document' );
michael@0 3404 assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'id2 bar[0] when appended to document' );
michael@0 3405 assert_equals( testEl.lastChild.properties.names.length, 1, 'id2 names.length when appended to document' );
michael@0 3406 assert_equals( testEl.lastChild.properties.names[0], 'foo', 'id2 names[0] when appended to document' );
michael@0 3407 assert_true( !testEl.lastChild.properties.names[1], 'id2 names[1] when appended to document' );
michael@0 3408 } catch(e) {
michael@0 3409 document.body.removeChild(testEl);
michael@0 3410 throw (e);
michael@0 3411 }
michael@0 3412 document.body.removeChild(testEl);
michael@0 3413 }, 'mutually referencing siblings with item parent');
michael@0 3414 test(function () {
michael@0 3415 //Root has two properties, foo and bar
michael@0 3416 //Bar has two properties, baz and qux
michael@0 3417 //Qux has one property, bar
michael@0 3418 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>');
michael@0 3419 assert_equals( testEl.properties.length, 2, 'root length' );
michael@0 3420 assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0]' );
michael@0 3421 assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1]' );
michael@0 3422 assert_true( !testEl.properties[2], 'root properties[2]' );
michael@0 3423 assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length' );
michael@0 3424 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0]' );
michael@0 3425 assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1]' );
michael@0 3426 assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length' );
michael@0 3427 assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0]' );
michael@0 3428 assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1]' );
michael@0 3429 assert_equals( testEl.properties.namedItem('baz').length, 0, 'root baz.length' );
michael@0 3430 assert_true( !testEl.properties.namedItem('baz')[0], 'root baz[0]' );
michael@0 3431 assert_equals( testEl.properties.namedItem('qux').length, 0, 'root qux.length' );
michael@0 3432 assert_true( !testEl.properties.namedItem('qux')[0], 'root qux[0]' );
michael@0 3433 assert_equals( testEl.properties.names.length, 2, 'root names.length' );
michael@0 3434 assert_equals( testEl.properties.names[0], 'foo', 'root names[0]' );
michael@0 3435 assert_equals( testEl.properties.names[1], 'bar', 'root names[1]' );
michael@0 3436 assert_true( !testEl.properties.names[2], 'root names[2]' );
michael@0 3437 assert_equals( testEl.lastChild.properties.length, 2, 'bar length' );
michael@0 3438 assert_equals( testEl.lastChild.properties[0], testEl.lastChild.firstChild, 'bar properties[0]' );
michael@0 3439 assert_equals( testEl.lastChild.properties[1], testEl.lastChild.lastChild, 'bar properties[1]' );
michael@0 3440 assert_true( !testEl.lastChild.properties[2], 'bar properties[2]' );
michael@0 3441 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'bar foo.length' );
michael@0 3442 assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'bar foo[0]' );
michael@0 3443 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'bar bar.length' );
michael@0 3444 assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'bar bar[0]' );
michael@0 3445 assert_equals( testEl.lastChild.properties.namedItem('baz').length, 1, 'bar baz.length' );
michael@0 3446 assert_equals( testEl.lastChild.properties.namedItem('baz')[0], testEl.lastChild.firstChild, 'bar baz[0]' );
michael@0 3447 assert_true( !testEl.lastChild.properties.namedItem('baz')[1], 'bar baz[1]' );
michael@0 3448 assert_equals( testEl.lastChild.properties.namedItem('qux').length, 1, 'bar qux.length' );
michael@0 3449 assert_equals( testEl.lastChild.properties.namedItem('qux')[0], testEl.lastChild.lastChild, 'bar qux[0]' );
michael@0 3450 assert_true( !testEl.lastChild.properties.namedItem('qux')[1], 'bar qux[1]' );
michael@0 3451 assert_equals( testEl.lastChild.properties.names.length, 2, 'bar names.length' );
michael@0 3452 assert_equals( testEl.lastChild.properties.names[0], 'baz', 'bar names[0]' );
michael@0 3453 assert_equals( testEl.lastChild.properties.names[1], 'qux', 'bar names[1]' );
michael@0 3454 assert_true( !testEl.lastChild.properties.names[2], 'bar names[2]' );
michael@0 3455 assert_equals( testEl.lastChild.lastChild.properties.length, 1, 'qux length' );
michael@0 3456 assert_equals( testEl.lastChild.lastChild.properties[0], testEl.lastChild, 'qux properties[0]' );
michael@0 3457 assert_true( !testEl.lastChild.lastChild.properties[1], 'qux properties[1]' );
michael@0 3458 assert_equals( testEl.lastChild.lastChild.properties.namedItem('foo').length, 0, 'qux foo.length' );
michael@0 3459 assert_true( !testEl.lastChild.lastChild.properties.namedItem('foo')[0], 'qux foo[0]' );
michael@0 3460 assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar').length, 1, 'qux bar.length' );
michael@0 3461 assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar')[0], testEl.lastChild, 'qux bar[0]' );
michael@0 3462 assert_true( !testEl.lastChild.lastChild.properties.namedItem('bar')[1], 'qux bar[1]' );
michael@0 3463 assert_equals( testEl.lastChild.lastChild.properties.namedItem('baz').length, 0, 'qux baz.length' );
michael@0 3464 assert_true( !testEl.lastChild.lastChild.properties.namedItem('baz')[0], 'qux baz[0]' );
michael@0 3465 assert_equals( testEl.lastChild.lastChild.properties.namedItem('qux').length, 0, 'qux qux.length' );
michael@0 3466 assert_true( !testEl.lastChild.lastChild.properties.namedItem('qux')[0], 'qux qux[0]' );
michael@0 3467 assert_equals( testEl.lastChild.lastChild.properties.names.length, 1, 'qux names.length' );
michael@0 3468 assert_equals( testEl.lastChild.lastChild.properties.names[0], 'bar', 'qux names[0]' );
michael@0 3469 assert_true( !testEl.lastChild.lastChild.properties.names[1], 'qux names[1]' );
michael@0 3470 document.body.appendChild(testEl);
michael@0 3471 try {
michael@0 3472 assert_equals( testEl.properties.length, 2, 'root length when appended to document' );
michael@0 3473 assert_equals( testEl.properties[0], testEl.firstChild, 'root properties[0] when appended to document' );
michael@0 3474 assert_equals( testEl.properties[1], testEl.lastChild, 'root properties[1] when appended to document' );
michael@0 3475 assert_true( !testEl.properties[2], 'root properties[2] when appended to document' );
michael@0 3476 assert_equals( testEl.properties.namedItem('foo').length, 1, 'root foo.length when appended to document' );
michael@0 3477 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'root foo[0] when appended to document' );
michael@0 3478 assert_true( !testEl.properties.namedItem('foo')[1], 'root foo[1] when appended to document' );
michael@0 3479 assert_equals( testEl.properties.namedItem('bar').length, 1, 'root bar.length when appended to document' );
michael@0 3480 assert_equals( testEl.properties.namedItem('bar')[0], testEl.lastChild, 'root bar[0] when appended to document' );
michael@0 3481 assert_true( !testEl.properties.namedItem('bar')[1], 'root bar[1] when appended to document' );
michael@0 3482 assert_equals( testEl.properties.namedItem('baz').length, 0, 'root baz.length when appended to document' );
michael@0 3483 assert_true( !testEl.properties.namedItem('baz')[0], 'root baz[0] when appended to document' );
michael@0 3484 assert_equals( testEl.properties.namedItem('qux').length, 0, 'root qux.length when appended to document' );
michael@0 3485 assert_true( !testEl.properties.namedItem('qux')[0], 'root qux[0] when appended to document' );
michael@0 3486 assert_equals( testEl.properties.names.length, 2, 'root names.length when appended to document' );
michael@0 3487 assert_equals( testEl.properties.names[0], 'foo', 'root names[0] when appended to document' );
michael@0 3488 assert_equals( testEl.properties.names[1], 'bar', 'root names[1] when appended to document' );
michael@0 3489 assert_true( !testEl.properties.names[2], 'root names[2] when appended to document' );
michael@0 3490 assert_equals( testEl.lastChild.properties.length, 2, 'bar length when appended to document' );
michael@0 3491 assert_equals( testEl.lastChild.properties[0], testEl.lastChild.firstChild, 'bar properties[0] when appended to document' );
michael@0 3492 assert_equals( testEl.lastChild.properties[1], testEl.lastChild.lastChild, 'bar properties[1] when appended to document' );
michael@0 3493 assert_true( !testEl.lastChild.properties[2], 'bar properties[2] when appended to document' );
michael@0 3494 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'bar foo.length when appended to document' );
michael@0 3495 assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'bar foo[0] when appended to document' );
michael@0 3496 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 0, 'bar bar.length when appended to document' );
michael@0 3497 assert_true( !testEl.lastChild.properties.namedItem('bar')[0], 'bar bar[0] when appended to document' );
michael@0 3498 assert_equals( testEl.lastChild.properties.namedItem('baz').length, 1, 'bar baz.length when appended to document' );
michael@0 3499 assert_equals( testEl.lastChild.properties.namedItem('baz')[0], testEl.lastChild.firstChild, 'bar baz[0] when appended to document' );
michael@0 3500 assert_true( !testEl.lastChild.properties.namedItem('baz')[1], 'bar baz[1] when appended to document' );
michael@0 3501 assert_equals( testEl.lastChild.properties.namedItem('qux').length, 1, 'bar qux.length when appended to document' );
michael@0 3502 assert_equals( testEl.lastChild.properties.namedItem('qux')[0], testEl.lastChild.lastChild, 'bar qux[0] when appended to document' );
michael@0 3503 assert_true( !testEl.lastChild.properties.namedItem('qux')[1], 'bar qux[1] when appended to document' );
michael@0 3504 assert_equals( testEl.lastChild.properties.names.length, 2, 'bar names.length when appended to document' );
michael@0 3505 assert_equals( testEl.lastChild.properties.names[0], 'baz', 'bar names[0] when appended to document' );
michael@0 3506 assert_equals( testEl.lastChild.properties.names[1], 'qux', 'bar names[1] when appended to document' );
michael@0 3507 assert_true( !testEl.lastChild.properties.names[2], 'bar names[2] when appended to document' );
michael@0 3508 assert_equals( testEl.lastChild.lastChild.properties.length, 1, 'qux length when appended to document' );
michael@0 3509 assert_equals( testEl.lastChild.lastChild.properties[0], testEl.lastChild, 'qux properties[0] when appended to document' );
michael@0 3510 assert_true( !testEl.lastChild.lastChild.properties[1], 'qux properties[1] when appended to document' );
michael@0 3511 assert_equals( testEl.lastChild.lastChild.properties.namedItem('foo').length, 0, 'qux foo.length when appended to document' );
michael@0 3512 assert_true( !testEl.lastChild.lastChild.properties.namedItem('foo')[0], 'qux foo[0] when appended to document' );
michael@0 3513 assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar').length, 1, 'qux bar.length when appended to document' );
michael@0 3514 assert_equals( testEl.lastChild.lastChild.properties.namedItem('bar')[0], testEl.lastChild, 'qux bar[0] when appended to document' );
michael@0 3515 assert_true( !testEl.lastChild.lastChild.properties.namedItem('bar')[1], 'qux bar[1] when appended to document' );
michael@0 3516 assert_equals( testEl.lastChild.lastChild.properties.namedItem('baz').length, 0, 'qux baz.length when appended to document' );
michael@0 3517 assert_true( !testEl.lastChild.lastChild.properties.namedItem('baz')[0], 'qux baz[0] when appended to document' );
michael@0 3518 assert_equals( testEl.lastChild.lastChild.properties.namedItem('qux').length, 0, 'qux qux.length when appended to document' );
michael@0 3519 assert_true( !testEl.lastChild.lastChild.properties.namedItem('qux')[0], 'qux qux[0] when appended to document' );
michael@0 3520 assert_equals( testEl.lastChild.lastChild.properties.names.length, 1, 'qux names.length when appended to document' );
michael@0 3521 assert_equals( testEl.lastChild.lastChild.properties.names[0], 'bar', 'qux names[0] when appended to document' );
michael@0 3522 assert_true( !testEl.lastChild.lastChild.properties.names[1], 'qux names[1] when appended to document' );
michael@0 3523 } catch(e) {
michael@0 3524 document.body.removeChild(testEl);
michael@0 3525 throw (e);
michael@0 3526 }
michael@0 3527 document.body.removeChild(testEl);
michael@0 3528 }, 'itemref referencing parent item');
michael@0 3529 test(function () {
michael@0 3530 //foo has one property, bar
michael@0 3531 var testEl = makeEl('div',{id:'id1'},'<div itemprop="bar"></div><div itemscope itemref="id1" itemprop="foo"></div>');
michael@0 3532 assert_equals( testEl.lastChild.properties.length, 1, 'length' );
michael@0 3533 assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'properties[0]' );
michael@0 3534 assert_true( !testEl.lastChild.properties[1], 'properties[1]' );
michael@0 3535 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'foo.length' );
michael@0 3536 assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'foo[0]' );
michael@0 3537 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 1, 'bar.length' );
michael@0 3538 assert_equals( testEl.lastChild.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0]' );
michael@0 3539 assert_true( !testEl.lastChild.properties.namedItem('bar')[1], 'bar[1]' );
michael@0 3540 assert_equals( testEl.lastChild.properties.names.length, 1, 'names.length' );
michael@0 3541 assert_equals( testEl.lastChild.properties.names[0], 'bar', 'names[0]' );
michael@0 3542 assert_true( !testEl.lastChild.properties.names[1], 'names[1]' );
michael@0 3543 document.body.appendChild(testEl);
michael@0 3544 try {
michael@0 3545 assert_equals( testEl.lastChild.properties.length, 1, 'length when appended to document' );
michael@0 3546 assert_equals( testEl.lastChild.properties[0], testEl.firstChild, 'properties[0] when appended to document' );
michael@0 3547 assert_true( !testEl.lastChild.properties[1], 'properties[1] when appended to document' );
michael@0 3548 assert_equals( testEl.lastChild.properties.namedItem('foo').length, 0, 'foo.length when appended to document' );
michael@0 3549 assert_true( !testEl.lastChild.properties.namedItem('foo')[0], 'foo[0] when appended to document' );
michael@0 3550 assert_equals( testEl.lastChild.properties.namedItem('bar').length, 1, 'bar.length when appended to document' );
michael@0 3551 assert_equals( testEl.lastChild.properties.namedItem('bar')[0], testEl.firstChild, 'bar[0] when appended to document' );
michael@0 3552 assert_true( !testEl.lastChild.properties.namedItem('bar')[1], 'bar[1] when appended to document' );
michael@0 3553 assert_equals( testEl.lastChild.properties.names.length, 1, 'names.length when appended to document' );
michael@0 3554 assert_equals( testEl.lastChild.properties.names[0], 'bar', 'names[0] when appended to document' );
michael@0 3555 assert_true( !testEl.lastChild.properties.names[1], 'names[1] when appended to document' );
michael@0 3556 } catch(e) {
michael@0 3557 document.body.removeChild(testEl);
michael@0 3558 throw (e);
michael@0 3559 }
michael@0 3560 document.body.removeChild(testEl);
michael@0 3561 }, 'itemref referencing parent without itemscope');
michael@0 3562 test(function () {
michael@0 3563 var testDiv = makeEl('div', {itemprop:'bar', id:'foo'}, '');
michael@0 3564 var testSpan = makeEl('span', {itemscope:'itemscope', itemref: 'foo', id: 'foo'}, '');
michael@0 3565 document.body.appendChild(testDiv);
michael@0 3566 document.body.appendChild(testSpan);
michael@0 3567 assert_equals(testSpan.properties.length, 1, 'has one property');
michael@0 3568 assert_equals(testSpan.properties[0], testDiv, 'has first property');
michael@0 3569 assert_equals(testSpan.properties.item(0), testDiv, 'has first property');
michael@0 3570 assert_equals(testSpan.properties.namedItem('bar').length, 1, 'has 1 foo property');
michael@0 3571 assert_equals(testSpan.properties.namedItem('bar').item(0), testDiv, 'div is foo property');
michael@0 3572 assert_equals(testSpan.properties.names.length, 1, 'only has one property');
michael@0 3573 document.body.removeChild(testDiv);
michael@0 3574 document.body.removeChild(testSpan);
michael@0 3575 }, 'itemref referencing element with same id');
michael@0 3576 test(function () {
michael@0 3577 //Root has three properties, foo, bar and baz
michael@0 3578 //Foo has two properties, bar and baz
michael@0 3579 var testEl = makeEl('div',{itemscope:'itemscope',itemref:'id1'},'<div itemscope itemprop="foo"><div itemprop="bar" id="id1"><div itemprop="baz"></div></div></div>');
michael@0 3580 assert_equals( testEl.properties.length, 3, 'outer length' );
michael@0 3581 assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0]' );
michael@0 3582 assert_equals( testEl.properties[1], testEl.firstChild.firstChild, 'outer properties[1]' );
michael@0 3583 assert_equals( testEl.properties[2], testEl.firstChild.firstChild.firstChild, 'outer properties[2]' );
michael@0 3584 assert_true( !testEl.properties[3], 'outer properties[3]' );
michael@0 3585 assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length' );
michael@0 3586 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0]' );
michael@0 3587 assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1]' );
michael@0 3588 assert_equals( testEl.properties.namedItem('bar').length, 1, 'outer bar.length' );
michael@0 3589 assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'outer bar[0]' );
michael@0 3590 assert_true( !testEl.properties.namedItem('bar')[1], 'outer bar[1]' );
michael@0 3591 assert_equals( testEl.properties.namedItem('baz').length, 1, 'outer baz.length' );
michael@0 3592 assert_equals( testEl.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'outer baz[0]' );
michael@0 3593 assert_true( !testEl.properties.namedItem('baz')[1], 'outer baz[1]' );
michael@0 3594 assert_equals( testEl.properties.names.length, 3, 'outer names.length' );
michael@0 3595 assert_equals( testEl.properties.names[0], 'foo', 'outer names[0]' );
michael@0 3596 assert_equals( testEl.properties.names[1], 'bar', 'outer names[1]' );
michael@0 3597 assert_equals( testEl.properties.names[2], 'baz', 'outer names[2]' );
michael@0 3598 assert_true( !testEl.properties.names[3], 'outer names[3]' );
michael@0 3599 assert_equals( testEl.firstChild.properties.length, 2, 'inner length' );
michael@0 3600 assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0]' );
michael@0 3601 assert_equals( testEl.firstChild.properties[1], testEl.firstChild.firstChild.firstChild, 'inner properties[1]' );
michael@0 3602 assert_true( !testEl.firstChild.properties[2], 'inner properties[2]' );
michael@0 3603 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length' );
michael@0 3604 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0]' );
michael@0 3605 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length' );
michael@0 3606 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0]' );
michael@0 3607 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1]' );
michael@0 3608 assert_equals( testEl.firstChild.properties.namedItem('baz').length, 1, 'inner baz.length' );
michael@0 3609 assert_equals( testEl.firstChild.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'inner baz[0]' );
michael@0 3610 assert_true( !testEl.firstChild.properties.namedItem('baz')[1], 'inner baz[1]' );
michael@0 3611 assert_equals( testEl.firstChild.properties.names.length, 2, 'inner names.length' );
michael@0 3612 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0]' );
michael@0 3613 assert_equals( testEl.firstChild.properties.names[1], 'baz', 'inner names[1]' );
michael@0 3614 assert_true( !testEl.firstChild.properties.names[2], 'inner names[2]' );
michael@0 3615 document.body.appendChild(testEl);
michael@0 3616 try {
michael@0 3617 assert_equals( testEl.properties.length, 3, 'outer length when appended to document' );
michael@0 3618 assert_equals( testEl.properties[0], testEl.firstChild, 'outer properties[0] when appended to document' );
michael@0 3619 assert_equals( testEl.properties[1], testEl.firstChild.firstChild, 'outer properties[1] when appended to document' );
michael@0 3620 assert_equals( testEl.properties[2], testEl.firstChild.firstChild.firstChild, 'outer properties[2] when appended to document' );
michael@0 3621 assert_true( !testEl.properties[3], 'outer properties[3] when appended to document' );
michael@0 3622 assert_equals( testEl.properties.namedItem('foo').length, 1, 'outer foo.length when appended to document' );
michael@0 3623 assert_equals( testEl.properties.namedItem('foo')[0], testEl.firstChild, 'outer foo[0] when appended to document' );
michael@0 3624 assert_true( !testEl.properties.namedItem('foo')[1], 'outer foo[1] when appended to document' );
michael@0 3625 assert_equals( testEl.properties.namedItem('bar').length, 1, 'outer bar.length when appended to document' );
michael@0 3626 assert_equals( testEl.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'outer bar[0] when appended to document' );
michael@0 3627 assert_true( !testEl.properties.namedItem('bar')[1], 'outer bar[1] when appended to document' );
michael@0 3628 assert_equals( testEl.properties.namedItem('baz').length, 1, 'outer baz.length when appended to document' );
michael@0 3629 assert_equals( testEl.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'outer baz[0] when appended to document' );
michael@0 3630 assert_true( !testEl.properties.namedItem('baz')[1], 'outer baz[1] when appended to document' );
michael@0 3631 assert_equals( testEl.properties.names.length, 3, 'outer names.length when appended to document' );
michael@0 3632 assert_equals( testEl.properties.names[0], 'foo', 'outer names[0] when appended to document' );
michael@0 3633 assert_equals( testEl.properties.names[1], 'bar', 'outer names[1] when appended to document' );
michael@0 3634 assert_equals( testEl.properties.names[2], 'baz', 'outer names[2] when appended to document' );
michael@0 3635 assert_true( !testEl.properties.names[3], 'outer names[3] when appended to document' );
michael@0 3636 assert_equals( testEl.firstChild.properties.length, 2, 'inner length when appended to document' );
michael@0 3637 assert_equals( testEl.firstChild.properties[0], testEl.firstChild.firstChild, 'inner properties[0] when appended to document' );
michael@0 3638 assert_equals( testEl.firstChild.properties[1], testEl.firstChild.firstChild.firstChild, 'inner properties[1] when appended to document' );
michael@0 3639 assert_true( !testEl.firstChild.properties[2], 'inner properties[2] when appended to document' );
michael@0 3640 assert_equals( testEl.firstChild.properties.namedItem('foo').length, 0, 'inner foo.length when appended to document' );
michael@0 3641 assert_true( !testEl.firstChild.properties.namedItem('foo')[0], 'inner foo[0] when appended to document' );
michael@0 3642 assert_equals( testEl.firstChild.properties.namedItem('bar').length, 1, 'inner bar.length when appended to document' );
michael@0 3643 assert_equals( testEl.firstChild.properties.namedItem('bar')[0], testEl.firstChild.firstChild, 'inner bar[0] when appended to document' );
michael@0 3644 assert_true( !testEl.firstChild.properties.namedItem('bar')[1], 'inner bar[1] when appended to document' );
michael@0 3645 assert_equals( testEl.firstChild.properties.namedItem('baz').length, 1, 'inner baz.length when appended to document' );
michael@0 3646 assert_equals( testEl.firstChild.properties.namedItem('baz')[0], testEl.firstChild.firstChild.firstChild, 'inner baz[0] when appended to document' );
michael@0 3647 assert_true( !testEl.firstChild.properties.namedItem('baz')[1], 'inner baz[1] when appended to document' );
michael@0 3648 assert_equals( testEl.firstChild.properties.names.length, 2, 'inner names.length when appended to document' );
michael@0 3649 assert_equals( testEl.firstChild.properties.names[0], 'bar', 'inner names[0] when appended to document' );
michael@0 3650 assert_equals( testEl.firstChild.properties.names[1], 'baz', 'inner names[1] when appended to document' );
michael@0 3651 assert_true( !testEl.firstChild.properties.names[2], 'inner names[2] when appended to document' );
michael@0 3652 } catch(e) {
michael@0 3653 document.body.removeChild(testEl);
michael@0 3654 throw (e);
michael@0 3655 }
michael@0 3656 document.body.removeChild(testEl);
michael@0 3657 }, 'itemref pointing to child of nested itemscope');
michael@0 3658
michael@0 3659 </script>
michael@0 3660 </body>
michael@0 3661 </html>

mercurial