Przetwarzanie mowy na tekst za pomocą Web Speech API


26 października 2020 / Michał Kortas


Zaciekawiły mnie możliwości, jakie daje Web Speech API. Ostatnio napisałem o przetwarzaniu mowy na tekst, więc naturalnym kierunkiem będzie sprawdzenie odwrotności tego procesu – przetwarzanie tekstu na mowę. Niestety, jeśli chodzi o kompatybilność, realnie działa to jedynie na stacjonarnym i mobilnym Google Chrome, oraz jeszcze na kilku innych, egzotycznych przeglądarkach. Być może niedługo interfejs będzie wspierany również w Microsoftowym Edgu. Jednak na razie pozostaje nam uzbroić się w cierpliwość i czekać na ruchy pozostałych dostawców. Continue reading Przetwarzanie mowy na tekst za pomocą Web Speech API


Tagi:


Web Speech API – nawigacja na stronie z audiodeskrypcją


19 października 2020 / Michał Kortas


Zaprzyjaźniałem się ostatnio z możliwościami Web Speech API przy okazji tworzenia nawigacji po aplikacji webowej. Konieczna była funkcjonalność odczytująca opisy aktywnych elementów. Posłużyłem się w tym celu interfejsem SpeechSynthesis, który jest już obecnie dość dobrze wspierany przez wiodące przeglądarki. Przyjąłem, że powinienem brać pod uwagę te elementy, które posiadają niepsute atrybuty aria-label, aria-labelledby lub aria-describedby. Dodatkowo chciałem, aby obsługiwane były również formularze i ich etykiety. Continue reading Web Speech API – nawigacja na stronie z audiodeskrypcją


Tagi:


Przegląd ECMAScript 6


25 lutego 2015 / Michał Załęcki


ECMAScript 6 jest nową choć nie najnowszą (ECMAScript 7), wersją standardu ECMAScript i bazuje na ECMAScript 5.1 z 2009 r.

Od lipca 2014, ES6 nie jest poszerzany o nowe funkcjonalności. Po procesie publikacji, który rozpocznie się w marcu 2015, ES6 będzie ukończony w czerwcu 2015.

Obecnie nie ma dobrych powodów, dla których nie mielibyśmy zacząć używać ES6 już dziś. Jest to możliwe dzięki takim narzędziom jak Traceur od Google czy Babel (6to5.js). Continue reading Przegląd ECMAScript 6



Web Components – artykuł konkursowy


14 sierpnia 2014 / Comandeer


Web ComponentsWakacje! Słońce, wysoka temperatura, półnagie kobiety na plaży… Meh. To najlepszy czas, żeby zaszyć się w swojej jaskinii programisty i wyhodować jakiegoś kodowego potworka. BUHAHAHAHA!

A ci z nas, którzy nie cierpią na ostre postacie agorafobii, z chęcią lubią prezentować innym efekty swej syzyfowej pracy. Ja również należę do tych ekshibicjonistów, dlatego też postanowiłem pochwalić się ideą (ok, istnieje coś w wersji mocno prealpha, aczkolwiek używalnej ;)) rodzącą się w bólach w mym umyśle. Ale od początku!

Na początku było Słowo…

…a kilkaset milionów lat później inteligentny zlepek komórek stworzył coś, co buńczucznie nazwał HTML-em. Dzięki temu wynalazkowi dzisiaj możemy oglądać słodkie kotki! Jest on także sponsorem dzisiejszego artykułu.

Któż nie zna tego wręcz prymitywnego w swej budowie języka znaczników? Wszyscy mamy z nim do czynienia na co dzień – wszak to język, w którym do nas przemawia Sieć. Lecz czy kiedykolwiek zastanawialiście się jaka to magia kryje się za tymi niepozornymi <tagami>. Na pewno nie! No bo cóż w tym takiego magicznego?

A jeśli powiem, że w tym prostym języku tkwi niesamowity potencjał, który może odmienić oblicze Sieci, naszej Sieci? „Oszalał, chce powrotu XHTML 2!” – zakrzyknie co bardziej rozgarnięty czytelnik. Sam bym za takie myśli dał sobie w pysk jakieś 2 lata temu… Ale o tamtego czasu zmieniło się bardzo dużo, by nie powiedzieć: wszystko!

