Example #1
0
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;
}