sunderls / swa

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SWA (prototype)

AMP offers built-in component(carousel, story .etc) with stricter syntax, together with CDN cache, it helps build fast web pages, because now developers couldn't mess around the code easily.

other than stricter HTML syntax and valiator, what about another approach - forbidding direct DOM manipulation?

lik we could separate the logic and view,

  1. developers write the logic
  2. but the view is controlled by the host

following demo is just a PoC demo

Demo

here is a demo

Jan-31-2020 01-58-13

Implementation

  1. host.html run the app (app.js) in an iframe, with swa.js as the runtime

  2. host ask app to generate the html

sendMessageToSandbox("render", {}, data => {
  $canvas.append(render(data.html))
})
  1. app return html representation to host, with 2 <p> and a <carousel>
sendMessageToHost("callback", {
  html: {
    tag: "div",
    children: [
      {
        tag: "p",
        children: [
          "I'm sandboxed script,  I can ask host to render what I want, like this built-in carousel"
        ]
      },
      {
        tag: "p",
        children: [
          "I cannot manipulate the DOM directly, so I couldn't make things too bad"
        ]
      },
      {
        tag: "carousel",
        props: {
          width: 400,
          height: 300,
          images: [
            "https://unsplash.it/400/300?image=11",
            "https://unsplash.it/400/300?image=10",
            "https://unsplash.it/400/300?image=12"
          ]
        }
      }
    ]
  }
})
  1. host receive the JSON, and render it into DOM
const render = ({ tag, children = [], props = {} }) => {
  switch (tag) {
    case "carousel":
      ...
      return $div
    default:
      const el = document.createElement(tag)
      for (let key in props) {
        el.setAttribute(key, props[key])
      }
      for (let child of children) {
        if (typeof child === "string") {
          el.append(document.createTextNode(child))
        } else {
          el.append(render(child))
        }
      }
      return el
  }
}

About