Declaratives, declaratives everywhere!

Declaratives, Declaratives Everywhere

Nie oszukujmy się: HTML nie powstał jako język dla zaawansowanych aplikacji. To język dla dokumentów – header nie ma nic wspólnego z titlebarem aplikacji a [data-action] nie są w stanie zastąpić sensownego data binding. Nic zatem dziwnego, że powstały całe potężne frameworki JS mające te braki naprawić: poczynając od standardowego, tradycyjnego i lekko trącego dziś myszką jQuery UI, przechodząc obok potężnego i nielubianego przeze mnie, przerośniętego ext.js na najnowszym dziecku Google, Angularze ze swoim sytemem modułów i nie do końca walidującym się HTML-em, kończąc. Żeby zrobić proste okienko z komunikatem (ok, w HTML 5 mamy dialog, który działa aż w Chrome 37+) ładujemy tonę JS-a, zamiast… umieścić odpowiedni kod HTML na stronie. Powiedzcie sami – czy nie ładniej zamiast

użyć po prostu:

Nie jest to jakiś nowy pomysł – w HTML de facto od zarania dziejów (tzn od powstania JS ;)) takie rzeczy istnieją. Najlepszym przykładem tego jest new Image, który równocześnie jest konstruktorem dla elementu img (a raczej – każdy tag img na stronie jest równocześnie obiektem Image w JS) czy też new Audio i tag audio. Oto mamy mały i poręczny element HTML, pod którym kryje się potężne JS-owe API. Jak bardzo jest to myślenie naturalne, wskazują dzieje Event Source API (aka Server Sent Events): jego pierwszą wersją był… tag eventsource, który nawet doczekał się implementacji w jednej z wersji Opery.

Ci, którzy znają XML, są całkowicie przyzwyczajeni do własnych tagów. W HTML jednak przez długie lata taka rzecz była niedostępna. Owszem, na upartego można było stworzyć sobie nowy tag, typu comandeertoboss, ale na tym nasze możliwości się kończyły. Nie było żadnego sensownego sposobu na stworzenie zależności, jak w parze new Imageimg. Co więcej, niektóre przeglądarki (tak, na ciebie patrzę, IE; na ciebie również, stary lisku) miały dziwne problemy ze stylowaniem tych elementów (IE potrzebował czegoś na kształt HTML5 shiv a lisek… serwowania jako XHTML). O problemach w DOM już nawet nie wspominam. Nie dało się i już. „Semantyczny” kod (tzn. taki, który po prostu dałoby się czytać) trzeba było osiągać na inne sposoby – tutaj ważne role pełniły (i wciąż pełnią!) mikroformaty oraz architektura BEM. XML-owy raj (gosh…) własnych znaczników był poza zasięgiem webdeveloperów. Do czasu…

Web Components are coming!

Choć aplikacje internetowe różnią się diametralnie od siebie (FB nijak się ma do Muro), pod maską tak naprawdę niewiele się różnią. Wszystkie stosują potężne frameworki JS do tworzenia interfejsów użytkownika. Takie rozwiązanie musi:

  • Udostępniać sensowny sposób tworzenia nowych elementów GUI
  • Posiadać system szablonów
  • Umożliwiać całkowitą enkapsulację (interfejs ma brać dane i tyle – co leży pod spodem, powinno być ukryte)
  • Być reużywalne (czyli można je zaimportować na każdej stronie WWW, która tego potrzebuje)
  • Posiadać system 2-way data binding lub posiadać sensowny sposób informowania o zmianach (system eventów/pub-sub)

Tylko patrząc na tą listę, każdy logicznie myślący człowiek widzi, że problemy te można rozwiązać na wiele różnych sposobów (stąd tak niesamowita liczba dostępnych frameworków JS). A jeśli powiem, że obecnie istnieje natywny mechanizm, który rozwiązuje te wszystkie problemy?

Uśmiechasz się ironicznie, prawda? Nie wierzysz mi a to już działa (tzn nie do końca, ale o tym później) i nazywa się „Web Components”. Jak sama nazwa wskazuje, składa się to z kilku elementów:

  • Custom elements – czyli sensowny sposób tworzenia nowych elementów GUI
  • Tag template – czyli sensowny system szablonów
  • Shadow DOM – czyli całkowita enkapsulacja
  • link[rel=import] – czyli całkowita reużywalność
  • Custom events – czyli sensowny sposób informowania o zmianach
  • Object.observe/DOM Mutation Observer – czyli 2-way data binding

