Archive for Sviluppo Web

Uniface plugin?

Ho pubblicato sul sito di uniface.info il post che segue in questa pagina.
Qualcuno vuol dire la sua qui in italiano?

========== ========== ========== ========== ========== ==========
Hi Unifacers,

In the current IT world driven from integrations could it be of interest to the Uniface world to have a standardized mode to develop and deploy plugins to Uniface apps? IMHO…YES!

I do not remember this specific subject being discussed, but it could be I was not part of the discussion or I have simply forgotten about it!

Pro…? Cons…? Pitfalls…? Tips…? Suggestions…?

Let’s argue about it!
========== ========== ========== ========== ========== ==========

UNIFACE plugins

Definition: a uniface plugin could be a full application (launcher, monitor, configurator, …) or a part of an application (module, library, …) that can be used together or integrated within a Uniface application. Each plugin is dedicated to a single business or technical object. Base for each plugin should be a microservice architecture, extended with a re-susable presentation layer.  The word “plugin” is used to identify a software that can easily be re-used in any Uniface installation and configuration.

Perimeter (DRAFT) for a “whatever” plugin:
SelfContainedUARname: UP_XXXX_whatever_VVV where:
– XXXX is a unique identifier of plugin provider
– whatever is the concept implemented in the plugin
– VVV is the plugin version
each plugin provider is responsible to maintain plugin info updated
Mission: [short description (max 250 char) defining the plugin interface perimeter]
PluginVersion: x.y[.z]
UnifaceVersionsSupported: Ux.Uy[, Ux1.Uy1][, Ux2.Uy2]
ComponentsNames: XXXX_*
GlobalObjects: Each plugin component is connected to its library named XXXX_*
Objects being part of SYSTEM_LIBRARY should have their names starting with XXXX_*
$variation and $language MUST be saved and restored from ALL plugin interactions
Objects being part of USYS variation should have their names starting with XXXX_*
Security: None | ???TBD???
DBMS: None | XXXX_APPMODEL
UserInterface: None | Char | C/S | Web
LanguagesSupported: “USA” MUST be supported! Further list of international codes from ISO-639-3
ServicesPerimeter: None | Uniface | LAN | Internet
PrintingPerimeter: None | Uniface | OtherToBeSpecified
DataExchangePerimeter: InLine | LocalFolder | MailBox | OtherToBeSpecified
OperationsList: simpleListOfOperationsAvailableWithoutParams but a short description
PresentationComponents: simpleListOfPresentationComponents with attribute: Contained | Indipendent and a short description
OtherPluginPreRequisites: None | ListOfOtherPlugin(s)ThatMUSTbeAvailable
PluginOptionals: None | ListOfOtherOptionalPlugins
OtherTechPreRequisites: None | ListOfOtherTechPreRequisites
DeliveryMode: OpenSources | UARonly | withSourcesIfRequested
TechDocumentation: None | Samples | Included
Contact: eMailAddress

Let’s try with an example
(thanks to Theo Neskeens providing initial GoogleMap Integration sample):
SelfContainedUARname: UP_GSAN_GMAP_100
Mission: Interface to Google Map, Services and Presentations
Version: 1.0.0
UnifaceVersion: 9.7
ComponentsNames: GSAN_*
GlobalObjects: None
Security: None
DBMS: None
UserInterface: C/S
LanguagesSupported: ITA
ServicesPerimeter: Internet
PrintingPerimeter: Uniface, GSAN_UPDF plugin
DataExchangePerimeter: InLine
OperationsList:
GSAN_GMAP_SVC.getDistance() get distance in km between two GeoPoints|Addresses|POIs in an UIL
GSAN_GMAP_SVC.getPathFromTo() get traveling steps between two GeoPoints|Addresses|POIs in an UIL
GSAN_GMAP_SVC.getStaticMap() get static map related to a GeoPoint|Address|POI in an UIL
PresentationComponents:
GSAN_GMAP_MAP Contained form showing either static or dynamic maps
OtherPluginPreRequisites: None
– <strong>PluginOptionals: GSAN_UPDF: to interactively print map to PDF
– OtherTechPreRequisites: Google Developer Account must be setup
DeliveryMode: UARonly
TechDocumentation: Samples
Contact: name.surname@domain.ext

Simpler HowTo:
– Add reference to UP_GSAN_GMAP_100 UAR file to the [RESOURCES] section of your ASN file
– Use in your application activate “GSAN_GMAP_SVC”.getDistance() with documented parameters to get distance between two addresses.
========== ========== ========== ========== ========== ==========

