niutech / showModalDialog

window.showModalDialog polyfill using a <dialog> element
https://niutech.github.io/showModalDialog/demo.html
Apache License 2.0
177 stars 88 forks source link

Perhaps a better solution #42

Closed bumprat closed 4 years ago

bumprat commented 5 years ago

Problem: To rewrite functions with showModalDialog into async/await is rather expensive.

My solution: 1st: Use "asyncify" helper function to make function asynchronous:

function asyncify (fn, awaitFor) {
  var fnStr = String(fn)
  var charArr = fnStr.split('')
  var curCur = {level:0, fnPos:-1}
  var fnPos = -1
  var awaitPos = []
  var asyncPos = []
  awaitFor = new RegExp(awaitFor, 'g')
  while ((match = awaitFor.exec(fnStr)) != null) {
      awaitPos.push(match.index)
  }
  charArr.forEach((c, index) => {
    if(c==='{'){
      curCur = {level:curCur.level+1, fnPos, parent:curCur}
      fnPos = -1
    }else if(c==='}'){
      curCur = curCur.parent
    }else if(fnStr.substr(index, 8)==='function'){
      fnPos = index 
    }else if(awaitPos.indexOf(index)>=0){
      var sf = curCur
      while(sf.fnPos<0){
        sf = sf.parent
      }
      asyncPos.push(sf.fnPos)
    }
  })
  awaitPos.forEach((pos) => {
    charArr[pos] = 'await ' + charArr[pos]
  })
  asyncPos.forEach((pos) => {
    charArr[pos] = 'async ' + charArr[pos]
  })
  return new Function("return " + charArr.join(''))()
}
function a(){
    function b(){
        window.showModalDialog()
    }
    showModalDialog()
}
asyncify(a, /(window\.)?showModalDialog/g)

/* will return 
async function a(){
    async function b(){
        await window.showModalDialog()
    }
    await showModalDialog()
}
*/

2rd: use showModalDialog polyfill by async/await