Brzmi tak pięknie, że aż musi być haczyk, prawda? Otóż… jest, taki jak zawsze w naszym dobrym, starym webdevelopingu: kompatybilność, którą na bieżąco można sprawdzić na stronie Are We Componentized Yet?. Ale jak to zwykle bywa, istnieją polyfille. Najpopularniejsze to Polymer (którego używam i który jest o wiele bardziej rozbudowany i oprócz wspomnianych wyżej rzeczy dostajemy w prezencie Pointer Events; „minusem” jest brak wsparcia dla IE9-, ale patrząc na ranking.pl to wcale nie jest minus ;)) i X-Tags (mniej rozbudowany, skupiający się przede wszystkim na custom elements, ale za to dostajemy obsługę dla IE9+). Natywnie wszystkie te rzeczy, jak widać, działają sensownie jedynie w Chrome 36+ (no i w Operze ;)), natomiast Firefox zostaje ciut z tyłu; Safari i IE przemilczę.

Skoro już wiemy co i gdzie (nie) działa, przyjrzyjmy się bliżej wszystkim tym elementom po kolei (nie liczcie na duży tutorial – nie chce mi się ;) poza tym napisano już doskonałe – oczywiście po angielsku – do których linki podam na końcu; ten artykuł potraktujcie jako dobry overview całej technologii).

Custom elements

To najczęściej wykorzystywany element (pun intented) Web Components i ich znak rozpoznawczy. Bez tego elementu (pun not intented) cała reszta nie ma żadnego sensu. Zatem w skrócie: tak, możesz tworzyć własne elementy HTML!

I zanim polecisz tworzyć comandeertoboss, wiadro zimnej wody na ochłodę: to nie jest aż tak proste! Custom element wygląda bowiem ciut inaczej niż zwykły element:

Jak widać, nazwa składa się z dwóch części, przedzielonych myślnikiem. Ten myślnik jest konieczny. Dlaczego? Gdyż przeglądarka inaczej traktuje elementy bez niego i z nim. Bez myślnika przeglądarka po prostu uznaje to za nieznany, niepoprawny element… i na tym się kończy. Natomiast gdy w nazwie myślnik występuje, przeglądarka zaznacza sobie ten element jako „prawdopodobnie custom element”.

„Do rzeczy – my chcemy pełnoprawnego custom elementa!” – zakrzykną webdeveloperzy, nielegalnie czytający ten artykuł w pracy. A więc – żeby przeglądarka rozpoznawała nasz tag jako… nasz tag ;) należy użyć funkcji document.registerElement:

Pozwoliłem sobie zapisać wynik funkcji do globalnego konstruktora TagName (dzięki temu mamy swój własny new Image – yay!). Jak widać, document.registerElement bierze jako 2. paremetr obiekt opcji, a w nim – prototyp naszego elementu. Tutaj ważne jest to, żeby obiekt TagNamePrototype dziedziczył po HTMLElement (albo jego pochodnych). Drugą opcją, obok prototype, jest extends – dzięki temu można rozszerzać już istniejące elementy; używa się ich jednak ciut inaczej:

Bardziej doświadczeni czytelnicy na pewno od razu zapytają czemu jest bezsensowny myślnik, skoro można to było rozwiązać za pomocą XML namespaces? Otóż: XML jest martwy ;) XHTML się nigdy nie przyjął, zatem naturalnym ruchem było wykorzystanie o wiele prostszego sposobu i to kompatybilnego ze starym HTML (tzw. bożek Backwards Compatibility).

W Sieci można znaleźć pełno custom elements, od bezsensownych po całkiem użyteczne.

template