Tuning applicativo

Chi ha esperienza nello sviluppo di applicazioni, soprattutto quelle gestionali, sa che spesso, dopo aver raggiunto l’obbiettivo iniziale di coprire gli aspetti funzionali indicati dalla fase di analisi, si rende prima o poi necessaria una fase di tuning applicativo.

Si cercano le possibili risposte alla domanda: come faccio a far fare alla mia applicazione le stesse cose che fa oggi ma più velocemente?
Si identificano i punti maggiormente critici e poi si procede…

In genere la tecnica chiave utilizzata è quella di evitare accessi ricorsivi al database lavorando su aree di memoria di processo opportunamente predisposte; alcuni giorni fa attuando su un caso specifico questa tecnica abbiamo sfruttato a fondo le liste Uniface associative (chiave=valore) con un metodo che potrebbe tornare utile in molte occasioni.

Si dovevano ottimizzare le funzionalità del ciclo attivo in una installazione gestionale che lavora su una anagrafica di circa 100.000 articoli; utilizzando il profiling applicativo, messo a disposizione da Uniface, abbiamo dapprima determinato che il punto critico in tutte le funzionalità del ciclo attivo era la determinazione di prezzo di vendita/sconti quantità, perché era costituita da un algoritmo multi-livello che doveva tenere in considerazione:
– listino standard
– listino tra quelli disponibili applicato al cliente
– campagne tra quelle disponibili applicabili al cliente
– promozioni tra quelle disponibili applicabili al cliente
– prezzi speciali ammessi per il cliente

A fronte di una ricerca articoli la determinazione di prezzo/sconti per quel cliente di ogni articolo al “momento” richiedeva con l’algoritmo multilivello circa 0.8 secondi. Non molto in valore assoluto ma un valore comunque impattante rispetto alla usabilità delle funzionalità del ciclo attivo in una schermata che presenta diversi articoli.

Abbiamo provato a trovare il miglioramento ricercato evitando di andare sul database per ogni articolo alla ricerca del prezzo da applicare ma cercandolo in memoria; la predisposizione della ricerca in memoria è stata fatta in questo modo:
1) Popolando all’ingresso della funzione applicativa una area di lavoro associata alla sessione applicativa (nel nostro caso NodoRete+IDprocesso)
2) Inserendo sull’area di lavoro TUTTI gli articoli che il cliente del momento può acquistare dal listino standard
3) Aggiornando gli articoli nell’area di lavoro per listino cliente, campagne, promozioni e prezzi speciali validi per il cliente del momento
4) Caricando in memoria il risultato finale ottenuto sull’area di lavoro: l’insieme completo degli articoli vendibili a quel cliente in quel momento comprensivi di prezzo e sconti quantità.
Questa parte di funzionalità è stata inserita all’inizio nella gestione offerte e nella gestione ordini clienti, subito dopo aver identificato il cliente, in modo da poter applicare tutte le regole del business necessarie per ogni specifico cliente; avviando le suddette funzioni applicative senza identificazione di un cliente specifico, viene caricato il contesto di vendita per un cliente generico, senza particolari facilitazioni economiche. Il caricamento in memoria richiede complessivamente da 3 ai 6 secondi (in funzione del cliente) all’avviamento della corrente funzione applicativa e utilizza in tutto solamente qualche MB (100.000 x 35bytes = 3,5 MB).

Come conviene costruire la matrice in memoria?
L’ideale sarebbe una lista associativa (chiave=valore) per poter sfruttare a fondo il linguaggio ProcScript disponibile in Uniface; per costruirla velocemente sono necessari due passaggi con il seguente snippet di codice:
– sql/data “select campo/iChiave,’=’,attributo/iNecessari from AreaDiLavoro where IDsessione=%%vSessione%%%”, “DEF”
– $$Matrice = $replace($result,1,”!;=!;”,”=”,-1) ; != è uguale a <GOLD>!<GOLD>;
Con queste due semplici istruzioni ci ritroveremo in memoria una lista Uniface di tipo associativo (chiave=valore) con un costrutto riconducibile al seguente:
ARTICOLO1=PREZZO1;SCONTO1.1;SCONTO1.2;SCONTO1.3
ARTICOLO2=PREZZO2;SCONTO2.1;SCONTO2.2;SCONTO2.3
avendo così la possibilità mediante il semplice utilizzo di quest’altra istruzione del ProcScript:
– attributiArticolo = $item(“ARTICOLO1”, $$Matrice)
di ritrovarci in attributiArticolo una lista posizionale contenente:
PREZZO1;SCONTO1.1;SCONTO1.2;SCONTO1.3
e potendo successivamente recuperare le singole componenti in modo posizionale:
– getitem vPrezzo, attributiArticolo, 1
– getitem vSconto1, attributiArticolo, 2
– getitem vSconto2, attributiArticolo, 3
– getitem vSconto3, attributiArticolo, 4
La risoluzione in memoria degli attributi di 1000 articoli random da una matrice che ne comprende 100.000 con copia del risultato ottenuto sulla MessageFrame di Uniface richiede solamente una ventina di centesimi di secondo: praticamente istantanea!

