diff --git a/showModalDialog.js b/showModalDialog.js index 87be6d7..10c2336 100644 --- a/showModalDialog.js +++ b/showModalDialog.js @@ -1,4 +1,7 @@ (function() { + // All references to document object will be on top window + var dialogDocument = window.top.document; + window.spawn = window.spawn || function(gen) { function continuer(verb, arg) { var result; @@ -18,43 +21,151 @@ var onRejected = continuer.bind(continuer, 'throw'); return onFulfilled(); }; - window.showModalDialog = window.showModalDialog || function(url, arg, opt) { + + // Override window.close function to close the last dialog created, + // if window.shoModalDialog function doesn't exist + window.close = window.showModalDialog ? window.close : function(close) { + return function() { + var dialogTags = dialogDocument.getElementsByTagName('dialog'); + var dialog = dialogTags[dialogTags.length - 1]; + if (dialog) + dialog.close(); + else + return close.call(); + }; + }(window.close); + + // Override window.shoModalDialog function if doesn't exist + 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 - var caller = showModalDialog.caller.toString(); - var dialog = document.body.appendChild(document.createElement('dialog')); + + // To create an interface for the showModalDialog place showModalDialog.interface in a comment inside + // e.g.: function showMaximizedDialog(url, args, options) { // showModalDialog.interface + var callerName = (showModalDialog.caller + '').indexOf('showModalDialog.interface') > -1 ? showModalDialog.caller.name : 'showModalDialog'; + + // If it's only an interface, call the caller from caller + var caller = (callerName === 'showModalDialog' ? showModalDialog.caller : showModalDialog.caller.caller); + var dialogTitle = 'dialog-title'; + caller = showModalDialog.caller.toString(); + var dialog = dialogDocument.body.appendChild(dialogDocument.createElement('dialog')); + var lastDialog = dialogDocument.querySelectorAll('dialog')[dialogDocument.querySelectorAll('dialog').length - 1]; dialog.setAttribute('style', opt.replace(/dialog/gi, '')); - dialog.innerHTML = '×'; - document.getElementById('dialog-body').contentWindow.dialogArguments = arg; - document.getElementById('dialog-close').addEventListener('click', function(e) { + dialog.innerHTML = '
'; + dialog.innerHTML += '×'; + dialog.innerHTML += '
'; + lastDialog.querySelector('#dialog-body').contentWindow.dialogArguments = arg; + lastDialog.querySelector('#dialog-close').addEventListener('click', function (e) { e.preventDefault(); dialog.close(); }); + + // -------------------------------------------------------------- + // Create the css part for the dialog + if (!dialogDocument.getElementById('dialog-css')) { + var css = '' + + '#dialog-close a {font-size: 20px; color: #FFF; text-decoration: none; outline: none;}' + + '#dialog-body {border: 0; width: 100%; height: 100%;}' + + '-->'; + + var head = dialogDocument.head || dialogDocument.getElementsByTagName('head')[0]; + var style = dialogDocument.createElement('style'); + + style.type = 'text/css'; + style.id = 'dialog-css'; + style.appendChild(dialogDocument.createTextNode(css)); + head.appendChild(style); + } + + // -------------------------------------------------------------- + // Make the dialog draggable + var pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; + + dialog.querySelector('#' + dialogTitle).onmousedown = dragMouseDown; + + function dragMouseDown(e) { + e = e || window.event; + e.preventDefault(); + // get the mouse cursor position at startup + pos3 = e.clientX; + pos4 = e.clientY; + dialogDocument.onmouseup = closeDragElement; + // call a function whenever the cursor moves + dialogDocument.onmousemove = elementDrag; + } + + function elementDrag(e) { + e = e || window.event; + e.preventDefault(); + // calculate the new cursor position + pos1 = pos3 - e.clientX; + pos2 = pos4 - e.clientY; + pos3 = e.clientX; + pos4 = e.clientY; + // set the element's new position + dialog.style.top = (dialog.offsetTop - pos2) + "px"; + dialog.style.marginLeft = (dialog.offsetLeft - pos1) + "px"; + } + + function closeDragElement() { + // stop moving when mouse button is released + dialogDocument.onmouseup = null; + dialogDocument.onmousemove = null; + } + dialog.showModal(); + //if using yield or async/await - if(caller.indexOf('yield') >= 0 || caller.indexOf('await') >= 0) { - return new Promise(function(resolve, reject) { - dialog.addEventListener('close', function() { - var returnValue = document.getElementById('dialog-body').contentWindow.returnValue; - document.body.removeChild(dialog); + if (caller.indexOf('yield') >= 0 || caller.indexOf('await') >= 0) { + return new Promise(function (resolve, reject) { + dialog.addEventListener('close', function () { + var returnValue = lastDialog.querySelector('#dialog-body').contentWindow.returnValue; + dialogDocument.body.removeChild(dialog); resolve(returnValue); }); }); } + //if using eval var isNext = false; var nextStmts = caller.split('\n').filter(function(stmt) { - if(isNext || stmt.indexOf('showModalDialog(') >= 0) + if (isNext || stmt.indexOf(callerName + '(') >= 0) return isNext = true; return false; }); + dialog.addEventListener('close', function() { - var returnValue = document.getElementById('dialog-body').contentWindow.returnValue; - document.body.removeChild(dialog); - nextStmts[0] = nextStmts[0].replace(/(window\.)?showModalDialog\(.*\)/g, JSON.stringify(returnValue)); - eval('{\n' + nextStmts.join('\n')); + var returnValue = lastDialog.querySelector('#dialog-body').contentWindow.returnValue; + dialogDocument.body.removeChild(dialog); + nextStmts[0] = nextStmts[0].replace(new RegExp('(window\.)?' + callerName + '\(.*\)' , 'g'), JSON.stringify(returnValue)); + var unclosedParenthesis = (nextStmts[0].match(/\(/g) || []).length - (nextStmts[0].match(/\)/g) || []).length; + var closeParenthesis = repeat(')', unclosedParenthesis); + nextStmts[0] += closeParenthesis; + var decodedStmts = nextStmts.join('\n').replace(/^function\s+\(\s*\)\s*{/, ''); + var unopenedBraces = (decodedStmts.match(/}/g) || []).length - (decodedStmts.match(/{/g) || []).length; + var openBraces = repeat('{', unopenedBraces); + eval(openBraces + '\n' + decodedStmts); }); + + // -------------------------------------------------------------- + // Function to repeat string + function repeat(pattern, count) { + if (count < 1) return ''; + var result = ''; + while (count > 1) { + if (count & 1) result += pattern; + count >>= 1, pattern += pattern; + } + return result + pattern; + } + throw 'Execution stopped until showModalDialog is closed'; }; -})(); \ No newline at end of file +})();