Każda większa aplikacja webowa korzysta z systemu szablonów – nic w tym dziwnego. Jeśli kilka różnych części GUI korzysta z tego samego rozwiązania, to można to wyrzucić do szablonu i jedynie podmieniać odpowiednie dane. Dotąd, z powodu ograniczeń JS, przeważająca część systemów szablonów client-side operowała na stringach. template przenosi szablony na poziom DOM. To tak naprawdę nic innego, jak osobne drzewko DOM na naszej stronie. Co więcej – całkowicie nieaktywne. Nie musimy się martwić o to, że obrazki doczytają się bez potrzeby – zawartość  template uaktywnia się dopiero po umieszczeniu wewnątrz strony. Do tego czasu wszystko w nim pozostaje nienaruszone. A jak szablonów używać?

Mogłoby być prostsze, ale i tak nie jest źle. A mamy za to natywny system szablonów!

Shadow DOM

Kto wie jak wygląda drzewko DOM dla elementu input? Pewnie większość z Was popuka się w czoło i stwierdzi, że zwariowałem – jakie drzewko? A to już Wam pokazuję jakie (wyciągnięte z Chrome):

Zszokowani? I właśnie o to chodzi! My, jako userzy, widzimy tylko efekt końcowy – pole formularza. Cała reszta siedzi pod spodem i jest obsługiwana przez przeglądarkę. Polecam spojrzeć jak bardzo złożony pod spodem jest np tag video (na pewno ma więcej kodu niż aplikacje niejednego z nas ;)). I to jest właśnie Shadow DOM – magiczny worek, ukrywający całą implementację pod ładnie wyglądającym tagiem. Do niedawna taką moc mieli jedynie twórcy przeglądarek. Jednak Shadow DOM zostało ustandaryzowane (prawie – to najczęściej zmieniająca się specyfikacja W3C ;)) i obecnie każdy z nas może tworzyć rzeczy podobne do pola input. Jak?

Tym sposobem stworzyliśmy akapit z niewidzialnym tekstem (sympatyczny kod? ;)) – nie ma go w źródle strony a inspektor elementów też niekoniecznie go pokazuje (dopóki nie zaznaczym odpowiedniej opcji w dev-tools). Oczywiście nic nie stoi na przeszkodzie, żeby włożyć tam coś bardziej skomplikowanego (Shadow DOM bardzo lubi tag template ;)) czy nawet… kolejne cieniste drzewko (because we always must be able to go deeper…).

Zalety? Całkowita enkapsulacja! Co więcej – Shadow DOM można podpiąć pod accessibility API (czyli czytniki ekranowe to widzą) i wykorzystywać na nim ARIA. Niemniej jest to sposób na rozdzielenie prezentacji naszego custom elementu od jego treści – treść podajemy normalnie w tagu (jak zawsze), natomiast cały sposób prezentacji zamykamy w Shadow DOM (a obsługa treści w Shadow DOM jest banalna, bo wystarczy w odpowiednim miejscu wstawić tag content). Proste i skuteczne.

Największa przewaga GUI w JS nad GUI w HTML? Możliwość importu tylko tych rzeczy, których potrzebujemy, w prosty, asynchroniczny i przyjemny sposób (patrz: AMD, CJS, UMD, ES6 Modules). W HTML takiej możliwości nie było… do niedawna. Od niedawna „moduły HTML” są jeszcze prostsze do wykorzystania niźli moduły JS (i mówi Wam to wielki fanatyk JS-a!). Wyobraźmy sobie, że stworzyliśmy super wypasiony custom element, z Shadow DOM, szablonami i całym potężnym API… I mamy problem: jak go załączać na wszystkich naszych stronach? 1. myśl – inline’ujemy – odpada w przedbiegach: 1000 linijek HTML-a to jednak nie to, co tygryski lubią najbardziej. 2. myśl – AJAX i wkładanie odpowiednich zasobów w odpowiednie miejsca. Działa a my mamy asynchroniczny lazy loading… Niemniej wymaga to ciut pracy i nie zawsze musi działać.

Zatem jesteśmy pokonani? Oczywiście, że nie! Z pomocą nadchodzi link[rel=import]! Pozwala on wydzielić z naszego kodu „moduł HTML” (zatem custom element oraz to wszystko, czego potrzebuje do działania) i dołączać go do wszystkich innych dokumentów (skoro nasze API przepisaliśmy na tag, to czemu nie mamy załączać go dzięki tagowi?). Wyobraźmy sobie kod naszego wypasionego custom elementu:

Po pewnym czasie może się to bardzo rozrosnąć… Dlatego wystarczy cały ten kod przerzucić do osobnego pliku .html i importować:

