(code, output)
| 113 | } |
| 114 | |
| 115 | async setHTML(code, output) { |
| 116 | this.clearEvents() |
| 117 | let loc = String(this.win.document.location) |
| 118 | if (loc != String(document.location) && !/\/empty\.html$/.test(loc)) { |
| 119 | this.frame.src = this.emptyPath + "empty.html" |
| 120 | await avaitEvent(this.frame, "load") |
| 121 | this.setupEnv() |
| 122 | return this.setHTML(code, output) |
| 123 | } |
| 124 | |
| 125 | let scriptTags = [], sandbox = this, doc = this.win.document |
| 126 | this.frame.style.display = "block" |
| 127 | let scriptRE = /<script\b[^>]*?(?:\bsrc\s*=\s*('[^']+'|"[^"]+"|[^\s>]+)[^>]*)?>([\s\S]*?)<\/script>/g |
| 128 | doc.documentElement.innerHTML = code.replace(scriptRE, function(_, src, content) { |
| 129 | let tag = doc.createElement("script") |
| 130 | if (src) { |
| 131 | if (/["']/.test(src.charAt(0))) src = src.slice(1, src.length - 1) |
| 132 | tag.src = src |
| 133 | } else { |
| 134 | tag.text = preprocess(content, sandbox).code |
| 135 | } |
| 136 | scriptTags.push(tag) |
| 137 | return "" |
| 138 | }) |
| 139 | |
| 140 | this.frame.style.height = "80px" |
| 141 | this.resizeFrame() |
| 142 | if (output) this.output = output |
| 143 | |
| 144 | for (let tag of scriptTags) { |
| 145 | sandbox.startedAt = Date.now() |
| 146 | sandbox.extraSecs = 2 |
| 147 | sandbox.win.__c = 0 |
| 148 | if (tag.src) { |
| 149 | doc.body.appendChild(tag) |
| 150 | await awaitEvent(tag, "load") |
| 151 | } else { |
| 152 | await new Promise(ok => { |
| 153 | let id = randomID() |
| 154 | sandbox.callbacks[id] = () => { delete sandbox.callbacks[id]; ok() } |
| 155 | tag.text += "\n;__sandbox.callbacks['" + id + "']();" |
| 156 | doc.body.appendChild(tag) |
| 157 | }) |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | if (scriptTags.length || doc.querySelector("img")) setTimeout(() => sandbox.resizeFrame(), 100) |
| 162 | } |
| 163 | |
| 164 | setupEnv() { |
| 165 | let win = this.win |
no test coverage detected