| <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> |
| <html> |
| <head> |
| <script src="../../resources/js-test.js"></script> |
| </head> |
| <body> |
| <script> |
| description("Make sure prototypes are set up using the window a property came from, instead of the lexical global object.") |
| |
| var subframe = document.createElement("iframe"); |
| document.body.appendChild(subframe); |
| var inner = subframe.contentWindow; // Call it "inner" to make shouldBe output shorter |
| |
| // Stash a property on the prototypes. |
| window.Object.prototype.isInner = false; |
| inner.Object.prototype.isInner = true; |
| |
| function classNameForObject(object) |
| { |
| // call will use the global object if passed null or undefined, so special case those: |
| if (object == null) |
| return null; |
| var result = Object.prototype.toString.call(object); |
| // remove '[object ' and ']' |
| return result.split(' ')[1].split(']')[0]; |
| } |
| |
| function constructorPropertiesOnWindow(globalObject) |
| { |
| var constructorNames = []; |
| var propertyNames = Object.getOwnPropertyNames(window); |
| for (var i = 0; i < propertyNames.length; i++) { |
| var value = inner[propertyNames[i]]; |
| if (value == null) |
| continue; |
| var type = classNameForObject(value); |
| // Ignore these properties because they do not exist in all implementations. They will be tested separately |
| if (type == "WebGLRenderingContextConstructor" || |
| type == "ArrayBufferConstructor" || |
| type =="Float32ArrayConstructor" || |
| type =="Float64ArrayConstructor" || |
| type =="Int8ArrayConstructor" || |
| type =="Int16ArrayConstructor" || |
| type =="Int32ArrayConstructor" || |
| type =="Uint8ArrayConstructor" || |
| type =="Uint8ClampedArrayConstructor" || |
| type =="Uint16ArrayConstructor" || |
| type =="Uint32ArrayConstructor" || |
| type == "FileReaderConstructor" || |
| type == "AudioContextConstructor" || |
| type == "SpeechSynthesisUtteranceConstructor") |
| continue; |
| if (!type.match('Constructor$')) |
| continue; |
| constructorNames.push(property); |
| } |
| return constructorNames.sort(); |
| } |
| |
| var constructorNames = constructorPropertiesOnWindow(inner); |
| |
| var argumentsForConstructor = { |
| 'Worker' : "'foo'", |
| } |
| |
| for (var x = 0; x < constructorNames.length; x++) { |
| var constructorName = constructorNames[x]; |
| var arguments = argumentsForConstructor[constructorName] || ""; |
| var argumentsString = "(" + arguments + ")"; |
| // Test first to see if the object is constructable |
| var constructedObject; |
| try { |
| constructedObject = eval("new inner." + constructorName + argumentsString); |
| } catch(e) { |
| continue; |
| } |
| |
| shouldBeTrue("(new inner." + constructorName + argumentsString + ").isInner"); |
| shouldBeTrue("(new inner." + constructorName + argumentsString + ").constructor.isInner"); |
| } |
| |
| document.body.removeChild(subframe); |
| </script> |
| </body> |
| </html> |