Time: 00:00:00 Slide: 00/00
Left: time 525' slides 0
Time/slide: 20" / 20" / 20"
html5 icon
ict-Media GmbH corporate logo

loading slides ...

HTML5
  • Background
  • Principles
  • Basics
  • Examples

Klaus Birkenbihl
HTML5 logo
Last modified: 2014-09-06.

Introduction

Goals:

Introducing

  • the author
  • these slides and this tutorial
  • W3C
  • rational for HTML5 (day)
Deco: Bamboo

Introduction

Introduction

  • W3C http://www.w3.org/
    • standardizes Web technologies
    • Led by Web inventor Tim Berners Lee
    • Run by its member organizations and a team of ~60
    • Following a consensus based standardization process
  • HTML5 http://www.w3.org/TR/html5/
    • In the broader sense: mark-up, styling and APIs for today's and future Web
      • Much of today's Web uses some features of HTML5
      • Modern Browsers implement it — though ...
      • ... much of it is still (and will remain) under development
    • Developed/standardized with broad participation
    • Eagerly implemented by browswer vendors — even before it has the blessings from standard bodies
    • Actively picked-up by the community

Introduction

  • Prerequisites
    • You should have some basic knowledge about HTML
    • You should have some programming skills, and should know a bit about HTML DOM and Javascript
    • You should know some CSS basics
  • Since you are Web developers this probably applies to you
friendly smilie

Introduction

  • Remarks and disclaimer
    • There are a lot of tutorials and demos available on the Web
      • You will not have problems to find follow-up material
    • All major browser vendors maintain developer pages with a lot of information
    • This tutorial can only introduce you to the new things
    • I will put some emphasis on background information
      • HTML5 can hardly be understood without knowing the genesis
    • All demos in this tutorial were developed for this tutorial (though some are inspired by whats out there)
    • I tried to keep demos simple but nevertheless themed (above the boring "Hello World!" level)
    • Also see: http://www.ict-media.de/html5-examples/ (probably needs some care!)

HTML Evolution

Goals:

Learn about HTML5

  • background
  • history
  • driving forces
  • environment
Deco: Reed

HTML Evolution

  • W3C publishes the HTML 4.0 recommendation in 1997-12
    • Should set a standard to improve interoperability between browsers
    • Covered most of the common practices
  • The big thing 3 month later: XML 1.0
    • Simple syntax
    • Extensible by design
    • Should become the base for most further W3C developments

HTML Evolution

  • XML advantages
    • Nearly unlimited extensibility (esp. due to name spaces)
    • XML languages could (relatively easily) be merged (name spaces)
    • One parser for all (never write a parser again … well?)
  • XML drawbacks
    • Implementation of name spaces
    • Some languages turned out to become rather complex (e. g. XML Schema, RDF-XML)

HTML Evolution

  • XML turned out to be a huge success
    • XML (as a metalanguage) was the base of 1000s of specialized data formats
    • W3C based its own developments on XML:
      • XSLT, XML Schema, RDF-XML, SVG, SOAP
    • OASIS Open http://oasis-open.org/ and W3C did and do a lot to promote XML in the business world
    • ...

HTML Evolution

HTML 4.0 is not XML

  • HTML and XML syntax based on SGML
  • HTML syntax easier to write – less formal
  • HTML parsing by browsers is rather sloppy
  • Authors tend to make use of browser sloppiness – writing invalid code
  • XML syntax is simple but strict
  • XML has a “draconian error handling”
  • XML enforces valid (well formed) coding – not well formed pages would throw an error

HTML Evolution

  • W3C goal: make HTML a member of the XML languages family
    • Would make HTML extensible
    • Authors would be forced to write clean code
    • Would fit into an XML based architecture
    • Would allow for compound documents (e.g. HTML + SVG or HTML + SMIL …)
  • Next steps were:
    • clean-up of HTML 4.0 → HTML 4.1
    • XHTML 1.0: HTML 4.1 in XML syntax
    • XHTML 1.1: a modularized version of XHTML

HTML Evolution

  • HTML 4.1 and XHTML 1 don't differ so much in syntax. In fact the XHTML 1 spec rather describes differences than a new language:
    • XHTML 1 has to be well formed. In practice:
      • Every tag has to be closed properly
      • Attributes must have values and these need to be enclosed in quotes
    • X(HT)ML is case sensitive (all HTML tag and attribute names are lower case in XHTML)
  • Much valid XHTML 1 code was also valid HTML 4.1 (but not the other way round).
  • All valid XHTML 1 code is understood by HTML 4.1 capable browsers.

HTML Evolution

  • The effect of XHTML on browsers:
    • When should a document be parsed as XML (draconian) rather than HTML (sloppy)?
    • Suggestion: documents served as text/html should be parsed as HTML, documents served as application/xhtml+xml should be parsed as XHTML (no matter what the doctype says).
    • Servers by default serve .html or .htm as text/html.
  • It was geeky and trendy to use XHTML, it also allowed for “unexpected reuse” by XML applications.
  • Much – rather most – XHTML out there is not really valid. But nobody cares (since it is served as text/html).

HTML Evolution

  • W3C worked in quite some areas (just a few):
    • XHTML 2 should fix issues of (X)HTML and make HTML extensible
    • XFORMS should provide a flexible, device independent user interaction
    • Ubiquitous web, mobile Web
    • Web Services was the big thing in business with XML, SOAP, WSDL, …
    • Semantic Web and RDF, OWL …
    • Security especially of XML

HTML Evolution

The W3C technology stack:

W3C Technology stack

HTML Evolution

  • There was life outside of W3C
    • The .com crisis
    • eBay, Google, Amazon became big players
    • Web 2.0 with blogs, crowd sourcing, social networks, tagging, mash-ups and Ajax
    • Alternate approaches for semantics: Micro formats, tagging ...
    • New browsers emerged: Mozilla, Safari, (and later) Chrome became big and challenged IE (and Opera)
  • A huge need for interoperability, more functionality and standards emerged

HTML Evolution

  • The need for standards caused a big debate how these standards should look like
    • Was XML the right thing to rely on?
    • Or would it harm the web with respect to existing sites and applications?
    • Sloppy vs draconian error handling?
    • Name spaces?
    • How to integrate semantics (RDFa?)?
    • What about multimedia support?
    • What about better support for HTML based applications?

HTML Evolution

  • logo WHATWG Unfortunately the discussion did not run well
    • In 2004 a group was formed outside of W3C to work on 2 specs: Web Forms 2.0 and Web Apps 1.0 later merged to HTML5. The name of the group: WHATWG. Editor: Ian Hickson
  • W3C was not really lucky with XHTML 2 logo W3c
    • In 2006 W3C chartered an HTML WG that was supposed to use the work of WHATWG as their basis
    • Unlike for other Working Groups W3C decided to open this one broadly for W3C none members aka (public) invited experts
    • In 2009 W3C announced that the work on XHTML 2 would not be continued
  • For more see: http://diveintohtml5.org/past.html and http://www.w3.org/html/wg/wiki/History

HTML Evolution

  • Everything fine now?
    • W3C and the world adopted HTML5 with great enthusiasm
    • But HTML5 did not fit well into the portfolio of established W3C technologies (see this slide)
    • There are two (nearly) identical documents out there:
      • one from W3C
      • one from WHATWG
    • both were edited by Ian Hickson (Google)
    • WHATWG and W3C have a different view on standards and standard processes
  • Nevertheless: WHATWG and W3C (having the important members in common) have a huge interest in the success of HTML5 as base for an inter-operable Web platform

