中文版本

Preface

The <iframe> HTML element represents a nested browsing context, embedding another HTML page into the current one. – iframe

I want to have a iframe library that can bring Internet resources into Snap! through iframe element and interoperate with Snap!.

With it, we can do many interesting things:

  • Display markdown documents programmatically
  • Display instructional video programmatically
  • Display online slides programmatically
  • Introducing 3D world/game, and using Snap! to program these 3D world
  • Embed the MicroBlocks into Snap!

The potential use cases are very diverse!

When I shared the demonstration videos, @Patch commented:

This library opens a new window for Snap!

And I replied:

I also see the iframe library in this way, so the icon I just added to this library is the emoji window: 🪟

I have always wanted a iframe library, but I have been hesitant to start because I am not fond of and skilled in frontend work. Fortunately, with ChatGPT, these tasks have become easy. By collaborating with ChatGPT, I don’t have to worry about technical details (which I used to be not good at in the past), and I can focus on expressing ideas. Soon, I have been able to create something that I couldn’t have done on my own.

For me, the value of ChatGPT is twofold. Objectively, it fills in the gaps in my knowledge. But its greater value is subjective: it greatly reduced my fear of unfamiliar fields, which I used to avoid working in.By making knowledge details irrelevant, ChatGPT makes programming exciting again, allowing us to focus more on our passions and project visions.

iframe library

Like previous work, we hope to achieve the following two goals:

No need to update the Snap! platform, no developer intervention required, all work is done in the user environment (just a Snap! project), which means ordinary users can continue to extend these capabilities. (This is an example of end-user programming)

We can fully utilize the liveness of Snap! and enjoy an efficient and pleasant development experience.

So the iframe library is built entirely within the Snap! IDE, “just an ordinary Snap! project”, without any modifications to the platform.

We will demonstrate how to use the iframe library through several examples:

  • Basic usage (introducing external websites)
  • Display markdown documents dynamically
  • Embedding MicroBlocks Project
  • Interoperate with 3D world (using Spline as an example)
  • Send a message from the iframe page to Snap!

Basic usage

Project link (Click to Run)

You can also open multiple pages, each page can be controlled by its id:

Display markdown documents dynamically

Project link (Click to Run)

Help documentation in Snap!

The official block documentation of Snap! is made in the form of pictures (right-click a block and click help...):

Compared to using markdown to write and display documents, this is not flexible (for example, it cannot display videos).

The main reason I built the iframe is to support displaying documents using markdown.

iframe can display markdown documents in various ways, such as writing markdown documents in the usual way, hosting them on the web, and then using iframe to open the document link.

I used a dynamic solution that is more Snap!-style: hosting only a universal markdown rendering page (default blank). If you are interested in how it works, you can check the page source code. The code that makes things work is only 4 lines!

1
2
3
4
5
6
window.addEventListener("message", (event) => {
  console.log("Received message from main page:", event.data);
  document.getElementById("messageContainer").innerHTML = marked.parse(
    event.data
  );
});

Through the postMessage API, messages sent from the Snap! page can be received in the iframe page.

This page displays markdown content controlled by blocks!

Embedding MicroBlocks Project

Some projects involve hardware and software collaboration. Embedded MicroBlocks project in Snap! , no need to open the MicroBlocks page separately to upload or view the hardware program.

Project link (Click to Run)

Interoperate with 3D world (using Spline as an example)

Refer to Spline library for Snap!

FAQ

What is the iframe library used for?

Deploy your own web application, introduce it into Snap! using the iframe library, and then you can provide it with a highly customizable graphical programming environment!

In the past, this type of project would usually require a software developer to complete, it was just a user-level Snap! project!

What to do next?

Currently, Snap! and iframe pages can send messages to each other via postMessage API, and these messages are asynchronous and non-blocking.

  • Snap! -> iframe
    • Snap! side: Use the postMessage block to send messages to a specific iframe page
    • iframe side: Use window.addEventListener('message', (event) => {}) to receive the messages from Snap!
  • iframe -> Snap!
    • Snap! side: Use the handle postMessage block to receive the messages from iframe pages
    • iframe side:
      • Use window.parent.postMessage(msg, "*") to send a message.

Sometimes we want to synchronize messages, such as Call and wait for the result.

Dynatalk focuses on communication among objects

I plan to create dynatalk-over-postmessage: building dynatalk on top of postMessage. Once completed, all capabilities of dynatalk will be used in the iframe library.

Update: dynatalk-over-postmessage is complete, the Spline library uses it.

What permissions does the iframe page support?

The current iframe page supports the following permissions: allow = "geolocation; microphone; camera; bluetooth; serial"

ChatGPT: List all options for iframe allow

How can the iframe page in Snap! be made resizable and draggable?

Using jQuery UI, specifically:

html

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<div
  id="snap_iframe_container"
  style="left: 30%; top: 200px; width: 500px; height: 300px; padding: 1em"
>
  <iframe
    allow="geolocation; microphone; camera; bluetooth; serial"
    src="https://wwj718.github.io"
    class="ui-widget-content"
    id="snap_iframe_myiframe"
    style="width: 100%; height: 100%"
  ></iframe>
</div>

css:

1
2
3
4
5
6
7
8
9
#resizable {
  width: 150px;
  height: 150px;
  padding: 0.5em;
}
.ui-resizable-helper {
  border: 20px solid #efefef;
  margin: -20px;
}

js:

1
2
3
$("#snap_iframe_container")
  .resizable({ helper: "ui-resizable-helper" })
  .draggable();

How to control the game in the iframe page?

Web games are usually controlled by mouse/keyboard, and Snap! cannot directly trigger mouse/keyboard events.

One solution is to use MicroBlocks’ mouse and keyboard library (using the rpi pico board), and the message flow is:

Snap! -> MicroBlocks board -> computer

Project link (Click to Run)

References