observable-forEach.window.js (1676B)
1 async function loadIframeAndReturnContentWindow() { 2 // Create and attach an iframe. 3 const iframe = document.createElement('iframe'); 4 const iframeLoadPromise = new Promise((resolve, reject) => { 5 iframe.onload = resolve; 6 iframe.onerror = reject; 7 }); 8 document.body.append(iframe); 9 await iframeLoadPromise; 10 return iframe.contentWindow; 11 } 12 13 promise_test(async t => { 14 const contentWin = await loadIframeAndReturnContentWindow(); 15 16 window.results = []; 17 18 contentWin.eval(` 19 const parentResults = parent.results; 20 21 const source = new Observable(subscriber => { 22 window.frameElement.remove(); 23 24 // This invokes the forEach() operator's internal observer's next steps, 25 // which at least in Chromium, must have a special "context is detached" 26 // check to early-return, so as to not crash. 27 subscriber.next(1); 28 }); 29 30 source.forEach(value => { 31 parentResults.push(value); 32 }); 33 `); 34 35 // If we got here, we didn't crash! Let's also check that `results` is empty. 36 assert_array_equals(results, []); 37 }, "forEach()'s internal observer's next steps do not crash in a detached document"); 38 39 promise_test(async t => { 40 const contentWin = await loadIframeAndReturnContentWindow(); 41 42 window.results = []; 43 44 contentWin.eval(` 45 const parentResults = parent.results; 46 47 const source = new Observable(subscriber => { 48 subscriber.next(1); 49 }); 50 51 source.forEach(value => { 52 window.frameElement.remove(); 53 parentResults.push(value); 54 }); 55 `); 56 57 assert_array_equals(results, [1]); 58 }, "forEach()'s internal observer's next steps do not crash when visitor " + 59 "callback detaches the document");