I tyle! Do całej zawartości zaimportowanego pliku dostaniemy się przez własność import owego link[rel=import] (tak, jak w przypadku template, tutaj również otrzymamy drzewko DOM). Tym prostym sposobem stworzyliśmy nasz 1. „moduł HTML”. Czekam z niecierpliwością kiedy Facebook i inne portale będą tak udostępniać swoje widgety.

Custom events

Każdy szanujący się custom element powinien rzucać jakieś zdarzenia. A czy jest jakiś lepszy sposób od użycia tutaj custom events?

Jak widać, można nadać zdarzeniu dowolną nazwę. Jedynym ograniczeniem jest to, że wszystkie dodatkowe dane zdarzenia są przekazywane jako event.detail. Niemniej jest to potężny DOM-owy element, pozwalający kontrolować działanie elementu (no przecież każdy z nas doskonale to wie! :D).

Object.observe/DOM Mutation Observer

Data binding w JS? Object.observe – służy do obserwowania zmian zachodzących w danym obiekcie JS i w chwili jakiejkolwiek zmiany, wykonuje daną czynność.

Coś pięknego prawda? Jeśli chodzi o same DOM, tutaj tę rolę pełni Mutation Observer, którego używanie już tak przyjemne nie jest, dlatego odeślę zainteresowanych do MDN ;)

Co prawda same te mechanizmy nie tworzą nam 2-way data binding out of box, ale wystarczy kilka minut, żeby takie rozwiązanie na ich podstawie przygotować. Jeśli chodzi o ES5 – tutaj można się ładnie pobawić przy pomocy getterów/setterów i eventów, by uzyskać podobne rozwiązanie.

Co dalej?

Jaki obecnie jest najlepszy sposób na tworzenie własnych custom elements? Użycie custom elementu polymer-element!

Chyba żartujesz?

Wszystkich zainteresowanych tym rozwiązaniem zapraszam do zapoznania się z projektem untitled-element, który jest bardzo ciekawym wrapperem dla polymer-element, generującym automatycznie dokumentację dla naszego custom elementu oraz używającym Bowera jako systemu rozprowadzania (Polymer stworzył niebotyczny ekosystem i de facto „czyste” custom elements są w zdecydowanej mniejszości).

Osobiście sam używam untitled-element, który jest podstawą mojego projektu dGUI (declarative GUI) – na razie są dwa nieskończone elementy, ale na dysku już mam zalążki kolejnych custom elementów, które w ostateczności złożą się na rozbudowane GUI aplikacji a’la desktopowej i nie tylko (node-webkit, yay!).

Większość devów oszalała na punkcie Web Components i nic dziwnego. Przepisano już połowę Sieci na nie: routery, asynchroniczne formularze, przycisk FB a nawet… console.log. Czy Web Components się przyjmą? Już to zrobiły. Czy ludzie je polubią? Już z nimi sypiają! Czy to dobrze? Tak i nie… Możliwości są bardzo duże, a wraz z nimi przyszła wielka odpowiedzialność (ale o niej to może innym razem!). Niemniej dobrze użyte WebComponents są przyszłością aplikacji webowych!

Linki i inspiracja:

Image courtesy of twobee at FreeDigitalPhotos.net


Tagi:


Jak uczyć się JavaScript? – książki, kursy i inne cuda…


10 sierpnia 2014 / Mr.Mr


logo języka JavaScriptBoom na uczenie się JavaScript nie mija. Cały czas co raz większe rzesze ludzi chcą wiedzieć jak działa ten język i jak używać go do budowania aplikacji internetowych (zresztą nie tylko internetowych). Sieć pełna jest rozmaitych zasobów, ale jak to zwykle bywa nie wszystkie są warte uwagi, inne są przeterminowane, a jeszcze inne np. niekompletne. Widać więc, że na szukającego wiedzy czycha wiele niebezpieczeństw. Ale nie bójcie się, jeśli dopiero zaczynacie Webroad.pl pomoże Wam znaleźć dokładnie to czego potrzebujecie!

Continue reading Jak uczyć się JavaScript? – książki, kursy i inne cuda…


Tagi:


Informacja o autorze jako przykład BEM i OOCSS


