środa, 25 lipca 2012

Office 365 Preview/2013 Preview - second shot! (aplikacje web + Office apps)

W dniu premiery oczy większości były skupione zasadniczo na nowych aplikacjach desktopowych Metro-podobnych Office 2013, jedynej prawdziwej aplikacji Metro OneNote MX oraz instalacji pakietu z chmury. W niedługim później czasie spłynęła druga część nowości związanych z Office, równie ważnych i przełomowych. W tym poście przedstawię krótko te zagadnienia, a mianowicie nowe aplikacje webowe pakietu oraz nowe podejście do pisania rozszerzeń w postaci Office apps, które działają zarówno w wersji desktopowej jak i webowej… Aby spełnić ten postulat nietrudno domyślić się, że aplikacje te pisze się w HTML5 i JS. Jedną z paru opcji dla ich dystrybuowania ma być Office Store.

Zacznijmy od aplikacji webowych pakietu, które w najnowszej wersji działają szybciej, korzystają z elementów HTML5, mają więcej funkcjonalności, zapewniają wygodną obsługę ekranów dotykowych i upodobniły się wizualnie do Metro. Jak najszybciej można zacząć sobie z nich korzystać? Można aktywować testową wersję 2013 na swoim koncie skydrive (co też uczyniłem) lub po prostu wejść na witrynę Office.com

Dostajemy odświeżoną wersję webową Worda, Excela, PowerPointa oraz OneNote.

offweb_01

Nie rozpisuję się o nich dużo, bo najlepiej je sobie pooglądać na żywo, jest też sporo artykułów w sieci na ten temat. Ja subiektywnie zwracam uwagę, że główne menu zajmuje pół strony, czyli nie jest więc aż tak radykalne jak w aplikacjach desktopowych, ma mniej opcji… Nie otwiera się też strona z szablonami na starcie… Może chodzi tu o to, by wersje webowe były jak najprostsze i miały mniej stron… Ogólnie mamy mniej funkcjonalności niż w wydaniu desktopowym, ale znacznie więcej niż w starszej wersji web.

offweb_02

Jednak z deweloperskiego punktu widzenia większa rewolucja dokonała się w możliwości pisania rozszerzeń. Owszem nadal można tworzyć dodatki jak w poprzednich wersjach czyli w .NET i poprzez wywoływanie COM-ów, ale dla sporej części przypadków wystarczy nowe podejście polegające na pisaniu aplikacji webowych w HTML5, JS, CSS3, jQuery… Najlepiej poczytać sobie o tym wertując w dół strony w MSDN począwszy od strony Office and SharePoint app development. Model aplikacji Office został opisany na stronie Overview of apps for Office.

Manifest plus webpage equals app for Office

Desktopowy Office posiada specjalny runtime do hostowania takich aplikacji, który używa komponentów z przeglądarki Internet Explorer (nie musi to być domyślna przeglądarka w systemie, ale powinna być w nim zainstalowana, przynajmniej IE9). Oczywiście są tu odpowiednie poziomy izolacji i zabezpieczenia… W przypadku wersji webowej pakietu nasza aplikacja jest hostowana w iframe z sandbox. To samo API w JavaScript obsługuje obie wersje Office.

