SlideShare uma empresa Scribd logo
1 de 65
Baixar para ler offline
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>

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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勉強会
 

Destaque

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
 

Destaque (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
 

Semelhante a 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
 

Semelhante a 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
 

Último

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...AliaaTarek5
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxLoriGlavin3
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfMounikaPolabathina
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Farhan Tariq
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersNicole Novielli
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Último (20)

Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
(How to Program) Paul Deitel, Harvey Deitel-Java How to Program, Early Object...
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptxThe Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
The Role of FIDO in a Cyber Secure Netherlands: FIDO Paris Seminar.pptx
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
What is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdfWhat is DBT - The Ultimate Data Build Tool.pdf
What is DBT - The Ultimate Data Build Tool.pdf
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...Genislab builds better products and faster go-to-market with Lean project man...
Genislab builds better products and faster go-to-market with Lean project man...
 
A Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software DevelopersA Journey Into the Emotions of Software Developers
A Journey Into the Emotions of Software Developers
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

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. ?