1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/js/xpconnect/tests/chrome/test_scriptSettings.xul Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,127 @@ 1.4 +<?xml version="1.0"?> 1.5 +<?xml-stylesheet type="text/css" href="chrome://global/skin"?> 1.6 +<?xml-stylesheet type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?> 1.7 +<!-- 1.8 +https://bugzilla.mozilla.org/show_bug.cgi?id=937317 1.9 +--> 1.10 +<window title="Mozilla Bug 937317" 1.11 + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> 1.12 + <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/> 1.13 + 1.14 + <!-- test results are displayed in the html:body --> 1.15 + <body xmlns="http://www.w3.org/1999/xhtml"> 1.16 + <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=937317" 1.17 + target="_blank">Mozilla Bug 937317</a> 1.18 + </body> 1.19 + 1.20 + <!-- test code goes here --> 1.21 + <iframe src="data:text/html,"></iframe> 1.22 + <script type="application/javascript"> 1.23 + <![CDATA[ 1.24 + 1.25 + /** Test for the script settings stack. **/ 1.26 + SimpleTest.waitForExplicitFinish(); 1.27 + addLoadEvent(function() { 1.28 + const Cu = Components.utils; 1.29 + Cu.import("resource://gre/modules/Promise.jsm"); 1.30 + iwin = window[0]; 1.31 + 1.32 + // Smoketest. 1.33 + is(Cu.getIncumbentGlobal(), window, "smoketest"); 1.34 + 1.35 + // Calling a cross-compartment non-scripted function changes the 1.36 + // compartment, but not the incumbent script settings object. 1.37 + var sb = new Cu.Sandbox(window, { wantComponents: true }); 1.38 + is(sb.Components.utils.getIncumbentGlobal(), window, "cross-compartment sb non-scripted"); 1.39 + is(iwin.Components.utils.getIncumbentGlobal(), window, "cross-compartment win non-scripted"); 1.40 + 1.41 + // If we call a scripted function in the other compartment, that becomes 1.42 + // the incumbent script. 1.43 + function gib() { return Components.utils.getIncumbentGlobal(); }; 1.44 + Cu.evalInSandbox(gib.toSource(), sb); 1.45 + iwin.eval(gib.toSource()); 1.46 + is(sb.gib(), sb, "cross-compartment sb scripted"); 1.47 + is(iwin.gib(), iwin, "cross-compartment win scripted"); 1.48 + 1.49 + // Eval-ing top-level script in another component makes that compartment the 1.50 + // incumbent script. 1.51 + is(Cu.evalInSandbox('Components.utils.getIncumbentGlobal()', sb), sb, 'eval sb'); 1.52 + is(iwin.eval('Components.utils.getIncumbentGlobal()'), iwin, 'eval iwin'); 1.53 + 1.54 + // Make sure that the callback mechanism works. 1.55 + function makeCallback(expectedGlobal, deferred, kind) { 1.56 + function cb(incumbentGlobal) { 1.57 + is(incumbentGlobal, expectedGlobal, "Callback got the right incumbent global: " + kind); 1.58 + if (deferred) 1.59 + deferred.resolve(); 1.60 + } 1.61 + info("Generated callback: " + kind); 1.62 + return cb; 1.63 + } 1.64 + 1.65 + var bound = Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, undefined, "simple bound")); 1.66 + is(bound(), window, "Bound method returns the right global"); 1.67 + 1.68 + // Callbacks grab the incumbent script at the time of invocation. 1.69 + // 1.70 + // Note - We avoid calling the initial defer |d| so that it's not in-scope for everything below. 1.71 + let initialDefer = Promise.defer(); 1.72 + setTimeout(Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, initialDefer, "same-global setTimeout")), 0); 1.73 + initialDefer.promise.then(function() { 1.74 + 1.75 + // Try cross-global setTimeout where |window| is the incumbent script when the callback is created. 1.76 + let d = Promise.defer(); 1.77 + iwin.setTimeout(Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, d, "cross-global setTimeout by |window|")), 0); 1.78 + return d.promise; 1.79 + }).then(function() { 1.80 + 1.81 + // Try cross-global setTimeout where |iwin| is the incumbent script when the callback is created. 1.82 + let d = Promise.defer(); 1.83 + iwin.wrappedJSObject.timeoutFun = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global setTimeout by |iwin|")); 1.84 + iwin.eval('setTimeout(timeoutFun, 0);'); 1.85 + return d.promise; 1.86 + }).then(function() { 1.87 + 1.88 + // The incumbent script override doesn't take effect if the callback is scripted. 1.89 + let d = Promise.defer(); 1.90 + iwin.wrappedJSObject.timeoutFun2 = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global setTimeout of scripted function")); 1.91 + iwin.eval('let timeoutFun2Wrapper = function() { timeoutFun2(); }'); 1.92 + setTimeout(iwin.wrappedJSObject.timeoutFun2Wrapper, 0); 1.93 + return d.promise; 1.94 + }).then(function() { 1.95 + 1.96 + // Try event listeners. 1.97 + let d = Promise.defer(); 1.98 + let body = iwin.document.body; 1.99 + body.addEventListener('click', Cu.getIncumbentGlobal.bind(Cu, makeCallback(window, d, "cross-global event listener"))); 1.100 + body.dispatchEvent(new iwin.MouseEvent('click')); 1.101 + return d.promise; 1.102 + 1.103 + }).then(function() { 1.104 + 1.105 + // Try an event handler set by |iwin|. 1.106 + let d = Promise.defer(); 1.107 + let body = iwin.document.body; 1.108 + iwin.wrappedJSObject.handler = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global event handler")); 1.109 + iwin.eval('document.body.onmousemove = handler'); 1.110 + body.dispatchEvent(new iwin.MouseEvent('mousemove')); 1.111 + return d.promise; 1.112 + 1.113 + }).then(function() { 1.114 + 1.115 + // Try an event handler compiled by a content attribute. 1.116 + let d = Promise.defer(); 1.117 + let body = iwin.document.body; 1.118 + iwin.wrappedJSObject.innerHandler = Cu.getIncumbentGlobal.bind(Cu, makeCallback(iwin, d, "cross-global compiled event handler")); 1.119 + iwin.eval("document.body.setAttribute('onmouseout', 'innerHandler()')"); 1.120 + body.dispatchEvent(new iwin.MouseEvent('mouseout')); 1.121 + return d.promise; 1.122 + }).then(function() { 1.123 + 1.124 + SimpleTest.finish(); 1.125 + }); 1.126 + }); 1.127 + 1.128 + ]]> 1.129 + </script> 1.130 +</window>