W testowaniu nowego Office 365 Preview w chmurze dobrze skorzystać z linka subskrybującego na stronie Sign up for an Office 365 Developer Site. Dostajemy wtedy więcej usług oraz narzędzia przeznaczone dla deweloperów! Drugi raz dokonywałem testowej rejestracji, bo nie potrafiłem jakoś zmienić konfiguracji z poprzedniego posta -:(

Wykonując polecenia ze wskazanej przeze mnie strony uruchamiamy nowe narzędzie o nazwie kodowej “Napa” w całości na stronie web (jakby zalążek webowego Visual Studio?). Do pisania aplikacji na Office nie potrzebujemy więc koniecznie Visual Studio.

365dev_01

365dev_02b

Po wybraniu rodzaju projektu, otwiera się nam projekt aplikacji webowej na stronie web. Poniżej widzimy kod JavaScript obsługujący dwa przyciski, które powodują odczytanie danych z zaznaczonej komórki w Excelu i zapis do niej. To przykładowy kod umieszczony domyślnie w szablonie projektu, standardowo jest też używane jQuery…

365dev_03

Naciskamy pierwszy przycisk na dole i następuje deploying aplikacji na serwer, po czym możemy otworzyć linka wyświetlającego webową wersję aplikacji Excel, która zawiera naszą aplikację.

365dev_05

A teraz niespodzianka… A co jeśli jednak wolimy Visual Studio, które daje trochę więcej możliwości? Naciskamy drugi przycisk, pobiera się nam potrzebny plik z naszym projektem, otwieramy go i mamy nasz projekt w Visual Studio 2012 RC! (mamy nieco mniejszy stopień abstrakcji - oprócz projektu webowego mamy też drugi projekt w C# lub VB.NET z manifestem). Ja używałem tej funkcjonalności, po wykonaniu czynności w końcowej części tego posta (instalacja odpowiednich rozszerzeń dla VS 2012), więc niewykluczone, że postępując w kolejności w jakiej to teraz opisuję, trzeba by więcej doinstalować…

365dev_06

Uruchamiam teraz projekt w trybie Debug, otwiera się nam automatycznie desktopowy Excel 2013, który zawiera w sobie naszą aplikację webową. Zgodnie z dokumentacją mogą pojawić się problemy z wyświetleniem aplikacji z uwagi na certyfikaty, które ja akurat miałem. Ale trzeba dać refresh w obszarze kontrolki webowej i potem wybrać czerwoną opcję, by otworzyć mimo niezalecania i wyświetli się nam wtedy nasza aplikacja, która wyglądem i zachowaniem nie różni się od tego, z czym mieliśmy doczynienia poprzednio na stronie webowej.

365dev_07

A może by tak bardziej tradycyjnie tworzyć aplikacje Office korzystając od początku z Visual Studio 2012?  Można i … tak. Należy doinstalować rozszerzenie Microsoft Office Developer Tools for Visual Studio 2012 (Web Platform Installer oprócz samego rozszerzenia zainstaluje wszystkie potrzebne składniki). Po instalacji w Visual Studio zostanie dodana masa szablonów dla Office 2013 w gałęziach Visual C# i Visual Basic. Oprócz kontynuacji projektów rozszerzeń z poprzednich wersji, znajdują się wśród nich także … projekty webowych aplikacji Office (w kategorii Apps nowe szablony App for Office 2013 i App for SharePoint 2013)

VS2012_off2013

Po wybraniu szablonu App for Office 2013 mogę uzyskać projekt, który … już dzisiaj utworzyliśmy korzystając z webowej aplikacji “Napa”. Tutaj dla odmiany prezentuję domyślną zawartość strony HTML.

VS2012_firstProj

Tak więc możemy wykorzystać HTML5 do pisania swoich rozszerzeń dla najnowszego Office. To kolejna pozycja po natywnych aplikacjach Windows 8 i aplikacjach hybrydowych PhoneGap nie mieszcząca się w pojęciu klasycznych aplikacji webowych…

środa, 18 lipca 2012

Office 365 Preview/2013 Preview na gorąco!

Nie mogłem się powstrzymać i zainstalowałem nowego Office 2013 zarówno w postaci tradycyjnego msi, jako 365, na Windows 7 i 8 (aby porównać), a także dodatkową aplikację dla Windows 8. Przejrzałem też bardziej dogłębne źródła wiedzy niż nagłówki popularnych portali internetowych… Ale po kolei.

Obejrzyjmy na początek oryginalne video z San Francisco, w którym zostają zademonstrowane w dość wyczerpujący sposób możliwości nowego Office. Po Ballmerze vice pokazuje na żywo cały Office na żywo w działaniu. Naprawdę warto!

Całość możemy zainstalować z tego miejsca. Wersja 32-bitowa jest polecana zarówno dla maszyn 32-bitowych, jak i … 64-bitowych. Wersja 64-bitowa też istnieje i dla obróbki dużych dokumentów wymagających dużo pamięci jest lepsza, ale może nie być zgodna z dotychczasowymi dodatkami. Instalacja z msi wydaje się taka … mało wyrazista, ot prosty instalator przypominający ten z Office 2010. W przypadku 365 po darmowej rejestracji na okres testów wersji rozwojowej z poziomu portalu istnieje możliwość instalacji oprogramowania na swoim komputerze (a dokładnie do 5 komputerów). Pobiera się niewielki plik, parę minut i już Office jest gotowy do działania (pewna synchronizacja nadal się wykonuje, ale możemy korzystać już z aplikacji). Instalacja ciekawiej wyglądająca, widać gdzie położono nacisk. Po instalacji nowy Office na komputerze wygląda tak samo niezależnie od sposobu instalacji (grupa aplikacji Office 2013), choć w Dodaj/Usuń Programy instalacja jest sygnowana innymi nazwami. Aha, w obu przypadkach potrzebujemy Windows 7 lub Windows 8. Są jednak oczywiście pewne różnice między instalacją z msi a Office 365 - instalacja 365 może działać obok starszych wersji. Odnośnie instalacji polecam wpis Installing the NEW Office 2013 Customer Preview - Step-by-Step.

Teraz to, co robi największe wrażenie (poza nowymi funkcjonalnościami w poszczególnych aplikacjach)

Interfejs Metro, dotyk, animacje

Jak wymyślono Metro dla aplikacji desktopowych? Czy są jakieś różnice między Windows 7 a Windows 8?

Czy można jeszcze jakoś na nowo wymyślić ekran startowy, okno otwierania i zapisywania plików, eksportu… Co by tu jeszcze zrobić z głównym menu w Office 2007/2010? Ha, można. Połączmy wszystko w jedną całość i nie upierajmy się … przy modalności naszego menu zamieniając go na stronę z klawiszem Back. W końcu twórcy Windows przestali się upierać przy menu Start zamieniając je na cały ekran… Czemu więc twórcy Office’a mieliby być gorsi?

W efekcie dostajemy ekran powitalny (w prawym górnym rogu mamy w tle rysunek, który można sobie wybrać podczas instalacji 365, mogę wyrazić swój nastrój przez emoticon, następuje integracja z moim kontem Microsoft)

Capture1

Ekran powitalny prowadzi nas do zmodernizowanej aplikacji z ribbonami

Capture2

Klikamy File i … przechodzimy na stronę, której zakładki odpowiadają pozycjom głównego menu z poprzednich wersji Office (wśród nich także …. zakładka New w 90% z naszym ekranem powitalnym). Zauważmy, że domyślnym miejscem zapisu jest chmura, ale można jeszcze wybrać sobie swój komputer… Przy wybieraniu konkretnego folderu wyskakuje niestety tradycyjne systemowe okno dialogowe dla zapisu/odczytu plików.

Capture3

Podobnie do Worda (btw - edytowanie plików PDF!) został zrealizowany Excel (btw - automatyczne wypełnianie kolumn na podstawie dwóch komórek), PowerPoint (btw - nowy widok dla prezentera, łatwa używanie multimediów z sieci np. Youtube), Publisher, OneNote (ten w pakiecie, jest też inny, ale o nim dalej), InfoPath (2 aplikacje), Access.

Odnośnie ekranów startowych to jest też tam taka efektowna kontrolka do nawigacji między szablonami i ich konfigurowania, np. w przypadku PowerPoint może to wyglądać następująco:

image

Outlook jest bardzo do nich podobny, ale przy starcie jest pokazywane okno do konfiguracji konta jak w 2010, a potem od razu otwiera się nam aplikacja z ribbonami (btw - kapitalne zebranie informacji kontaktowych dla adresata z możliwością zadzwonienia na Skype!, ActiveSync teraz nie tylko dla Exchange, ale także dla hotmaila i gmaila!, podgląd w popup do głównych zakładek, które teraz są na dole!)

Capture2

Na zakończenie ogólnych wrażeń z UI, uwaga że w bardzo wielu miejscach pojawiają się animacje przesunięcia np. przy zmianie czegoś z listy, zmiany strony. Te aplikacje naprawdę żyją!  Co do dotyku, to bardzo wiele można nim zrobić, działają gesty multi-touch np. pinch & stretch. Mamy pokaz, że dotyk może być przydatny także do bardziej złożonych aplikacji biznesowych, w co niektórzy jakiś czas temu powątpiewali! Nowy Office staje się wzorem dla nowoczesnych aplikacji biznesowych, które są gotowe na erę tabletów…

Czy są jakieś różnice między zachowaniem i wyglądem aplikacji Office w Windows 7 i Windows 8? Wyglądają dokładnie tak samo…

Prawdziwe aplikacje Metro i rewolucyjne menu dla aplikacji biznesowych

Specjalnie dla Windows 8 zostaną wydane obok ich desktopowych odpowiedników dwie prawdziwe aplikacje Metro - dla OneNote i Lync. Aplikacja Metro dla OneNote obecnie nazwana została jako OneNote MX (od Metro eXperience), ale docelowo MX ma zniknąć z jej nazwy. Była pokazywana w San Francisco, możemy ją też za free pobrać  z Windows Store dla Windows 8 Release Preview, co też uczyniłem. Należy zwrócić uwagę, że aplikacja ta posiada innowacyjne menu w kształcie koła, które pozwala dokonywać wyboru bardziej złożonych opcji i może … zastąpić ribbona! A więc jest to pomysł, jak osadzić w Metro aplikacje biznesowe, które do tej pory korzystały z ribbonów. Sam wygląd menu zmienia się w zależności od kontekstu, jeśli np. wybieramy kolor to wygląda jak niżej:

Untitled

Temat też dogłębnie opisał Paul Thurrott (człowiek od teorii spiskowych MS, z kubkiem kawy) na swoim blogu w poście Office 2013 Public Preview: Metro-Style OneNote. Zresztą napisał też kilkanaście innych świetnych postów o Office 2013, analizując zmiany w każdej aplikacji z osobna oraz poruszając dla nich wspólne tematy.

Chmura i synchronizacja

Tu krótko, ale dobitnie. Pomijając już nawet dominującą wersję 365 i jej instalację z chmury, to mamy naprawdę łatwą możliwość współdzielenia tych samych danych na wszystkich naszych komputerach, smartfonach i tabletach, a przestrzeń w chmurze jest domyślną lokalizacją dla zapisywanego dokumentu!. Pamiętane jest nawet ostatnio odwiedzane przez nas miejsce w danym dokumencie!

Społeczność i komunikacja

Chcemy zadzwonić do przyjaciela z maila na Skype?  Chcemy opublikować dokument jako post na blogu np. bloggerze? (po co ja jeszcze tego posta napisałem w Windows Live Writer?) Nic prostszego! Jest to wszystko standardowo wspierane, jak wiele innych rzeczy z social networking.

Na razie na tyle. Oczywiście to nie wszystko,  ale ogólnie mam nadzieję udało mi uchwycić to co chciałem.

wtorek, 10 lipca 2012

JsRender - odc.2

W tym odcinku zaawansowane możliwości biblioteki JsRender na podstawie artykułu Client Insight: Advanced JsRender Templating Features.

Pojedynczy obiekt z propercjami

Zamiast:

<div>{{:address.street1}}</div>

<div>{{:address.street2}}</div>

<div>{{:address.city}}, {{:address.state}} {{:address.postalCode}}</div>

Konstrukcja for (w tym przypadku przypomina with z niektórych języków)

{{for address}}

       <div>{{:street1}}</div>

       <div>{{:street2}}</div>

       <div>{{:city}}, {{:state}} {{:postalCode}}</div>

{{/for}}

Zewnętrzne szablony:

  1. renderTemplate = function (tmplName, targetSelector, data) {
  2. var file = formatTemplatePath(tmplName);
  3. $.get(file, null, function (template) {
  4. var tmpl = $.templates(template);
  5. var htmlString = tmpl.render(data);
  6. if (targetSelector) {
  7. $(targetSelector).html(htmlString);
  8. }
  9. return htmlString;
  10. });
  11. };

Szablony można definiować w postaci samego HTML z tagami JsRender albo zawierając w tagach <script>.

Specjalne ścieżki:

  • #view
  • #data
  • #parent
  • #index
  1. <div>{{:#data.section}}</div>
  2. <div>{{:#parent.parent.parent.parent.data.name}}</div>
  3. <div>{{:#view.data.section}}</div>

Wyrażenia:

+,  -,  *,  /,  ||,  &&,  !,  ?:, (), %, <=, >=, <,  >, ===, !==

Wspierana jest ewaluacja, ale nie przypisanie wyrażenia.

Własne tagi, helpery i konwertery

  1. {{myConverter:name}}
  2. {{myTag name}}
  3. {{:~myHelper(name)}}
  4. {{:~myParameter}}

Własny tag - np. własna kontrolka

{{:rating}}

{{createStars averageRating max=5/}} - lepiej tworzyć przy pomocy JS i CSS

  1. $.views.tags({
  2. createStars: function (rating) {
  3. var ratingArray = [], defaultMax = 5;
  4. var max = this.props.max || defaultMax;  //odwołanie do deklaratywnego property
  5. for (var i = 1; i <= max; i++) {
  6. ratingArray.push(i <= rating ?
  7. "rating fullStar" : "rating emptyStar");
  8. }
  9. var htmlString = "";
  10. if (this.tmpl) {
  11. // Use the content or the template passed in with the template property.
  12. htmlString = this. renderContent(ratingArray);
  13. } else {
  14. // Use the compiled named template.
  15. htmlString = $.render.compiledRatingTmpl(ratingArray);
  16. }
  17. return htmlString;
  18. }

Własne konwertery

<div class="text highlightText">{{priceAlert:salePrice}}</div>

<img src="{{ensureUrl:boxArt.smallUrl}}" class="rightAlign"/>

  1. $.views.converters({
  2. ensureUrl: function (value) {
  3. return (value ? value : "/images/icon-nocover.png");
  4. },
  5. priceAlert: function (value) {0
  6. return (value < 10 ? "1 Day Special!" : "Sale Price");
  7. }
  8. });

Konwertery są tutaj dedykowane dla bezparametrowej konwersji. W przypadku potrzeby przekazywania parametrów należy stosować helpery lub własne tagi.

Helpery

Dwa sposoby definiowania

  1. $.views.helpers({  //widoczne we wszystkich szablonach
  2. todaysPrices: { unitPrice: 23.40 },
  3. extPrice:function(unitPrice, qty){
  4. return unitPrice * qty;
  5. }
  6. });

Przekazanie jako opcje przy wywoływaniu metody render

  1. $.render.myTemplate( data, {
  2. todaysPrices: { unitPrice: 23.40 },
  3. extPrice:function(unitPrice, qty){
  4. return unitPrice * qty;
  5. }
  6. });

Odwoływanie się do helperów w szablonie

{{: ~extPrice(~todaysPrices.unitPrice, qty) }}

{{for ~getGuitars('acoustic')}} ... {{/for}}

Wiele parametrów

  1. $.views.helpers({
  2. concat:function concat() {
  3. return "".concat.apply( "", arguments );
  4. }
  5. })

Możliwość umieszczania kodu w bloku {{* }} (stosować w ostateczności, miesza warstwę prezentacji z logiką –Smutek)

  1. <script id="myTmpl" type="text/x-jsrender">
  2. <tr>
  3. <td>{{:name}}</td>
  4. <td>
  5. {{for languages}}
  6. {{:#data}}{{*
  7. if ( view.index === view.parent.data.length - 2 ) {
  8. }} and {{*
  9. } else if ( view.index < view.parent.data.length - 2 ) {
  10. }}, {{* } }}
  11. {{/for}}
  12. </td>
  13. </tr>
  14. </script>

Potrzebujemy ustawić opcję allowCode na wartość true (domyślnie jest false)

  1. $.templates("movieTmpl", {
  2. markup: "#myTmpl",
  3. allowCode: true
  4. });
  5. $("#movieRows").html(
  6. $.render.movieTmpl(my.vm.movies)
  7. );

Lepiej jednak logikę przenosić do helperów

niedziela, 8 lipca 2012

JsRender - odc.1

Tym razem jakieś spojrzenie na bibliotekę JsRender promowaną przez Johna Papę. Cechuje ją m.in bezkodowa składnia, brak zależności od jQuery i DOM, większa szybkość działania w porównaniu do szablonów jQuery, duża rozszerzalność - m.in wsparcie dla tworzenia własnych funkcji itd. Razem z biblioteką JsViews wydają się być lepszą alternatywą dla szablonów jQuery. Dostrzegł to m.in zespół jQuery UI…  Na początek trochę notatek sporządzonych na podstawie artykułu Client Insight: Using JsRender with JavaScript and HTML.

Przykładowy szablon:

  1. <script id="myMovieTemplate" type="text/x-jsrender ">
  2. <div>{{:#index+1}}: {{:name}} ({{:releaseYear}})</div>
  3. </script>

Renderowanie szablonu HTML w postaci <script> z id:

$("#movieContainer").html($("#myMovieTemplate").render(my.vm.movies));

Renderowanie ze stringa:

jsviews.templates({
movieTemplate: document.getElementById("myMovieTemplate").innerHTML
});
document.getElementById("movieContainerNojQuery").innerHTML
= jsviews.render.movieTemplate(my.vm.movies);

Popularne wyrażenia składniowe:

{{PropertyName}} - wartość property elementu z danymi
{{:movie.releaseYear}} - zagnieżdżona property
{{:movie.releaseYear < 2000}} - proste porównanie
{{:movie.name}} - wartość bez kodowania
{{>movie.name}} - wartość zakodowana w HTML
{{html:movie.name}} - wartość zakodowana w HTML
boxArt.smallUrl = boxArt['smallUrl']

JsRender wykrywa, czy przekazany parametr z danymi jest tablicą czy też nie.

Dane hierarchiczne:

iteracja po tablicy:

{{for cast}}

       <div>{{:stageName}}</div>

{{/for}}

bezpośrednie odwołanie się do data contextu:

{{for phone}}<div>{{:#data}}</div>{{/for}}

Wyrażenia warunkowe:

{{if boxArt.smallUrl}}

     <img src="{{:boxArt.smallUrl}}"/>

{{else}}

     <img src="../images/icon-nocover.png"/>

{{/if}}

 

{{if fullPrice !== salePrice}}

      <div class="text highlightText">

      PRICED TO SELL!</div>

{{/if}}

 

{{if qtyInStock >= 10}}

       In Stock

{{else qtyInStock}}

Only {{:qtyInStock}} left!

{{else}}

       Not available.

{{/if}}

Odwołania hierarchiczne do rodzicach, po indeksach:

    <img src="{{:#parent.parent.data[2].boxArt.smallUrl}}"/>

Używanie liczników i bardziej złożonych logicznych wyrażeń:

    {{for movies}}

    <div class="caption">

         {{:#index}}: {{:name}}

     </div>

    {{/for}}

Jednoczesna iteracja po więcej niż 1 tablicy:

{{for stars cast}}
      <div class="text">{{:name}}</div>
{{/for}}

Zagnieżdżanie szablonów - nazwy lub selectory jQuery:

{{for myArray tmpl="myTmpl"/}}


<ul>
         {{for movies
             tmpl="#movieTemplateMedium"/}}
</ul>

czwartek, 5 lipca 2012

Mobilne aplikacje webowe (przykład P&P)

Tym razem spojrzałem na koncepcję zawartą w Building Modern Mobile Web Apps. Jakieś ogólne wrażenia? Trzeźwy, miejscami wręcz smutny, produkcyjny realizm bez popadania w entuzjazm odnośnie najnowszych osiągnięć z HTML5 i CSS3. Co jest zrozumiałe, bo za cel postawiono sobie możliwość obsługi w jakimś stopniu jak największej liczby mobilnych urządzeń, także tych starszych, sprzed kilku lat… O ile zrobienie uniwersalnej webowej aplikacji wspierającej w miarę nowe standardy, wymaga pewnej rozwagi, o tyle zrobienie mobilnej aplikacji webowej wiąże się z parokrotnie większą złożonością zadania. Oprócz większych różnic i ograniczeń przy wspieraniu nowych standardów HTML5 i CSS3, dodatkowo dochodzą znane nie od dzisiaj przypadłości związane z urządzeniami mobilnymi tj. limitowany ilościowo dostęp do sieci, który może być wolny; mniejsza wydajność itp.  Tak więc nadal w wielu przypadkach nie wystarczy zmienić tylko layout i wygląd strony w CSS, by cieszyć się na danym urządzeniu szybką i odpowiednio wyglądającą stroną Web. Czasami trzeba zmienić pewne koncepcje, zrezygnować z części używanych bibliotek itp.

A teraz parę rzeczy, na które chciałem zwrócić uwagę.

W temacie pisania aplikacji mobilnych pojawia się często pytanie, czy pisać natywne czy może lepsza byłaby aplikacja webowa w HTML5. Jest na to oczywista odpowiedź, że jest to zależne od naszych wymagań, naszych możliwości i na jakim zbiorze urządzeń chcemy udostępniać nasze oprogramowanie. Wiadomo HTML5 jest najbardziej uniwersalny i tańszy niż dobre rozpoznawanie każdej z platform z osobna, ale strony webowe nadal nie mają dostępu do różnych funkcjonalności urządzeń, nie pozwalają na dokładnie taki sam user experience jak aplikacje natywne. Pewnym kompromisem między aplikacjami natywnymi a webowymi są aplikacje hybrydowe. Są to aplikacje natywne zawierające kontrolkę przeglądarki webowej, które zazwyczaj używają frameworków opakowujących w JavaScript część natywnej funkcjonalności (wiele urządzeń pozwala z poziomu kontrolki odwoływać się do natywnej aplikacji).

Device APIs Working Group - powstające standardy pozwalające stronom HTML korzystać z kolejnych funkcjonalności urządzeń

Frameworki do tworzenia międzyplatformowych rozwiązań

Bogaty, niezależny od platformy interfejs.

Przydatne preprocesory: LESS, Sass

We used the number input type to improve the user experience on supported browsers. Using this input type triggers a numeric keyboard on many touch browsers, and constrains keyboard input to numbers only on many QWERTY or T-9 devices.

We chose not to implement HTML5 form validation, as support for this feature on target browsers was poor and the specification insufficient for our particular needs. We also already had robust server-side data validation in place using ASP.NET.

We chose not to implement the HTML5 date input type, as support was inconsistent on our target browsers. We instead implemented the range feature using two select menus, each prepopulated with a month and date value.

It’s possible to detect support for this input type using a JavaScript feature test, but due to spotty implementation, a large number of devices return a false positive. These devices pass a feature test for the date input type, but only display a simple text input field.

Placeholdery: placeholder według W3C nie powinien być używany do danych liczbowych

Własne widgety wejścia - możliwe, ale najlepiej unikać

Obrazki

  • CSS Sprites
  • Umieszczanie zakodowanych obrazków w atrybutach data-* (przydatne narzędzia typu “data uri generator”)
  • SVG i Canvas - nadal różnie wspierane
  • Dostarczanie różnych wersji w zależności od gęstości pikseli

There will be no single, pixel-perfect reference version of the design. Each device (and browser) will render the design to the best of its capabilities.

The first benefit comes from a mobile-first approach to structuring your style sheets. Most smartphones now include a browser that supports CSS media queries, but users may be using an older device, or a low-cost feature phone. A mobile-first approach structures your CSS so that the smallest, and least capable device doesn’t receive the styles destined for more capable devices.

When developing an explicitly mobile experience, it’s a best practice to provide users with an easily discoverable link to the original desktop web app. This is useful for several reasons:

  • Mobile devices are typically small, so it’s not always possible to include the same content and features that were found in the desktop version. Users may therefore be looking for something quite specific from the original app and it’s important to provide them a means of accessing it.
  • Despite your best efforts, the mobile optimized version may not be suitable for a user’s device. It’s unlikely the (typically far heavier and more complex) desktop app will perform any better, but as mobile devices vary greatly in their capabilities, access to the desktop version may be useful to certain users.
  • Many explicitly mobile experiences are accessed using a subdomain or different URL (e.g. m.domain.com, domain.com/mobile). Users on blogs or social networks may share this URL and it’s therefore possible users will reach your mobile site accidentally after clicking such a link. Successfully detecting and rerouting these users may not always be possible, so it’s important to have this link in place.

Obsługa różnych przeglądarek i urządzeń

  • user-agent + korzystanie z baz danych o przeglądarkach po stronie serwera
  • wykrywanie funkcjonalności po stronie klienta

Remember as well that mobile devices have much slower CPUs and significantly less RAM than their desktop counterparts. You may therefore not be able to use a library in the same way as you would have on the desktop. Just because the library supports an animation, effect, or transition, doesn't mean it will make sense to use it in a production environment. This is particularly true of animations and transitions performed using JavaScript (as opposed to those using CSS).

Autorzy wybrali frameworki: mobilne jQuery, Mustache (lekkie templetowanie)

Single Page Application (SPA)

Single page applications have become very popular. As a consequence, there are many JavaScript frameworks and libraries that are specifically intended to support this pattern. In general, they are often referred to as "JavaScript MVC". Some popular frameworks at the time of writing are:

Those of you following the HTML5 specification may ask why we choose to use the hashchange event instead of the newer (and better) pushstate. Our reason was simply that some of our targeted devices did not support pushstate, whereas they all supported hashchange. There are libraries such as history.js that will attempt to use pushstate and fall back to hashchange only as necessary. However, we wanted to avoid taking another external dependency. In general though, using pushstate is preferred over using hashchange because it allows URLs to be consistent between SPAs and their more traditional counterparts.

The jqPlot library was not used in the Mileage Stats Mobile web app due to its size (more than 200KB minified and gzipped). Charting libraries such as flot and Flotr2 were also considered but were not utilized in Mileage Stats Mobile due to limited support across the set of target browsers. In order to provide a consistent and predictable solution to all target browsers, the server-side rendered chart technique was chosen.

wtorek, 3 lipca 2012

Architektura nowoczesnej aplikacji webowej (przykład P&P)

Przykładowa aplikacja Project Silk: Client-Side Web Development for Modern Browsers z witryny Patterns & Practises jest kolejną próbą praktycznego sformalizowania - po przyjęciu pewnych założeń - dość szerokiego terminu “aplikacja HTML5”.

Przykładowa aplikacja po wykonaniu wskazanych kroków oczywiście działa, a dokument ma przeszło 300 stron… Jego lektura po pewnym czasie staje się nieco nużąca, pewne rzeczy są dość oczywiste, pewne rzeczy moim zdaniem dość ogólnie, innym razem sporo szczegółów, co nie zawsze jest koniecznie przydatne do wytworzenia pewnej wizji na całość…, pewne rzeczy się powtarzają w myśl od ogółu do szczegółu, co czasami jednak wydawało się pewnym nadmiarem….  Ale do rzeczy, z tej całości wynotowałem parę sentencji, które prezentuję poniżej:

1. Kolejne upomnienie dla wszystkich tych, którzy myślą, że do otrzymania pełnej nowoczesnej aplikacji HTML5 wystarczy zamienić w dotychczasowych mocno serwerowych  aplikacjach tagi w HTML4 na tagi z HTML5… Super nie będzie, ale w sumie to też byłaby jakaś forma aplikacji w HTML5 (co dowodzi szerokości tego pojęcia).  Natomiast jak chcemy mówić o nowoczesnej aplikacji webowej, to musimy zmienić całościowe podejście, zacząć myśleć o bogatym kliencie, który wymienia się głównie samymi danymi ze stroną serwerową. Często objawia się to niewielką ilością pełnych przeładowań stron (podejście hybrydowe - część widoków przeładowywana lokalnie po stronie klienta zwykle związana z tą samą tematyką/modułem w ramach dużej aplikacji), a nawet mamy oficjalny wzorzec aplikacji jednostronicowej tzw. single-page interface (np. serwisy twitter, hot mail, office live, …). Co nam daje lokalne przeładowywanie widoków? Zyskamy na szybkości zmieniając poprzez wywołania AJAX tylko pewne obszary strony (nie ładujemy od nowa całej strony, przesyłamy zazwyczaj tylko dane zamiast całego HTML), co dodatkowo można zoptymalizować poprzez trzymanie części danych w lokalnym cache po stronie klienta (co jednocześnie odciąży serwer). Po drugie efekty przejścia - animacje i  tranzycje…, które napotkają na ograniczenia przy pełnym przeładowywaniu stron. Hola, hola, to po co jeszcze przyciski “back” i “next” w przeglądarce, po co złożone adresy? Nawigacji lokalnej nie wymyślono sobie od teraz, adresy z # do wskazanych obszarów tej samej strony już istnieją od jakiegoś dłuższego czasu.  Taki sposób adresowania z # został wykorzystany przez Silverlight do wspierania lokalnej nawigacji, która z powodzeniem integruje się z paskiem adresowym i historią przeglądarki, a Silverlight nie był tu pierwszy. API w bibliotekach JavaScript i w samym HTML5 nie jest tutaj gorsze, a nawet daje więcej możliwości…(więcej szczegółów w pkt. 4). Na zakończenie uwaga, że nawet najnowsze ASP.NET MVC można używać w diametralnie różny sposób. Można nadal po stronie serwera wykonywać większość zmian na widokach oraz je przeładowywać, ale można też zastosować nowoczesne, klienckie podejście i kontrolery wykorzystywać jedynie do zwracania samych danych. Nie popadajmy też zawsze w skrajności w skrajność, czasami umiejętne połączenie operacji po stronie serwera i klienta może być w pewnych sytuacjach bardziej optymalne (np. szablony HTML używane po stronie klienta mogą mieć pewne wstawki zmodyfikowane przez stronę serwerową; czasami lepiej jest pobrać z serwera jakiś fragment HTML niż budować go dynamicznie po stronie klienta itp).

2. Modularyzacja kodu po stronie klienckiej. Niewątpliwie jak chcemy zbudować porządną, łatwo zarządzalną i rozszerzalną aplikację, nie obejdziemy się bez tworzenia kodu JavaScript w postaci odseparowanych modułów. Jeśli chodzi o warstwę UI, wizualne elementy, autorzy postawili na tworzenie widgetów w jQuery UI, co jest jakby odpowiednikiem tworzenia kontrolek. Elementy logiczne niezwiązane z UI radzą zrealizować w ramach modularyzacji samego JavaScript. Mi osobiście zabrakło tutaj pokazu praktycznego zastosowania view modeli Knockout z data bindingiem… W Silverlight/WPF udało mi wypracować koncepcję polegającą na umiejętnym łączeniu podejścia MVVM z kontrolkami (czasami także własnymi) bez popadania w ortodoksję w jedną lub drugą stronę… Może i tutaj się mi się uda, ale nie za sprawą tej publikacji. Odnośnie kwestii modularyzacji samego JS autorzy wspominają także o Prototype i script.aculo.us, natomiast jako bardziej całościowe dla aplikacji wymieniają z nazwy takie frameworki jak sproutcore, yui czy dojo toolkit.

image

3. Tak naprawdę autorzy chcieli - przynajmniej w części zagadnień - “być dobrzy” dla jak największej liczby klientów, także dla tych, którzy… w swoich przeglądarkach mają wyłączoną obsługę JavaScript. W przypadku nawigacji przełożyło się to na generowanie linków po stronie serwera do tradycyjnej nawigacji z pełnym przeładowywaniem stron, natomiast po wykryciu obsługi JavaScript w przeglądarce zastępowanie serwerowej struktury lokalną. To zastępowanie dotyczy nie tylko nawigacji, ale też fragmentów HTML, akcji na przyciskach, klas CSS … W trybie z JavaScript oferujemy użytkownikowi animacje, tranzycje między stronami, wywołania AJAX … (tzw. podejście progressive enhancement - dodawanie funkcjonalności w zależności od możliwości przeglądarki). Dla dużych “światowych” witryn podejście z pewnością bardzo pożądane, ale w przypadku mniejszych projektów skierowanych dla określonych grup odbiorców, czy nie oznacza zbyt dużego nakładu pracy?  Wtedy każda wbudowana funkcjonalność w przeglądarkę wiąże się z … dodatkową pracą, bo nie dość, że normalnie coś obsługujemy, to implementujemy także alternatywne rozwiązanie, jakby tej funkcjonalności nie było.

4. W pkt.1 zapowiedziałem więcej szczegółów odnośnie zorganizowania lokalnej nawigacji w HTML5 i JavaScript. Autorzy proponują skorzystanie z plug-inu jQuery o nazwie BBQ, który jest odpowiedzialny za modyfikacje w adresie URL. Przekłada się to na obsługę deep-linking (parsowanie, mergowanie linków podczas ich tworzenia i aktualizowania, możliwość dynamicznej modyfikacji, metody: getState - zwraca obiekt z elementami klucz-wartość i pushState) oraz na integrację z historią przeglądarki. Samo API HTML5 też wspiera lokalną nawigację. Mamy tu m.in zdarzenie hashchange (obsługiwane np. w IE8 i IE9). BBQ wykorzystuje je, a dodatkowo radzi sobie także w przeglądarkach, które go nie obsługują. Przy tematyce samego HTML5 i nawigacji warto uczynić dygresję, że sam HTML5 dostarcza też API do zarządzania historią przeglądarki bez identyfikatora fragmentu (window.history - pushState i replaceState, wspierane np. w IE9)

5. Cachowanie danych autorzy realizują za pomocą swojego obiektu JS zamiast lokalnego storage w HTML5 i innych podobnych API, co pozwala im być bardziej cross-browser (np. obsłużyć IE7). Podobnie jak w pkt.3 swój punkt widzenia dla takiego podejścia uzależniam od rzeczywistej skali projektu.

6. W kwestii layoutu autorzy nie wchodzą bardzo w techniczne szczegóły, bardziej skupiają się na samych koncepcjach. Warto odnotować, że wspominają o dość popularnym 960 Grid System.

7. Walidacja JS po stronie klienta powinna być traktowana w kategorii udogodnienia, a nie zastąpienia walidacji po stronie serwera. Wymagają tego względy bezpieczeństwa.

8. Unit testy. O ile strona serwerowa z ASP.NET MVC wydaje się dość przewidywalna, o tyle warto wspomnieć o testowaniu warstwy klienckiej w JavaScript. Autorzy proponują skorzystanie z frameworka QUnit używanego przez samą bibliotekę jQuery.