Il limite di questo approccio è ovviamente il fatto che NON è possibile aggiornare con un’altra sessione applicativa un singolo prezzo per il cliente del momento e vederlo utilizzato immediatamente; è necessario uscire e rientrare nella funzione che utilizza il metodo descritto per vedere aggiornati i prezzi utilizzati…ma è una approssimazione accettata nella quasi totalità delle aziende.

Chi volesse approfondire mi contatti a gianni.sandiglianoATunifacesolutions.com.

Gianni

Uniface e i Web Services, 1. parte – Generalità

Il W3C definisce un “web service” come “un modulo software disegnato per supportare l’interoperabilità e l’interazione tra macchine collegate in rete”.
I Web Services sono univocamente il fulcro delle possibili integrazioni tra ambienti applicativi eterogenei per piattaforma, sistema, linguaggio ma le tecnologie utilizzate si differenziano; negli anni aziende diverse, leader di mercato, hanno  sfortunatamente avuto idee diverse su quale potesse essere la soluzione ideale per garantire interoperabilità ed interazione in rete. Questo fatto ha generato sostanzialmente due tipi diversi di Web Services:
1 – basati sulla specifica SOAP
2 – in linea con i criteri REST
La specifica SOAP è di poco più anziana dei criteri REST (SOAP 1.0 del 1998, mentre 2000 Tesi di laurea di Roy Fielding per REST) ma mentre SOAP è stato adottato da subito su larga scala, REST ha ricevuto una notevole spinta solo negli ultimi anni, in base al suo ampio utilizzo dovuto alla semplicità dei criteri che lo caratterizzano, in linea con le tecnologie comunemente in uso. Va chiarito che REST NON è una specifica formale ma una serie di criteri oggetto di raccomandazione a supporto di una architettura software per la gestione di dati in ambiente ipertestuale.

Un minimo di approfondimento su entrambi i tipi di Web Services:
SOAP = acronimo per Simple Object Access Protocol: può operare su differenti protocolli di rete, ma HTTP è il più comunemente utilizzato per il trasporto, anzi è l’unico ad essere stato standardizzato dal W3C. La busta SOAP si basa su XML e la sua struttura segue la classica configurazione Head-Body, analoga ad HTML. Il segmento opzionale Header contiene meta-informazioni come quelle che riguardano il routing, la sicurezza, le transazioni e parametri per l’Orchestration. Il segmento obbligatorio Body trasporta il contenuto informativo che talora viene detto carico utile (payload). Questo deve seguire uno schema definito dal linguaggio “XML Schema”. SOAP può essere utilizzato in due modi diversi:
– il client controlla in un Service Registry l’oggetto d’interesse e sviluppa il messaggio secondo i parametri contenuti nel Service Registry.
– il client conosce a priori i parametri e non necessita di consultare il service registry. All’interno del body del messaggio si inseriscono i dati scritti nel formato concordato.