HTML Evolution

  • W3C's plan (since 2011):
    • Move HTML5 forward on the consensus based standard track: in Last Call since May 2011, expected to become a Recommendation (W3C speak for solid, reliable standard) in 2014
    • HTML.next to keep pace with WHATWG
  • WHATWG
    • Invented what they call the “living standard”: version less, incremental, changing with the pace of the technology
    • Speak rather of HTML than HTML5 (version less, sic!)
    both were 2011 edited by Ian Hickson (Google)
  • Browser vendors are busy implementing HTML5 today. (Sometimes with different pace and different priorities. See: http://caniuse.com/)

HTML Evolution

  • It's much haywire:
    • Jul 2012: WHATWG and W3C Split. Hickson steps down as W3C HTML5 Editor
    • Dec 2012: W3C freezes HTML5 as Candidate Recommendation (declared as feature complete), HTML5 Recommendation in 2014 Q4.
    • Well: W3C Candidate Recommendation 6 August 2013,
      W3C Candidate Recommendation 04 February 2014, W3C Candidate Recommendation 29 April 2014,
      W3C Last Call Working Draft 17 June 2014, W3C Candidate Recommendation 31 July 2014
    • Dec 2012: publishes first drafts of HTML 5.1, picking-up WHATWG stuff and new features
    • Plan for HTML5.1 Recommendation in 2016 Q4.
    • HTML5 extension specifications as a means for modularization, “reducing social conflict”
    • XML strikes back: Polyglot Markup:
      A robust profile of the HTML5 vocabulary. W3C Candidate Recommendation 17 July 2014. Started 2010,
      "This specification summarizes design guidelines for authors who wish their XHTML or HTML documents to be conforming whether parsed as HTML or as XML."
    • W3C DOM4, W3C Last Call Working Draft 10 July 2014
    • The driving forces behind HTML5 are still the browser vendors
    • Functionality of new features is implemented by at least one browser vendor before it goes to a specification

HTML Evolution

2 grasroot-level geek's opinions (from http://programmers.stackexchange.com/questions/86510/why-not-xhtml5):

So, HTML5 is the Big Step Forward, I'm told. The last step forward we took that I'm aware of was the introduction of XHTML. The advantages were obvious: simplicity, strictness, the ability to use standard XML parsers and generators to work with web pages, and so on.

How strange and frustrating, then, that HTML5 rolls all that back: once again we're working with a non-standard syntax; once again, we have to deal with historical baggage and parsing complexity; once again we can't use our standard XML libraries, parsers, generators, or transformers; and all the advantages introduced by XML (extensibility, namespaces, standardization, and so on), that the W3C spent a decade pushing for good reasons, are lost.

Fine, we have XHTML5, but it seems like it has not gained popularity like the HTML5 encoding has. See this SO question, for example. Even the HTML5 specification says that HTML5, not XHTML5, "is the format suggested for most authors."

Do I have my facts wrong? Otherwise, why am I the only one that feels this way? Why are people choosing HTML5 over XHTML5?

I hope I'm not the only one who's glad with the loss of all XML's disadvantages in HTML5. For example, let's compare valid HTML5 to valid XHTML.

HTML5: <!DOCTYPE html>Hello World

XHTML: <?xml version="1.0" encoding="iso-8859-1"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd"><html xml:lang="en" lang="en" xmlns="http://www.w3.org/1999/xhtml"><head><title></title></head><body>Hello World</body></html>

HTML Evolution

WHATWG handing over HTML5 to W3C (as from the bible)

HTML Evolution

?

Goals, Principles, Technologies of HTML5

Goals:

Learn about HTML5

  • design principles
  • its view on standards
  • underlying technologies
  • readyness
  • some tools & frameworks
Deco: Autumn Trees

Goals, Principles, Technologies of HTML5

HTML5 is a break-up

  • and the break-up (break-down?) of XHTML
  • Its based on best practices in the Web
  • It introduced a new conformance concept (distinction between browser conformance and document conformance)
    • To conform a browser has to do more than just process correct documents correctly
  • W3C had to make concessions:
    • Give-up on XML architecture for future HTML
    • Open a WG to the public (by inventing “public invited experts”)

Goals, Principles, Technologies of HTML5

from http://dev.w3.org/html5/html-design-principles/:

  • Compatibility
    • Support Existing Content
    • Degrade Gracefully
    • Do not Reinvent the Wheel
    • Pave the Cow Paths
    • Evolution Not Revolution
  • Interoperability
    • Well-defined Behavior
    • Avoid Needless Complexity
    • Handle Errors
  • Utility
    • Solve Real Problems
    • Priority of Constituencies
    • Secure By Design
    • Separation of Concerns
    • DOM Consistency
  • Universal Access
    • Media Independence
    • Support World Languages
    • Accessibility

Goals, Principles, Technologies of HTML5

  • Support Existing Content:
    • e.g.:
        <b>this is<i>really bad</b>HTML</i>
      but we can easily agree that it is meant to be rendered as
      this is really bad HTML
      so browsers should do so.
  • Degrade Gracefully:
    • Meaning HTML5 should be designed in a way that old browsers can deliver the content “gracefully degraded” e.g.
        <canvas> fallback </canvas>
      will deliver
      fallback
      in case a browser cannot render a canvas.

Goals, Principles, Technologies of HTML5

  • Do not Reinvent the Wheel (&Pave the Cow Paths):
    • If there is some accepted construct or practice available don't specify a new one
      • eg. the contenteditable attribute
  • Evolution Not Revolution:
    • Evolve an existing design rather than throwing it away
      • e.g. allow XML syntax and classic HTML syntax as well
  • Solve Real Problems:
    • pragmatic solutions in favor of abstract architecture [rather weak? Even the most abstract architecture claims to solve real problems]

Goals, Principles, Technologies of HTML5

  • Priority of Constituencies:
    • users over authors over implementers over specifiers over theoretical purity [theoretical==architectural???]
  • Secure By Design:
    • E.g. Cross-document messaging instead of (the more flexible but risky) cross-site scripting
  • Separation of Concerns:
    • E.g. allow separation of content and presentation
      • This is a really old W3C mantra!

Goals, Principles, Technologies of HTML5

  • DOM Consistency:
    • HTML and XHTML syntax should be designed to produce mostly [?] consistent DOM trees
      • Once the document is parsed there should be no need to worry about the original syntax
    • E.g. The HTML (text/html) parser puts elements in the http://www.w3.org/1999/xhtml namespace in the DOM for compatibility with the XML syntax of HTML 5
  • Well-defined Behavior:
    • Clearly specified behavior over implementation-defined behavior. [this is what specs are made for!]

Goals, Principles, Technologies of HTML5

  • Avoid Needless Complexity:
    • Another core W3C virtue [though some specs lack simplicity for whatever reason]
  • Handle Errors:
    • Error handling should be defined (in the spec)
    • Prefer graceful error recovery to hard failure
  • Media Independence:
    • W3C used to call (a very similar thing) device independence before
    • The main goal of the ubiquitous Web

Goals, Principles, Technologies of HTML5

  • Support World Languages:
    • This finds a strong base in work of the W3C Internationalization (aka I18n) Activity together a.o. with the Unicode consortium
  • Accessibility:
    • W3C's Web Accessibility Initiative (WAI) provides a lot of input for this one (and thoroughly comments on how HTML5 follows this design principle).

Goals, Principles, Technologies of HTML5

Goals, Principles, Technologies of HTML5

  • the DOM Browser builds an initial DOM from the (declarative) HTML
  • (declarative) CSS specifies how DOM nodes are to be rendered
  • (procedural) Javascript reads and modifies the DOM and reacts on events and user interaction
    • Javascript also interacts — constrained by the browser for security reasons — with the underlying OS

Goals, Principles, Technologies of HTML5

  • the DOM Introducing the DOM:
    • Each document is represented in a browser by an Object, the Document Object consisting of
      • A URL/IRL/URI/IRI
      • A DOM tree structure with nodes of type Element, Attribute, Text and a few more with associated methods, properties and events
      • An API to access and manipulate nodes in the DOM
      • Eventlisteners to react on network, system or user caused events
  • CSS
    • Provides a selector mechanism to select collections of Elements
    • declaration blocks that assign a presentation to selections
    • means for media distinction

Goals, Principles, Technologies of HTML5

  • the DOM Javascript:
    • Language to access APIs and manipulate the DOM tree
    • Can also manipulate the styles associated with DOM Elements
    • Used to trap events on the DOM
  • HTML:
    • Defines the (initial) DOM tree
    • Can hold special Elements (containing CSS, Javascript code and more)

Goals, Principles, Technologies of HTML5

One year ago:

Can I use HTML5 today?
  • Short answer: maybe
  • Longer answer: yes if
    • You can live with the fallbacks or
    • You do not need to support each and every browser out there or
    • You carefully check the capabilities of all the browsers you wish to support wrt the features you need

Goals, Principles, Technologies of HTML5

Today:

Can I use HTML5 today?
  • Short answer: you probably have to
  • Longer answer: yes
    • You will be more productive
    • You will get better performance
    • You have more functions and features
    • IE6 world wide market share below 5%, in most of Europe <1%

Goals, Principles, Technologies of HTML5

  • Once you are familiar with HTML5 and you understand how it works you might want to engage the help of a framework like Webshims Lib http://afarkas.github.io/webshim/demos/, a modular capability-based polyfill-loading library which includes
  • Today polyfills are rather used to emulate and test experimental features. E.g. Polymer http://www.polymer-project.org/
  • Caveat: the browsers that need most of this stuff are also those with the worst Javascript performance. So not every emulation makes sense. Sometimes a fallback is the better solution.
  • An a bit outdated curio: users that want/have to stick to IEx {x>=6 <=9} may want to install Google Chrome Frame plug-in

Goals, Principles, Technologies of HTML5

A curio:

Wolf in a sheep's clothing: Google Chrome Frame plug-in for MS Internet Explorer (6 to 9)

A foreign HTML engine as browser plugin

a wulf (Google Chrome) wearing a sheep's (IE) fur

Goals, Principles, Technologies of HTML5

  • We saw the design goal: Graceful Degradation.
  • Sometimes graceful is not graceful enough
  • Sometimes one can play tricks on browsers to make them perform better
  • Given the dynamics in Browser dissemination, polyfills for HTML4.1 lose importance

Goals, Principles, Technologies of HTML5

  • Web apps, mobile apps with HTML5
    • are supposed to run without a browser (resp. without a visible browser chrome, aka fullscreen)
    • but use the same HTML, CSS, Javascript and APIs
    • are portable
    • special care is to be taken wrt security
  • Adobe Phonegap http://phonegap.com/ provides APIs to access typical device resources (camera, address book, accelerometer ...) not yet standardized for HTML5
  • Chrome Platform https://developer.chrome.com/home/platform-pillar development on base of Chrome

Goals, Principles, Technologies of HTML5

?

HTML5 Mark-Up

Deco: Blind weed

Goals:

Learn about new HTML5 mark-up

  • new elements
  • improved elements
  • compound documents, new features
  • new attributes
  • Web components

HTML5 Mark-Up

Achievements of new Mark-up

  • More structure oriented (some say semantic) mark-up (~10 elements replacing <div class=xxx> constructs)
  • Better forms and user interaction
  • Multimedia mark-up
  • Possibility to have nested use of HTML, SVG and MathML
  • A <canvas> element provides an interface to low level graphics APIs
  • Microdata for integration of semantics (RDFa as an alternative?)

HTML5 Mark-Up

Achievements of new Mark-up

  • New events for many elements (~50 events for the document – many are inherited by elements)
  • New doctype <!DOCTYPE html> instead of e.g. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • Pretty long list of deprecated tags (most to implement by browser vendors but not allowed in valid documents)
    • Especially presentational or safety threading tags are deprecated
  • Permission for omission of many opening or closing tags
  • Introducing custom attributes (syntax data-*)
  • Web components with <template> and <element> for custom elements.

HTML5 Structural Elements

Goals:

Learn how to structure documents with HTML5

Deco: Blind weed

HTML5 Structural Elements

  • New elements allow authors to better indicate the purpose of parts of their documents
  • These new elements are <section> <nav> <article> <aside> <hgroup> <header> <footer> and recently <main>
  • Update (May 21st 2013): <hgroup> has been deprecated by W3C.
    • Removed from the August 2013 Candidate Recomendation
    • Still (Sep 2014) part of the WHATWG living standard
    • flagged as an error by the W3C validator
  • It is strongly recommended that authors section their documents explicitly by use of the <article> <aside> <nav> <section> sectioning elements

HTML5 Structural Elements

The document outline

  • Structure of a document derived by applying an algorithm that uses sectioning elements, heading elements, and sectioning root elements
  • Document outlines are useful in many ways. Especially the accessibility of a website gains from a good outline
  • Unfortunately the HTML5 outline algorithm is rather complex (mainly due to trying to be backward compatible and able to generate HTML4 document outlines)
  • Instead of trying to fully understand the algorithm – applying good practice in web page design is the better strategy

HTML5 Structural Elements

The document outline

  • Sectioning elements: <article>, <section>, <nav>, and <aside>
  • Sectioning root elements: <body>, <blockquote>, <details>, <fieldset>, <figure> and <td>
  • Heading elements <h1><h6> and <hgroup> define the header of a section
    • <hgroup> only can contain <h1><h6> grouping them to form a single section header
  • If a <h*> or a <hgroup> element is not the first heading element in a section it implicitly opens a new (sub)section

HTML5 Structural Elements

A few good practices:

  • Avoid implicit sectioning (only one heading per sectioning element)
  • Use sectioning elements only if they shall be part of the outline
  • Use sectioning elements according to their semantics:
    • <article> parts of the document that could be syndicated on their own
    • <section> other parts of a document (e.g. chapters)
    • <nav> list of links related to the document
    • <aside> content that is related part not part of the document flow

HTML5 Structural Elements

An example:

    <article lang=zh>
      <h1>他会说汉语吗?</h1>
      <p>这是我的朋友。他是德国人。</p>
      <p>他不会受汉语,他会说一点英语。</p>
      <section lang=de>
        <h1>HTML5 auf chinesisch?</h1>
        <p>Leider kann ich überhaupt nicht Chinesisch sprechen.</p>
      </section>
      <section lang=en>
        <h1>Would English be an option?</h1>
        <p>Maybe it works to give the presentation in English.</p>
        <p>I bet many in the audience can follow an English presentation</p>
      </section>
      <p>对不起。</p>
    </article>
              

Lets render it:

HTML5 Structural Elements

With a little CSS we can indent according to structure:




      article, section {
          padding-left: 3em;
      }


              

Lets render it:

HTML5 Structural Elements

A flexible and easily maintainable structure for e.g. technical documents:

  • A flexible and easily maintainable structure for e.g. technical documents
  • Unlimited nesting
  • Automatic numbering
  • Easy change of section level
image visualizing cascaded sectioning

HTML5 Structural Elements

An example:

  <article>
    <h1>Main Header</h1>
    <p>Text body in the main section.</p>
    <p>another main paragraph</p>
  
    <section>
      <p>a paragraph on level 2 before 
        the header.</p>
      <h1>Header on level 2</h1>
      <p>Paragraph on level 2</p>
    
      <section>
        <h1>Header on level 3</h1>
        <p>Paragraph on level 3</p>
      </section>
  
    
        <!-- simply moving the following section to here -->
        <!-- makes it a level 3 section -->
  
    </section>
  
    <section>
      <h1>Another Header on level 2</h1>
      <p>Level 2 paragraph.</p>
    </section>
  
    <p>Level 1 paragraph</p>
  </article>        
                

Simply by placing a section into the section body of another one we can easily change the structure (note we only use <h1> for all headings). Let's make this section level 3.

HTML5 Structural Elements

Yes there is some CSS 2.1 that does the numbering magic and indentation:

   
      section {
        margin-left: 2em;
      }

      h1:before {
        counter-increment: headings;
        content: counters(headings, ".") " ";
      }

      article, article section:first-of-type {
        counter-reset: headings;
      }
              

That's all!

HTML5 Structural Elements

CSS explained:

  • :first-of-type pseudoelement selects the first sibling of its type in the list of children of its parent element.
  • Numbering is controlled by counter-increment and counter-reset properties
  • resetting a counter in a descendant element … creates a new instance of the counter
  • Scope of a counter
    • starts on the first element in the document that has a 'counter-reset' for that counter
    • includes the element's descendants
    • and its following siblings with their descendants
  • content:counter(n) selects the current counter of name n
  • counters(n,s) joins all counters of name n using the string s

HTML5 Structural Elements

Summary on structural elements

  • <body> main content of a document
  • <nav> a section that mainly links to other pages
  • <aside> content that is tangentially related to the content around it
  • <header> header (or intro) of a section
  • <footer> footer of a section
  • <main> main part of an element
  • <address> contact information for <body> or <article>
  • sectioning content <article>, <aside>, <nav>, <section> starts a new section
  • <blockquote>, <body>, <details>, <dialog>, <fieldset>, <figure>, <td> are sectioning root elements that start new outlines
  • Heading content <hx> implicitly starts a new section if not first hx within a section (avoid!)

HTML5 Structural Elements

?

Forms and User Interaction

Goals:

  • new in forms
  • see new features in action
Deco: Blind weed

Forms and User Interaction

  • Derived from WHATWG standard Web Forms 2.0
  • Forms can be annotated in a way that a lot of input checking can be done without any scripting
    • <input> is enhanced by new types like number range date color search tel email url
    • <input> has an attributes placeholder for hints, autofocus min max step
    • There is an <output>, a <progress> and a <meter> element
    • required and especially pattern attributes for even more checking. pattern accepts regular expressions to test for complex patterns.
    • There is a <datalist> element for input suggestions
  • Lets play!

Forms and User Interaction

CSS3 :valid and :invalid pseudo attributes allow feedback while typing.

Our example is using:



    input:valid {background-color:green;}
    input:invalid {background-color:red;} 

              

Forms and User Interaction

  • <output> <progress> <meter>
  • A means to present/visualize results measurements or computations

Forms and User Interaction

Example:

  <form oninput="comp();">
      <label>factor 1: 
        <input id=a type=range  min=1  max=10 step=1  value=1  />
        <output id=a1 value=1>1</output>
      </label>
      <label>factor 2: 
        <input id=b type=range  min=1  max=10 step=1  value=1  />
        <output id=b1 value=1>1</output>
      </label>
      <label>Progressbar sum:<br/>
          <progress id=s1 max=20 value=2>No progressbar available</progress> 
          <output id=s value=1>1</output>
      </label>
      <label>Meter product:<br/>
          <meter id=p1 min=0 low=20 high=80 value=1 optimum=60 max=100>No meter available</meter>
          <output id=p value=1>1</output>
      </label>
  </form>
  
  <script type="text/javascript">
      function $(id){return document.getElementById(id)};
      function comp(){
        var x = a1.value = Number(a.value);
        var y = b1.value = Number(b.value);
        $('p1').value=$('p').value=x*y;;
        $('s1').value=$('s').value=x+y;
      }
  </script>
              

Forms and User Interaction

  • Yes!
    • You can do these things also by CSS and Javascript.
  • Yes!
    • Many Javascript frameworks can do it for you. E.g. jquery holds a lot of options.

Editable Content
(also Introducing Local Storage)

Goals:

  • show an example of browser heritage in HTML5
  • learn about editing of content
  • learn about local storage as an aside
Deco: Blind weed

Editable Content
(also Introducing Local Storage)

  • Heritage from browsers now in HTML5
  • Authors can provide a means for users to edit a document
  • Either by switching on design mode for a document or by activating editable content for a specific element

Editable Content
(also Introducing Local Storage)

Interlude:

  • Sometimes HTML5 is a mess
    • The reason is: in case of doubt it takes the grap that is out there
  • Proof by example
    • There is a document property designMode which is to specify if documents are editable
    • There is an element attribute contenteditable which is to specify if elements are editable
    • The first one offers a subset of the second one's feature (making just the document's body editable.
    • Why different names for the same concept? Answer: because browsers implement it.

Editable Content
(also Introducing Local Storage)

  • contenteditable attribute is reflected in the element interface by the contenteditable property.
  • isContentEditable is a property that can be used to check if an element can be edited. isContentEditable returns the boolean values true and false as you would expect. It does not tell you if the property was inherited from ancestor elements or if it was set by the contentEditable property.
  • contenteditable property can have the values "true", "false", "inherited" (case insensitive)

Now lets do a bit brainteasing!

Editable Content
(also Introducing Local Storage)

Question: if p is an p element object, what is the effect of the following Javascript constructs according to the HTML5 spec?

  • p.contentEditable = false;
  • document.designMode = true;
  • p.contentEditable = !p.ContentEditable;
  • document.designMode = "true";
  • document.designMode = "oFF";
  • p.contentEditable = "FaLsE";

Editable Content
(also Introducing Local Storage)

Solution

p.contentEditable = false;

Sets p.contentEditable to false? Nope it sets it to "false".
The only values allowed for contentEditable are ASCII case-insensitive matches of "true", "false" or "inherit".
So you better never use in this way: if(contentEditable). Why?
p.isContentEditable will be set to false by this assignment as a side effect. So you better use this for tests.

Editable Content
(also Introducing Local Storage)

Solution

document.designMode = true;

Switching design mode on? No! It will simply be ignored.

Editable Content
(also Introducing Local Storage)

Solution

p.contentEditable = !p.ContentEditable; 

Toggles p.contentEditable? Nope! Sets p.contentEditable to "false". Always!!! Why??? To toggle use p.contentEditable = !p.isContentEditable;

Editable Content
(also Introducing Local Storage)

Solution

document.designMode = "true";

Switching design mode on? (You think you are smart now?) It will simply be ignored. To switch design mode on you may use ASCII case-insensitive matches of the string "on". To switch design mode off … guess what?

Editable Content
(also Introducing Local Storage)

Solution

            document.designMode = "oFF";

YEP!

Editable Content
(also Introducing Local Storage)

Solution

p.contentEditable = "FaLsE";

Sets p.isContentEditable to false and p.contentEditable to "FaLsE"

Confused?

Editable Content
(also Introducing Local Storage)

Example document

  <article>
    <h1> Editing</h1>
    <div>
      <p contenteditable="true" id=edit>
        Please feel free to edit this paragraph. 
        <span contenteditable="false"
          >but dont touch this section
        </span>
        OK?
      </p>
    </div>
    <button type=button onclick="saveEdits()">Save</button>
    <button type=button onclick="restoreEdits()">Restore</button>
    <button type=button onclick="clear()">Clear</button>
    <button type=button onclick="reset()">Reset</button>
  </article>
              

Editable Content
(also Introducing Local Storage)

A bit CSS to make things more readable



    body  { background-color:#000000; color:#ff8000; }
    [contenteditable="true"]  { color:#ffffff; }
    [contenteditable="false"] { color:#ff8000; }


              

Example document

Editable Content
(also Introducing Local Storage)

The purpose of contentEditable/designMode is to provide a Richt Text Editing capability within HTML5

  • HTML Editing APIs https://dvcs.w3.org/hg/editing/raw-file/tip/editing.html aims to provide a specification for HTML editing APIs
    • started in 2011 it is a preliminary draft
    • The specification was published by the W3C Editing APIs Community Group.
    • It is not a W3C Standard nor is it on the W3C Standards Track

Editable Content
(also Introducing Local Storage)

How to save changes?

  • One concept: localStorage
  • Allows to store key-value pairs on a per domain base
  • Each domain may access only the storage of its domain
  • Four simple methods:
    • setItem(key,value) stores value under key in local storage
    • getItem(key) returns the value stored under key
    • removeItem(key)removes key and associated value from local storage
    • clear() clears local storage (for this domain)
  • This is a very simple option to store local information
  • The Indexed DB API is a more sophisticated approach

Editable Content
(also Introducing Local Storage)

  function saveEdits(){
    window.localStorage.setItem
      ("edits",document.getElementById("edit").innerHTML);
  }

  function restoreEdits(){
    var e = window.localStorage.getItem("edits");
    if (e) document.getElementById("edit").innerHTML = e;
  }

  function clearStorage(){
    window.localStorage.clear();
  }

  function reset(){
    location = location;
  }
              

Multimedia Mark-Up

Goals:

  • learn about multimedia in HTML5
  • learn how to control a presentation from the multimedia API
Deco: Blind weed

Multimedia Mark-Up

  • HTML5 makes video and audio first class citizens of the Web
  • Good:
    • No plug-ins required
    • Integration with other elements possible
    • Part of the DOM (can be accessed and controlled via Javascript and CSS)
  • Still open
    • No agreement on video or audio formats
      • Long lasting discussion between browser vendors on licences, patents, and ownership for various formats
    • No fine control over buffering and dynamic quality control

Multimedia Mark-Up

Media elements provide a lot of events, attributes/properties and methods

  • Media events: onloadedmetadata; onloadeddata; oncanplay; oncanplaythrough; onplaying; onended; onwaiting; ondurationchange; ontimeupdate; onplay; onpause; onratechange; onvolumechange
  • Media attributes/properties: defaultPlaybackRate; playbackRate; volume; muted; currentTime; mediaGroup; ...
  • Media methods: play(); pause(); canPlayType(DOMString type);
  • Readonly properties: buffered; seekable; duration; paused; played; readyState; …
  • Following readonly properties are of type TimeRanges: buffered; seekable; played;

Multimedia Mark-Up

A simple example

  <!DOCTYPE html>
  <html>
    <head>
      <title>... — ict-Media GmbH</title>
    </head>
    <body>
      <h1>A simple video player</h1>
      <video src="video-s.ogv" controls muted>
        Your browser does not support this video format
      </video>
    </body>
  </html>
              

Multimedia Mark-Up

  • video and audio have a “parent Object” media in common that provides many properties, methods and events to control playing
  • More than one media object can be controlled by one media controller
  • A set of events, attributes and methods allow to control media from the document

Multimedia Mark-Up

  • Media elements can be grouped to be controlled in synch
  • Media elements can have text tracks (inband or outband) that provide subtitles, captions, metadata …
  • A lot of it is not (yet) implemented though
  • Effects and filters can be inherited from CSS or even from SVG

Multimedia Mark-Up

Lets control our video from the DOM, HTML mark-up

  <body>
    <video id=video src="video-s.ogv"></video><br/>
    <p>
      <progress id=progressBar value=0></progress><br/>
      Position <span id=currentTime> </span>/
               <span id=videoDuration> </span>.
      Playback rate: <span id=speed> </span>
    </p>
    <p>
      <button onclick="setPlayStop()" id=playStop disabled>play</button>
    </p>
    <p id=speedButtons>
      <button onclick="setspeedButtons(0.25)" disabled>slow</button>
      <button onclick="setspeedButtons(1)" disabled>normal</button>
      <button onclick="setspeedButtons(4)" disabled>fast</button>
    </p>
  </body>
  </html>
              

Multimedia Mark-Up

To do:

  • catch document.readyState == 'interactive' (mark-up is parsed) to initialize events, variables for elements
    • document.load could be too late since by then some video events may already have happened (esp. Firefox)
  • video loadedmetadata event initializes and activates video controls
  • other video events update video dependent infos
  • control buttons set associated properties of the video element

Multimedia Mark-Up

Init our video player


  // Variables to hold elements 

  var video, playStop, speedButtons, videoDuration,
      currentTime, progressBar, speed; 

  // When document is "interactive" ("complete" might be
  // too late for some video events)

  document.addEventListener('readystatechange', 
    function(){
      if (document.readyState == 'interactive') init(); 
    },
    false);
              

Multimedia Mark-Up

Initialize our video player

  function init(){
      // Helper functions
      function select(s){ // elements
        var a = document.querySelectorAll(s);
        return a.length == 1 ? a[0] : a;
      }
      function addVEvts(){ //Video events
        for (var i=0;i<arguments.length;i++)
          video.addEventListener(arguments[i],
            function(e){vEvt(e.type)},
            false);
      }
      // Retrieve elements
      video = select("#video"), playStop = select("#playStop"),
        currentTime = select("#currentTime"), speed = select("#speed"), 
        progressBar = select("#progressBar"), videoDuration = 
        select("#videoDuration"), speedButtons = select('#speedButtons *');
      // Set Video events
      addVEvts('canplay','loadedmetadata','loadeddata','canplaythrough',
        'playing','ended','waiting','timeupdate','play','pause',
        'ratechange');
  }
              

Multimedia Mark-Up

Video event processing for our video player

  function vEvt(which){

      function timeupdate(){progressBar.value=video.currentTime;
                  currentTime.textContent = tm(video.currentTime);}
                  
      function play(){playStop.textContent = "pause";}
      
      function pause(){playStop.textContent = "play";}
      
      function ratechange() {speed.textContent = String(video.playbackRate);}
      
      function loadedmetadata() {  // initialize and activate controls () see next slide}
      
      switch(which){
        case 'timeupdate': timeupdate(); break;
        case 'loadedmetadata': loadedmetadata(); break;
        case 'ratechange': ratechange(); break;
        case 'play': play(); break;
        case 'pause': pause(); break;
      }
  }
              

Multimedia Mark-Up

loadedmetadata event: initialize and activate controls


        function loadedmetadata() { // initialize

          video.muted=true;

          playStop.disabled = false;
                for (var i=0;i<speedButtons.length;i++)
            speedButtons[i].disabled = false;

          progressBar.style.width = (video.videoWidth)+"px";
          progressBar.max = video.duration;

          videoDuration.textContent = tm(video.duration);
          currentTime.textContent = tm(video.currentTime);
          speed.textContent = video.playbackRate;
                }
              

Multimedia Mark-Up

Here the controls for our video player

  function setPlayStop() {
      if (video.paused) {
          if (video.ended) video.currentTime = 0; // rewind
          video.play();
      } else {video.pause();}
  }

  function setspeedButtons(i){video.playbackRate = i;}

  function tm(t){
      return ("0"+Math.floor(t/3600)).substr(-2)+":"+
             ("0"+Math.floor(t % 3600) / 60).substr(-2)+":"+
             ("0"+Math.round(t % 60)).substr(-2);
  }
              

Multimedia Mark-Up

Web Components

Goals:

  • touch the bleeding edge of HTML5
  • heads-up for a big extension of the concept (really a big jump!)
Deco: Blind weed

Web Components

  • a component model for the Web comprising across CSS, Javascript, HTML-Mark-up, DOM(s):
    • encapsulation
    • inheritance
    • reusability
    • based on (declarative!) HTML mark-up
  • today mainly pushed by Google (and Mozilla)
  • hottest topic on meeting and conferences
  • W3C was awarded for it with the 2014 Net Awards in "Best New Web Technology"

Web Components

  • the idea: to have some OO-HTML
    • allow creation of new elements
      • allow new elements to inherit from existing ones
    • allow import of HTML-Documents
    • allow use of templates
    • allow to hide fragments of the DOM
      • the shadow DOM
  • nicely fits into the HTML5 parsing and DOM building process compared with JS DOM manipulation

Web Components

a surprising example

  • we saw this forms playground before
    • take is e.g. the <input ... type=range element rendered as a slider
    • you may have done or seen it: such a slider can be programmed using some divs, CSS and Javascript
    • exactly this is what most browser vendors do internally
    • but how comes you cannot find or access it in the DOM? Well Browsers hides this part of the DOM (and its CSS and names and ...)
    • the technical term for a hidden part of the DOM is Shadow DOM
    • Chrome graciously allows to display a Shadow DOM in its developper tools
  • Shadow DOM is one essential concept of Web Components
  • what will a native video element hide?

Web Components

Google Chrome: inspection of a <input ... type=range element

Google Chrome screenshot

Web Components

Some rules

  • events fired in shadow DOM subtree can be listened to in the document
  • when crossing the shadow DOM boundary, the events are re-targeted to the shadow parent element
  • but how comes you cannot find or access it in the DOM? Browsers hide this part of the DOM
  • holes in the Shadow DOM: DOM childs of the parent of a shadow DOM subtree might be accessed by and integrated into the shadow DOM
  • there are means to assign CSS properties from outside

Web Components

  • Templates :
    • not too much new stuff:
      • Template content is not part of the DOM
      • it will be inserted (and executed) when applied
      • a Template has a content property, which accesses its content
  • Example
 
    <head>
      <meta charset="UTF-8">
      <title>templates — ict-Media GmbH</title>
      <template class=record>
        <div>
            <strong class=name>Name</strong> worked as  
            <span class=func>function</span>
        </div>
      </template>
      <script>
        function addrecord(l, n, f) {
          var t = document.querySelector(".record");
          var m = t.content.cloneNode(true);
          // Populate content.
          m.querySelector('.name').textContent = n;
          m.querySelector('.func').textContent = f;
          document.querySelector(l).appendChild(m);
        }
      </script>
    </head>
    <body>
      <h1>Templates</h1>
        <div id=list1>
          <script>
            addrecord("#list1","Karl","emperor");
            addrecord("#list1","Hubert","hunter");
            addrecord("#list1","Martin","coat cutter");
          </script>
        </div>
    </body>
                
It will be rendered as:

Templates

Karl worked as emperor
Hubert worked as hunter
Martin worked as coat cutter

Web Components

Custom Elements

  • custom elements are created by registing them
  • the name must contain a "-"
  • custom elements can extent other (also custom) elements (inheritance)
  • callbacks for creation, insertion, deletion of a custom element instance and for attribute changes

Web Components

Custom Elements with shadow Dom example:

 
<body>
    <h1>Ohmsches Gesetz</h1>
    
    <p>Wir benutzen <code>&lt;x-slider&gt;</code> &mdash; den 
      logarithmischen Slider von <code>html5-tag.de</code>.</p>
      
    <x-slider min=0.0001  max=10000000 id=U value=1>V Spannung</x-slider><br />
    <x-slider min=0.000001 max=1000000 id=I value=1>A Strom</x-slider><br />
    <x-slider min=0.1  max=100000000 id=R value=1>&#x2126; Widerstand</x-slider>

</body>
                

x-Slider has the following properties:

  • has a logarithmic slider
  • has a numeric display (eng-format)
  • element textContent will be attached.

This is all a developer needs to know about it

Web Components

The computations of Custom Elements example:

 

function init(){

    // adjust other sliders to confom to Ohm's law
    function sliderAdjust(e){
        if (e.target == U) I.setAttribute("value",U.value/R.value);
        if (e.target == I) R.setAttribute("value",U.value/I.value);
        if (e.target == R) I.setAttribute("value",U.value/R.value);
    };      
    
    // assign vars to elements
    var U = document.getElementById("U");
    var I = document.getElementById("I");
    var R = document.getElementById("R");

    // listen to slider changes
    U.addEventListener("x-slider-changed",sliderAdjust);
    I.addEventListener("x-slider-changed",sliderAdjust);
    R.addEventListener("x-slider-changed",sliderAdjust);
}

                

Web Components

3 ways to define the x-slider element used in our Custom Elements example:

  1. straight forward copying the code
  2. element guts in a shadow dom
  3. HTML import using template and shadow dom

Web Components

1. straight forward copying the code:

 
(function() {

    function formatEng(n){
        var mod = ["p","n","µ","m"," ","K","M","G","T"];
        var exp=4;
        var m = n;
        for (; m>=1000; m/=1000) exp +=1;
        for (; m<1; m*=1000) exp -=1;
        m = String(m);
        if (m.indexOf(".") === -1) m += ".";
        return (m + "0000").substr(0,5) + " " + mod[exp];
    }
    
    // first we inherit from <span>
    var XSliderProto = Object.create(HTMLSpanElement.prototype);
    var l10 = Math.log10 || function(x){return Math.log(x) / Math.LN10};
    var e10 = function(x){return Math.pow(10,x)};

    //we do more when the element is created
    XSliderProto.createdCallback = function() {

        // add some properties to our custom element
        this.value = this.getAttribute("value");
        this.name = this.getAttribute("name");
        this.min = this.getAttribute("min");
        this.max = this.getAttribute("max");
        
        // populate custom element
        this.innerHTML = 
            "<style scoped>span {font-size: 200%;}</style>" + // note the use of scoped CSS here
            "<input type=range class=slider min=" + l10(this.min) + " max=" + l10(this.max) + " step=" + 0.001 + " value=" + l10(this.value) +" />" + 
            "<span class=value>" + formatEng(this.value) +"</span>" +
            "<span class=descr>" + this.textContent + "</span>";

        var slider = this.querySelector("input.slider");
        var numeric = this.querySelector("span.value");
        
        // slider change event
        var that = this;
        slider.addEventListener("change",function(e){
            var v = e10(slider.value)
            numeric.textContent = formatEng(v);
            if (that.value != v){
                that.value = v;
                if (that.getAttribute("value") != v)
                    that.setAttribute("value",v);
            }
        });
    }

    // we define a callback in case of user interaction
    XSliderProto.attributeChangedCallback = function(attrName, oldVal, newVal){
        if (attrName == "value") {
            if (oldVal != newVal){
                var slider = this.querySelector("input.slider");
                var numeric = this.querySelector("span.value");
                
                if (this.value != this.getAttribute("value")){ // call after computed change?
                    this.value = newVal;
                    slider.value = l10(newVal);
                    numeric.textContent = formatEng(newVal);
                }

                else { // call after manual change ... do computations
                    var event = new CustomEvent("x-slider-changed");
                    this.dispatchEvent(event);
                }
            }
        }
    }
    
    // finally register new element
    var XSlider = document.registerElement('x-slider', {prototype: XSliderProto});

})();
                

Web Components

2. element guts in a shadow dom:

 

(function() {

    function formatEng(n){
        var mod = ["p","n","µ","m"," ","K","M","G","T"];
        var exp=4;
        var m = n;
        for (; m>=1000; m/=1000) exp +=1;
        for (; m<1; m*=1000) exp -=1;
        m = String(m);
        if (m.indexOf(".") === -1) m += ".";
        return (m + "0000").substr(0,5) + " " + mod[exp];
    }

    // first we inherit from <span>
    var XSliderProto = Object.create(HTMLSpanElement.prototype);
    var l10 = Math.log10 || function(x){return Math.log(x) / Math.LN10};
    var e10 = function(x){return Math.pow(10,x)};

    //we do more when the element is created
    XSliderProto.createdCallback = function() {

        // create shadow root
        shadow = this._shadow = this.createShadowRoot();

        // add some properties to our custom element
        this.value = this.getAttribute("value");
        this.name = this.getAttribute("name");
        this.min = this.getAttribute("min");
        this.max = this.getAttribute("max");
        
        // populate shadow DOM
        shadow.innerHTML = 
            "<style>span {font-size: 200%;}</style>" +
            "<input type=range class=slider min=" + l10(this.min) + " max=" + l10(this.max) + " step=" + 0.001 + " value=" + l10(this.value) +" />" + 
            "<span class=value>" + formatEng(this.value) +"</span>" +
            "<span class=desr><content></content></span>"; // shadow host innerHTML goes to <content>

        var slider = shadow.querySelector("input.slider");
        var numeric = shadow.querySelector("span.value");
        
        // slider change event
        var that = this;
        slider.addEventListener("change",function(e){
            var v = e10(slider.value)
            numeric.textContent = formatEng(v);
            if (that.value != v){
                that.value = v;
                if (that.getAttribute("value") != v)
                    that.setAttribute("value",v);
            }
        });
    }

    // we define a callback in case of user interaction
    XSliderProto.attributeChangedCallback = function(attrName, oldVal, newVal){
        if (attrName == "value") {
            if (oldVal != newVal){
                var slider = this._shadow.querySelector("input.slider");
                var numeric = this._shadow.querySelector("span.value");
                
                if (this.value != this.getAttribute("value")){ // call after computed change?
                    this.value = newVal;
                    slider.value = l10(newVal);
                    numeric.textContent = formatEng(newVal);
                }

                else { // call after manual change ... do computations
                    var event = new CustomEvent("x-slider-changed");
                    this.dispatchEvent(event);
                }
            }
        }
    }
    
    // finally register new element
    var XSlider = document.registerElement('x-slider', {prototype: XSliderProto});

})();

                

Web Components

3. HTML import using template and shadow dom:

 
<template class="xslider">
    <style>span {font-size: 200%;} </style>
    <input type=range class=slider step="0.02"/>
    <span class=value></span><span class=descr><content>
      <!-- shadow host innerHTML goes here --></content>
      </span>
</template>

<script type="text/javascript">
(function() {
  
    function formatEng(n){
        var mod = ["p","n","µ","m"," ","K","M","G","T"];
        var exp=4;
        var m = n;
        for (; m>=1000; m/=1000) exp +=1;
        for (; m<1; m*=1000) exp -=1;
        m = String(m);
        if (m.indexOf(".") === -1) m += ".";
        return (m + "0000").substr(0,5) + " " + mod[exp];
    }
    
    // first we inherit from <span>
    var XSliderProto = Object.create(HTMLSpanElement.prototype);
    var l10 = Math.log10 || function(x){return Math.log(x) / Math.LN10};
    var e10 = function(x){return Math.pow(10,x)};

    //we do more when the element is created
    XSliderProto.createdCallback = function() {

        // add some properties to our custom element
        this.value = this.getAttribute("value");
        this.name = this.getAttribute("name");
        this.min = this.getAttribute("min");
        this.max = this.getAttribute("max");
        
        // dig template fragment (traverse imp boundary via 'imp' property)
        var imp = document.querySelector("link[href$=\"x-slider.html\"]").import;
        /* (traverse template boundary via 'content' here - 
           why the hell do we use a template here) */
        var template = imp.querySelector("template").content.cloneNode(true);
        
        // adjust Shadow dom elements
        var slider = template.querySelector("input.slider");
        var numeric = template.querySelector("span.value");
        slider.setAttribute("min",l10(this.min));
        slider.setAttribute("max",l10(this.max));
        slider.setAttribute("value",l10(this.value));
        slider.setAttribute("step",0.001);
        
        numeric.textContent = formatEng(parseInt(this.value));        

        // create shadow root
        shadow = this._shadow = this.createShadowRoot();
        // attach fragment to the shadow root 
        shadow.appendChild(template);

        // slider change event
        var that = this;
        slider.addEventListener("change",function(e){
            var v = e10(slider.value)
            numeric.textContent = formatEng(v);
            if (that.value != v){
                that.value = v;
                if (that.getAttribute("value") != v)
                    that.setAttribute("value",v);
            }
        });
    }

    // we define a callback in case of user interaction
    XSliderProto.attributeChangedCallback = function(attrName, oldVal, newVal){
        if (attrName == "value") {
            if (oldVal != newVal){
                var slider = this._shadow.querySelector("input.slider");
                var numeric = this._shadow.querySelector("span.value");
                
                if (this.value != this.getAttribute("value")){ // call after computed change?
                    this.value = newVal;
                    slider.value = l10(newVal);
                    numeric.textContent = formatEng(newVal);
                }

                else { // call after manual change ... do computations
                    var event = new CustomEvent("x-slider-changed");
                    this.dispatchEvent(event);
                }
            }
        }
    }
    
    // finally register new element
    var XSlider = document.registerElement('x-slider', {prototype: XSliderProto});

})();

</script>

                

Web Components

We cannot cover it all — here a summary and some links

  • New way of thinking: everything is an element
    • not a JS Object neither a function
  • there a lot of thinking on how can we make best out of it
  • http://webcomponents.org/ holds much of the activities
  • some tools to support good style and productive development are out there — lead by polymer http://www.polymer-project.org/

Web Components

A word on Polymer (graphic from Eric Bidelman):

Polymer architecture

Drag'n drop

Goals:

  • another concept inherited from browsers
  • useful but not nicely specified
  • build a demo for later use
  • files will use it too
Deco: more flowers

Drag'n drop

  • HTML5 can let you do drag'n drop
  • You can drag various types of content (including files) to elements that allow dropping these types
  • Let's use it to do a little game: The Towers of Hanoi for now Towers of Hanoi
    • We use: 5 events ondragstart, ondragenter, ondragover, ondrop, ondragend
    • We use a dataTransfer object (at least I tried)

Drag'n drop

A disc looks like this (red parts vary from disc to disc):

<div class=disk id=s#>=</div>

Towers are the container of disks (where you drop the disks) and look like this:

<div class=tower id=t#>

<!-- disks follow -->

</div>

Following is the HTML mark-up:

Drag'n drop

  <div class=game>
    <div class=tower id=t1>
      <div class=disk id=s1>=</div>
      <div class=disk id=s2>==</div>
      <div class=disk id=s3>===</div>
      <div class=disk id=s4>====</div>
      <div class=bottom id=z1>/\/\/\/\/\/\/\/\/\</div>
    </div>
    <div class=tower id=t2>
      <div class=bottom id=z2>/\/\/\/\/\/\/\/\/\</div>
    </div>
    <div class=tower id=t3>
      <div class=bottom id=z3>/\/\/\/\/\/\/\/\/\</div>
    </div>
  </div>
            

Drag'n drop

A little bit of CSS ...

  div.game {
    width: 350px;
    height: 140px;
    margin: 10px;
    position: relative;
    background-color:
      #000080;
    }

  div.tower {
    width: 100px;
    position: absolute;
    bottom: 10px;
    background-color:
      #0000f0;
    }

              
  #t1 {left:10px}
  #t2 {left:120px}
  #t3 {left:230px}

  div.disk, div.bottom{
    text-align: center;
    }
              

Drag'n drop

First we have to initialize the drag'n drop events:


var disks, towers, draggedone;

function init(){
    disks = document.getElementsByClassName("disk");
    towers = document.getElementsByClassName("tower");

    for (var i = 0;i<disks.length;i++){
      disks[i].draggable = i==0;
      disks[i].addEventListener("dragstart",dragstart);
    }

    for (var i = 0;i<towers.length;i++){
      towers[i].addEventListener("dragover", dragover);
      towers[i].addEventListener("drop", drop);
      towers[i].addEventListener("dragenter", dragenter);
    }
}

            

Drag'n drop

The first event (when we drag a draggable disc):


  function dragstart(ev) {

    // write Diks-ID into dataTransfer Object
    ev.dataTransfer.setData('text', ev.target.id);

    // since dataTransfer is protected in dragenter we have to have a variable
    draggedone = ev.target.id;
  }
            

Drag'n drop

Event when we enter a potential target (a tower in our game)
this holds the complete logic of the game:


  function dragenter (ev) {
    // get tower that has been entered by drag and get disk-ID
    var tower = ev.currentTarget; 
    var disk = draggedone;

    // get disks that are already on tower
    var disksOnTower = tower.getElementsByClassName("disk"); 
    if (disksOnTower.length==0 || disksOnTower[0].id>disk){

      // here if no disks yet on tower or the top disk is bigger than the dragged disk  
      tower.diskCanBeDroppedHere = true; // we have to remember it for dragover
      ev.preventDefault(); // yes please!
      return;
    }

    tower.diskCanBeDroppedHere = false; // sorry no drop allowed here
  }

            

Drag'n drop

Event when we drag over a target tower:

  function dragover(ev){

    if (ev.currentTarget.diskCanBeDroppedHere)
      ev.preventDefault(); // if we may drop here ...

    }
    
    
            

rather crazy, isn't it?

Drag'n drop

Event when we drop the disc on our tower:


  function drop(ev) {
    // find disk and tower involved
    var tower = ev.currentTarget;
    var disk = document.getElementById(ev.dataTransfer.getData('text'));
    ev.dataTransfer.dropEffect = 'move';
    // put disk on top of tower
    tower.insertBefore(disk,tower.firstChild);
    // re-adjust draggability
    for (var i=0; i<towers.length;i++){ // for all towers
      var e = towers[i].getElementsByClassName("disk"); // get disks
      if (e.length) e[0].draggable = true; // top disk is draggable
      for (var j=1;j<e.length;j++){
        e[j].draggable = false; // all others are not
      }
    }
    ev.preventDefault(); // ... whatever the default is!!!
  }

            

Drag'n drop

Finally there are 3 more events and things to know:

  • dragleave, dragend and drag (fires while dragged is moved)
  • Beside text file can be dragged and dropped (see later)
  • Yes, dragging elements could be emulated with mouse events
  • As with editable content: drag and drop hold quite some flaws (don't miss: The HTML5 drag and drop disaster http://www.quirksmode.org/blog/archives/2009/09/the_html5_drag.html on QuirksMode)
  • Quote from Ian Hickson: "The drag-and-drop API is horrible, but it has one thing going for it: IE6 implements it, as do Safari and Firefox."

The File API

Goals:

  • access files via dialog or drag'n drop
  • use files and metadata
  • access file contents
Deco: Banana trees

The File API

  • FileList interface, which represents an array of individually selected files from the underlying system of the client.
  • Blob interface, which represents immutable raw binary data
  • File interface, which inherits from blob and includes readonly informational attributes about a file
  • FileReader interface, which provides methods to read a File or a Blob
  • URI scheme for use with binary data such as files
  • Related APIs
    • XMLHttpRequest
    • drag and drop API
    • HTML input Element File Upload state

The File API

Building a FileList using a <input type=file ... > element e.g:

  • The HTML Mark-up:
    <body>
      <input onchange="getFL(event)" multiple type="file">
    </body>
            
  • The getFL function:
      function getFL(e){
        var fL = e.target.files;
        
        var l = document.createElement('ul');
        for (var f=0; f<fL.length; f++)
          l.innerHTML +=
          '<li>' + fL[f].name + " " + fL[f].type + " " + fL[f].size + " Bytes</li>";
            // filename mime-type length in bytes
          document.body.appendChild(l);
      }
            

This is all it takes.

The File API

Using createObjectURL to refer to the file

  • Same as before but we add the following block to function getFL:

  l = document.createElement('div');
  for (var f=0; f<fL.length; f++)
    if (fL[f].type.substr(0,6)=="image/")
      l.innerHTML += 
        '<img src='+URL.createObjectURL(fL[f])+' alt="Bild Filenr. '+f+'" height=100/> ';

  document.body.appendChild(l);
            

The File API

Just the same but using drag'n drop (not much change required):

  • The new HTML mark-up:


    <body onload="init()">
      <p>Drop images here:
        <img  id=box src="imagebox.jpg" alt"the picture box">
      </p>
    </body>
            
  • The script to do drag'n drop:
  function init() {
    var box=document.getElementById
      ("box");
    box.addEventListener
      ("dragenter", nop, false);
    box.addEventListener
      ("dragover", nop, false);
    box.addEventListener
      ("drop", getFL, false);
  }
              
  function nop(e){
    e.stopPropagation();
    e.preventDefault();
  }
  function getFL(e){
    e.stopPropagation();
    e.preventDefault();
    var fL = e.dataTransfer.files;
              

The File API

Getting the contents using the FileReader interface:

  • FileReader can read the file contents into:
    • an ArrayBuffer or
    • a String (by applying an encoding)
    • a DataUrl

The File API

  • ArrayBuffer
    • a buffer for raw binary data
    • to access the data, simple datastructures can be superimposed forming a typed array
    • Example:
        var buff = new ArrayBuffer(32);
        var shortIntArray = new Int16Array(buff);
        for (var i=0; i<shortIntArray.length; i++)
          shortIntArray[i] = i;
                          
      shortIntArray will have length of 16 and hold integers 0 — 15.
  • DataUrl
    • according to RFC2937 (The "data" URL scheme) a DataUrl has the following format:
      data:[<mediatype>][;base64],<data>
      it holds the "real" data either ASCII or base64 encoded.

CSS3

Goals:

learn about:

  • HTML5 presentation
  • things that you (designers) waited for desperately
Deco: Autumn leaves

CSS3

A short CSS refresh:

  • CSS3 consists of
    • selectors each associated with a sequence of declarations
    • declarations consist of a property with assigned values
    • conditional groups (e.g. media queries)
  • 
      @media print {
        /* hide navigation controls when printing */
        #navigation { display: none }
      }
                  

CSS3

  • CSS3 provides a lot of new styling opportunities
  • While the HTML5 spec is presented in a monolithic document CSS3 comes in modules 1)
  • Some are standards already, others are drafts
  • Browser vendors play with new features often by prefixing experimental declarations with a vendor id
    • Vendor ids are e.g. -moz-, -webkit-, -ms-, -o-
  • A lot of new selectors and new declarations open-up new opportunities
  • recent fundamental changes:
    • new box model --- calc(...) function --- cascaded variables

1) Not completely true for HTML5 anymore. W3C develops HTML5 related modules (extension specs) that when ready may be integrated into HTML5 spec.

CSS3 new features

Goals:

  • develop a demo for new features
  • explain the separation of content and presentation
Deco: Autumn leaves

CSS3 new features

  • Let's face the challenge: our Towers of Hanoi example should rather look like this
  • The rules:
    • No change in mark-up (structure)
    • No change in Javascript (logic)
    • Only changes in CSS [file] (presentation)
    • No graffiti (SVG, Canvas ...)
  • A lot of new selectors and new declarations open-up new opportunities
  • We will make use of quite some of the new CSS3 capabilities

CSS3 new features

This is the CSS we have so far:

    div.game {
    width: 350px;
    height: 140px;
    margin: 10px;
    position: relative;
    background-color: #000080;
    }

    div.tower {
    width: 100px;
    position: absolute;
    bottom: 10px;
    background-color: #0000f0;
    }
                
    #t1 {left:10px}
    #t2 {left:120px}
    #t3 {left:230px}

    div.disk, div.bottom{
    text-align: center;
    }
                

CSS3 new features

First let's get rid of the text in disks and bottoms:

  • The following rule should suffice:
    .disk .bottom{ font-size: 0px; }
  • Unfortunately it destroys the whole geometry of our example

CSS3 new features

Let's do the basic geometry (colors are chosen randomly for now):

The game container should for now be OK:

    div.game {
    width: 350px;
    height: 140px;
    margin: 10px;
    position: relative;
    background-color: #ff00ff;
    }
                

We use position: relative; to allow absolute positioning within the game area!

The three containers for our towers are also OK:

    div.tower {
    width: 100px;
    position: absolute;
    bottom: 1px;
    background-color: #0080FF;
    }
    #t1 {left:10px}
    #t2 {left:120px}
    #t3 {left:230px}
                

We only change the distance from the bottom to 1 pixel

CSS3 new features

Let's continue on the basic geometry (colors are chosen randomly for now):

The bottom should now become a pole. We give it a width and a height and center it within the pile:

    div.bottom{
    height:120px;
    width: 10px;
    position: absolute;
    left:45px;
    bottom: 0px;
    background-color: #00c000;
    }
                

disks get a height of 20 pixels and an individual width:

    .disk { height: 20px;
    background-color: #ff0000;}

    #s1 { width: 30px;
    margin-left: 35px;}
    #s2 { width: 50px;
    margin-left: 25px;}
    #s3 { width: 70px;
    margin-left: 15px;}
    #s4 { width: 90px;
    margin-left: 5px;}
                

Easy up to here? Here is the result!

CSS3 new features

  • Basic geometry seems to be OK. But it doesn't look nice. (Btw: everything up to now would work in CSS2!)
  • What we should improve
    • More 3D like look
    • Poles behind disks please, tower container invisible
    • Disks individually colored
    • The game container should look more like a stage
  • We are done with the geometry. None of the declarations so far (except removal of preliminary color) will be changed anymore.

CSS3 new features

This will be our stage, rounded border at the top, ridge border at the bottom and throwing a shadow. Set a basis for z-index.

      .game {
      background-color: #a0a0a0;
      border-radius:
          10px 10px 0px 0px;
      border-bottom-style: ridge;
      border-width: 5px;
      box-shadow:
          7px 7px 3px #505050;
      z-index :-0;
      }
                

Here come the poles. Slightly rounded border, gradient for 3D effect, throws shadow on stage placed behind the disks:

      div.bottom {
      border-radius: 2px;
      box-shadow: 
          15px 3px 7px #606060;
      background: 
          -radial-gradient
          (40% 45%, #80c0ff, #1a60d0);
      z-index:-1;
      }
                

Let me see! Huh where are the discs now?

CSS3 new features

The disks are still there. (They only lost their color!). Let's bring them back to life! Rounded border, shadow throwing …

.disk{
    border-radius: 8px;
    box-shadow: 15px 3px 7px 
    #606060;
    }
                

And an individual gradient for each disc for the 3D effect. We are done!

    #s1 {
    background: radial-gradient
    (40% 30%, closest-corner, 
    #ffff00, #45352a);}
    #s2 {
    background: radial-gradient
    (40% 30%, closest-corner,
    #ff4000, #602727);}
    #s3 {
    background: radial-gradient
    (40% 30%, closest-corner,
    #ff00ff, #601a60);}
    #s4 {
    background: radial-gradient
    (40% 30%, closest-corner,
    #40ff00, #276027);}
                

Here the final result!

CSS3 Fonts (and animation)

Goals:

  • develop a demo for new features
  • explain the separation of content and presentation
Deco: Autumn leaves

CSS3 Fonts (and animation)

Another example: use of fonts

  • @font-face {descriptor : value;descriptor : value; ...} rule allows for linking to fonts
  • A font face can bind a font locally to a font-family
  • Fonts can be in format woff (Web Open Font Format, .woff ), truetype (.ttf), opentype (.ttf, .otf), embedded-opentype (.eot) and svg (.svg, .svgz)
  • Font references can be by url(...) and by local(...) if the font is locally installed

CSS3 Fonts (and animation)

Example HTML mark-up:

                <article>
                <div id=content>
                <p>
          In principio erat Verbum, et Verbum erat apud Deum, et
          Deus erat Verbum. Hoc erat in principio apud Deum. Omnia
          per ipsum facta sunt: et sine ipso factum est nihil, quod
          factum est. In ipso vita erat, et vita erat lux
                <img src="../images/creation-adam-eve-jean-fouquet.jpg"
                alt="Creation of Adam and Eve"/>
          hominum: et lux in tenebris lucet, et tenebrae eam non
          comprehenderunt. 
                </p>
                <p>
          Fuit homo missus a Deo, cui nomen erat Ioannes. Hic venit
          in testimonium ut testimonium perhiberet de lumine, ut omnes
              

… and so on. Only normal paragraphs following.

CSS3 Fonts (and animation)

Example the magic is in the CSS:

The fonts:


@font-face {
  font-family: "initial";
  src: local(GriffDinShi),
    url(GriffDinShi.ttf);
  }

@font-face {
  font-family: "bodytext";
  src: url(GutenbergTextura.ttf);
  }
                

Article setup:


article {
  font-family: "bodytext";
  font-size: 26px;
  text-shadow: 1px 1px 1px #808040;
  line-height : 80%;
  opacity : 0.85;

  width: 550px;
  margin-left:100px;
  padding :40px;
  background: 
      url("../images/parchment.jpg");
  background-size: 100% 100%;
  }
                

CSS3 Fonts (and animation)

Example the magic is in the CSS:

The initials:

p:first-letter {
  float: left;
  font-size: 340%;
  font-family: "initial";
  margin-right: 0.1em;
  color: #501000;
  text-shadow: 3px 3px 2px #400000;
  }
                

Other setup:

p {
  clear: left;
  opacity : 0.85;
  }

img {
  float: right;
  width: 300px;
  margin: 10px;
  }
                

CSS3 Fonts (and animation)

Example but when we make two small amendments:

The content div:
<div id=content onclick="this.style.opacity=.07">

And provide a bit of style:

                #content {  
                transition-property: opacity;
                transition-duration: 10s;
                }
              

we have a little aging animation using CSS3 transition.

CSS3 Fonts (and animation)

CSS3 transitions are simple:

  • Can in general be applied when a numeric property changes
  • You simply select
    • the property of the transition
    • the duration of the transition
    • optional: a (maybe sophisticated) timing function
    • optional: a delay
  • transitions can overlap
  • A good example and description: http://webkrauts.de/artikel/2011/css-3-im-praxistest-transition

CSS3

Example and when we make another small amendment:

And provide a bit of style:

                #content {  
                column-count: 2;
                column-gap: 0.7em;
                column-rule: 2px solid #C7B5A7;
                }
              

we have a CSS3 multicolumn layout.

CSS3 flexible boxes

Goals:

  • learn and apply a new formating concept
  • (one of the things you desperately missed)
Deco: Autumn leaves

CSS3 flexible boxes

Flexible boxes

  • are a concept to place boxes in a container box
  • boxes can grow, shrink, wrap, align according to authors needs

related standard (similar purpose, different model): CSS3 grid layout http://www.w3.org/TR/css3-grid-layout/

CSS3 flexible boxes

Flexible boxes concept and terms:

  • boxes are arranged along a main axis in a container
    • the direction of the main axis is specified in the containers CSS property flex-direction
    • values include row row-reverse column column-reverse
  • the perpendicular axix to the main axis is called cross axis
  • boxes can be aligned relative to the cross axis in the container
    • the CSS property is align-items
    • values include flex-start flex-end center baseline stretch

CSS3 flexible boxes

Flexible boxes concept and terms:

  • boxes can be justified along the main axis in the container
    • the CSS property is justify-content
    • values include flex-start flex-end center space-between space-around
  • boxes have the ability to grow and shrink
    • the CSS properties are flex-grow flex-shrink flex-basis or short flex
    • values include flex-start flex-end center space-between space-around

CSS3 flexible boxes

Flexible boxes example:

  • 3 boxes left to right (in an ltr environment) should take the height of the container:
    • the container (id container)
    • 3 boxes ids: nav main widgets
  • widgets has a fixed width: 250px
  • nav should take-up 20% of the remaining space
  • main will take the rest
  • all boxes should have a margin: 10px

CSS3 flexible boxes

Flexible boxes example. Here the CSS:

  #container {
      display: flex;
      align-items: stretch;
      height: 90%;
    }
    #container * {
      margin: 10px
    }
    #nav {
      flex-shrink: 1;
      flex-grow: 1;
    } 
    #main {
      flex-shrink: 4;
      flex-grow: 4;
    } 
    #widgets {
      flex-shrink: 0; 
      flex-grow: 0; 
      flex-basis: 250px; 
    }

How long do you fiddle for this with float? Or — even worse — using layout tables?

More beautiful things you can do with flex boxes in this example.

CSS3 computations and variables

Goals:

still a bit experimental

  • compute properties
  • properties from attributes
  • cascaded variables for properties
  • toggle properties
Deco: Autumn leaves

CSS3 computations and variables

Computing properies with calc()

  • CSS Values and Units Module Level 3 http://www.w3.org/TR/css3-values/ (CR) describes calculations in CSS3
  • CSS data types:
    • textual: predefined keywords, quoted strings, URLs, and custom-idents, (e.g. counter names)
    • numeric: integer, number, percentage,
      • length absolute (cm, mm, in, px(==1"/96), pt, pc)
      • length relative
        • to fonts (em, ex, ch, rem)
        • to 1% of viewport dimensions (vw, vh, vmin, vmax)
      • other units(angle, time, frequency, resolution, ...)
    • functional notations: url(...), rgb(...), counter(...),

CSS3 computations and variables

Use of calc:

  • calc can compute expressions build with operators +, -, *, /
  • calc must yield a type that is valid where the expression is placed
  • syntactical caveats: binary + and - must be enclosed in space, no space allowed between calc and (
  • examples:
    • width: calc(100%/2 - 20px);margin: calc(20px/2);
    • :root {font-size: calc(100vh/40)} now 1rem = 1/40th viewport height. This was used for these slides btw.
  • At risk in CR. Meaning: might be postponed.

CSS3 computations and variables

Access to element attributes to compute a property

  • CSS Values and Units Module Level 3 http://www.w3.org/TR/css3-values/ (CR) describes access to elements in CSS3
    • attr allows to pick values from attributes
    • syntax is attr( <attr-name> <type-or-unit>? [ , <fallback> ]? )
    • <type-or-unit>? is one of string, color, url, integer, number, length, angle, time, frequency,
      em, ex, px, rem, vw, vh, vmin, vmax, mm, cm, in, pt, pc, deg, grad, rad, ms, s, Hz, kHz, %
      can be used in calc()

bad news: rather not implemented by now. At risk in CR.

CSS3 computations and variables

example (simple bar chart, data in HTML mark-up):

    <style type="text/css">
    #chart div {
      background-color: attr(data-color);
      height: 20px;
      width: attr(data-value px);
    }
    </style>
    <div id=chart>
      <div data-value=100 data-color=red></div>
      <div data-value=150 data-color=green></div>
      <div data-value=250 data-color=blue></div>
      <div data-value=125 data-color=yellow></div>
    </div>
                
should render like this:

CSS3 computations and variables

Toggle properties instead of inheriting

  • CSS Values and Units Module Level 3 http://www.w3.org/TR/css3-values/ (CR) describes toggling of properties
  • attr allows to pick values from attributes
  • syntax is toggle( <value>, <value> [, <value> ...] )
  • instead of inheriting a property from a parent element it will be toggled according to the following rule:
    • find index of inherited property value in toggle <value> list
    • instead of inherited value use value with index=(index(inherited value) + 1) mod length(valuelist)
  • examples:
    em: {font-style: toggle(italic, normal)}
    ul: {list-style-type: toggle(square, disc, circle)}
                

bad news: rather not implemented by now. At risk in CR.

CSS3 computations and variables

Cascading variables

  • CSS Custom Properties for Cascading Variables Module Level 1 http://www.w3.org/TR/css-variables-1/ (LCWD) describes use of variables in CSS
  • inspired by LESS or SASS CSS preprocessors
  • syntax: a selectors property var-<varname>: <value>; sets a cascading variable <varname> with value <value>
    • example: :root {var-em-color: red;} sets a variable var-em-color to the value red.
  • syntax: assigning a variable to a property <property>: var(<varname>; assigns the value of variable <varname> to <property>
    • example: {background-color: var(em-color);} sets the property background-color to the value of the variable em-color.
  • variable scopes follow cascading rules.

bad news: Cascading Variables are rather not implemented by now.

CSS3

There is a lot more on CSS3 e.g.:

HTML5 Pixels : Canvas

Goals:

  • Graphics and HTML5
  • the 2D context: HTML5 grafitti
Deco: Orchids

The Canvas API

HTML5 has 2 approaches to graphics:

  • SVG
    • A big vector based XML language
    • Declarative
    • Allows to declare graphical object, animations, transformations, groups, filters
    • Basis for many complex graphical applications
  • Canvas
    • A place where you can drop or extract pixels
    • Has (procedural) “context-APIs” that define how you do it
    • HTML spec holds the 2D context (meanwhile there is work on level 2),
    • another popular context is webgl a Web version of Opengl

The Canvas API

HTML5 has 2 approaches to graphics:

  • SVG and Canvas can both be used to produce graphics
  • The way both work is fundamentally different
  • A bunch of tools ad frameworks exist for both to provide higher levels of abstraction and adopt them to specific applications
  • SVG generates an XML DOM representing the graphical objects, filters, transformations, animations ...
  • The DOM can be manipulated by scripts
  • The presentation can be controlled by CSS
  • CANVAS is about writing pixels onto a canvas (fast, close to the graphics hardware)
  • Once an object has been painted any manipulation is on base of pixels
  • Painting methods and properties are provided by contexts

The Canvas API

The Canvas element — a box (like a img or video)

  • 2 attributes: width and height
  • 3 methods:
    • toDataUrl([type,[...]]) returns a data://... URL (RFC 2397) that contains the image (pixels) in the canvas
    • toBlob(callback [, type, ... ]) returns a blob object representing a file containing the image (pixels) in the canvas
    • getcontext(contextId) creates a context object associated with the canvas. This is where the graphic methods live
  • A bunch of tools ad frameworks exist for both to provide higher levels of abstraction and adopt them to specific applications

We will look at the (simple) “2D” context

The Canvas API

The “2d” context API:

  • General:
    • canvas attribute refers to the owning canvas element
    • save() pushes most of the context state on a stack
    • restore() pops the context state
  • Compositing:
    • globalAlpha property to specify transparency of pixels painted onto the canvas
    • globalCompositeOperation property to specify how already present pixels interact with newly painted ones

The Canvas API

visualization of different globalComposite modes
  • globalCompositeOperation (graphics from modzilla)
  • Let's do our own experiments

The Canvas API

Transformations

  • scale(x,y)
  • translate(x,y)
  • rotate(angle)
  • Based on transformation Matrix:
    • transform(m11,m12,m21,m22,dx,dy)
    • setTransform(m11,m12,m21,m22,dx,dy)

Images:

  • drawimage can draw bitsmaps received from img, canvas or video elements. See video example or video example

The Canvas API

Video to canvas ...

  function canplay() {
    // more code here
    w = video.videoWidth;
    h = video.videoHeight;
    canvas.width = w;
    canvas.height = h;
    ctx = canvas.getContext("2d"); // load Context API
    ctx.translate(w/2,h/2);
    ctx.scale(-1/1.42,1/1.42);
    ctx.drawImage(video,-w/2,-h/2,w,h);
  } 

  function timeupdate(){
    progressBar.value=video.currentTime;
    currentTime.textContent = tm(video.currentTime);
    ctx.rotate(Math.PI/60);
    ctx.drawImage(video,-w/2,-h/2,w,h);
  } 
            

The Canvas API

Properties to control line styles:

  • lineWidth, lineCap, lineJoin, miterLimit

Various methods for path composing

  • beginPath, closePath
  • fill, stroke, clip
  • quadraticCurveto, bezierCurveTo, arcTo, arc, rect
  • IsPointinPath

Text properties and methods

  • Properties: font, textAlign, textBaseline
  • Methods: fillText, strokeText, measureText

The Canvas API

In addition to path methods there are 3 rectangle methods

  • clearRect, fillRect, strokeRect

Styles and shadows for strokes and fills

  • Properties:strokeStyle, fillStyle, shadowOffsetX, shadowOffsetY, shadowBlur, shadowColor
  • Methods: createLinearGradient, createRadialGradient, createPattern
  • And a method to define colorstops for a gradient: colorStop

The Canvas API

That's nearly all about the canvas 2D context except that tere is a way to access the canvas on pixel level

  • There is a datatype (interface) ImageData that has 3 properties:
    • width, height and data
    • data is of type CanvasPixelArray
  • CanvasPixelArray for an image of size w,h is an array of length w*h*4 to access (e.g. the opacity component of row y, column x the index is w*y*4+x*4+3)
  • Methods createImageData, getImageData and putImageData can be used to access or set Canvas pixels.

The Canvas API

image data structure visualization

The ImageData interface allows direct access to pixels in any rectangular area of a canvas.

Web Workers

Goals:

learn about:

  • multi threading in Web applications
  • its capabilities and limitations
Deco: dandelion

Web Workers

Client site multi threading:

  • simple API
  • thread safe message communication between workers and application
  • methods in application:
    • windows.Worker(script-url) (Constructor)
    • worker.postMessage(message)
    • worker.onmessage(event)
    • worker.terminate()
  • methods in worker thread:
    • self.postMessage(message)
    • self.onmessage(event)
    • self.close()

Web Workers

What they can use/access

  • Javascript standard functions
  • atob()and btoa()
  • timer functions
  • XMLHttpRequest() keine XML (DOM) Unterstützung
  • Web Storage
  • Worker()
  • navigator object

Web Workers

Data passed between the main page and workers are copied, not shared. Objects are serialized as they're handed to the worker, and subsequently, de-serialized on the other end.

I'll show you an example which demonstrates some essential limitations of Web Workers:

  • Lack of shared storage.
    • postmessage, onmessage must be used to share data.
  • Can only work on copies of objects
    • requires serialising (stringifying) of Objects.
  • Causes a lot of garbage collections

Web Workers

The idea of the example.

This Petri Net models the control flow between Web Workers and the client for the balls simulatation (with 5 balls).

Web Workers

Code for the Cosmos of balls (Planet) :

  function Cosmos(width,height,minr,maxr,count,attraction,ctx){
    var deltaT=1; // time between 2 calcs of new positions
    function Planet(x,y,r,c,id)
      {...}  // a ball with ... with a web worker
    function initdone(planet)
      {...} // checks if everything was initialized ...
    function startCompute()
      {...} // asks workers to compute their ball's speed and position ...
    function computedone(planet)
      { ... // new position computing finished?
      /* if we have to draw on the display */ drawPlanets() //(25 fps)
      setTimeout(startCompute,deltaT);
      }
    function drawPlanets()
      {...} // draws the current positions on canvas
    this.close = function (){{...} // stop it
             

Web Workers

Code for the Cosmos of balls (Planet) :


            
    // start it all ... randomly distribute balls
    for (var i=0; i<count; i++){ //...
      planets[i] = new Planet(...,i);
    }
    drawPlanets();
    // initialize Web Workers with static data
    var planetsReady = 0;
    for (var i=0; i<count; i++){
      planets[i].worker.postMessage({
        cmd: "init", ...
      });
    }
  }
            

Web Workers

Code for the Ball (Planet) Object:

  function Planet(x,y,r,c,id){ // a ball
    this.id=id;
    this.stat = {radius : r, mass : r*r*r};
    this.phys = {position : {x: x,y: y}, speed : {x: 0, y : 0}};
    this.close = function (){this.worker.terminate();};
    this.color = c;
    this.worker = new Worker("worker.js");
    planetsPhys[this.id] = this.phys;
    planetsStat[this.id] = this.stat;
    var that = this;
    this.worker.onmessage = function(event){
      var m = event.data;
      switch (m.mtype){
        case 'initdone' : initdone(that); break;
        case 'computedone' : 
          that.phys.speed = m.phys.speed;
          that.phys.position = m.phys.position;
          computedone(that);
        break;
      }  
    }  
  }
            

Web Workers

Code to create the balls:



      for (var i=0; i<count; i++){
        r = Math.random()*(maxr-minr)+minr;
        planets[i] = new Planet(
          Math.random()*(width-2*r)+r,
          Math.random()*(height-2*r)+r,
          r,
          "rgb(" + Math.floor(Math.random()*96+32) + ","
                + Math.floor(Math.random()*96+32) + "," 
                 + Math.floor(Math.random()*96+32) + ")",
          i  // id
        )
      }
            

Web Workers

Code to initialize the workers:



      var planetsReady = 0;
      for (var i=0; i<count; i++){
        planets[i].worker.postMessage({
          cmd: "init",
          stats : planetsStat,
          id : i,
          count : count,
          attraction : attraction,
          size : {w:width, h:height}
        });
      }
           

Web Workers

Code to call workers to compute a new position:

      var t1,t2,t3;
      // t1 ::= time of last drawPlanets
      // t2 ::= time of last computations
      // t3 ::= now
      function startCompute(){ 
        // computes for every ball the current speed and position
        planetsReady = 0; if (close) return;
        t3 = Date.now();
        var dt = t3-t2; // dt ::= time since last compute
        t2 = t3;
        for (var i=0; i<count; i++)
          planets[i].worker.postMessage({
            cmd:'compute',
            planetsPhys : planetsPhys,
            dt : dt
          });
      }
            

Web Workers

Code of the workers:

  self.onmessage = function(event){
    var m = event.data;
    switch (m.cmd){
      case 'init' : // copy global ?constants?
        self.stats = m.stats,
        self.id = m.id,
        self.count = m.count,
        self.attraction = m.attraction,
        self.size = m.size,
        self.collisionBefore = new Array(self.count);
        postMessage({mtype:"initdone"}); break;
      case 'compute' :   // compute new position and speed of ball    
        compute(m.planetsPhys, m.dt);
        postMessage({mtype:"computedone",phys:m.planetsPhys[self.id]});
        break;
    }
  }
  function compute(pP,dt){...} ? // a bit of physics 
            

Web Workers

(Bonus) canvas draw:

      function drawPlanets(){
        // draws the current positions on canvas
        ctx.clearRect(0, 0, width, height);
        for (var i=0;i<count;i++){
          ctx.fillStyle = planets[i].color;
          ctx.beginPath();
          ctx.arc(planets[i].phys.position.x,
            planets[i].phys.position.y,
            planets[i].stat.radius,
            0,2*Math.PI,false);
          ctx.fill();
          ctx.stroke();
          ctx.closePath();
        }
      }
            

WebSockets and Server-Sent Events

Goals:

  • Web communications beyond basic HTTP
Deco: poppy

WebSockets and Server-Sent Events

Back to the roots:

  • full duplex (TCP like connection instead of connectionless HTTP)
    • no need for polling
    • no HTTP headers required
    • connection oriented (state can be preserved)
  • simple API
  • Reducing amount of data transferred
  • Reducing latency
  • Needs a server that supports WebSockets
    • and requires a dedicated IP/Port address
  • Hacks are available

WebSockets and Server-Sent Events

WebSockets — is it still the Web?:

  • WebSockets Interface:
    • Variable readyState,
    • Constants: CONNECTING, OPEN, CLOSING, CLOSED
    • Events: onopen, onerror, onclose, onmessage
    • Methods: send (was postMessage), close
  • a WebSocket protocol (IETF draft). Implementations are available
    • opening handshake from HTTP
    • TCP based (foresees sub-protocols and extensions)
  • sockets programming (default via port 80(!) ...)
    • higher level protocols still to be implemented by developer

WebSockets and Server-Sent Events

Server-Sent Events — Websockets light:

  • connection is maintained
    • no need for polling
    • connection oriented (state can be preserved)
  • server sends mime type text/event-stream
  • simple API
  • reducing latency
  • no need for polling
  • Any HTTP server will do
  • Example:
  •               
        var evtSource = new EventSource("demo.php");
       
        evtSource.onmessage = function(e) {
          var le = document.createElement("li");
          le.innerHTML = "server sent: " + e.data;
          messages.appendChild(newElement);
        }
                  

More (to come) in HTML5

Deco: Autumn Trees

More (to come) in HTML5

  • There is the CORS standard to allow content from different origins safely (Jan 2014)
  • There is an API for Offline applications
  • An API to add pages to the browsing history
  • HTML Microdata and RDFa to specify semantics
  • HTML5 Web Messaging to exchange data cross origin
  • Web Indexed Database indexedDB (noSQL database
  • Offline pages
  • Access to sensors and devices (GPS (geolocation), camera, compass, motion, touch …)
  • WebRTC
  • ...

Thank you all ...
it was a long day!

Deco: Autumn Trees HTML5 car plate

Travel safe!

Thanks Xu Han for the image!

List of Demos and Examples

Deco: Oak

List of Demos and Examples