2019-12-24 00:54:17 +01:00
|
|
|
const iframeAPI = function(){
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
const methods = [
|
|
|
|
{
|
|
|
|
name: "own window",
|
|
|
|
prepare: function(){
|
|
|
|
return {
|
|
|
|
window,
|
|
|
|
cleanup: function(){}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "simple",
|
|
|
|
prepare: function(){
|
|
|
|
const iframe = document.createElement("iframe");
|
|
|
|
iframe.style.display = "none";
|
|
|
|
document.body.appendChild(iframe);
|
|
|
|
|
|
|
|
return {
|
|
|
|
window: iframe.contentWindow,
|
|
|
|
cleanup: function(){
|
|
|
|
iframe.parentNode.removeChild(iframe);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "window.frames",
|
|
|
|
prepare: function(){
|
|
|
|
const iframe = document.createElement("iframe");
|
|
|
|
document.body.appendChild(iframe);
|
|
|
|
const window = frames[frames.length - 1];
|
|
|
|
return {
|
|
|
|
window,
|
|
|
|
cleanup: function(){
|
|
|
|
document.body.removeChild(iframe);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "window[window.length - 1]",
|
|
|
|
prepare: function(){
|
|
|
|
const iframe = document.createElement("iframe");
|
|
|
|
document.body.appendChild(iframe);
|
|
|
|
const iframeWindow = window[window.length - 1];
|
|
|
|
return {
|
|
|
|
window: iframeWindow,
|
|
|
|
cleanup: function(){
|
|
|
|
document.body.removeChild(iframe);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "sneaky window[...]",
|
|
|
|
prepare: function(){
|
|
|
|
const index = window.length;
|
|
|
|
const iframe = document.createElement("iframe");
|
|
|
|
document.body.appendChild(iframe);
|
|
|
|
const iframeWindow = window[index];
|
|
|
|
return {
|
|
|
|
window: iframeWindow,
|
|
|
|
cleanup: function(){
|
|
|
|
document.body.removeChild(iframe);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "nested iFrames",
|
|
|
|
prepare: function(){
|
|
|
|
const index = window.length;
|
|
|
|
const iframe = document.createElement("iframe");
|
|
|
|
document.body.appendChild(iframe);
|
|
|
|
const iframeWindow = window[index];
|
|
|
|
iframeWindow.document.write("<iframe></iframe>");
|
|
|
|
return {
|
|
|
|
window: iframeWindow[0],
|
|
|
|
cleanup: function(){
|
|
|
|
document.body.removeChild(iframe);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
2023-04-19 14:34:37 +02:00
|
|
|
name: "removed iframe",
|
2019-12-24 00:54:17 +01:00
|
|
|
prepare: async function openWindow(){
|
2023-04-19 14:34:37 +02:00
|
|
|
const iframe = document.createElement("iframe");
|
|
|
|
document.body.appendChild(iframe);
|
|
|
|
const iframeWindow = iframe.contentWindow;
|
|
|
|
document.body.removeChild(iframe);
|
|
|
|
console.log("window of iframe directly after removing", iframeWindow);
|
|
|
|
return new Promise(function(resolve){
|
|
|
|
window.setTimeout(function(){
|
|
|
|
console.log("window of iframe in timeout", iframeWindow);
|
|
|
|
resolve(iframeWindow);
|
|
|
|
}, 1000);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
|
|
|
["/", "about:blank", "about:blank#"].forEach(function(url){
|
|
|
|
methods.push({
|
|
|
|
name: "window.open " + url,
|
|
|
|
prepare: async function openWindow(){
|
|
|
|
const newWindow = window.open(url);
|
2019-12-24 00:54:17 +01:00
|
|
|
if (newWindow){
|
|
|
|
return {
|
|
|
|
window: newWindow,
|
|
|
|
cleanup: function(){
|
|
|
|
newWindow.close();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
return new Promise(function(resolve){
|
|
|
|
window.addEventListener("click", function openWindowEventListener(){
|
|
|
|
window.removeEventListener("click", openWindowEventListener);
|
|
|
|
resolve(openWindow());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
2023-04-19 14:34:37 +02:00
|
|
|
});
|
|
|
|
});
|
2019-12-24 00:54:17 +01:00
|
|
|
|
|
|
|
function getPerformer(callback){
|
2021-06-12 00:50:05 +02:00
|
|
|
return async function perform(method){
|
2023-04-19 14:34:37 +02:00
|
|
|
console.log("run iframe method", method.name);
|
2019-12-24 00:54:17 +01:00
|
|
|
const api = await method.prepare();
|
|
|
|
callback(api.window, method.name);
|
|
|
|
api.cleanup();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
forEachMethod: function(callback){
|
|
|
|
methods.forEach(getPerformer(callback));
|
|
|
|
},
|
|
|
|
performMethod: function(callback, name){
|
|
|
|
methods.filter(function(method){
|
|
|
|
return method.name === name;
|
|
|
|
}).forEach(getPerformer(callback));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}();
|