Upgrade to Pro — share decks privately, control downloads, hide ads and more …

QooXDoo

 QooXDoo

Presentation about QooXDoo javascript framework.

3a453374a79becf33b3a6659389a56c4?s=128

Radek Benkel

December 18, 2011
Tweet

More Decks by Radek Benkel

Other Decks in Technology

Transcript

  1. http://qooxdoo.org 1

  2. EXAMPLES 2

  3. EXAMPLES 3

  4. EXAMPLES 4

  5. 5

  6. IT'S NOT A TOY 6

  7. IT'S NOT A TOY let's count files: Penny:downloads singles$ wget

    http://downloads..../qooxdoo-1.5-sdk.zip [...] HTTP request sent, awaiting response... 200 OK Length: 67875249 (65M) [application/zip] !!! Saving to: `qooxdoo-1.5-sdk.zip' 100%[=======================================>] 67,875,249 616K/s in 96s 2011-10-01 19:10:51 (693 KB/s) - `qooxdoo-1.5-sdk.zip' saved [67875249/67875249] Penny:downloads singles$ tar -xf qooxdoo-1.5-sdk.zip Penny:downloads singles$ ls -R qooxdoo-1.5-sdk | wc -l 15517 !!! (includes test files, icons for 3 themes etc.) 7
  8. IT'S NOT A TOY let's see example api page: 8

  9. IT'S NOT A TOY qx.Class.define("foo.lib.io.HttpRequest", { type: 'abstract', extend :

    qx.io.request.Xhr, implement: [IFooInterface, IBarInterface], include : [app.MMessage], properties : { showLoadingDialog : { check : "Boolean", init : true } }, construct : function(vUrl, vMethod) { this.base(arguments, vUrl); this.addListener("fail", this._onError, this); }, members : { _onError : function() { this.showError(Tools.tr("io.request:error")); }, } }); let's see some code: 9
  10. IT'S NOT A TOY qx.Class.define("foo.lib.io.HttpRequest", { type: 'abstract', class type

    extend : qx.io.request.Xhr, implement: [IFooInterface, IBarInterface], include : [app.MMessage], properties : { showLoadingDialog : { check : "Boolean", init : true } }, construct : function(vUrl, vMethod) { this.base(arguments, vUrl); this.addListener("fail", this._onError, this); }, members : { _onError : function() { this.showError(Tools.tr("io.request:error")); }, } }); let's see some code: 10
  11. IT'S NOT A TOY qx.Class.define("foo.lib.io.HttpRequest", { type: 'abstract', extend :

    qx.io.request.Xhr, inheritance implement: [IFooInterface, IBarInterface], include : [app.MMessage], properties : { showLoadingDialog : { check : "Boolean", init : true } }, construct : function(vUrl, vMethod) { this.base(arguments, vUrl); this.addListener("fail", this._onError, this); }, members : { _onError : function() { this.showError(Tools.tr("io.request:error")); }, } }); let's see some code: 11
  12. IT'S NOT A TOY qx.Class.define("foo.lib.io.HttpRequest", { type: 'abstract', extend :

    qx.io.request.Xhr, implement: [IFooInterface, IBarInterface], interfaces include : [app.MMessage], properties : { showLoadingDialog : { check : "Boolean", init : true } }, construct : function(vUrl, vMethod) { this.base(arguments, vUrl); this.addListener("fail", this._onError, this); }, members : { _onError : function() { this.showError(Tools.tr("io.request:error")); }, } }); let's see some code: 12
  13. IT'S NOT A TOY qx.Class.define("foo.lib.io.HttpRequest", { type: 'abstract', extend :

    qx.io.request.Xhr, implement: [IFooInterface, IBarInterface], include : [app.MMessage], mixins ! properties : { showLoadingDialog : { check : "Boolean", init : true } }, construct : function(vUrl, vMethod) { this.base(arguments, vUrl); this.addListener("fail", this._onError, this); }, members : { _onError : function() { this.showError(Tools.tr("io.request:error")); }, } }); let's see some code: 13
  14. IT'S NOT A TOY qx.Class.define("foo.lib.io.HttpRequest", { type: 'abstract', extend :

    qx.io.request.Xhr, implement: [IFooInterface, IBarInterface], include : [app.MMessage], properties : { showLoadingDialog : { check : "Boolean", like C#, but better :) init : true } }, construct : function(vUrl, vMethod) { this.base(arguments, vUrl); this.addListener("fail", this._onError, this); }, members : { _onError : function() { this.showError(Tools.tr("io.request:error")); }, } }); let's see some code: 14
  15. IT'S NOT A TOY qx.Class.define("foo.lib.io.HttpRequest", { type: 'abstract', extend :

    qx.io.request.Xhr, implement: [IFooInterface, IBarInterface], include : [app.MMessage], properties : { showLoadingDialog : { check : "Boolean", init : true } }, construct : function(vUrl, vMethod) { this.base(arguments, vUrl); this.addListener("fail", this._onError, this); }, members : { protected member (also private & public) _onError : function() { this.showError(Tools.tr("io.request:error")); }, } }); let's see some code: 15
  16. OVERENGINERED? 16

  17. OVERENGINERED? NO. 17

  18. OVERENGINERED? NO. WELL DESIGNED! 18

  19. BUT! 19

  20. BUT! YOU HAVE TO KNOW WHAT YOU ARE DOING 20

  21. BUT! YOU HAVE TO KNOW WHAT YOU ARE DOING IN

    ANOTHER CASE... 21
  22. 22

  23. QOOXDOO + FRAMEWORK = GUI TOOLKIT 23

  24. LOT OF FEATURES 24

  25. LOT OF FEATURES BUT WE DON'T HAVE TIME TO TALK

    ABOUT ALL OF THEM, SO... 25
  26. LOT OF FEATURES BUT WE DON'T HAVE TIME TO TALK

    ABOUT ALL OF THEM, SO... HTTP://QOOXDOO.ORG/ABOUT 26
  27. THINGS WORTH MENTIONING * * IMHO 27

  28. DOCUMENTATION 28

  29. DOCUMENTATION 463

  30. DOCUMENTATION 30 + PLAYGROUND (RIA & MOBILE) + DEMOS

  31. MIXINS 31

  32. MIXINS Something like interfaces, but with implementation. 32

  33. MIXINS qx.Mixin.define("foo.lib.tools.MAwesomeLogger", { members : { logWithTrace : function(what) {

    console.log(what); console.trace(); } } }); qx.Class.define("foo.app.Bar", { include: [foo.lib.tools.MAwesomeLogger], construct: function() { this.logWithTrace(this); } } 33
  34. PROPERTIES 34

  35. 35

  36. qx.Class.define('foo.bar', { extend: qx.core.Object, properties: { phrase: { // autogenerate

    setter and getter and ... apply: '_applyPhrase' // fire on property modification (not init!) - return // value is ignored nullable: true, // can be null event: 'someEvent' // default changeFoo - fires on property change check: ['suit up', 'bazinga'], // check possible inserts, also could be defined as a // function - works only in development! transform: '_transformPhrase' // transform value - BEFORE check and apply validate: qx.util.Validate.string // works in development and production }, awesome: { init: false, check: 'Boolean' } nerd: { init: false, check: 'Boolean' } }, members: { _transformPhrase: function(value) { return value + '!'; } _applyPhrase: function(value, old, name) { if (value === 'suit up!') { this.toggleAwesome('awesome'); } else if (value === 'bazinga!') { this.toggleAwesome('nerd'); } } } }); 36
  37. LOT OF CONSISTENT(!) GUI COMPONENTS 37

  38. GUI COMPONENTS 38

  39. GUI COMPONENTS 39

  40. GUI COMPONENTS 40

  41. GUI COMPONENTS 41

  42. GUI COMPONENTS 42 Themeable of course ;)

  43. EASY KEY/COMMANDS BINDING 43

  44. EASY KEY/COMMANDS BINDING var findWindow = new qx.ui.window.Window('search'); //findWindow configuration...

    var find = new qx.event.Command("Ctrl+F"), close = new qx.event.Command('Esc'); find.addListener("execute", function() { findWindow.open(); }, this); close.addListener("execute", function() { findWindow.close(); }, this); 44
  45. EASY ELEMENTS POSITIONING (WITH LAYOUTS) 45

  46. EASY ELEMENTS POSITIONING 46

  47. EASY REST CALLS 47

  48. EASY REST CALLS 48 var description = { index: {

    method: "GET", url: "/photos" } create: { method: "POST", url: "/photos" } show: { method: "GET", url: "/photos/:id" } update: { method: "PUT", url: "/photos/:id" } } var photos = new qx.io.rest.Resource(description); //declaratively photos.map('destroy', 'DELETE', '/photos/:id'); //programatically photos.index(); // --> GET /photos photos.show({id: 1}); // --> GET /photos/1 // "success" is fired when any request associated to resource receives a response photos.addListener("success", function(e) { e.getAction(); // --> "index" or "show" }); // "indexSuccess" is fired when the request associated to the index action receives a response photos.addListener("indexSuccess", function(e) { e.getAction(); // --> "index" });
  49. HTML EDITOR OUT OF THE BOX 49

  50. HTML EDITOR 50 "The html editor does have some issues.

    Just not to give the impression that it would try to compete with more advanced editors like ckEditor, etc., because it doesn't. Still fine for many products, though." [Andreas Ecker]
  51. ADVANCED BUILD TOOL 51

  52. ADVANCED BUILD TOOL 52 Penny:frontend singles$ ./generate.py list >>> Available

    jobs: - api -- create api doc for the current library - api-data -- create api doc json data files - build - clean -- remove local cache and generated .js files (source/build) - distclean -- remove the cache and all generated artefacts of this library (source, build, ...) - fix -- normalize whitespace in .js files of the current library (tabs, eol, ...) - info -- collects environment information like the qooxdoo version etc., and prints it out - inspector -- create an inspector instance in the current library - lint -- check the source code of the .js files of the current library - migration -- migrate the .js files of the current library to the current qooxdoo version - pretty - profiling -- includer job, to activate profiling - simulation-build -- (experimental) create a runner app for simulated interaction tests - simulation-run -- (experimental) launches simulated interaction tests generated with simulation-build - source - source-all -- create source version of current application, with all classes - source-hybrid -- create a hybrid version (app classes as source files, others compiled) - test -- create a test runner app for unit tests of the current library - test-source -- create a test runner app for unit tests (source version) of the current library - translation -- create .po files for current library
  53. WORKS: STANDALONE (IN BROWSER), INSIDE EXISTING WEBPAGES OR NATIVE (WITHOUT

    GUI) 53
  54. MOBILE SUPPORT 54

  55. MOBILE SUPPORT 55

  56. DEVELOPER FRIENDLY (TESTS & TOOLS) 56

  57. DEVELOPER FRIENDLY 57

  58. DEVELOPER FRIENDLY 58

  59. LOCALIZATION AND TRANSLATION 59

  60. AND MUCH MORE... 60

  61. "WAIT

  62. NOT REALLY... 62

  63. 63 HTTP://WWW.LORDOFULTIMA.COM/EN/

  64. QUESTIONS? 64

  65. THANKS! 65

  66. 66 name: Radosław Benkel nick: singles www: http://www.rbenkel.me twitter: @singlespl

    * and I have nothing in common with http://www.singles.pl ;]