function scopesAtIndex(parsed, index) { return tree.filter( scopes(parsed), scope => { var n = scope.node; var start = n.start, end = n.end; if (n.type === 'FunctionDeclaration') { start = n.params.length ? n.params[0].start : n.body.start; end = n.body.end; } return start <= index && index <= end; }, s => s.subScopes); }
export async function generateHTML(morph, htmlResource, options = {}) { if (htmlResource && !htmlResource.isResource) { options = htmlResource; htmlResource = null; } let { isFragment = false, addStyles = true, container: containerOpts, removeTargetFromLinks = true, addMetaTags, addScripts, appendHTML, title = false } = options, renderFreeStanding = containerOpts == false, {width: containerWidth, height: containerHeight, id: containerId} = containerOpts || {}, root = morphToNode(morph), htmlClassName = `html-${morph.name.replace(/[\s|"]/g, "-")}`; root.style.transform = ""; if (removeTargetFromLinks) { tree.postwalk(root, (node) => { if (String(node.tagName).toLowerCase() !== "a") return; if (node.target === "_blank" && !node.getAttribute("href").startsWith("http")) node.setAttribute("target", ""); }, n => n.childNodes); } let morphHtml = root.outerHTML, html; if (!renderFreeStanding) { morphHtml = `<div class="exported-morph-container ${htmlClassName}"` + (containerId ? ` id="${containerId}" ` : '') + `>` + `${morphHtml}\n</div>`; } if (isFragment) { html = addStyles ? morphicStyles() + morphHtml : morphHtml; if (appendHTML) html += appendHTML; } else { html = `<head> ${title ? `<title>${title}</title>` : ''} <meta content="utf-8" http-equiv="encoding"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type">`; if (addMetaTags) { let metaTags = typeof addMetaTags === "function" ? addMetaTags(morph, htmlResource, options) : addMetaTags, tagMarkup = []; for (let spec of metaTags) { let markup = "<meta" for (let prop in spec) markup += ` ${prop}="${spec[prop]}"`; markup += ">"; tagMarkup.push(markup); } html += "\n" + tagMarkup.join("\n") } if (addStyles) html += morphicStyles(); if (addScripts) html += addScripts; html += `</head><body style="margin: 0; overflow: hidden; width: 100%; height: 100%;">\n` + morphHtml + "\n"; if (appendHTML) html += appendHTML + "\n"; html += "</body>" } if (htmlResource) await htmlResource.write(html); // FIXME cleanup for HTML morphs... they "disappear" let htmlMorphs = []; htmlMorphs.push(...morph.withAllSubmorphsSelect(ea => ea.isHTMLMorph)); htmlMorphs.forEach(ea => { let o = ea.owner, i = o.submorphs.indexOf(ea); ea.remove(); setTimeout(() => o.addMorphAt(ea, i), 0) }); return html; }