2 sierpnia 2014 / Michał Załęcki


screenshot_00119Wiadomo, że przykład kodu tłumaczy pewne zagadnienie lepiej niż sucha teoria. Poniższy elementu interfejsu został stworzony na potrzeby Bydgoszcz Web Development Meetup #4 jako demo do mojej prezentacji o dobrych praktykach CSS, BEM i OOCSS. W kodzie zastosowane jest kilka ciekawych podejść m. in. logiczne grupowanie selektorów [  ]. Podstawowymi zaletami takiego rozwiązania jest duża przenośność, przynajmniej częściowe rozdzielenie selektorów używanych w CSS od tych, z których korzystamy w JavaScript oraz duża czytelność kodu – szczególnie ważna gdy nad jednym projektem pracuje więcej developerów.

HTML

SCSS

Struktura całego projektu może niektórym wydać się skomplikowana, ale niesie ze sobą szereg zalet, które rosną proporcjonalnie do wielkości projektu. Podejście jest diametralnie różne od tego, które proponuje SMACSS. Bardziej od samych elementów, których dotyczy CSS ważniejsze są warstwy abstrakcji.

screenshot_00118

Poniższy kod dotyczy wyłącznie komponentu informacji o autorze, pełen kod znajduje się w repozytorium na GitHub.

Starsze wersje IE mają problem z animacjami SVG realizowanymi w CSS. Zachowanie ikon po najechaniu możemy zmienić wykorzystując wykrywanie funkcjonalności dzięki Modernizr i to, że nadaje on stosowaną klasę elementowi html.

JavaScript

Kodu JavaScript nie ma zbyt wiele. Po inicjalizacji WOW.js nadajemy ścieżką odpowiednie atrybuty tak by można było je następnie animować po najechaniu na ikony portali społecznościowych. Ostatnim elementem jest wykrycie czy użytkownik posiada ekran dotykowy i dostosowanie zachowania jednego z elementów.

Przydatne materiały

 


Tagi:


Notification API – sposób na powiadomienia w (nie)dalekiej przyszłości?


4 lutego 2014 / Michał Załęcki


Przeważnie lubimy być powiadamiani o różnych wydarzeniach. Powiadomienia pełnią rolę stricte informacyjną lub zachęcają nas do konkretnego działania: odpisanie na wiadomość, kliknięcie itd. W moim przypadku najczęściej powiadamia mnie Skype czy inne aplikacje dla Modern UI jak kalendarz no i mój smartfon.

Zarówno sam Modern UI jak i smartfony mają, czy raczej miały, przewagę nad stronami w kwestii powiadomień gdyż potrafią wyświetlić je „na interfejsie”. Powoli przeglądarki zaczynają do tego dojrzewać. W Google Chrome zaimplementowano nawet osobny zasobnik na powiadomienia. Mozilla Firefox za to sztywno trzyma się specyfikacji W3C, która nadal jest w fazie working draft.

Continue reading Notification API – sposób na powiadomienia w (nie)dalekiej przyszłości?



Aplikacja: Lista mailingowa w HTML5 (IndexedDB i AppCache)


24 stycznia 2014 / Michał Załęcki


Gdy HTML5 przestawał być odległą przyszłością głośno mówiło się o tym, że pozwoli on na pisanie aplikacji, cokolwiek to by miało oznaczać. Pozostawmy jednak nomenklaturę i zajmijmy się tym co ma dla nas faktyczne znaczenie. Czas zweryfikował możliwości HTML5, a specyfikacja dojrzała. My zaczęliśmy korzystać z dobrodziejstw nowego narzędzia.

Continue reading Aplikacja: Lista mailingowa w HTML5 (IndexedDB i AppCache)


Tagi:


Wszystko o Modernizr – część 3


19 stycznia 2014 / Michał Janicki


W trzeciej części kursu opiszę metody z grupy Extensibility. Domyślnie podczas tworzenia własnej paczki ta grupa jest ukryta i jeśli chce się mieć dostęp do niej, należy ją ręcznie zaznaczyć.

Modernizr.addTest()

Zacznę od bardzo przydatnej i bardzo prostej w obsłudze funkcji, która służy do dodawania własnych testów.

Continue reading Wszystko o Modernizr – część 3