1 Realizacja Aplikacji InternetowychJavaScript
2 W trakcie ogladania tego slajdu (2-4min)Oczekiwanie na zwrot różnych treści (głównie w tradycyjnych witrynach) zajmuje na świecie ~ osobo-minut to oznacza 66 osobo-lat albo np. 86 lotów na Marsa (wg. czasów np. lądownika Curiosity)
3 Tradycyjne strony Strona jest kompletowana (markup+dane) po stronie serwerowej Struktura DOM-a jest w zasadzie okreslona w momencie wysyłki z serwera Strona może zawierać javascript dla dodania efektów, dynamiki, formatowania, zmiany layout-u dla różnych rodzajów urzadzeń Historia, uprawnienia itd. mają naturalne odbicie w URL-ach
4 SPA Markup (mockup) HTML może być ładowany z bez/z małą ilościa danychDane są doładowywane asynchronicznie Brak wielokrotnego przesyłania redundantnych elementów (tagi/DOM/skrypty) Przeniesienie cześci ciężaru renderowania na stronę kliencką Mniejsze obciążenie łączy/serwerów Brak migania/zamrażania strony Wrażenie pracy z resoponsywną aplikacją
5 SPA vs strona serwerowaPrzy SPA serwer odpowiada za przesłanie inicjalnego mockup-u strony (definicji) ew. wypełnionej wstępnie danymi Dane: formaty natywne HTML, obrazki lub JSon XML Podejście hybrydowe Backend vs API
6 Rozwiązania klienckieSilverlight Flash/Flex HTML 5 + CSS 3 Javascript CofeeScript, Dart, TypeScript GWT (java 2 javascript) Traceur (google: kompilator javascript next 2 javascript) Ecma Harmony / Narcisius (jw) Script# (c# 2 javascript) Pyjamas (python 2 javascript)
7 Javascript i biblioteki klienckieBiblioteki operujące na DOOM JQuery, Prototype, MooTools Frameworki: Yui, Sencha ExtJS, Dojo, Knockout, EmberJS, Angular, Aurelia, Meteor BackBone ReactJS Bootstrap CSS, Less, Sass
8 Narzędzia Debugowanie, profiling: Pakiety, komendyFireBug, Chrome Developer Tools, IE Inspector / WebDeveloper Fiddler Pakiety, komendy npm, jspm.io, Bower, Grunt Testy jednostkowe i akceptacyjne Junit Jasmine Automatyczne uruchamianie testów: Selenium Headless browsers PantomJS Zombi+NodeJs, ENVJS. + Rhino engine
9 Realizacja Aplikacji InternetowychTESTOWANIE
10 Testowanie Jakieś testy są potrzebne … Testy jednostkoweTesty integracyjne Testy akceptacyjne lub end-to-end
11 Środowisko Framework Narzędzia dodatkowe FireUnitŚrodowisko uruchomieniowe Przeglądarka uruchamiana ręcznie Selenium + przeglądarka Na serwerze: PhantomJS (SlimerJS,CasperJS…) Node.js + Chimera | Karma rhino + env.js,
12 Framework QUnit (używany np. przez wiele plug-inów JQuery)module('calculator'); test('add numbers', function() { var calc = new Calculator(); equals(4, calc.add(2, 2)); })
13 Framework Jasmine (BDD, hierarchiczna definicja setup-ów)describe('panda',function(){ it('is happy',function(){ expect(panda).toBe('happy'); });
14 Framework Mocha (BDD, hierarchiczna definicja setup-ów, pozwala używać różnych assert libraries, raportuje wolne testy przy t. asynchr., coverrage) describe('panda',function(){ it('is happy',function(){ assert.equal('happy',panda.state); expect(panda).toBe('happy'); });
15 Framework Screw.Unit JSSpecdescribe("Calculator", function() { it("should add numbers", function() { var calc = new Calculator(); expect(calc.add(2, 2)).to(equal, 4); }); }); JSSpec describe("Calculator", function() { with(this) { it("should add numbers", function() { var calc = new Calculator(); calc.add(2, 2).should(equal(4)); }); }});
16 Framework jsUnitTest jsUnitTest + jShouldanew Test.Unit.Runner({ testCalculatorAdd: function() { with (this) { var calc = new Calculator(); assertEqual(4, calc.add(2, 2)); }} }); jsUnitTest + jShoulda context('Calculator', { should('add numbers', function() { with (this) { var calc = new Calculator(); assertEqual(4, calc.add(2, 2)); }})
17 Framework I wiele innych m.inUnittest, jsAssertUnit, YUItest, Qooxdoo, JSUnit, JSUnit , Crosscheck, Ecmaunit, Dojo Objective Harness, FireUnit, Qunit, RhinoUnit, JSpec
18 Tools Smoke Amok MockMenew Smoke.Stub(Calculator, 'add').and_return(5); Smoke.Mock(Calculator).should_receive('add').at_least('once') .with_arguments(2, 2).and_return(5); Amok var mock = amok.mock(Calculator); mock.should_receive('add').with_args(2, Number) .times(1).and_return(5); MockMe mock(Calculator).andDo(function() { SomethingThatUsesCalculator.calculate("2 + 2"); verify(Calculator.add)(2, 2); });
19 Tools qMock Jack Interesujace: JSMockito, Sinon.js, Mock.jsvar mock = new Mock(); mock.expects(1).method('add').withArguments(2, 2).andReturn(5); Jack jack.expect("Calculator.add").exactly("1 time") .withArguments(2, 2).mock(function() { … return sth; }) jack.create("mock", ['add', 'substract']); .whereArgument(0).isOneOf(2, 3, 4); Interesujace: JSMockito, Sinon.js, Mock.js
20 Istotne uwagi Izolacja od drzewa DOM i globalnych odwołań do obiektówLokalne referencje do używanych obiektów Rozluznienie połączeń miedzy obiektami Mozliwość stosowanania wzorca obserwator (event) Stosowanie broker event (serviceBus) do komunikacji
21 Pokrycie kodu testami JSCoverage Istambul …
22 Realizacja Aplikacji InternetowychJQuery
23 JQuery Silny model selekcjiWsparcie dla typowych akcji np. ustawienie obsługi zdarzenia, dodanie, usunięcie klasy stylu itd. Gotowe rozwiazania typowych problemów Rozszerzalny model - wtyczki Dużo gotowych wtyczek Testowalny
24 JQuery Problem: wyszukiwanie elementów na stronie np:for ( var (i in document.getElementsByTagName("p") ) { i.onclick = function(event) { alert("Hello!"); } } JQuery: $("p").click(function(event){ alert("Hello!!"); }
25 Jquery – Referencjonowanie // Standard. jQuery $ jQuery(document).ready( function () { alert('DOM is ready!'); }); // Shortcut, but same thing as above. jQuery( function () { alert('No really, the DOM is ready!'); }); // Shortcut with fail-safe usage of $ jQuery(function($) {alert('Seriously its ready!'); }); { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://slideplayer.pl/12184931/71/images/25/Jquery+%E2%80%93+Referencjonowanie.jpg", "name": "Jquery – Referencjonowanie", "description": " // Standard. jQuery $ jQuery(document).ready( function () { alert( DOM is ready! ); }); // Shortcut, but same thing as above. jQuery( function () { alert( No really, the DOM is ready! ); }); // Shortcut with fail-safe usage of $ jQuery(function($) {alert( Seriously its ready! ); });", "width": "1024" } 26 JQuery Problem: wyszukiwanie elementów na stronie np:for ( var (i in document.getElementsByTagName("p") ) { i.onclick = function(event) { alert("Hello!"); } } JQuery: $("p").click(function(event){ alert("Hello!!"); }
27 JQuery Selektor zwraca kolekcję obiektów DOM "owiniętych" w obiekty JQuery (dodatkowe metody) Pojedynczy obiekt można owinac stosujac $ np. $(this) Kolekcję można ją zapamiętać i wyłuskać z niej referencje do poszczególnych elementów var jqlinki = $("a"); var pierwszy_link = linki[0]; Kolekcję można też sprowadzic do tablicy obiektów DOM var jqlinki = $("a").get();
28 JQuery - selektory Selektory zwracają kolekcję elementów JQuery opakowujących elementy DOM: $("*") – wszystko $("a") - po nazwie tagu $('#myDivId') - po id $('.myCssClass'), $(‘a.myCssClass')- po klasie CSS $("[id]") – po atrybucie $("[id=wartosc]") – po wartości atrybutu Np. $('div').each( function() { alert($(this).html(); });
29 JQuery – selektory strukturalne$ (“selektor1, selektor2, selektorN”) $("p,a,div,code.bold") $("rodzic > dziecko") $(„p>a") $("przodek potomek") $("p a.bold") $ (“poprzedni+nastepny”) $ (“label.MyLabelClass + input”) $ (“poprzedni ~ cale_rodzenstwo”) $ (“h3 ~ p”)
30 JQuery - atrybuty $("[id]") $("p[id][name]")$("[id=wartosc]") $("input[name='newsletter']") $("[id~=slowo]") $("input[name~='test']") $("[id|=poczatek_do_kreski_lub_rowny]") $("a[hreflang|='en']") $("[id*=podciag]") $("input[name~='xx']") $("[id^=poczatek]") $("input[name^='news']") $("[id$=koniec]") $("input[name^=letter']")
31 JQuery - selektory Selektory można łaczyć i dodawać$("a.myCssClass, '#myDivId>a")
32 JQuery – modyfikatory selekcji:animated, :checked, :disabled :enabled, :empty, :hidden, :visible, :selected :file, :checkbox, :button, :header, :password, :radio, :reset, :submit, :text :even, :odd, :first, :first-child, :last, :last-child, :parent :contains() $("div:contains('John')") :has() $("div:has('p')") :not(sektor) $("input:not(:checked) + span") :eq(), :lt(), :gt() $("td:eq(2)")
33 JQuery – filtry .eq(), .first(), .last(), .slice(od,[do]) $('li').eq(2) $('li').eq(-1) $('li').slice(3,-2) .filter(selector), filter(function) $('li').filter(':even') $('li').filter(function(index) { return index % 3 == 2; }) .has(selektor_potomka), .has(DOM_element_potomny) $('li').has('ul') .not(selektor), not(DOM_elementy), not(function(index)) $('li').not(':even') $("p").not( $("#selected")[0] )
34 JQuery – pobieranie zawartości.get([pozycja]) - pobieranie elementów Dom $("a").get() .html() $('div.demo-container').html(); $( "#myDiv p:first" ) .html( "New first paragraph!" ); .length, size() var n = $("div").length; .val() $('select.foo option:selected').val() .attr() var title = $("em").attr("title"); $("em").attr("title“,”new title”);
35 JQuery – trawersowanie drzewa.find(), .end() – kończy ostatnie find $("p").find("a") .siblings(), .children(), .contents(), .closest(), .next(), .prev(), .parent(), .parents() .prevAll(), .nextAll(), .andSelf() $("div:last").prevAll(".myClass") .nextUntil(), .parentsUntil(), .prevUntil() #("#term-2").nextUntil("dt") .offsetParent() – pozycja na ekranie .add() $('li').add('p')
36 JQuery – ZMIANY .replaceAll(co_zastapic_selekcja) $("Paragraph.").replaceAll("p") .replaceWith(noweElementy), replaceWith(funkcja), $('.second').replaceWith( "New heading
"); $('.third').replaceWith($('.first'));
37 JQuery – transformacje.map( callback(this, index) ) var oneBased = $.map([0,1,2,3,4], function(value){return value+1;}); var ids = $(':checkbox').map(function() { return this.id; })
38 JQuery – predykaty .hasClass() $('#mydiv').hasClass('foo').is() $(this).is(".blue,.red")
39 JQuery – modyfikacje .addClass(), removeClass() $('p').addClass('myClass yourClass'); .toggleClass( className ), .toggleClass( className, switch ), .toggleClass( function(index, class), [ switch ] ) $("p").click(function () { $(this).toggleClass("highlight"); }); .removeAttr() $(this).next().removeAttr("disabled") .css(), .attr(), .val() $(‘p’). css( { fontSize: "100px", color: "red“ } )
40 JQuery – zdarzenia .error(), .resize(), .scroll() $('#book').error(function() { alert('Handler called.') }); .load()*, .ready(), .unload()* .blur(), .change(), .focus(), .select(), .submit() $('form').submit(function() { alert('Handler for .submit() called.'); return false; }); .focusin(), .focusout(), .keydown(), .keypress(), .keyup() .hover(), .mousedown(), .mouseenter(), .mouseleave(), .mousemove(), .mouseout(), .mouseover(), .mouseup(), .click(), .dblclick(), on() $('#target').click( function() { alert(‘click handler called.'); } ); * - deprecated -> on(“load”…
41 JQuery – efekty .hide(), show() $('p').addClass('myClass yourClass');.focus() .slideDown(), .slideToggle(), .slideUp() ("div").slideDown("slow"); .fadeIn(), .fadeOut(), .fadeTo() $("div:hidden:first").fadeIn("slow"); .animate(), .stop(), .delay(), jQuery.fx.off $('#book').animate({ width: ['toggle', 'swing'], height: ['toggle', 'linear'], opacity: 'toggle' }, 5000, function() { // Animation complete. }); );
42 JQuery – Ajax load(), jQuery.get(), jQuery.getJSON(), jQuery.getScript(), jQuery.post() $.get("test.cgi", { name: "John", time: "2pm" }, function(data){ alert("Data Loaded: " + data); }); $('#result').load('ajax/test.html', function() { alert('Load was performed.'); }); jQuery.ajax(), jQuery.ajaxSetup(), $.ajax({ type: 'POST', url: url, data: data, success: success, dataType: dataType }); .ajaxComplete(), .ajaxError(), .ajaxSend(), .ajaxStart(), .ajaxStop(), .ajaxSuccess(), . jQuery.param(), .serialize(), .serializeArray()
43 JQuery – Różne .clone(), .append(), appendTo(), .prepend(), .prependTo(), text(), html() $('h2').appendTo($('.container')); $("p").text("Some new text."); .unwrap(), .wrap(), .wrapAll(), .wrapInner() $("span").wrap("New heading
').replaceAll('.inner'); $(‘’).replaceWith(‘’); .detach(), .empty(), .remove() $('.hello').empty();
44 JQuery – Literatura Materiały: Ksiązki Doc do VS jquery.com“JQuery in Action” “Learning jQuery” “jQuery UI” “jQuery Cookbook” Doc do VS
45 Realizacja Aplikacji InternetowychExt-Js
46 Ext-JS (Sencha, Aptana)Ext-core – skrócona wersja – bez frameworka UI Ext-all – pełna wersja z kontrolkami Jako selektora DOM może korzystać z GWT, jQuery, DOM, YUI Framework: Komercyjny Komercyjny: Ext builder
47 Ext - core Uruchamianie skryptów na DOM Szukanie elementow po idExt.onReady(function() { ... }); Szukanie elementow po id var el=Ext.get('myElementId'); el.addClass('error'); Lekkie "nietrwałe" referencje Ext.fly('elId').hide(); Szukanie elementow Ext.query('div:nth-child(2)'). findParent('div');
48 Ext - core Zdarzenia AnimacjeExt.fly('myEl').on('click', function(e, t) { alert("clicked!!!"); }); Animacje var el=Ext.get('myElementId'); el.slideOut('t', { easing: 'easeOut', duration: .5, remove: false, useDisplay: false });
49 Ext - "klasy" DziedziczeniePerson = Ext.extend(Object, { constructor: function(first, last){ this.firstName = first; this.lastName = last; } getName: function(){ return this.firstName + ' ' + this.lastName; } }); var p1 = new Person('John', 'Smith');
50 Ext - narzędzia Odwołania do klasy bazowej Przestrzenie nazwMyClass = Ext.extend(Object, { constructor: function(config){ MyClass.constructor.call(this, config); }, foo: function(){ ... } }); Przestrzenie nazw Ext.namespace( 'MyCompany', 'MyCompany.Application'); Ext.namespace('MyCompany.Application');
51 Ext – wzorzec obserwatorvar MyClass = Ext.extend(Ext.util.Observable, { constructor: function(config){ this.addEvents('datachanged'); // event MyClass.constructor.call(this, config); }, update: function(){ // jakies transformacje // Przy "odpaleniu" zdarzenia mozemy okreslic // parametry ktore maja byc przekazane this.fireEvent('datachanged', this, this.data.length); } }); // Subskrypcja eventu var c = new MyClass(); c.on('datachanged', function(obj, num){ /* obsluga.*/ });
52 Ext - DOM Modyfikacja DOMa createHtml (przestarzale), markupinsertHtml,insertBefore,insertAfter, insertFirst, append, overwrite Ext.DomHelper.append(document.body, { id: 'my-div', cn: [{ tag: 'a', href: 'http://www.yahoo.com/', html: 'My Link', target: '_blank' }] });
53 Ext - DOM Skryptowanie: var myEl = document.createElement('a');myEl.href = 'http://www.yahoo.com/'; myEl.innerHTML = 'My Link'; myEl.setAttribute('target', '_blank'); var myDiv = document.createElement('div'); myDiv.id = 'my-div'; myDiv.appendChild(myEl); document.body.appendChild(myDiv);
54 Ext - AJAX Globalne handlery: Typowe wołanie:Ext.Ajax.on('beforerequest', this.showSpinner, this); Ext.Ajax.on('requestcomplete', this.hideSpinner, this); Ext.Ajax.on('requestexception', this.hideSpinner, this); Typowe wołanie: Ext.Ajax.request({ url: 'ajax_demo/sample.json', success: function(response, opts) { var obj = Ext.decode(response.responseText); console.dir(obj); }, failure: function(response, opts) { console.log('server-side failure with status code ' + response.status); }});
55 Ext - GUI ViewPort, Window Toolbar, Progresbar, TabPanel, Panel,Editor, DataPicker, DataView Button, ButtonGroup
56 Ext - przykład Ext.onReady(function() { var item1 = new Ext.Panel({ title: 'Accordion Item 1', html: '
57 Ext - przykład Ext.onReady(function() { var item1 = new Ext.Panel({ }); var accordion = new Ext.Panel({ region:'west', margins:' ', split:true, width: 210, layout:'accordion', items: [item1, item2, item3, item4, item5] }); var viewport = new Ext.Viewport({ layout:'border', items:[ accordion, { region:'center', margins:' ', cls:'empty',bodyStyle:'background:#f1f1f1', html:'
58 Ext – przykład: reużycie kontrolekExt.onReady(function() { MyPanel = extend(Ext.Panel, { title: 'Accordion Item 1', html: '
59 Ext-GUI Przykłady: Lauout Drag&Drop Form Desktop
60 Ext-GUI Rozluznienie powiazań m. Komponentami Lokalne referencjeObserwator Mediator: publish/subscribe Simplebus Ext.bus
61 Realizacja Aplikacji InternetowychAngularJS
62 Kompleksowy framework JS“opinionated” Dwukierunkowy binding HTML jako szablon – deklaratywna składnia MVC - MVVM Dependency Injection Rozszerzalny Testowalny Dobrze współpracuje z JQuery, Bootstrap 2.0 NIEKOMPATYBILNY Z 1. (1.5 w. przejściowa)
63 Dyrektywy Atrybuty: Tagi
64 Binding
65 Kontroler
66 Kontroler angular.module('myApp', []) .controller('MyController', ['$scope', function($scope) { $scope.elementsToShow = [ {content:'aaa', exists:true}, {content:'bbb', exists:false}]; $scope.neneralInfo = "Info"; $scope.getClass = function() { if (..) return "claccSuffix"; }); }]);
67 Kontroler
68
69
70
71 Filtry (1.0) / potoki (2.0) {{ data | filter:options }}{{ element.price | currency }} currency uppercase date:' h:mma dd/MM/yyyy‘ limitTo:8 ng-repeat="…|orderBy:'-content'"
72 Formatowanie ng-class/ ngClass (2.0) ng-show / [hidden]
73 ng-pristine, ng-submitted ng-invalid, ng-valid ng-dirty Formatowanie ng-pristine, ng-submitted ng-invalid, ng-valid ng-dirty ng-scope, ng-isolate-scope ng-binding
74 Zdarzenia ng-submit / submit ng-init / initng-click (1.0) / click (2.0) ng-submit / submit ng-init / init
75 Dane i binding binding {{GeneralInfo}} ng-repeat="todo in todos"ngFor (2.0) ngModel (2.0)
76 Modularyzacja ng-include="'sub-page.html‘"ng-controller= "MyController as ctrl«
77 Custom element
78 Custom element
79 Modularyzacja ng-include="'sub-page.html‘"ng-controller= "MyController as ctrl«
80 Serwisy, DI app.controller('MyController', ['$http', $log, function($http, $log){ }]); Serwisy
81 Serwisy, DI app.controller('MyController', ['$http', $log, function($http, $log){ }]); Leniwa inicjalizacja Model singleton Standardowe s.: $anchorScroll, $animate, $cacheFactory, $compile, $controller, $document, $exceptionHandler, $filter, $http, $httpBackend, $interpolate, $interval, $locale, $location, $log, $parse, $q, $rootElement, $rootScope, $sce, $sceDelegate, $templateCache, $templateRequest, $timeout, $window Serwisy
82 Własny serwis var myModule = angular.module('myModule', []); myModule.factory('myService', function() { var serviceInstance; // inicjalizacja return serviceInstance; }); myModule.factory('myServiceWithDep', [$log, myService, function($log, mySrvc){ return ...;
83 Wykorzystanie DI – serwis locatorvar di = angular.injector(['myModule', 'ng']); var split = di.get('splitter'); var contr = di.instantiate('MyController'); Pot. wykorzystanie cache
84 Własne filtry {{name | reverse}}angular.module('myApp', []) .filter('reverse', function() { return function(input, uppercase) { input = input || ''; var out = ""; for (var i = 0; i < input.length; i++) { out = input.charAt(i) + out; } // conditional based on optional argument if (uppercase) { out = out.toUpperCase(); return out; }; })
85 Angular - kontekst $scope może być zagnieżdzonymoże odwołać sie do rodzica i odczytać jego wartości nie może odczytać wartości dzieci
86 Angular - wady Relatywnie drobne błedy potrafią spowodować niedziałanie całej strony Wolno działa pod starszymi przeglądarkami IE7, IE8 Pot. wolny dla skomplikowanych stron Trudno zrzumieć niektóre interakcje Niektóre mechanizmy są trudne np uaktualnianie scope vs event loop vs binding
87 Realizacja Aplikacji InternetowychReactJS
88 ReactJS - jeszcze inne podejściehttps://facebook.github.io/react/ var Hello = React.createClass({displayName: 'Hello', render: function() { return React.createElement("div", null, "Hello ", this.props.name); } }); ReactDOM.render( React.createElement(Hello, {name: "World"}), document.getElementById('container') );
89 ReactJS - jeszcze inne podejścieSkupia się na izolacji komponentów (za to kod html jest pomieszany z kodem js). Unika zarządzania stanem – przy każdej zmianie cały widok jest renderowany ponownie (w przeglądarce lub na serwerze) Koncepcja funkcyjna: wyświetlenie strony polega na wyrenderowaniu html-a na podstawie stanu Modele sa zwykłymi obiektami js Jednokierunkowe wiązanie Szybki - asynchroniczne odświeżanie widoku (kolejka) może być bardziej efektywne niż natychmiastowe odświeżanie przy b. rozbudowanych aplikacjach
90 Realizacja Aplikacji InternetowychCoffeeScript
91 Instalacja Node.js + coffee-script.js CoffeeSharp.zipNUGet: Install-Package CoffeeSharp Coffee.exe CoffeeScriptHttpHandler.dll CoffeeSharp.dll Jurassic.dll
92 Motywacja Zwięzła składnia Redukcja szumu {} itd Dodatkowe możliwościPoprawione problemy (==, var) Produkowany jest dobry kod Javascript Informacje Ksiazki: Screencast:
93 Podstawy Komentarz # Przypisanie – tworzy zmienna Abc =5 var Abc = 5Bloki realizowane za pomoca wcięć if happy and knowsIt clapsHands() chaChaCha() else showIt() if (happy && knowsIt) { clapsHands(); chaChaCha(); } else { showIt();
94 Operatory Operatory CoffeeScript vs JavaScript is isnt not and ortrue, yes, on false, no, off @, this of in, ? === !== ! && || true false this in Brak odpowiednika alert "I knew it!" if elvis? if (typeof elvis !== "undefined" && elvis !== null) alert("I knew it!");
95 Interpolacja zmiennychZmienne w " " podlegają interpolacji a w ' ' nie podlegają author = "Wittgenstein" quote = "A picture is a fact. -- #{ author }" sentence = "#{ 22 / 7 } is a decent approximation of π" var author, quote, sentence; author = "Wittgenstein"; quote = "A picture is a fact. -- " + author; sentence = "" + (22 / 7) + " is a decent approximation of π";
96 Wieloliniowe literały i komentarze blokowehtml = ''' cup of coffeescript ''' ### CoffeeScript Compiler v1.1.2 Released under the MIT License
97 Kaskadowe porównania cholesterol = 127healthy = 200 > cholesterol > 60 var cholesterol, healthy; cholesterol = 127; healthy = (200 > cholesterol && cholesterol > 60);
98 Funkcje Składnia ala Ruby, zwraca wynik ostaniej instrukcjiNawiasy przy wywołaniach można pomijać square(x) -> x*x test(x,y) -> a=5 x+y+a function square(x) { return x*x; } function test(x,y) { var a = 5; return x+y+5; } z = square 5 var z = square(5);
99 Funkcje i this Account = (customer, cart) -> @customer = customer@cart = cart $('.shopping_cart').bind 'click', (event) -> var Account; var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; Account = function(customer, cart) { this.customer = customer; this.cart = cart; return $('.shopping_cart').bind('click', __bind(function(event) { return this.customer.purchase(this.cart); }, this)); };
100 Obiekty Składnia wymaga wcięć math = root: Math.sqrt square: squarecube: (x) -> x * square x math = { root: Math.sqrt, square: square, cube: function(x) { return x * square(x); } };
101 Wszystko jest wyrażeniemgrade = (student) -> if student.excellentWork "A+" else if student.okayStuff if student.triedHard then "B" else "B-" else "C" eldest = if 24 > 21 then "Liz" else "Ike" var eldest, grade; grade = function(student) { if (student.excellentWork) { return "A+"; } else if (student.okayStuff) { if (student.triedHard) { return "B"; } else { return "B-"; } return "C"; }; eldest = 24 > 21 ? "Liz" : "Ike";
102 Pętle for, while, until, Petle zwracają wartośćeat food for food in ['toast', 'cheese', 'wine'] var food, _i, _len, _ref; _ref = ['toast', 'cheese', 'wine']; for (_i = 0, _len = _ref.length; _i < _len; _i++) { food = _ref[_i]; eat(food); }
103 Pętle Zwrot z petli mozna przypisaccubes = (math.cube num for num in list) cubes = (function() { var _i, _len, _results; _results = []; for (_i = 0, _len = list.length; _i < _len; _i++) { num = list[_i]; _results.push(math.cube(num)); } return _results; })();
104 Przypisania wielokrotnetheBait = 1000 theSwitch = 0 [theBait, theSwitch] = [theSwitch, theBait] var theBait, theSwitch, _ref; theBait = 1000; theSwitch = 0; _ref = [theSwitch, theBait], theBait = _ref[0], theSwitch = _ref[1];
105 switch switch (day) { case "Tue": go(relax); break;case "Thu": go(iceFishing); case "Fri": case "Sat": if (day === bingoDay) { go(bingo); go(dancing); } case "Sun": go(church); default: go(work); switch day when "Tue" then go relax when "Thu" then go iceFishing when "Fri", "Sat" if day is bingoDay go bingo go dancing when "Sun" then go church else go work
106 try/catch/finally try allHellBreaksLoose() try { allHellBreaksLoose();catsAndDogsLivingTogether() catch error print error finally cleanUp() try { allHellBreaksLoose(); catsAndDogsLivingTogether(); } catch (error) { print(error); } finally { cleanUp(); }
107 Sklejanie tablic numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]copy = numbers[0..numbers.length] middle = copy[3..6] var copy, middle, numbers; numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; copy = numbers.slice(0, numbers.length); middle = copy.slice(3, 7);
108 Sklejanie tablic numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]var numbers, _ref; numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]; [].splice.apply(numbers, [3, 4].concat(_ref = [-3, -4, -5, -6])), _ref;
109 Przypisania mogą dekomponowac strukturyvar city, futurists, name, street, _ref, _ref2; futurists = { sculptor: "Umberto Boccioni", painter: "Vladimir Burliuk", poet: { name: "F.T. Marinetti", address: ["Via Roma 42R", "Bellagio, Italy 22021"] } }; _ref = futurists.poet, name = _ref.name, _ref2 = _ref.address, street = _ref2[0], city = _ref2[1]; futurists = sculptor: "Umberto Boccioni" painter: "Vladimir Burliuk" poet: name: "F.T. Marinetti" address: [ "Via Roma 42R" "Bellagio, Italy 22021" ] {poet: {name, address: [street, city]}} = futurists
110 Przypisania mogą dekomponowac zakresytag = "
111 Argumenty Funkcji gold = silver = rest = "unknown"awardMedals = (first, second, others...) -> gold = first silver = second rest = others contenders = [ "Michael Phelps" "Liu Xiang" "Yao Ming" "Allyson Felix" "Shawn Johnson" "Roman Sebrle" "Guo Jingjing" "Tyson Gay" "Asafa Powell" "Usain Bolt" ] awardMedals contenders... var awardMedals, contenders, gold, rest, silver; var __slice = Array.prototype.slice; gold = silver = rest = "unknown"; awardMedals = function() { var first, others, second; first = arguments[0], second = arguments[1], others = 3 <= arguments.length ? __slice.call(arguments, 2) : []; gold = first; silver = second; return rest = others; }; contenders = ["Michael Phelps", "Liu Xiang", "Yao Ming", "Allyson Felix", "Shawn Johnson", "Roman Sebrle", "Guo Jingjing", "Tyson Gay", "Asafa Powell", "Usain Bolt"]; awardMedals.apply(null, contenders);
112 Klasy CoffeScript oferuje koncepcję klasKlasy mają składnię zbliżoną do obiektów Wspierane jest dziedziczenie i odwołania do klas bazowych
113 class Animal constructor: -> move: (meters) -> + " moved #{meters}m." class Snake extends Animal move: -> alert "Slithering..." super 5 sam = new Snake "Sammy the Python" sam.move() class Horse extends Animal alert "Galloping..." super 45 tom = new Horse "Tommy the Palomino" tom.move()
114 var Animal, Horse, Snake, sam, tom;var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor; child.__super__ = parent.prototype; return child; }; Animal = (function() { function Animal(name) { this.name = name; } Animal.prototype.move = function(meters) { return alert(this.name + (" moved " + meters + "m.")); return Animal; })();
115 Snake = (function() { __extends(Snake, Animal); function Snake() { Snake.__super__.constructor.apply(this, arguments); } Snake.prototype.move = function() { alert("Slithering..."); return Snake.__super__.move.call(this, 5); }; return Snake; })(); Horse = (function() { __extends(Horse, Animal); function Horse() { Horse.__super__.constructor.apply(this, arguments); } Horse.prototype.move = function() { alert("Galloping..."); return Horse.__super__.move.call(this, 45); return Horse; sam = new Snake("Sammy the Python"); tom = new Horse("Tommy the Palomino"); sam.move(); tom.move()
116 Realizacja Aplikacji InternetowychWygląd …
117 Wygląd czyli CSS to początekZerowanie stylów LESS, SASS Twitter BootStrap
118 Zerowanie stylów Problem: w poszczególnych przeglądarkach różne są domyślne wartości dla poszczególnych znaczników Minimum: * { padding: 0; margin: 0; } Podstawowy: * { vertical-align: baseline; font-weight: inherit; font-family: inherit; font-style: inherit; font-size: 100%; border: 0 none; outline: 0; padding: 0; margin: 0; } Zerujące CSS-y: Eric Meyer, Shaun Inmann, Chris Poteet
119 Zerowanie stylów Zalety: Piszemy od zera, a nie łatamyTylko wybrane (zdefiniowane) style będą dostępne Wiele rzeczy jest prostszych np. okreslamy padding I nie musimy werifikować czy przypadkiem marginnie jest gdzieś ustawiony Łatwiej opanować róznicew między przegladarkami
120 Zerowanie stylów Wady: Wieksza waga wytrynyTrzeba zdefiniować wszystko od początku = sporo pracy I tak nie załatwia wszystkich problemów kompatybilnościwych
121 Preprocesory CSS Najpopularniejsze: LESS, SASSPozwalają uzywać rozszerzeń np: Zagnieżdzanie reguł Zmienne Instrukcje warunkowe Funkcje Importowanie plików Mix-iny Wymagają dodatkowego kroku - kompilacji
122 Twitter - Bootstrap Pozwala szybko tworzyć strony z gotowych elementówDostępnych wiele gotowych rozwiązań/tematów 12 kolumnowy grid oparty na pixelach/procentach Reaktywny Wiele gotowych do użycia komponentów i wtyczek Wielo-platformowy: smartfony, przeglądarki