REST = acronimo per REpresentational State Transfer: Web services di tipo REST permettono di richiedere ad un sistema l’accesso a determinate risorse ricevendo in cambio una rappresentazione testuale delle medesime attraverso l’uso di un predefinito ed uniforme insieme di operazioni “stateless”. Le risorse sono identificate attraverso un URI (Uniform Resource Identifier) mentre le operazioni che si utilizzano sono quelle tipiche del protocollo HTTP (HTTP verbs): GET, POST, PUT, DELETE, OPTIONS. La rappresentazione testuale della risorsa ricevuta in risposta può essere strutturata in modi diversi, ad esempio: XML, HTML, JSON o addirittura semplice testo; JSON è il formato che più ha preso piede nel corso del tempo. Un sistema che voglia essere pienamente compatibile con una architettura REST dovrebbe comprendere ed implementare in modo rispettoso le seguenti caratteristiche:
– modello client-server: separazione netta delle competenze, client = interfaccia, server = accesso funzionale alle informazioni.
– dialogo di tipo stateless: ciascuna richiesta da un qualunque client contiene tutte le informazioni necessarie e lo stato della sessione è totalmente gestito lato client. Lo stato della sessione può essere trasferito al server e, se necessario, mantenuto persistente per il tempo necessario a gestire la transizione allo stato successivo.
– risposte cacheable: ogni tipo di dialogo web deve essere definito “cacheable” o “non cacheable”; i servizi REST dovrebbero sempre essere gestibili in cache dai nodi sui quali transitano.
– sistema a livelli: ogni client non deve riconoscere se è collegato al server vero e proprio o ad un suo intermediario; gli intermediari diversi possono essere implementati al fine di poterli  specializzare su funzioni diverse (sicurezza, gestione dei carichi e conseguente scalabilità, ecc)
– “code on demand”: alcuni server possono, anche su base temporanea, estendere, anche in modo specifico, le funzionalità di un client attraverso il trasferimento di codice eseguibile.
– interfaccia uniforme: è fondamentale nella definizione di qualsiasi insieme di servizi REST; dovrebbero SEMPRE essere soddisfatte le seguenti linee guida:
. Identificazione delle risorse: specifiche risorse sono identificate nella richiesta, per esempio utilizzando direttamente URI di riferimento. L’identificazione delle risorse da richiedere è concettualmente separata dalla loro rappresentazione restituita al richiedente. Ad esempio: il server può inviare informazioni dal suo database come HTML, XML o JSON, la cui struttura nulla ha a che vedere con quella interna del server.
.. Manipulazione delle risorse mediante la loro rappresentazione: quando un client riceve la reppresentazione di una risorsa, inclusi eventuali metadati, ottiene sufficienti informazioni per modificare o cancellare la risorsa.
… Messaggi auto-descrittivi: ciascun messaggio include sufficienti informazioni per permetterne la completa gestione del suo contenuto. Ad esempio: quale parser va invocato per riconoscere il contenuto potrebbe essere specificato con un “Internet media type” (conosciuto anche come MIME type).
…. Hypermedia come motore degli stati applicativi (HATEOAS): avendo avuto accesso una applicazione REST inizialmente a un URI, il client REST dovrebbe essere in grado di avere sufficenti informazioni, per essere in grado di utilizzare i (hyper)link ricevuti per accedere a tutte le ulteriori possibili azioni o risorse necessarie. Mano a mano che il dialogo tra server e client prosegue il server restituisce ulteriori (hyper)links che abilitano il client all’esplorazione dell’ecosistema applicativo disponibile sul server.

Entrambi i protocolli si basano su trasporto mediante HTTP ed entrambi sono correntemente supportati da Uniface:
– SOAP con il driver SOP: inizialmente in versione 1.0, ora in versione 2.0.
– REST sin da Uniface7 con la costruzione di componenti Web che restituiscono un contenuto coerente con i criteri elencati.
Nella seconda parte vedremo dei semplici esempi di come si implementano o come si fruisce di “web services” con Uniface con entrambi i protocolli.

Migliorare le applicazioni Uniface esistenti

Negli ultimi due mesi sono stato spesso coinvolto in attività di consulenza mirate a migliorare applicazioni Uniface esistenti.
Ci sono a tutt’oggi in produzione, sia a livello internazionale che in Italia, applicazioni Uniface 5, Uniface 6, Uniface 7, Uniface 8 e, ovviamente, Uniface 9.
L’ambiente di sviluppo si è ampiamente evoluto nei suoi 30+ anni di presenza sul mercato ed ancora oggi continua ad evolvere piuttosto rapidamente: la nuova versione Uniface 10 ne è l’immediata controprova.
Le nuove funzionalità, rese disponibili nel corso degli anni, vanno integrate nelle modalità di sviluppo originarie facendo attenzione a mantenere l’integrità funzionale dell’applicazione originale.

Nella prima fase di queste attività si esplorano gli “Standard & Guidelines” adottati nello sviluppo dell’applicazione, che nella terminologia corrente vengono denominati “Framework di sviluppo”.
Analizzando il modo con cui l’applicazione è stata sviluppata si possono tracciare le linee di potenziale miglioramento, che ricadono in 6 possibili passi:

  1. Da “Stacked forms” char a “Stacked forms” GUI
    2. Da “Stacked forms” GUI a “NonModal forms” GUI
    3. Su “NonModal forms” GUI inclusione di una API applicativa
    4. Da “NonModal forms” GUI a “Web 2.0 pages”
    5. Da “Web 2.0 pages” a “Mobile pages”
    6. Da “Mobile pages” a “Fully partitionable application”

Lo sforzo necessario per ammodernare un applicazione è ovviamente funzione del punto di partenza e del punto di arrivo selezionato. Conviene definire tre obbiettivi: uno a breve, uno a medio ed uno a lungo termine; in questo modo risulta in genere possibile miscelare la quotidiana attività di manutenzione evolutiva dell’applicazione con gli obbiettivi di miglioramento aziendali rilasciando progressivamente le novità sviluppate sul proprio mercato di riferimento.

Chi volesse approfondire l’argomento mi contatti: gianni.sandiglianoATunifacesolutions.com

Uniface 10 Enterprise Edition, disponibile!

Il mese di settembre 2016 verrà ricordato come quello in cui è stato rilasciato Uniface 10 Enterprise Edition.

EccoVi la schermata iniziale con cui si presenta il nuovo ambiente di sviluppo:
schermatainizialeu10-2

Sono talmente tante le novità che risulta impossibile elencarle sinteticamente!

Chi vuole avere ulteriori informazioni mi contatti: gianni.sandiglianoATunifacesolutions.com

Installazione di Uniface – Problemi con Uniface Tomcat?

Installando Uniface in ambiente Windows vengono configurati alcuni servizi all’interno del sistema operativo in modo che l’ambiente Uniface si avvi automaticamente all’avvio del sistema stesso.

Fino alla versione U9.6 i servizi Windows configurati sono stati 3:
– Uniface URouter
– Uniface Tomcat
– Uniface SolidDB
A partire dalla versione U9.7 si riducono a 2 essendo SolidDB stato sostituito da SqlLite come DBMS di default di ogni installazione.

Durante il processo di installazione vengono richiesti i vari parametri che contribuiscono all’installazione dei vari servizi. Eventuali problemi di installazione di URouter o di SolidDB, ad esempio una sovrapposizione della porta TCP in ascolto con altri software o con altre versioni di Uniface, possono essere facilmente individuati e debuggati analizzando i relativi log files.

Un poco più complessa è la configurazione di Tomcat, costituita dalle varie variabili di ambiente necessarie a questo software che svolge funzione di “application server”. Può capitare che l’installazione di Tomcat si sovrapponga ad altri software installati utilizzanti anch’essi questo “application server” piuttosto diffuso.
Come si fa a verificarla ed eventualmente modificarla dopo l’installazione?

Per prima cosa bisogna procurarsi la stringa di comando per l’avvio del servizio Uniface Tomcat definita all’atto dell’installazione di Uniface. Per fare questo è sufficiente dalla Microsoft Management Console dedicata ai servizi del sistema operativo accedere alle proprietà del servizio incriminato. Vi troverete dinnanzi ad un formato simile a questo:

<DISK:><PATH>tomcat8.exe //RS//<YourServiceID>

Copiate l’intera riga di comando e incollatela in una finestra di “prompt dei comandi”, modificandola in questo modo:

<DISK:><PATH>tomcat8W.exe //ES//<YourServiceID>

Le modifiche apportate sono 2:
– Aggiunta del carattere W al termine del nome dell’eseguibile prima del punto separatore dell’extension, per puntare ad un altro eseguibile disponibile nell’installazione di Tomcat.
– Nel primo parametro modifica di //RS// (che significa Run Service) con //ES// (che significa Edit Service)

Eseguite il vostro comando e vi troverete in una finestra che vi permetterà di modificare i parametri del vostro servizio Uniface Tomcat.

Per chi fosse interessato ad un approfondimento sul tema, consiglio la lettura della pagina: https://tomcat.apache.org/tomcat-8.0-doc/windows-service-howto.html

Buona lettura!

Da “Standard & Guidelines” a “Framework”

L’argomento che si dibatte più frequentemente in questi ultimi anni durante le attività su Uniface è quello che definisce il titolo di questo articolo: stabilire i metodi / criteri di sviluppo per riscrivere od estendere le proprie applicazioni al mondo Web/Mobile.

Più che un articolo che fornisce una soluzione ideale vuole essere l’inizio di una riflessione su quale sia il metodo scelto, ed eventualmente applicato, per:
– migrare una applicazione client/server esistente a 3 livelli
– sviluppare estensioni a 3 livelli per una applicazione client/server esistente

Nell’ambito della classica architettura applicativa a 3 livelli DATI -> SERVIZI -> (API) -> PRESENTAZIONE risulta in particolare sempre un poco ostica la decisione di quale/i componente/i di programmazione della presentazione lato browser (MV*) includere nel proprio framework per via della molteplicità di proposte e di scelte offerte dal mercato. Potete dare un’occhiata al sito http://todomvc.com per comprendere cosa si intenda per “molteplicità”.

Le proposte disponibili sul mercato vanno sostanzialmente suddivise in due gruppi:
– Framework server-side
– Framework client-side
e la decisione sulla strada da seguire per perseguire gli obbiettivi che l’applicazione si propone di affrontare e risolvere non sempre risulta immediata. In molti casi un ragionevole equilibrio tra le funzionalità svolte dal server e quelle attuate dal client è necessario ma non sempre è immediata la linea di demarcazione tra i due fronti in quanto molto (se non tutto!) dipende dalle funzionalità che si devono sviluppare. L’ideale sarebbe sviluppare applicazioni utilizzando un framework che sia in grado di lavorare su entrambi i fronti (Vedere http://isomorphic.net).

La difficoltà legata alla molteplicità di scelte tecnologiche disponibili va in genere a braccetto con l’esigenza di mantenere il miglior grado di indipendenza dai browser disponibili sulle varie piattaforme, utilizzate dagli utenti; alcune di queste accoppiate browser/piattaforma fanno parte del mondo mobile, per cui si portano appresso esigenze specifiche a livello di presentazione e richiedono di conseguenza un approccio, perlomeno in parte, dedicato. Quando questo approccio dedicato diventa prioritario nel panorama complessivo si parla di “Mobile First Framework”.

Le scelte che ho riscontrato essere maggiormente utilizzate ad oggi sono:
– Bootstrap + jQuery
– AngularJS
– ReactJS
– Custom / Personalizzato (della serie “uso quello che mi serve quando mi serve!”)

Ringrazio anticipatamente chi volesse aggiungere un contributo o una riflessione.

Sviluppo applicazioni Web – Mobile

Con il rilascio della versione 9.7.02 si è aperta la possibilità di sviluppare e rilasciare applicazioni mobile con Uniface.

Lo sviluppo con Uniface di applicazioni mobile presuppone conoscenza nello sviluppo di applicazioni Web con integrazione delle tecnologie che stanno alla base del web 2.0 (HTML5 / CSS3 / Javascript) nel contesto delle DSP (Dynamic Server Pages), la cosiddetta “programmazione lato browser”.

Al fine di permettere agli sviluppatori Uniface Desktop (Client/server) di approcciare lo sviluppo web/mobile DA ZERO gli ULab hanno rilasciato sul canale YouTube dedicato a Uniface una serie di filmati che sono raccolti in un articolo introduttivo disponibile su uniface.info alla pagina:

http://unifaceinfo.com/html5-javascript-css3-training-videos-uniface-developers-uniface-info/

I brevi filmati chiariscono alcuni punti fermi dello sviluppo Web/Mobile, dando un compito specifico ad ognuna delle tecnologie di base coinvolte nella programmazione lato browser:

  1. HTML5: gives a meaning to data.
  2. CSS3: styles elements presented on screen, paper, or other media.
  3. Javascript: a scripting language to enable interactive sites.

Nell’ambito dei filmati viene fatto riferimento ad un paio di siti di supporto:
1) http://caniuse.com che costituisce uno dei principali riferimenti per conoscere il livello di supporto, e di conseguenza la portabilità, di una specifica funzionalità della programmazione lato browser.
2) http://css3generator.com che permette un approccio semplificato a quelle direttive CSS3 che dovessero essere differenziate e/o moltiplicate nella loro sintassi per ottenere una effettiva portabilità attraverso i vari browser e le loro versioni.

Un’ultima avvertenza, consiglio la visione dei filmati in quest’ordine:
1) HTML5
2) CSS3
3) Javascript

Buona visione!