Single Page Apps - The Future

demystified by Aaron Rosenzweig

aaron@chatnbike.com

Codivus, Inc.

The future looks like:

<html>
  <head>
    <title>My App</title>
    <script src="enyo/enyo.js"></script>
    <script src="source/package.js"></script>
  </head>
  <body class="enyo-unselectable">
    <script>
      new MyApp().renderInto(document.body);
    </script>
  </body>
</html>

That's it - nothing more

The future is objects

Sound familiar?

To see the future

We must embrace the past

What does old mean?

Growing old is mandatory

Growing up is optional

https://www.youtube.com/watch?v=OFHYSbDl-cY

Chronology

Hypercard

Hypertext

Webcrawler

WebKit / WebObjects

Prototype / Scriptaculous

Ajax (Web 2.0)

Page-by-page Apps

Single Page Apps

What is WO missing?

WO in the future

WebOS Framework Chronology

Palm -> HP -> LG -> Open Source

Why WebOS tools / Enyo?

Why not Enyo / Ares?

Yes indeed

White man trick Indian once?

Shame on White man

White man trick Indian twice?

Shame on Indian

Read licenses carefully

Mojo example

<html>
  <head>
    <script src="/usr/palm/frameworks/mojo/mojo.js"></script>
  </head>
  <body>
    <div class="palm-page-header">
      <div class="title">
        My First webOS App!
      </div>
    </div>

    <button class="palm-button" id="my-awesome-button">
      I'm an awesome button!
    </button>

    <div id="content">
          Hello, world!<br/>
          <img src="icon.png"/>
    </div>
  </body>
</html>

jQuery Mobile example

<html>
  <head>
    <link rel="stylesheet" href="jquery.mobile-1.4.5.min.css">
    <script src="jquery-1.11.2.min.js"></script>
    <script src="jquery.mobile-1.4.5.min.js">
  </head>
  <body>
    <div data-role="page">
      <div data-role="header">
        <h1>Welcome To My Homepage</h1>
      </div>
  <div data-role="main" class="ui-content">
        <p>I Am Now A Mobile Developer!!</p>
      </div>
      <div data-role="footer">
        <h1>Footer Text</h1>
      </div>
    </div>
  </body>
</html>

Mojo and jQuery Mobile

Slow you down?

Enyo:

<html>
  <head>
    <title>My App</title>
    <script src="enyo/enyo.js"></script>
    <script src="source/package.js"></script>
  </head>
  <body class="enyo-unselectable">
    <script>
      new MyApp().renderInto(document.body);
    </script>
  </body>
</html>

That is it?

It is not magic

When your Javascript object renders itself it does something like:

document.write(
  "<p style="color: blue;" id="helloworld">Hello, World!</p>"
);

But you will never write any of that yourself, just like you never write SQL because EOF handles that for you.

In Enyo you write this:

enyo.kind({
  name: "HelloWorld",
  kind: "Control",
  tag: 'p',
  content: 'Hello, World!',
  style: 'color: blue'
});

Components and subcomponents

Enyo apps define one large control comprising the application's entire hierarchy of controls, then render that into "document.body", replacing all the HTML that loaded with the page.

This makes the creation of new instances painless

var control2 = new HelloWorld({});

If we want to override our control's default content, we can explicitly declare a new value

var control2 = new HelloWorld({
  content: "Hello, Everyone!"
});

Or we can change the content after creation:

control2.setContent("Goodbye, World!");

The same pattern applies to other properties, too. For instance, you could call

control2.setStyle("color: red");

and the "style" attribute would change, with the "styleChanged" method then being called.

Typically you'll use "addClass" and "applyStyle" instead, which are smart about how they adjust the style properties, ensuring that changes made by other code is preserved. So this would be better:

control2.applyStyle("color", "red");

In Enyo, controls have many capabilities beyond simply rendering their own content. Because a control may host other controls, it's possible for a single control to contain a complex hierarchy of DOM elements. For example, we might have a control that hosts a header and an unordered list with several list elements.

Header with list elements:

enyo.kind({
  name: "HeaderList",
  kind: "Control",
  tag: "div",
  components: [
        { tag: "p", content: "The Additive Primary Colors" },
        { tag: "ul", components: [
          { tag: "li", name: "red", content: "red" },
          { tag: "li", name: "green", content: "green" },
          { tag: "li", name: "blue", content: "blue" } ] } ]
});

Any component listed in a kind's "components" block will be added to a special hash called "$", based on its name property. So, we could do:

var list = new HeaderList({});
list.$.red.applyStyle("color", "red");
list.$.green.applyStyle("color", "green");
list.$.blue.applyStyle("color", "blue");

Note, using the IDE even code completion will work on the dollar sign components.

Note that if you try to modify the "content" property of our "list" variable, nothing will happen. For a component, having children takes precedence over having content. In this case when the "list" component is rendered, you only get the content of the children, not the "content" of the component.

Let us launch the Ares IDE

npm -d install ares-ide
~/node_modules/.bin/ares-ide -b

What will happen?

Playing with Ares IDE:

Tid Bits regarding Enyo / Ares:

Why not use iOS tools?

Download the example projects

SpaceForward
Left, Down, Page DownNext slide
Right, Up, Page UpPrevious slide
POpen presenter console
HToggle this help