Ample SDK: Standards- Ample SDK: Standards- based GUI Framework based GUI Framework for Client-side for Client-side Applications Applications The Ajax Experience 2009 September 14-16 in Boston, MA
May 10, 2015
Ample SDK: Standards-based Ample SDK: Standards-based GUI Framework GUI Framework for Client-side Applicationsfor Client-side Applications
The Ajax Experience 2009September 14-16 in Boston, MA
Sergey Ilinsky
http://www.ilinsky.comhttp://twitter.com/ilinsky
1. The Landscape of Client-side GUI Technologies2. Ample SDK: Das Experiment3. Using Ample SDK: Basics4. Extending on Ample SDK5. Showcase6. Resources7. Q&A
Agenda
October 17, 2007, Ajaxian.com
Re-inventing XMLHttpRequest: Cross-browser implementation with sniffing capabilities
Highlights:
Fully functional implementation of XHR for IE7-
Some 20 issues fixed in native implementations. (New reports are still coming)
Extended to support [transparent] request sniffing.
So I took on to re-inventing (re-implementing) web browser
1. The Landscape of Client-Side GUI Technologies
1.1 Server-Side vs. Client-Side1.2 Libraries vs. Frameworks1.3 Web Browsers
1.1 Server-Side vs. Client-Side
Server-Side- app is orchestrated on the server- data and UI communicated to client combined- client-side hooks are not welcome
Client-Side- app is orchestrated on the client (browser)- data communicated separately from UI
1.2 GUI Libraries vs. Frameworks
Libraries:- help executing smaller development tasks- often used to «pimp-up» web-pages
Frameworks:- bring another abstraction level- used to build «rich applications»
1.3 Web Browsers
Two camps:Internet Explorer vs. Modern Browsers
Problems:- Incompatible (sometimes incomplete) APIs
- Too many versions, cool stuf in latest versions- Poor GUI facilities
Hm.. But don't many libraries and frameworks clean
that mess successfully while adding missing glyphs?
Yes, they do.
Every in its own way.
2. Ample SDK: Das Experiment
2.1 Objectives2.2 Solution Architecture2.3 Browser-within-a-browser?2.4 Ample SDK Application Lifetime2.5 Technologies Breakdown
2.1 Objectives
Do not have:- new programming model- new APIs
Do have:- ease of use (eliminate learning curve if possible)- better GUI technologies- separation of concerns- extensible architecture
Meet Ample SDK
Ample SDK is a piece of software that runs transparently in the layer between web browser and application. While running it provides the Logic of the application with standard cross-
browser access to the User Interface.
2.2 Solution Architecture
Runtime- runtime.js
UI Languages- xhtml/xhtml.js- xul/xul.js+xul/xul.css- svg/svg.js- ...
2.3 Browser-within-a-browser?
Ample SDK is in a way a web-browser (GUI aspect)
- understands MLs (XHTML, XUL, SVG..)- provides DOM APIs (Core, Events, Selectors APIs)- uses CSS for styling (pseudo-classes, pseudo-elemnts)
2.4 Ample SDK Application Lifetime
2.5 Technologies Breakdown
- Runtime- Scripting Technologies- XML Technologies- Styling Technologies
- UI Markup Technologies
Runtime: Scripting Technologies
- Document Object Model- DOM Core (Level 2)- DOM Events (Level 3)- Selectors API
- XML APIs- DOMParser, XMLSerializer- XSLTProcessor- XMLHttpRequest
- UI Managers- Focus Manager- Drag&Drop Manager- Resize Manager- Capture Manager- SPI History Manager
- Componentization Model
Runtime: XML technologies
- Xinclude 1.0- SMIL3.0 (selected modules)- XML Schema 1.1 (datatypes module)
Runtime: Styling Technologies
- CSS 2.1- CSS3 Namespaces- CSS3-UI (pseudo-classes, pseudo-elements)
UI Markup Technologies
- XHTML1- XUL- SVG 1.2 Tiny- XHTML5 (in development)- XForms 1.1 (planned)
3. Using Ample SDK: Basics
- XML for UI- CSS for Style- JavaScript for Logic
Hello World!
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Hello, World!</title> <!-- (A) Ample SDK runtime and UI language --> <script type="text/javascript" src="ample/runtime.js"></script> <script type="text/javascript" src="ample/languages/xhtml/xhtml.js"></script> <!-- (1) Styling --> <style type="text/ample+css"> b { color: red; } </style> <!-- (2) Logic --> <script type="text/javascript"> function alertHelloWorld(oEvent) { alert('Element "' + oEvent.target.tagName + '" was clicked'); } </script> </head> <body> <!-- (3) Layout --> <script type="application/ample+xml"> <b onclick="alertHelloWorld(event)">Hello, World!</b> </script> </body></html>
The Programming Model
Programming against Ample SDK is as simple as doing it against... right, cross-browser browser!
3.1 Laying out Application UI
Application GUI is created with XML or JS
staticly: XML (XHTML, XUL, SVG..)
dynamicly: JavaScript (DOM)or XML + importNode
Embedding XML UI into a web page
a) Inline, using a script tag with type="application/ample+xml"<body> <!-- other HTML code --> <script type="application/ample+xml"> <!-- Ample SDK inline XML markup --> </script> <!-- other HTML code --></body>
b) Referencing a resource, using a script tag with src attribute<body> <!-- other HTML code --> <script type="application/ample+xml" src="ui.xml"></script> <!-- other HTML code --></body>
c) Inline, using ample.open() and ample.close()<body> <!-- other HTML code --> <script type="text/javascript">ample.open()</script> <!-- Ample SDK inline XML markup --> <script type="text/javascript">ample.close()</script> <!-- other HTML code --></body>
Using XHTML 1 and XHTML 5
<article> <header> <h1>Apples</h1> <p>Tasty, delicious fruit!</p> </header> <p>The apple is the pomaceous fruit of the apple tree.</p> <section> <h1>Red Delicious</h1> <p>These bright red apples are the most common found in many supermarkets.</p> </section> <section> <h1>Granny Smith</h1> <p>These juicy, green apples and make a great filling for apple pies.</p> </section> <footer> <h1>Apples</h1> <p>Tasty, delicious fruit!</p> </footer></article>
Using XUL (Mozilla technology)
<xul:tabbox xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> <xul:tabs> <xul:tab label="checkbox" /> <xul:tab label="textbox" /> <xul:tab label="datepicker" /> </xul:tabs> <xul:tabpanels> <xul:tabpanel> <xul:checkbox /> </xul:tabpanel> <xul:tabpanel> <xul:textbox /> </xul:tabpanel> <xul:tabpanel> <xul:datepicker /> </xul:tabpanel> </xul:tabpanels></xul:tabbox>
Using SVG1.2 Tiny
<svg:svg viewBox="0,0 400,400" height="400px" width="400px" xmlns:svg="http://www.w3.org/2000/svg" xmlns:smil="http://www.w3.org/2008/SMIL30/"> <svg:circle cx="200" cy="200" r="10" fill="red" opacity="1" stroke="black" stroke-width="1"> <smil:animate begin="click" decelerate="0.5" to="200" attributeName="r" dur="500ms"/> </svg:circle></svg:svg>
Works in Internet Explorer 5.5 too
Modules Implemented:5. Document Structure8. Paths9. Basic Shapes10. Text12. Animation (SMIL)
Using DOM-Core for building UI dynamically
var sXULNameSpace = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var popup = ample.getElementById("items-popup");var item4 = ample.createElementNS(sXULNameSpace, "xul:menuitem");popup.appendChild(item4);item3.setAttribute("label", "Item 3");item3.setAttribute("value", "3");
var oRequest = new XMLHttpRequest;oRequest.open("GET", "wizard.xml", false);oRequest.onreadystatechange = function() {
if (oRequest.readyState == 4) {var oFragment = ample.importNode(oRequest.responseXML.documentElement, true);ample.querySelector("#target").appendChild(oFragment);
}}
Using XInclude to merge XML documents
1. <div xmlns:xi="http://www.w3.org/2001/XInclude">2. <xi:include href="Menubar.xml" />3. <xi:include href="Editor.xml" />4. <xi:include href="Statusbar.xml" />5. </div>
3.2 Styling Application UI
Styling GUI is done with CSS... nicely.
Embedding CSS stylesheets in a web page
a) Inline, using a style tag with type="text/ample+css"
<style type="text/ample+css"> /* Ample SDK inline stylesheet */</style>
b) Referencing a resource, using a link tag with href attribute
<link type="text/ample+css" rel="stylesheet" href="stylesheet.css"/>
Using CSS for styling UI
1) Namespaced selectors for styling component@namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";xul|menulist { width: 200px;}
2) Pseudo-class selectors for styling component state@namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";xul|datepicker:focus { background-color: pink;}
3) Pseudo-element selectors for styling component view@namespace xul "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";xul|colorpicker::input { border: solid 1px blue;}xul|colorpicker::button { background-image: url("colorpicker.png");}
3.3 Writing Application Logic
Implementing application [View] logic is about receiving UI events and updating UI state
appropriately. In Ample SDK the Application UI is represented by a DOM tree (mainly built with
UI elements), that you can access or modify in a standard and consistent way.
UI events are fired on elements in the tree with which the user interacts. Once dispatched they propagate through the tree and can be picked
up for handling.
Embedding JavaScript GUI Logic into a web page
a) Inline, using a script tag with type="text/javascript"<script type="text/javascript"> /* JavaScript UI Logic */</script>
b) Referencing a resource, using script tag with src attribute<script type="text/javascript" src="application.js"></script>
The ample scripting object
The ample scripting object in the Ample SDK is similar to the document scripting object
available in the browser
Navigating / Altering UI Document Tree
a) Navigating the tree- firstChild, lastChild, previousSibling, nextSibling, childNodes,
parentNode etc.- getElementById, getElementsByTagName and
getElementsByTagNameNS- querySelector and querySelectorAll
b) Altering the tree- setAttribute / setAttributeNS, getAttribute / getAttributeNS and
removeAttribute / removeAttributeNS- createElement / createElementNS, createTextNode,
appendChild, insertBefore, removeChild and replaceChild- importNode
Registering Event Handlers and Handling UI Events
a) Dynamically, using the DOM Events API
// Alert event current target tagNameoElement.addEventListener("click", function(oEvent) { alert(oEvent.currentTarget.tagName)}, true);
// Cancel user selection (Also in IE)oElement.addEventListener("mousedown", function(oEvent) {
oEvent.preventDefault();}, false)
b) Inline, using a on{event} attribute
<xul:scale onchange="alert(this.getAttribute('value'))" min="0" max="100" value="50"/>
Using Drag And Drop Manager
Events: dragstart, drag, dragend, dragenter, dragleave, dropProperties: $draggable, $droppablePseudo-classes: drag, drop
<div xmlns:aml="http://www.amplesdk.com/ns/aml" ondrop="if (event.relatedTarget.parentNode != event.target) event.target.appendChild(event.relatedTarget)"> <div aml:droppable="true" class="droppable"> <div aml:draggable="true" class="draggable"> Container 1: drag me and drop to another container </div> <div aml:draggable="true" class="draggable"> Container 2: drag me and drop to another container </div> </div> <div aml:droppable="true" class="droppable">
</div></div>
.draggable { width: 100px; height: 100px; background-color: pink; border: solid 1px red; cursor: move;}.droppable { width: 300px; height: 320px; padding: 10px; float: left; background-color: lightgreen; border: solid 1px green;}div:drag { border-color: black; position: relative;}div:drop { border-style: dashed;}
Using Resize Manager
Events: resizestart, resize, resizeendCSS Pseudo-classes: resizeProperties: $resizable
<div aml:resizable="true" class="resizable" xmlns:aml="http://www.amplesdk.com/ns/aml"> Resize me</div>
@namespace "http://www.w3.org/1999/xhtml";
div.resizable { width: 250px; height: 250px; background-color: pink; border: solid 1px red; max-width: 500px;}div.resizable:resize { background-color: lightyellow;}
Using History Manager
Methods: $bookmark(state)Events: hashchange
ample.addEventListener("hashchange", function(oEvent) {// Implement logicalert(navigator.location.hash)
}, false);
Using Capture Manager
Methods: $setCapture/$releaseCapture, $setModal/$releaseModalEvents: capture, modal
<div> <button onclick="alert('Hello')">alert</button> <div id="dialog" style="border: solid 1px red"> <button onclick="this.parentNode.$releaseCapture(true)">release capture</button> </div> <button onclick="ample.getElementById('dialog').$setCapture(true)">set capture</button></div>
Using XML APIs
Transforming XML document with XSL-T example// Load stylesheet documentoXMLHttpRequest.open("GET", "stylesheet.xsl", false);oXMLHttpRequest.send(null);var oStylesheet = oXMLHttpRequest.responseXML;
// Load input documentoXMLHttpRequest.open("GET", "input.xml", false);oXMLHttpRequest.send(null);var oInput = oXMLHttpRequest.responseXML;
// Create XSLTProcessor and import stylesheet into itvar oXSLTProcessor = new XSLTProcessor;oXSLTProcessor.importStylesheet(oStylesheet);
// Transform input document to output document and alert resultvar oOutput = oXSLTProcessor.transformToDocument(oInput);alert(new XMLSerializer().serializeToString(oOutput));
JSON vs. XML
JSON/XML for dataXML/JSON for UI
Whatever you like!
4. Extending on Ample SDK
4.1 Prototyping Objects / Creating new APIs4.2 Creating Custom Markup Languages4.3 Implementing Global UI Managers
4.1 Prototyping objects/ Defining new APIs
Objects inheritance in Ample SDK (simplified):
AMLNode::AMLDocumentAMLCharacterData::
AMLTextAMLElement::
MyComponent
AMLElement.prototype.listenOnce = function(sEvent, fHandler) {this.addEventListener(sEvent, function(oEvent) {
// Remove event listenerthis.removeEventListener(sEvent, arguments.callee, false);
// Handle EventfHandler.call(this, oEvent);
}, false)}
4.2 Creating Custom Markup Language
// Create new Namespace objectvar MyNamespace = new AMLNamespace;
// Register new Namespace with Ample SDKample.domConfig.setNamespace("http://www.mysite.com/ns/ui");
Creating Custom Component
// Define Component Constructorvar MyButton = function() {
// This is the constructor};
// Set Component PrototypeMyButton.prototype = new AMLElement;
// Register new Component with NamespaceMyNamespace.setElement("button", MyButton);
Defining Component Presentation
MyCombobox.prototype.$getTagOpen = function() {return '<div class="my-combobox">\
<input type="text" \value="' + this.getAttribute("text")+ '" \class="my-combobox—input" />\
<div class="my-combobox—button"/>\<div class="my-combobox—gateway">';
}
MyCombobox.prototype.$getTagClose = function() {return ' </div>\
</div>';}
Specifing attribute default values
MyCombobox.attributes = {disabled: "false"
}
Handling UI Events at the Component Level
Event handlers defined on component classes are executed at the bubbling or target phase only if event default action was not prevented
MyCombobox.handlers = {focus: function(oEvent) {
// TODO: dispatch DOMActivate event}
}
Handling Attribute changes
MyCombobox.handlers = {"DOMAttrModified": function(oEvent) {
}}
Handling Component Insertion / Removal
MyCombobox.handlers = {// Component inserted into document"DOMNodeInsertedIntoDocument": function(oEvent) {
},// Component removed from document"DOMNodeRemovedFromDocument": function(oEvent) {
}}
Defining Properties and Methods
// PropertyMyCombobox.prototype.tabIndex = 0;
// MethodMyCombobox.prototype.selectItem = function(oItem) {
}
A domain-specific UI markup technology?
Maybe "CocoaML"?
4.3 Writing Global UI Managers
A UI Manager is a plugin that reacts to primitive UI events and synthetizes other more enhanced ones
Mouse Gesture UI Manager?
5. Showcase
Implementation Aspects:
Application Logic:PAC approach
UI Technology:XHTML+XUL+Custom components
Server-side — 2 services:- Static for UI- Dynamic for Data (JSON to SOAP)
Wrapping up: Why Ample SDK is relevant?
- Natural programming model- Uses APIs that will stay- Better UI building bricks — XUL et alii- Enables quite a bit of SVG in Internet Explorer- Allows creating DS markup technologies
6. Resources
IRC Channels#amplesdk on irc.freenode.net#amplesdk-dev on irc.freenode.net (Framework Developers)
Mailing Lists / Discussion Groupshttp://groups.google.com/group/amplesdkhttp://groups.google.com/group/amplesdk-dev (Framework Developers)
Bugtrackerhttp://www.amplesdk.com/bugtracker/
Documentation (online/offline)http://www.amplesdk.com/reference/
Developer ToolsAptana IDE pluginFirebug plugin (in development)
Questions?Questions?
Thanks!