<pre name="code" class="javascript"><pre name="code" class="javascript">//showModalDialog.js文件
(function() {
window.spawn = window.spawn || function(gen) {
function continuer(verb, arg) {
var result;
try {
result = generator[verb](arg);
} catch (err) {
return Promise.reject(err);
}
if (result.done) {
return result.value;
} else {
return Promise.resolve(result.value).then(onFulfilled, onRejected);
}
}
var generator = gen();
var onFulfilled = continuer.bind(continuer, 'next');
var onRejected = continuer.bind(continuer, 'throw');
return onFulfilled();
};
window.showModalDialog = window.showModalDialog || function(url, arg, opt) {
url = url || ''; //URL of a dialog
arg = arg || null; //arguments to a dialog
opt = opt || 'dialogWidth:300px;dialogHeight:200px'; //options: dialogTop;dialogLeft;dialogWidth;dialogHeight or CSS styles
//调用showModalDialog的函数会生成caller的属性
var caller = showModalDialog.caller.toString();
var dialog = document.body.appendChild(document.createElement('dialog'));
dialog.setAttribute('style', opt.replace(/dialog/gi, ''));
dialog.innerHTML = '<a href="#" id="dialog-close" style="position: absolute; top: 0; right: 4px; font-size: 20px; color: #000; text-decoration: none; outline: none;">×</a><iframe id="dialog-body" src="' + url + '" style="border: 0; width: 100%; height: 100%;"></iframe>';
document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
document.getElementById('dialog-close').addEventListener('click', function(e) {
e.preventDefault();
dialog.close();
});
dialog.showModal();
//if using yield
if(caller.indexOf('yield') >= 0) {
return new Promise(function(resolve, reject) {
dialog.addEventListener('close', function() {
var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
document.body.removeChild(dialog);
resolve(returnValue);
});
});
}
//if using eval
var isNext = false;
var nextStmts = caller.split('\n').filter(function(stmt) {
//从showModalDialog这一行开始截取
if(isNext || stmt.indexOf('showModalDialog(') >= 0)
return isNext = true;
return false;
});
dialog.addEventListener('close', function() {
var returnValue = document.getElementById('dialog-body').contentWindow.returnValue;
document.body.removeChild(dialog);
//把showModalDialog那行替换成一个返回值
nextStmts[0] = nextStmts[0].replace(/(window\.)?showModalDialog\(.*\)/g, JSON.stringify(returnValue));
//继续执行截断后的代码
eval('{\n' + nextStmts.join('\n'));
});
throw 'Execution stopped until showModalDialog is closed';
};
})();
//demo.js
<!DOCTYPE html>
<html>
<head>
<title>showModalDialog polyfill demo</title>
</head>
<body>
<h1>showModalDialog polyfill demo</h1>
<form action="">
<p>
<input id="button1" type="button" value="Show Modal Dialog using yield">
</p>
<p>
<input id="button2" type="button" value="Show Modal Dialog using eval">
</p>
</form>
<iframe src="http://ghbtns.com/github-btn.html?user=niutech&repo=showModalDialog&type=watch&count=true" height="30" width="118" frameborder="0" allowTransparency="true"></iframe>
<script src="showModalDialog.js"></script>
<script>
document.getElementById('button1').addEventListener('click', function() {
spawn(function*() {
var ret = yield window.showModalDialog("demo-modal.html", "some argument", "dialogWidth:500px;dialogHeight:200px");
alert("Returned from modal: " + ret);
});
});
</script>
<script>
document.getElementById('button2').addEventListener('click', function() {
var ret = window.showModalDialog("demo-modal.html", "some argument", "dialogWidth:500px;dialogHeight:200px");
alert("Returned from modal: " + ret);
});
</script>
</body>
</html>