Archive for DOM

Suspend in the browser, resume on the desktop.

Posted in Appsterdam, consulting, Context, Naiad, Smalltalk, Spoon with tags , , , , , , , , on 29 October 2016 by Craig Latta

In yesterday’s post, I showed how Bert Freudenberg’s SqueakJS can extend Smalltalk‘s traditional host platform integration for the web, with DOM access through my class ThisWebpage. With this we can build any front-end HTML5 webapp behavior that any other JavaScript framework can. Another thing we can do with ThisWebpage is install the native-app version of Squeak, giving us the full speed of Eliot Miranda’s Cog virtual machine.

Running Smalltalk on the web is a satisfying thing, but there are times when you need more speed or host operating system access than JavaScript in a web browser can provide. Eventually, we’ll be able to embed native code in web browsers using WebAssembly, which will be a big improvement. Even then, though, there will still be the platform access compromises that come with a sandboxed web environment. So, one obvious thing to do with our JavaScript access is move our Smalltalk processes to the desktop, where we can use the high-performance Cog virtual machine.

platform portability

Smalltalk is an image-based system. In addition to modeling an idealized processor, with its own instruction set, the Smalltalk virtual machine models the processor’s memory. The virtual machine can make a snapshot of this memory, as a normal host platform file called an image. This snapshot captures the complete execution state of the Smalltalk system (the object memory), including the program counters of every process that was running at the time. The virtual machine can also resume this snapshot, restoring that system state so that the system may continue. This is similar to the “sleep” function of a laptop.

Since the virtual machine provides a consistent platform abstraction above whatever host is running it, we can suspend the system on one host and resume it on another. Smalltalk programmers have taken great advantage of this for years, writing single systems which run on multiple operating systems (e.g., Macintosh and Windows). Java attempted to provide consistent execution semantics, under the tagline “write once, run anywhere” (with mixed results), but this did not extend to a continuous memory image. We can make an object memory snapshot with SqueakJS in a web browser, and resume it with Cog in a native app.

exporting ourselves

SqueakJS uses the HTML5 “indexed database” feature for persistent storage, making it look like a normal filesystem. We can write a snapshot of the running SqueakJS system this way. We can then use ThisWebpage to download the snapshot to the user’s machine. We add a link to the document in which SqueakJS runs, and synthesize a click on it, invoking the download.

We also use ThisWebpage to detect the user’s host operating system, and download a platform-specific Cog installer. I’ve written installers for macOS, Windows, and Linux. Each one downloads the Cog virtual machine, installs a platform handler for “squeak://” URLs that runs Cog, and invokes a squeak:// URL that runs our snapshot. This URL encodes the name of the snapshot file, Cog parameters (such as whether or not to run the system headless), and a base64-encoded JSON dictionary of other parameters that the Smalltalk object memory can process.

making contact

Now our object memory is running both in the browser in SqueakJS, and in Cog as a native app. The current Black Page Digital object memory for Squeak connects the two with a remote-messaging network service. When the SqueakJS-hosted instance invokes the local one, it also forks a process that periodically attempts a remote-messaging connection. When the memory resumes on a non-web host, it starts a WebSocket-based server to provide remote messaging service.

With the two Squeaks connected, objects in one can send messages to objects in the other, creating a distributed system. The Cog-based system now has access to the DOM of the web browser through ThisWebpage in the SqueakJS-based system, and the SqueakJS-based system has unsandboxed access to the host operating system through the Cog-based system. In particular, SqueakJS can use Cog to run network servers, so one can create a distributed system from SqueakJS instances running in many web browsers on many machines.

In tomorrow’s post, I’ll discuss the remote messaging protocol in more detail. After that, I’ll introduce a distributed network service that takes advantage of it.


SqueakJS changes its world with ThisWebpage

Posted in Appsterdam, consulting, Context, Naiad, Smalltalk, Spoon with tags , , , , , , , , , , , , on 28 October 2016 by Craig Latta

a new platform

Since becoming a virtual-machine-based app, Smalltalk has integrated well with other operating systems, providing the illusion of a consistent unified platform. With the ascendancy of JavaScript, the common execution environment provided by web browsers is effectively another host operating system. Smalltalk runs there too now, thanks to Bert Freudenberg’s SqueakJS. So in addition to macOS, Windows, and Linux, we now have the Web host platform.

While all platforms expose some of their functionality to apps through system calls, the Web exposes much more, through its Document Object Model API (DOM). This gives Smalltalk a special opportunity to enable livecoded apps on this platform. It also means that Smalltalk can interoperate more extensively with other Web platform apps, and participate in the ecosystem of JavaScript frameworks, both as a consumer and a producer.

to JavaScript and back

The part of SqueakJS which enables this is its bidirectional JavaScript bridge. This is implemented by class JSObjectProxy, and some special support in the SqueakJS virtual machine. One may set Smalltalk variables to JavaScript objects, send messages to JavaScript objects, and provide Smalltalk block closures as callback functions to JavaScript. One may interact with any JavaScript object in the Web environment. This means we can manipulate DOM objects as any other JavaScript framework would, to create new HTML5 user interfaces and modify existing ones.

In particular, we can embed SqueakJS in a web page, and modify that web page from SqueakJS processes. It would be very useful to have a Smalltalk object model of the host web page. I have created such a thing with the new class ThisWebpage.

reaching out with ThisWebpage

I chose the name of ThisWebpage to be reminiscent of “thisContext”, the traditional Smalltalk pseudo-variable used by an expression to access its method execution context. In a similar way, expressions can use ThisWebpage to access the DOM of the hosting Web environment. One simple example is adding a button:

  createButtonLabeled: 'fullscreen'
  evaluating: [Project current fullscreen: true]

Behind the scenes, ThisWebpage is doing this:

(JS document createElement: 'input')
  at: #type
  put: 'button';
  at: #onclick:
  put: [Project current fullscreen: true]

Class JSObjectProxy creates JS, an instance of itself, during installation of the JavaScript bridge. It corresponds to the JavaScript DOM object for the current web browser window, the top of the DOM object graph. By sending createElement:, the expression is invoking one of the DOM methods. The entire set of DOM methods is well-documented online (for example, here’s the documentation for Document.createElement).

So far, ThisWebpage has some basic behavior for adding buttons and frames, and for referring to the document elements in which SqueakJS is embedded. It can also create links and synthesize clicks on them. This is an important ability, which I use in making a Squeak object memory jump from SqueakJS in a web browser to a native Cog virtual machine on the desktop (the subject of tomorrow’s post).

The possibilities here are immense. ThisWebpage is waiting for you to make it do amazing front-end things! Check it out as part of the Context 7 alpha 1 release.


%d bloggers like this: