SlideShare une entreprise Scribd logo
1  sur  65
Télécharger pour lire hors ligne
The Joy of writing JavaScript Applications
How Qooxdoo puts the fun back into programming for the
                        web


                     Tobias Oetiker

                 OETIKER+PARTNER AG


22nd Large Installation System Administration Conference
The Browser: my application platform




      Applications in the Browser: Netscapes original Plan.
      Performance: SquirelFish, V8, Tracemonkey engines.
      JavaScript graduated with Web 2.0
      Widget libraries for breakfast, lunch and dinner.
      A separte hack for every browser.
Qooxdoo: application in the browser




      Web 2.0 is all about the look and feel.
      Web pages with eye candy.
      Applications running in the browser.
      Back to client/server computing.
      Qooxdoo is a complete environment.
Qooxdoo features



      Turns JS into a grown up OO language.
      No HTML or CSS knowledge required.
      Cross Browser: >= FF 1.5, Safari 3, Chrome, IE6, Opera8.
      Multilingual.
      Full API Documentation.
      Users works ’inside the box’.
      LGPL, EPL
      Fun.
Jump right in




      Install Python. http://www.python.org/download/
      Unpack Qooxdoo. http://qooxdoo.org/download/
      Get Js2-mode for emacs
      http://code.google.com/p/js2-mode/
      Do this NOW!
Jump right in




      Install Python. http://www.python.org/download/
      Unpack Qooxdoo. http://qooxdoo.org/download/
      Get Js2-mode for emacs
      http://code.google.com/p/js2-mode/
      Do this NOW!
Generating the first application


      Point your path to qooxdoo-0.8-sdk/tools/bin
      Change directory to your development space.
      Run create-application.py –name hello
      CD into the hello directory.
      Run generate.py source
      Point your browser to hello/source/index.html
Generating the first application


      Point your path to qooxdoo-0.8-sdk/tools/bin
      Change directory to your development space.
      Run create-application.py –name hello
      CD into the hello directory.
      Run generate.py source
      Point your browser to hello/source/index.html
generated files



   hello/generate.py
   hello/config.json
   hello/source/resource/hello/test.png
   hello/source/translation/readme.txt
   hello/source/class/hello/test/DemoTest.js
   hello/source/class/hello/Application.js
   hello/source/index.html
   hello/Manifest.json
   hello/readme.txt
source code: hello/source/class/hello/Application.js I
 1   /* Tell qooxdoo that we need the resources in hello /*
 2   # asset ( hello /*)
 3   */
 4   qx . Class . define ( quot; hello . Application quot; ,
 5   {
 6      extend : qx . application . Standalone ,
 7      members :
 8      {
 9         main : function ()
10         {
11           // Call super class
12           this . base ( arguments );
13           // Enable logging in debug variant
14           if ( qx . core . Variant . isSet ( quot; qx . debug quot; , quot; on quot; ))
15           { // native logging capabilities
16              qx . log . appender . Native ;
17              // additional cross - browser console .
18              // Press F7 to toggle visibility
19              qx . log . appender . Console ;
20           }
source code: hello/source/class/hello/Application.js II

21             // Create a button
22             var button1 = new qx . ui . form . Button (
23                                     quot; First Button quot; , quot; hello / test . png quot; );
24             // Document is the application root
25             var doc = this . getRoot ();
26             // Add button to document at fixed coordinates
27             doc . add ( button1 , { left : 100 , top : 50});
28             // Add an event listener
29             button1 . addListener ( quot; execute quot; , function ( e ) {
30               alert ( quot; Hello World ! quot; );
31             });
32         }
33     }
34   });

     The original Qooxdoo hello world application,
     modified to fit the slide.
Qooxdoo and JavaScript




      It’s just like Perl and OO
      It’s all about anonymous functions
      and closures . . . and scoping.
Qooxdoo and JavaScript




      It’s just like Perl and OO
      It’s all about anonymous functions
      and closures . . . and scoping.
Qooxdoo and JavaScript




      It’s just like Perl and OO
      It’s all about anonymous functions
      and closures . . . and scoping.
A function pointer example




1   var add_alert = function (a , b ){
2       alert ( ’ The Result is : ’ +( a + b ));
3   }
4   add_alert (1 ,2);
Scoping for the naïve

    You know scoping from other languages
1   var j = 100;
2   var z = 22;
3   for ( var z = 1; z <10; z ++){
4      var j = z ;
5   }
6   alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z );




                             Or so you thought
Scoping for the naïve

    You know scoping from other languages
1   var j = 100;
2   var z = 22;
3   for ( var z = 1; z <10; z ++){
4      var j = z ;
5   }
6   alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z );




                             Or so you thought
Scoping for the disillusioned

    JavaScript scoping works only within function blocks.
1   var j = 100;
2   var z = 22;
3   for ( var z = 1; z <10; z ++){( function (){
4      var j = z ;
5   })()}
6   alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z );




                Note that z is outside the function block!
Scoping for the disillusioned

    JavaScript scoping works only within function blocks.
1   var j = 100;
2   var z = 22;
3   for ( var z = 1; z <10; z ++){( function (){
4      var j = z ;
5   })()}
6   alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z );




                Note that z is outside the function block!
A simple closures example
 1   var set ;
 2   var get ;
 3   var j =2;
 4   ( function (){ // the magic javascript scope trick
 5       var j ;
 6       set = function ( x ){ j = x };
 7       get = function (){ alert ( ’ Hidden j is ’+ j )};
 8   })(); // end of scope
 9   set (33);
10   get ();
11   alert ( ’ Outside j is still ’+ j );




                       Everything as expected.
A simple closures example
 1   var set ;
 2   var get ;
 3   var j =2;
 4   ( function (){ // the magic javascript scope trick
 5       var j ;
 6       set = function ( x ){ j = x };
 7       get = function (){ alert ( ’ Hidden j is ’+ j )};
 8   })(); // end of scope
 9   set (33);
10   get ();
11   alert ( ’ Outside j is still ’+ j );




                       Everything as expected.
A simple closures example
 1   var set ;
 2   var get ;
 3   var j =2;
 4   ( function (){ // the magic javascript scope trick
 5       var j ;
 6       set = function ( x ){ j = x };
 7       get = function (){ alert ( ’ Hidden j is ’+ j )};
 8   })(); // end of scope
 9   set (33);
10   get ();
11   alert ( ’ Outside j is still ’+ j );




                       Everything as expected.
A broken function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){
3       var g = z ;
4       j [ g ] = function ( a ){
5              alert ( ’ The value for j [ ’ + a + ’] is ’+ g );
6       };
7   }
8   j [2](2);




            JavaScript! Has! No! Scope! For! Loop! Blocks!
A broken function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){
3       var g = z ;
4       j [ g ] = function ( a ){
5              alert ( ’ The value for j [ ’ + a + ’] is ’+ g );
6       };
7   }
8   j [2](2);




            JavaScript! Has! No! Scope! For! Loop! Blocks!
A broken function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){
3       var g = z ;
4       j [ g ] = function ( a ){
5              alert ( ’ The value for j [ ’ + a + ’] is ’+ g );
6       };
7   }
8   j [2](2);




            JavaScript! Has! No! Scope! For! Loop! Blocks!
A working function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){( function (){ // for a block
3       var g = z ;
4       j [ g ] = function ( a ){
5              alert ( ’ The value for j [ ’ + a + ’] is ’+ g );
6       };
7   })()} // end of block
8   j [2](2);




       Again the anonymous function trick comes to the rescue.
A working function factory

1   var j = [];
2   for ( var z = 1; z <10; z ++){( function (){ // for a block
3       var g = z ;
4       j [ g ] = function ( a ){
5              alert ( ’ The value for j [ ’ + a + ’] is ’+ g );
6       };
7   })()} // end of block
8   j [2](2);




       Again the anonymous function trick comes to the rescue.
fun with this

1   var hello = {
2             world : ’ You ’ ,
3             show : function (){
4       alert ( ’ Hello ’+ this . world + ’ this : ’+ this ); }
5   };
6   hello . show ();              // method call
7   var plain = hello . show ; // function pointer
8   var world = ’ Me ’;           // change this . world
9   plain ();                     // method call




    this refers to                   this refers to the browsers
    the hello object.                base Window object.
fun with this

1   var hello = {
2             world : ’ You ’ ,
3             show : function (){
4       alert ( ’ Hello ’+ this . world + ’ this : ’+ this ); }
5   };
6   hello . show ();              // method call
7   var plain = hello . show ; // function pointer
8   var world = ’ Me ’;           // change this . world
9   plain ();                     // method call




    this refers to                   this refers to the browsers
    the hello object.                base Window object.
Class definition



    In its most basic form, a Qooxdoo class is very simple.
1   qx . Class . define ( ’ my . first . Class ’ );

    In reality you would use something like this
1   qx . Class . define ( quot; my . cool . Class quot; , {
2      // declare constructor , members , ...
3   });

    A regular class can then be instantiated
1   var myClass = new my . cool . Class ;
Class inheritance



    The map contains the meat of the class.
1   qx . Class . define ( quot; my . cool . Class quot; ,
2   {
3      extend : my . great . SuperClass ,
4      construct : function () { ... } ,
5      destruct : function () { ... }
6   });

    Embrace and extend.
Static members


    Static member names are in the statics key.
    They use UPPERCASE names by convention.
1   qx . Class . define ( quot; my . cool . Class quot; , {
2      statics : {
3         FOO : VALUE ,
4         BAR : function () { ... }
5      }
6   });

    Static members are accessed with their full name:
1   my . cool . Class . FOO = 3.141;
2   my . cool . Class . BAR ();
Static members


    Static member names are in the statics key.
    They use UPPERCASE names by convention.
1   qx . Class . define ( quot; my . cool . Class quot; , {
2      statics : {
3         FOO : VALUE ,
4         BAR : function () { ... }
5      }
6   });

    Static members are accessed with their full name:
1   my . cool . Class . FOO = 3.141;
2   my . cool . Class . BAR ();
Instance Members


    Instance members reside in the members map.
1   qx . Class . define ( quot; my . cool . Class quot; , {
2      members : {
3         foo : VALUE ,
4         bar : function () { ... }
5      }
6   });

    Use new to create an instance.
1   var myClass1 = new my . cool . Class ;
2   myClass1 . foo = 3.141;
3   myClass1 . bar ();
Instance Members


    Instance members reside in the members map.
1   qx . Class . define ( quot; my . cool . Class quot; , {
2      members : {
3         foo : VALUE ,
4         bar : function () { ... }
5      }
6   });

    Use new to create an instance.
1   var myClass1 = new my . cool . Class ;
2   myClass1 . foo = 3.141;
3   myClass1 . bar ();
Calling the Superclass


 1   qx . Class . define ( quot; my . cool . Class quot; ,
 2   {
 3      extend : my . great . SuperClass ,
 4      construct : function ( x ) {
 5         this . base ( arguments , x ); // superclass constructor
 6      }
 7      members : {
 8         foo : function ( x ) {
 9           this . base ( arguments , x );
10         }
11      }
12   });

     The this.base construct works for both constructor and
     member functions.
Generic access to static members


 1   qx . Class . define ( quot; my . cool . Class quot; ,
 2   {
 3      extend : qx . core . Object ,
 4      construct : function ( x ){ this . base ( arguments , x )} ,
 5      statics : {
 6         PI : 3.141
 7      }
 8      members : {
 9         circumference : function ( radius ) {
10           return 2 * this . self ( arguments ). PI * radius ;
11         }
12      }
13   });

     this.self only works for subclasses of qx.core.Object
mixins


1   qx . Mixin . define ( ’ my . cool . MMixin ’ ,{
2         // code and variables like in a class
3   });

    Like classes, but without inheritance.
    By convention Mixin names start with ’M’.
1   qx . Class . define ( ’ my . cool . Class ’ , {
2      include : [ my . cool . MMixin , my . other . cool . MMixin ]
3      ...
4   });

    Include mixins when creating new classes.
1   qx . Class . include ( qx . ui . core . Widget , qx . MWidgetFeatures );

    Or even inject them into an existing class.
class access control




    There is the following naming convention for class members.
1   publicMember
2   _protectedMember
3   __privateMember

    In the Qooxdoo build process it is optionally possible to
    randomize the names of private members to protect access.
static, abstract and singleton classes

1   qx . Class . define ( ’ my . static . Class ’ , {
2      type : ’ static ’
3      statics : { ... };
4   });

    Neither members nor constructors are allowed in static classes.
1   qx . Class . define ( ’ my . abstract . Class ’ , {
2      type : ’ abstract ’
3   });

    Abstract classes must be sub-classed for use.
1   qx . Class . define ( ’ my . singleton . Class ’ , {
2      type : ’ singleton ’
3   });
4   var instance = my . singleton . Class . getIntance ()

    There is only one instance which gets created on the first call.
Browser specific code


     Normally Qooxdoo takes care of all browser differences, but if
     you must intervene . . .
 1   members : {
 2     foo : qx . core . Variant . select (
 3       ’ qx . bom . client . Engine . NAME ’ , {
 4          ’ mshtml | opera ’: function () {
 5              // Internet Explorer or Opera
 6          },
 7          ’ default ’: function () {
 8              // All other browsers
 9          }
10       }
11     )
12   }
The demo Browser




1   $ cd $QX / frontend / application / demobrowser /
2   $ ./ generate . py build
3   $ gnome - open build / index . html

    Or surf to http://demo.qooxdoo.org/current/demobrowser
The API Documentation




1   $ cd $QX / frontend / framework
2   $ ./ generate . py api
3   $ gnome - open api / index . html

    Or surf to http://demo.qooxdoo.org/current/apiviewer
The Qooxdoo generator


  Python is the sole dependency
      generator.py is the tool
      it gets called by generate.py
  The generator has many functions
      source - prep development code
      build - prep code for deployment
      api - build api doc
      lint - check your code for beauty
      pretty - fix the code layout
      ...
Running your Qooxdoo program in source




    Use source code during development
1   $ cd hello
2   $ ./ generate . py source
3   $ gnome - open source / index . html

    As long as you do not use any new classes, press reload in the
    browser to see changes.
Deploying your Qooxdoo program




1   $ cd hello
2   $ ./ generate . py build
3   $ cp - rp build ~/ public_html / hello

        only two js files
        code gets optimized and compressed
        no external dependencies
Button, TextField and some Action
 1   // Create a textfield
 2   var tf1 = new qx . ui . form . TextField ( ’ Demo Text ’ );
 3   // Add button to root
 4   root . add ( tf1 , { column : 0 , row : 0});
 5   // Create a button
 6   var bt1 = new qx . ui . form . Button (
 7           ’ Open Alert ’ , ’ lisa08 / test . png ’ );
 8   // Add button to root
 9   root . add ( bt1 , { column : 1 , row : 0});
10   // Add an event listener
11   bt1 . addListener ( ’ execute ’ , function ( e ) {
12     // closure !!
13     this . info ( ’ TextField : ’+ tf1 . getValue ());
14     alert ( ’ TextField : ’ + tf1 . getValue ());
15   });




     Try F7 to see inline console!
The Layout Manager



     Qooxdoo Widgets can contain other widgets.
     Layout manager positions child widgets.
     qx.ui.container.Composite basic
     qx.ui.container.Scroll draws scroll bars
     qx.ui.window.Window directs children to an inner
     composite pane.
     Layout manager set at construction time
     Modified with setLayout method.
Container and Layout
 1   // a container with horizontal layouyt manager
 2   var hbox = new qx . ui . layout . HBox ();
 3   hbox . setSpacing (4); // set property
 4
 5   // assign layout
 6   var ctr1 = new qx . ui . container . Composite ( hbox );
 7   ctr1 . setWidth (600); ctr1 . setHeight (40);
 8   // layout properties : position
 9   root . add ( ctr1 ,{ column : 0 , row : 1 , colSpan : 2});
10
11   var tf2 = new qx . ui . form . TextField ( ’ Some More Text ’ );
12   var bt2 = new qx . ui . form . ToggleButton ( ’ AllowGrowY ’ );
13   bt2 . addListener ( ’ changeChecked ’ , function ( e ) {
14         // modify widget property
15         tf2 . setAllowGrowY ( e . getData ());
16             this . info ( ’ New Value for AllowGrowY : ’+ e . getData ());
17   });
18   ctr1 . add ( tf2 ); ctr1 . add ( bt2 );
Grid Layout




      qx.ui.layout.Grid
      fully dynamic
      ideal for dialogs
      one widget per cell
      row and column spans
      minimal and maximal column and row sizes
      fixed row and column sizes
About the Qooxdoo Layout Widgets


      A container widget needs a layout manager to place its
      children.
      The layout manager object has properties.
      Every widget has basic properties like: alignment,
      growability, shrinkability, stretchability, margins, padding,
      width and height.
      Each widget can have layout-specific properties.
      Layout properties get checked as the widget is added to a
      layout.
  Lets play with the layout demos!
Localized Applications
 1   var lmgr = qx . locale . Manager . getInstance ();
 2   var bt3 = new qx . ui . form . ToggleButton (
 3         this . tr ( ’ Translate ! ’)
 4   );
 5   root . add ( bt3 , { column : 1 , row : 3});
 6   bt3 . addListener ( ’ changeChecked ’ , function ( e ) {
 7         var lang = e . getData () ? ’ de ’ : ’ en ’;
 8         lmgr . setLocale ( lang );
 9         this . info ( ’ Language set to : ’+ lang );
10   });

         add locale to config.json
         ./generate.py translation
         translate de.po
         ./generate.py source
calling code on the server




      JSON RPC for transport
      various language bindings
      often minimal server code
      async with callbacks
      qx.io.Rpc
An RPC Example: Client
 1   var rpc = new qx . io . remote . Rpc ( ’ jsonrpc . cgi ’ , ’ myclass ’ );
 2   var bt4 = new qx . ui . form . Button ( this . tr ( ’ Call RPC ’ ));
 3   root . add ( bt4 , { column : 1 , row : 4});
 4   var that = this ; // we want this ’ this ’!
 5   var callback = function ( result , ex , id ) {
 6         that . RpcRunning = null ; // free the reference
 7         if ( ex == null ) {
 8              alert ( ’ The RPC call returned : ’+ result );
 9              that . info ( ’ RPC call returned : ’+ result );
10         } else {
11              alert ( ’ Async ( ’ + id + ’) exception : ’ + ex );
12              that . error ( ’ Async ( ’ + id + ’) exception : ’ + ex );
13         }
14   };
15   bt4 . addListener ( ’ execute ’ , function ( e ) {
16         that . RpcRunning = rpc . callAsync (
17              callback , ’ mymethod ’ , ’ Hello ’ );
18   });

     The example only works on a cgi enabled webserver.
An RPC Example: Server CGI
     source/jsonrpc.cgi:
 1   # !/ usr / bin / perl -w
 2   use strict ;
 3   use lib qw ( perl );
 4
 5   use CGI ;
 6   # use CGI :: Fast ;
 7   use CGI :: Session ;
 8   use Qooxdoo :: JSONRPC ;
 9
10   # $Qooxdoo :: JSONRPC :: debug =1;
11   my $cgi = new CGI ;
12   # while ( my $cgi = new CGI :: Fast ){
13       my $session = new CGI :: Session ;
14       Qooxdoo :: JSONRPC :: handle_request ( $cgi , $session );
15   # }

     For best performance use CGI::Fast and configure
     CGI::Session to keep the session data in a database.
An RPC Example: the myclass service

     source/perl/Qooxdoo/Services/myclass.pm:
 1   package Qooxdoo :: Services :: myclass ;
 2   use strict ;
 3
 4   # for now let everyone access the methods
 5   sub GetAccessibility { ’ public ’ };
 6
 7   sub method_mymethod {
 8       my $error = shift ;
 9       my $arg = shift ;
10       return ’ The argument was : ’. $arg ;
11   }
12
13   1;

     The myclass module gets loaded dynamically.
An RPC Example: Getting it to work



      Install language bindings from Qooxdoo website.
      ln -s /var/www/lisa08 build
      ./generate.py build
      cp -rp source/jsonrpc.cgi source/perl build
      Open the application in the browser.
      Make sure the cgis are actually executed
      Watch the Apache error log while testing.
Organizing the code into multiple classes



      Object orientation “by the book”.
      One file per class.
      Java’s file name based approach.
      Supported by the generator.
      Ideal for code re-use.
      Use Inline Docs!
      ./generate.py api
The textclick class I
 1   /* *
 2     * textclick combines a textfield and a button .
 3     */
 4   qx . Class . define ( quot; lisa08 . ui . textclick quot; ,
 5   {
 6      extend : qx . ui . container . Composite ,
 7      /* *
 8        * @param button_text { String } button text .
 9        */
10      construct : function ( button_text ) {
11         this . base ( arguments ,
12              new qx . ui . layout . HBox (). set ({ spacing : 4})
13         );
14         this . __tf = new qx . ui . form . TextField ();
15         this . __bt = new qx . ui . form . Button ( button_text );
16         this . add ( this . __tf );
17         this . add ( this . __bt );
18      },
19
20
The textclick class II


21     members :
22     {
23     /* *
24       * Get a handle to the Button widget .
25       */
26        getButton : function () { return this . __bt } ,
27     /* *
28       * Get a handle to the TextField widget .
29       */
30        getTextField : function () { return this . __tf } ,
31        __bt : null ,
32        __tf : null
33     }
34   });
Using the textclick class



1   var mywi = new lisa08 . ui . textclick (
2               this . tr ( ’ Copy Text from Example 1 ’ ));
3
4   mywi . getButton (). addListener ( ’ execute ’ , function ( e ) {
5        mywi . getTextField (). setValue ( tf1 . getValue ());
6        this . info ( ’ Set textfield to ’+ tf1 . getValue ());
7   });
8
9   root . add ( mywi ,{ column : 0 , row : 5 , colSpan : 2});
The Message Bus

         Communication in “large” applications.
         Singleton message bus class.
         Careful with references: memory leaks!

 1   var mywi2 = new lisa08 . ui . textclick (
 2                            this . tr ( ’ Send Hello to Textfield ’ ));
 3   var bus = qx . event . message . Bus . getInstance ();
 4   mywi2 . getButton (). addListener ( ’ execute ’ , function ( e ) {
 5         bus . dispatch ( ’ mybus .1 ’ , ’ Hello World ’ );
 6         this . info ( ’ Sent Hello World on this bus ’ );
 7   } , this ); // context provided for console
 8   bus . subscribe ( ’ mybus .1 ’ , function ( m ){
 9         mywi2 . getTextField (). setValue ( m . getData ());
10         this . info ( ’ Got ’+ m . getData ()+ ’ from the bus ’ );
11   } , this );
12
13   root . add ( mywi2 ,{ column : 0 , row : 6 , colSpan : 2});
Code walk through of the SmokeTrace application.
?
Tobi Oetiker <tobi@oetiker.ch>

Contenu connexe

Tendances

Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Wilson Su
 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcescorehard_by
 
Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8Wilson Su
 
Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in RustIngvar Stepanyan
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Wilson Su
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516SOAT
 
The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185Mahmoud Samir Fayed
 
Javascript basics
Javascript basicsJavascript basics
Javascript basicsFin Chen
 
Project fast food automaton
Project fast food automatonProject fast food automaton
Project fast food automatonvarun arora
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」matuura_core
 
The Ring programming language version 1.5.1 book - Part 9 of 180
The Ring programming language version 1.5.1 book - Part 9 of 180The Ring programming language version 1.5.1 book - Part 9 of 180
The Ring programming language version 1.5.1 book - Part 9 of 180Mahmoud Samir Fayed
 
Wwe Management System
Wwe Management SystemWwe Management System
Wwe Management SystemNeerajMudgal1
 
20110424 action scriptを使わないflash勉強会
20110424 action scriptを使わないflash勉強会20110424 action scriptを使わないflash勉強会
20110424 action scriptを使わないflash勉強会Hiroki Mizuno
 

Tendances (18)

TDD per Webapps
TDD per WebappsTDD per Webapps
TDD per Webapps
 
Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8Practical JavaScript Programming - Session 6/8
Practical JavaScript Programming - Session 6/8
 
Server1
Server1Server1
Server1
 
Oxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resourcesOxygine 2 d objects,events,debug and resources
Oxygine 2 d objects,events,debug and resources
 
Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8Practical JavaScript Programming - Session 5/8
Practical JavaScript Programming - Session 5/8
 
Sbaw091006
Sbaw091006Sbaw091006
Sbaw091006
 
Building fast interpreters in Rust
Building fast interpreters in RustBuilding fast interpreters in Rust
Building fast interpreters in Rust
 
Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8Practical JavaScript Programming - Session 1/8
Practical JavaScript Programming - Session 1/8
 
Rust ⇋ JavaScript
Rust ⇋ JavaScriptRust ⇋ JavaScript
Rust ⇋ JavaScript
 
Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516Tests unitaires mock_kesako_20130516
Tests unitaires mock_kesako_20130516
 
The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185The Ring programming language version 1.5.4 book - Part 69 of 185
The Ring programming language version 1.5.4 book - Part 69 of 185
 
Nantes Jug - Java 7
Nantes Jug - Java 7Nantes Jug - Java 7
Nantes Jug - Java 7
 
Javascript basics
Javascript basicsJavascript basics
Javascript basics
 
Project fast food automaton
Project fast food automatonProject fast food automaton
Project fast food automaton
 
連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」連邦の白いヤツ 「Objective-C」
連邦の白いヤツ 「Objective-C」
 
The Ring programming language version 1.5.1 book - Part 9 of 180
The Ring programming language version 1.5.1 book - Part 9 of 180The Ring programming language version 1.5.1 book - Part 9 of 180
The Ring programming language version 1.5.1 book - Part 9 of 180
 
Wwe Management System
Wwe Management SystemWwe Management System
Wwe Management System
 
20110424 action scriptを使わないflash勉強会
20110424 action scriptを使わないflash勉強会20110424 action scriptを使わないflash勉強会
20110424 action scriptを使わないflash勉強会
 

En vedette

Heden, verleden en toekomst van video conferencing
Heden, verleden en toekomst van video conferencingHeden, verleden en toekomst van video conferencing
Heden, verleden en toekomst van video conferencingrobert blaas
 
Penelitian Pasar Pameran
Penelitian Pasar PameranPenelitian Pasar Pameran
Penelitian Pasar PameranNoersal Samad
 
Persiapan Sebelum Mengunjungi Objek Wisata Alam
Persiapan Sebelum Mengunjungi Objek Wisata AlamPersiapan Sebelum Mengunjungi Objek Wisata Alam
Persiapan Sebelum Mengunjungi Objek Wisata AlamNoersal Samad
 
The role of TANDBERG videoconferencing in the new way of working
The role of TANDBERG videoconferencing in the new way of workingThe role of TANDBERG videoconferencing in the new way of working
The role of TANDBERG videoconferencing in the new way of workingrobert blaas
 
LISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial HandoutsLISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial HandoutsTobias Oetiker
 

En vedette (6)

Heden, verleden en toekomst van video conferencing
Heden, verleden en toekomst van video conferencingHeden, verleden en toekomst van video conferencing
Heden, verleden en toekomst van video conferencing
 
Penelitian Pasar Pameran
Penelitian Pasar PameranPenelitian Pasar Pameran
Penelitian Pasar Pameran
 
Persiapan Sebelum Mengunjungi Objek Wisata Alam
Persiapan Sebelum Mengunjungi Objek Wisata AlamPersiapan Sebelum Mengunjungi Objek Wisata Alam
Persiapan Sebelum Mengunjungi Objek Wisata Alam
 
The role of TANDBERG videoconferencing in the new way of working
The role of TANDBERG videoconferencing in the new way of workingThe role of TANDBERG videoconferencing in the new way of working
The role of TANDBERG videoconferencing in the new way of working
 
Web 2.0
Web 2.0Web 2.0
Web 2.0
 
LISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial HandoutsLISA Qooxdoo Tutorial Handouts
LISA Qooxdoo Tutorial Handouts
 

Similaire à LISA QooxdooTutorial Slides

Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesGanesh Samarthyam
 
The mighty js_function
The mighty js_functionThe mighty js_function
The mighty js_functiontimotheeg
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015Michiel Borkent
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016Manoj Kumar
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Guillaume Laforge
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5arajivmordani
 
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume LaforgeGR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume LaforgeGR8Conf
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst TipsJay Shirley
 
What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?Christophe Porteneuve
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineMovel
 

Similaire à LISA QooxdooTutorial Slides (20)

dojo.Patterns
dojo.Patternsdojo.Patterns
dojo.Patterns
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Advanced Debugging Using Java Bytecodes
Advanced Debugging Using Java BytecodesAdvanced Debugging Using Java Bytecodes
Advanced Debugging Using Java Bytecodes
 
Es6 hackathon
Es6 hackathonEs6 hackathon
Es6 hackathon
 
The mighty js_function
The mighty js_functionThe mighty js_function
The mighty js_function
 
ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015ClojureScript loves React, DomCode May 26 2015
ClojureScript loves React, DomCode May 26 2015
 
ES6 PPT FOR 2016
ES6 PPT FOR 2016ES6 PPT FOR 2016
ES6 PPT FOR 2016
 
The Beauty of Java Script
The Beauty of Java ScriptThe Beauty of Java Script
The Beauty of Java Script
 
Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008Groovy Introduction - JAX Germany - 2008
Groovy Introduction - JAX Germany - 2008
 
Groovy
GroovyGroovy
Groovy
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
The Beauty Of Java Script V5a
The Beauty Of Java Script V5aThe Beauty Of Java Script V5a
The Beauty Of Java Script V5a
 
Java script for web developer
Java script for web developerJava script for web developer
Java script for web developer
 
Php 7 evolution
Php 7 evolutionPhp 7 evolution
Php 7 evolution
 
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume LaforgeGR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
10 Catalyst Tips
10 Catalyst Tips10 Catalyst Tips
10 Catalyst Tips
 
Trimming The Cruft
Trimming The CruftTrimming The Cruft
Trimming The Cruft
 
What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?What's up with Prototype and script.aculo.us?
What's up with Prototype and script.aculo.us?
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy Cresine
 

Dernier

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embeddingZilliz
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 

Dernier (20)

Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Training state-of-the-art general text embedding
Training state-of-the-art general text embeddingTraining state-of-the-art general text embedding
Training state-of-the-art general text embedding
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptxE-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
E-Vehicle_Hacking_by_Parul Sharma_null_owasp.pptx
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 

LISA QooxdooTutorial Slides

  • 1. The Joy of writing JavaScript Applications How Qooxdoo puts the fun back into programming for the web Tobias Oetiker OETIKER+PARTNER AG 22nd Large Installation System Administration Conference
  • 2. The Browser: my application platform Applications in the Browser: Netscapes original Plan. Performance: SquirelFish, V8, Tracemonkey engines. JavaScript graduated with Web 2.0 Widget libraries for breakfast, lunch and dinner. A separte hack for every browser.
  • 3. Qooxdoo: application in the browser Web 2.0 is all about the look and feel. Web pages with eye candy. Applications running in the browser. Back to client/server computing. Qooxdoo is a complete environment.
  • 4. Qooxdoo features Turns JS into a grown up OO language. No HTML or CSS knowledge required. Cross Browser: >= FF 1.5, Safari 3, Chrome, IE6, Opera8. Multilingual. Full API Documentation. Users works ’inside the box’. LGPL, EPL Fun.
  • 5. Jump right in Install Python. http://www.python.org/download/ Unpack Qooxdoo. http://qooxdoo.org/download/ Get Js2-mode for emacs http://code.google.com/p/js2-mode/ Do this NOW!
  • 6. Jump right in Install Python. http://www.python.org/download/ Unpack Qooxdoo. http://qooxdoo.org/download/ Get Js2-mode for emacs http://code.google.com/p/js2-mode/ Do this NOW!
  • 7. Generating the first application Point your path to qooxdoo-0.8-sdk/tools/bin Change directory to your development space. Run create-application.py –name hello CD into the hello directory. Run generate.py source Point your browser to hello/source/index.html
  • 8. Generating the first application Point your path to qooxdoo-0.8-sdk/tools/bin Change directory to your development space. Run create-application.py –name hello CD into the hello directory. Run generate.py source Point your browser to hello/source/index.html
  • 9. generated files hello/generate.py hello/config.json hello/source/resource/hello/test.png hello/source/translation/readme.txt hello/source/class/hello/test/DemoTest.js hello/source/class/hello/Application.js hello/source/index.html hello/Manifest.json hello/readme.txt
  • 10. source code: hello/source/class/hello/Application.js I 1 /* Tell qooxdoo that we need the resources in hello /* 2 # asset ( hello /*) 3 */ 4 qx . Class . define ( quot; hello . Application quot; , 5 { 6 extend : qx . application . Standalone , 7 members : 8 { 9 main : function () 10 { 11 // Call super class 12 this . base ( arguments ); 13 // Enable logging in debug variant 14 if ( qx . core . Variant . isSet ( quot; qx . debug quot; , quot; on quot; )) 15 { // native logging capabilities 16 qx . log . appender . Native ; 17 // additional cross - browser console . 18 // Press F7 to toggle visibility 19 qx . log . appender . Console ; 20 }
  • 11. source code: hello/source/class/hello/Application.js II 21 // Create a button 22 var button1 = new qx . ui . form . Button ( 23 quot; First Button quot; , quot; hello / test . png quot; ); 24 // Document is the application root 25 var doc = this . getRoot (); 26 // Add button to document at fixed coordinates 27 doc . add ( button1 , { left : 100 , top : 50}); 28 // Add an event listener 29 button1 . addListener ( quot; execute quot; , function ( e ) { 30 alert ( quot; Hello World ! quot; ); 31 }); 32 } 33 } 34 }); The original Qooxdoo hello world application, modified to fit the slide.
  • 12. Qooxdoo and JavaScript It’s just like Perl and OO It’s all about anonymous functions and closures . . . and scoping.
  • 13. Qooxdoo and JavaScript It’s just like Perl and OO It’s all about anonymous functions and closures . . . and scoping.
  • 14. Qooxdoo and JavaScript It’s just like Perl and OO It’s all about anonymous functions and closures . . . and scoping.
  • 15. A function pointer example 1 var add_alert = function (a , b ){ 2 alert ( ’ The Result is : ’ +( a + b )); 3 } 4 add_alert (1 ,2);
  • 16. Scoping for the naïve You know scoping from other languages 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){ 4 var j = z ; 5 } 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Or so you thought
  • 17. Scoping for the naïve You know scoping from other languages 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){ 4 var j = z ; 5 } 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Or so you thought
  • 18. Scoping for the disillusioned JavaScript scoping works only within function blocks. 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){( function (){ 4 var j = z ; 5 })()} 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Note that z is outside the function block!
  • 19. Scoping for the disillusioned JavaScript scoping works only within function blocks. 1 var j = 100; 2 var z = 22; 3 for ( var z = 1; z <10; z ++){( function (){ 4 var j = z ; 5 })()} 6 alert ( ’ And the Winner is j : ’+ j + ’ z : ’+ z ); Note that z is outside the function block!
  • 20. A simple closures example 1 var set ; 2 var get ; 3 var j =2; 4 ( function (){ // the magic javascript scope trick 5 var j ; 6 set = function ( x ){ j = x }; 7 get = function (){ alert ( ’ Hidden j is ’+ j )}; 8 })(); // end of scope 9 set (33); 10 get (); 11 alert ( ’ Outside j is still ’+ j ); Everything as expected.
  • 21. A simple closures example 1 var set ; 2 var get ; 3 var j =2; 4 ( function (){ // the magic javascript scope trick 5 var j ; 6 set = function ( x ){ j = x }; 7 get = function (){ alert ( ’ Hidden j is ’+ j )}; 8 })(); // end of scope 9 set (33); 10 get (); 11 alert ( ’ Outside j is still ’+ j ); Everything as expected.
  • 22. A simple closures example 1 var set ; 2 var get ; 3 var j =2; 4 ( function (){ // the magic javascript scope trick 5 var j ; 6 set = function ( x ){ j = x }; 7 get = function (){ alert ( ’ Hidden j is ’+ j )}; 8 })(); // end of scope 9 set (33); 10 get (); 11 alert ( ’ Outside j is still ’+ j ); Everything as expected.
  • 23. A broken function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){ 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 } 8 j [2](2); JavaScript! Has! No! Scope! For! Loop! Blocks!
  • 24. A broken function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){ 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 } 8 j [2](2); JavaScript! Has! No! Scope! For! Loop! Blocks!
  • 25. A broken function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){ 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 } 8 j [2](2); JavaScript! Has! No! Scope! For! Loop! Blocks!
  • 26. A working function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){( function (){ // for a block 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 })()} // end of block 8 j [2](2); Again the anonymous function trick comes to the rescue.
  • 27. A working function factory 1 var j = []; 2 for ( var z = 1; z <10; z ++){( function (){ // for a block 3 var g = z ; 4 j [ g ] = function ( a ){ 5 alert ( ’ The value for j [ ’ + a + ’] is ’+ g ); 6 }; 7 })()} // end of block 8 j [2](2); Again the anonymous function trick comes to the rescue.
  • 28. fun with this 1 var hello = { 2 world : ’ You ’ , 3 show : function (){ 4 alert ( ’ Hello ’+ this . world + ’ this : ’+ this ); } 5 }; 6 hello . show (); // method call 7 var plain = hello . show ; // function pointer 8 var world = ’ Me ’; // change this . world 9 plain (); // method call this refers to this refers to the browsers the hello object. base Window object.
  • 29. fun with this 1 var hello = { 2 world : ’ You ’ , 3 show : function (){ 4 alert ( ’ Hello ’+ this . world + ’ this : ’+ this ); } 5 }; 6 hello . show (); // method call 7 var plain = hello . show ; // function pointer 8 var world = ’ Me ’; // change this . world 9 plain (); // method call this refers to this refers to the browsers the hello object. base Window object.
  • 30. Class definition In its most basic form, a Qooxdoo class is very simple. 1 qx . Class . define ( ’ my . first . Class ’ ); In reality you would use something like this 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 // declare constructor , members , ... 3 }); A regular class can then be instantiated 1 var myClass = new my . cool . Class ;
  • 31. Class inheritance The map contains the meat of the class. 1 qx . Class . define ( quot; my . cool . Class quot; , 2 { 3 extend : my . great . SuperClass , 4 construct : function () { ... } , 5 destruct : function () { ... } 6 }); Embrace and extend.
  • 32. Static members Static member names are in the statics key. They use UPPERCASE names by convention. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 statics : { 3 FOO : VALUE , 4 BAR : function () { ... } 5 } 6 }); Static members are accessed with their full name: 1 my . cool . Class . FOO = 3.141; 2 my . cool . Class . BAR ();
  • 33. Static members Static member names are in the statics key. They use UPPERCASE names by convention. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 statics : { 3 FOO : VALUE , 4 BAR : function () { ... } 5 } 6 }); Static members are accessed with their full name: 1 my . cool . Class . FOO = 3.141; 2 my . cool . Class . BAR ();
  • 34. Instance Members Instance members reside in the members map. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 members : { 3 foo : VALUE , 4 bar : function () { ... } 5 } 6 }); Use new to create an instance. 1 var myClass1 = new my . cool . Class ; 2 myClass1 . foo = 3.141; 3 myClass1 . bar ();
  • 35. Instance Members Instance members reside in the members map. 1 qx . Class . define ( quot; my . cool . Class quot; , { 2 members : { 3 foo : VALUE , 4 bar : function () { ... } 5 } 6 }); Use new to create an instance. 1 var myClass1 = new my . cool . Class ; 2 myClass1 . foo = 3.141; 3 myClass1 . bar ();
  • 36. Calling the Superclass 1 qx . Class . define ( quot; my . cool . Class quot; , 2 { 3 extend : my . great . SuperClass , 4 construct : function ( x ) { 5 this . base ( arguments , x ); // superclass constructor 6 } 7 members : { 8 foo : function ( x ) { 9 this . base ( arguments , x ); 10 } 11 } 12 }); The this.base construct works for both constructor and member functions.
  • 37. Generic access to static members 1 qx . Class . define ( quot; my . cool . Class quot; , 2 { 3 extend : qx . core . Object , 4 construct : function ( x ){ this . base ( arguments , x )} , 5 statics : { 6 PI : 3.141 7 } 8 members : { 9 circumference : function ( radius ) { 10 return 2 * this . self ( arguments ). PI * radius ; 11 } 12 } 13 }); this.self only works for subclasses of qx.core.Object
  • 38. mixins 1 qx . Mixin . define ( ’ my . cool . MMixin ’ ,{ 2 // code and variables like in a class 3 }); Like classes, but without inheritance. By convention Mixin names start with ’M’. 1 qx . Class . define ( ’ my . cool . Class ’ , { 2 include : [ my . cool . MMixin , my . other . cool . MMixin ] 3 ... 4 }); Include mixins when creating new classes. 1 qx . Class . include ( qx . ui . core . Widget , qx . MWidgetFeatures ); Or even inject them into an existing class.
  • 39. class access control There is the following naming convention for class members. 1 publicMember 2 _protectedMember 3 __privateMember In the Qooxdoo build process it is optionally possible to randomize the names of private members to protect access.
  • 40. static, abstract and singleton classes 1 qx . Class . define ( ’ my . static . Class ’ , { 2 type : ’ static ’ 3 statics : { ... }; 4 }); Neither members nor constructors are allowed in static classes. 1 qx . Class . define ( ’ my . abstract . Class ’ , { 2 type : ’ abstract ’ 3 }); Abstract classes must be sub-classed for use. 1 qx . Class . define ( ’ my . singleton . Class ’ , { 2 type : ’ singleton ’ 3 }); 4 var instance = my . singleton . Class . getIntance () There is only one instance which gets created on the first call.
  • 41. Browser specific code Normally Qooxdoo takes care of all browser differences, but if you must intervene . . . 1 members : { 2 foo : qx . core . Variant . select ( 3 ’ qx . bom . client . Engine . NAME ’ , { 4 ’ mshtml | opera ’: function () { 5 // Internet Explorer or Opera 6 }, 7 ’ default ’: function () { 8 // All other browsers 9 } 10 } 11 ) 12 }
  • 42. The demo Browser 1 $ cd $QX / frontend / application / demobrowser / 2 $ ./ generate . py build 3 $ gnome - open build / index . html Or surf to http://demo.qooxdoo.org/current/demobrowser
  • 43. The API Documentation 1 $ cd $QX / frontend / framework 2 $ ./ generate . py api 3 $ gnome - open api / index . html Or surf to http://demo.qooxdoo.org/current/apiviewer
  • 44. The Qooxdoo generator Python is the sole dependency generator.py is the tool it gets called by generate.py The generator has many functions source - prep development code build - prep code for deployment api - build api doc lint - check your code for beauty pretty - fix the code layout ...
  • 45. Running your Qooxdoo program in source Use source code during development 1 $ cd hello 2 $ ./ generate . py source 3 $ gnome - open source / index . html As long as you do not use any new classes, press reload in the browser to see changes.
  • 46. Deploying your Qooxdoo program 1 $ cd hello 2 $ ./ generate . py build 3 $ cp - rp build ~/ public_html / hello only two js files code gets optimized and compressed no external dependencies
  • 47. Button, TextField and some Action 1 // Create a textfield 2 var tf1 = new qx . ui . form . TextField ( ’ Demo Text ’ ); 3 // Add button to root 4 root . add ( tf1 , { column : 0 , row : 0}); 5 // Create a button 6 var bt1 = new qx . ui . form . Button ( 7 ’ Open Alert ’ , ’ lisa08 / test . png ’ ); 8 // Add button to root 9 root . add ( bt1 , { column : 1 , row : 0}); 10 // Add an event listener 11 bt1 . addListener ( ’ execute ’ , function ( e ) { 12 // closure !! 13 this . info ( ’ TextField : ’+ tf1 . getValue ()); 14 alert ( ’ TextField : ’ + tf1 . getValue ()); 15 }); Try F7 to see inline console!
  • 48. The Layout Manager Qooxdoo Widgets can contain other widgets. Layout manager positions child widgets. qx.ui.container.Composite basic qx.ui.container.Scroll draws scroll bars qx.ui.window.Window directs children to an inner composite pane. Layout manager set at construction time Modified with setLayout method.
  • 49. Container and Layout 1 // a container with horizontal layouyt manager 2 var hbox = new qx . ui . layout . HBox (); 3 hbox . setSpacing (4); // set property 4 5 // assign layout 6 var ctr1 = new qx . ui . container . Composite ( hbox ); 7 ctr1 . setWidth (600); ctr1 . setHeight (40); 8 // layout properties : position 9 root . add ( ctr1 ,{ column : 0 , row : 1 , colSpan : 2}); 10 11 var tf2 = new qx . ui . form . TextField ( ’ Some More Text ’ ); 12 var bt2 = new qx . ui . form . ToggleButton ( ’ AllowGrowY ’ ); 13 bt2 . addListener ( ’ changeChecked ’ , function ( e ) { 14 // modify widget property 15 tf2 . setAllowGrowY ( e . getData ()); 16 this . info ( ’ New Value for AllowGrowY : ’+ e . getData ()); 17 }); 18 ctr1 . add ( tf2 ); ctr1 . add ( bt2 );
  • 50. Grid Layout qx.ui.layout.Grid fully dynamic ideal for dialogs one widget per cell row and column spans minimal and maximal column and row sizes fixed row and column sizes
  • 51. About the Qooxdoo Layout Widgets A container widget needs a layout manager to place its children. The layout manager object has properties. Every widget has basic properties like: alignment, growability, shrinkability, stretchability, margins, padding, width and height. Each widget can have layout-specific properties. Layout properties get checked as the widget is added to a layout. Lets play with the layout demos!
  • 52. Localized Applications 1 var lmgr = qx . locale . Manager . getInstance (); 2 var bt3 = new qx . ui . form . ToggleButton ( 3 this . tr ( ’ Translate ! ’) 4 ); 5 root . add ( bt3 , { column : 1 , row : 3}); 6 bt3 . addListener ( ’ changeChecked ’ , function ( e ) { 7 var lang = e . getData () ? ’ de ’ : ’ en ’; 8 lmgr . setLocale ( lang ); 9 this . info ( ’ Language set to : ’+ lang ); 10 }); add locale to config.json ./generate.py translation translate de.po ./generate.py source
  • 53. calling code on the server JSON RPC for transport various language bindings often minimal server code async with callbacks qx.io.Rpc
  • 54. An RPC Example: Client 1 var rpc = new qx . io . remote . Rpc ( ’ jsonrpc . cgi ’ , ’ myclass ’ ); 2 var bt4 = new qx . ui . form . Button ( this . tr ( ’ Call RPC ’ )); 3 root . add ( bt4 , { column : 1 , row : 4}); 4 var that = this ; // we want this ’ this ’! 5 var callback = function ( result , ex , id ) { 6 that . RpcRunning = null ; // free the reference 7 if ( ex == null ) { 8 alert ( ’ The RPC call returned : ’+ result ); 9 that . info ( ’ RPC call returned : ’+ result ); 10 } else { 11 alert ( ’ Async ( ’ + id + ’) exception : ’ + ex ); 12 that . error ( ’ Async ( ’ + id + ’) exception : ’ + ex ); 13 } 14 }; 15 bt4 . addListener ( ’ execute ’ , function ( e ) { 16 that . RpcRunning = rpc . callAsync ( 17 callback , ’ mymethod ’ , ’ Hello ’ ); 18 }); The example only works on a cgi enabled webserver.
  • 55. An RPC Example: Server CGI source/jsonrpc.cgi: 1 # !/ usr / bin / perl -w 2 use strict ; 3 use lib qw ( perl ); 4 5 use CGI ; 6 # use CGI :: Fast ; 7 use CGI :: Session ; 8 use Qooxdoo :: JSONRPC ; 9 10 # $Qooxdoo :: JSONRPC :: debug =1; 11 my $cgi = new CGI ; 12 # while ( my $cgi = new CGI :: Fast ){ 13 my $session = new CGI :: Session ; 14 Qooxdoo :: JSONRPC :: handle_request ( $cgi , $session ); 15 # } For best performance use CGI::Fast and configure CGI::Session to keep the session data in a database.
  • 56. An RPC Example: the myclass service source/perl/Qooxdoo/Services/myclass.pm: 1 package Qooxdoo :: Services :: myclass ; 2 use strict ; 3 4 # for now let everyone access the methods 5 sub GetAccessibility { ’ public ’ }; 6 7 sub method_mymethod { 8 my $error = shift ; 9 my $arg = shift ; 10 return ’ The argument was : ’. $arg ; 11 } 12 13 1; The myclass module gets loaded dynamically.
  • 57. An RPC Example: Getting it to work Install language bindings from Qooxdoo website. ln -s /var/www/lisa08 build ./generate.py build cp -rp source/jsonrpc.cgi source/perl build Open the application in the browser. Make sure the cgis are actually executed Watch the Apache error log while testing.
  • 58. Organizing the code into multiple classes Object orientation “by the book”. One file per class. Java’s file name based approach. Supported by the generator. Ideal for code re-use. Use Inline Docs! ./generate.py api
  • 59. The textclick class I 1 /* * 2 * textclick combines a textfield and a button . 3 */ 4 qx . Class . define ( quot; lisa08 . ui . textclick quot; , 5 { 6 extend : qx . ui . container . Composite , 7 /* * 8 * @param button_text { String } button text . 9 */ 10 construct : function ( button_text ) { 11 this . base ( arguments , 12 new qx . ui . layout . HBox (). set ({ spacing : 4}) 13 ); 14 this . __tf = new qx . ui . form . TextField (); 15 this . __bt = new qx . ui . form . Button ( button_text ); 16 this . add ( this . __tf ); 17 this . add ( this . __bt ); 18 }, 19 20
  • 60. The textclick class II 21 members : 22 { 23 /* * 24 * Get a handle to the Button widget . 25 */ 26 getButton : function () { return this . __bt } , 27 /* * 28 * Get a handle to the TextField widget . 29 */ 30 getTextField : function () { return this . __tf } , 31 __bt : null , 32 __tf : null 33 } 34 });
  • 61. Using the textclick class 1 var mywi = new lisa08 . ui . textclick ( 2 this . tr ( ’ Copy Text from Example 1 ’ )); 3 4 mywi . getButton (). addListener ( ’ execute ’ , function ( e ) { 5 mywi . getTextField (). setValue ( tf1 . getValue ()); 6 this . info ( ’ Set textfield to ’+ tf1 . getValue ()); 7 }); 8 9 root . add ( mywi ,{ column : 0 , row : 5 , colSpan : 2});
  • 62. The Message Bus Communication in “large” applications. Singleton message bus class. Careful with references: memory leaks! 1 var mywi2 = new lisa08 . ui . textclick ( 2 this . tr ( ’ Send Hello to Textfield ’ )); 3 var bus = qx . event . message . Bus . getInstance (); 4 mywi2 . getButton (). addListener ( ’ execute ’ , function ( e ) { 5 bus . dispatch ( ’ mybus .1 ’ , ’ Hello World ’ ); 6 this . info ( ’ Sent Hello World on this bus ’ ); 7 } , this ); // context provided for console 8 bus . subscribe ( ’ mybus .1 ’ , function ( m ){ 9 mywi2 . getTextField (). setValue ( m . getData ()); 10 this . info ( ’ Got ’+ m . getData ()+ ’ from the bus ’ ); 11 } , this ); 12 13 root . add ( mywi2 ,{ column : 0 , row : 6 , colSpan : 2});
  • 63. Code walk through of the SmokeTrace application.
  • 64. ?