Mapy źródeł – CSS & JS source maps

Może spotkałeś(-aś) się z plikami .map, na przykład używając bibliotek JavaScript’owych. Ten post tłumaczy, do czego one służą i dlaczego warto ich używać.

Temat: Tworzenie stron internetowych
Dział: Front-end
Poziom: Średniozaawansowany

Krótkie wprowadzenie

Kod w przeglądarce po stronie klienta nie musi być czytelny. Poniższe przykłady są równoznaczne.

p.lead,
header.lead,
header .lead {
  text-align: center;
  font-size: 2rem;
}

#navigation {
  padding: 0 20px 1em 20px;
}

header .lead,header.lead,p.lead{text-align:center;font-size:2rem}#navigation{padding:0 20px 1em}
var typeFilter = function (type, array) {
  var test = function (value) {
    return (value.length)
        ? (value[0].toLowerCase() === type.toLowerCase())
        : false;
  };
  return $filter('filter')(array, test);
};
var f=function(e,r){var t=function(r){return r.length?r[0].toLowerCase()===e.toLowerCase():!1};return $filter("filter")(r,t)};

 

Istnieje wiele sposobów na skompresowanie swojego kodu, ale o praktycznych aspektach za chwilę. Minifikacja* (usuwanie zbędnych znaków) jest bardzo pożyteczną praktyką ze względu na wielkość pliku. Niestety komplikuje to debugowanie.

Debugowanie nieczytelnego kodu CSS

Tutaj zaczyna się magia: DevTool w przeglądarce jest w stanie odtwożyć z której linijki jakiego pliku źródłowego dany fragment pochodzi, jeśli dostarczymy mu mapę. Oznacza to, że możesz mieć wgląd w źródła nawet kiedy strona wczytuje „zmielony” i nieczytelny kod.

* Kalka z angielskiego (minification). Tak brzmi hasło w Wikipedii. Dlatego nie lubię pisać na techniczne tematy po polsku.

Praktyka

Jeśli już korzystasz z jakiegokolwiek narzędzia wymagającego używania konsoli (gulp, Grunt, npm scripts) na pewno poradzisz sobie ze znalezieniem opcji umożliwiających wygenerowanie mapy. W przypadku różnego rodzaju dodatków do edytora/IDE może być różnie. Ja zwykle używam gulp’a, albo wtyczki do edytora Brackets. Opisywanie każdego narzędzia nie ma sensu. Zamiast tego proponuję prosty i darmowy program, z którym każdy powinien sobie poradzić.

Aplikacja Koala

Koala. Ustawienia z prawej umożliwiają wygenerowanie mapy.

Jak to działa?

Mapę do kodu można dołączyć na dwa sposoby:

  1. Za pomocą komentarza na końcu pliku:
    /*# sourceMappingURL=style.css.map */
    //# sourceMappingURL=/katalog/functions.js.map
  2. Poprzez nagłówek HTTP X-SourceMap:
    X-SourceMap: /inny_katalog/script.js.map

Szczerze powiedziawszy, nie spotkałem się jeszcze z zastosowaniem tej drugiej opcji.

Składnia pliku to dość czytelny na pierwszy rzut oka JSON. Przykładowo:

{
  "version": 3,
  "file": "style.css",
  "sources": [
    "style.scss"
  ],
  "mappings": ";AAAA,AAAA,IAAI,CAAC;EACH,…",
  "names": []
}

Najciekawszą częścią jest oczywiście mappings. Dane tam zapisane można przetłumaczyć jako:

wiersz: kolumna->w_źródła:k_źródła, kolumna->w_źródła:k_źródła

Dobrym sposobem na zrozumienie o co chodzi jest zobaczenie wizualizacji.

Algorytm to VLQ zakodowany w Base64. Ciekawostka: format ten został po raz pierwszy zdefiniowany do kodowania muzyki w formacie MIDI.

Techniczne szczegóły

Jeśli dalej Ci mało, to prawdopodobnie masz za dużo wolnego czasu. Odsyłam do oryginalnej dokumentacji. Poza tym polecam poradnik Introduction to JavaScript Source Maps i post How do source maps work?, dzięki którym ogarnąłem ten temat.


Obsługa gamepada w przeglądarce

Ostatnio podpiąłem do mojego kompa pad przez USB. Do czego ta zabawka służy, niby każdy wie. Mimo to zamiast włączyć grę, zacząłem się zastanawiać, jak jeszcze można takie urządzenie wykorzystać. Rezultaty mnie zaskoczyły, dlatego chcę się nimi podzielić.

Szczegóły techniczne

// Jeśli nie piszesz aplikacji internetowych, pomiń ten fragment. Poniżej znajdziesz kilka ciekawszych rzeczy (obiecuję).

Specyfikacja W3C pozostaje szkicem, choć pierwsze wdrożenie prototypu API w publicznej przeglądarce da się określić na rok 2012. W telegraficznym skrócie, mamy do czynienia z dwoma detektorami zdarzeń i prostym interfejsem (obiektem) JavaScript.

Informacje o podłączonych urządzeniach pobrać można dzięki navigator.getGamepads(). Dostajemy obiekt w którym pod kolejnymi indeksami kryją się interfejsy padów.
Przykład odczytanych danych:

{
index: 0, // Identyfikator/slot
id: "EX10 GAMEPAD (Vendor: 0f0d Product: 0009)",
connected: true,
mapping: "",
axes: [
-0.7176470756530762,
0.5372549295425415,
0.003921627998352051,
// itd
],
buttons: [
{
pressed: false,
value: 0
},
{
pressed: true,
value: 1
},
// itd
],
timestamp: 51682
};

Wszystkie atrybuty są tylko do odczytu.

Póki co, monitorowane zdarzenia dostępne przez API to:
gamepadconnected i gamepaddisconnected.
window.addEventListener("gamepadconnected", function(event) {
console.log(event.gamepad);
});

Omawiam tu z grubsza tylko niezbędne minimum, dlatego do dalszej nauki polecam szczegółowy poradnik na developer.mozilla.org.

Kalibracja i mapowanie

Niestety nic nie jest tak proste, na jakie wygląda na pierwszy rzut oka. Oryginalne, nowe pady połączone przez Bluetooth nie powinny sprawiać problemu. Inne modele potrafią zaskoczyć różnymi konfiguracjami: od innej kolejności przycisków i osi, po d-pad zgłaszający się jako oś, zamiast zestawu przycisków. Twórcy specyfikacji też przewidzieli taką ewentualność. Dodanie ustawień sterowania w aplikacji jest co najmniej zalecane, nawet pomimo standaryzacji.

Precyzja gałek

Osie analogowe zwracają wartości od -1 do 1. Wartość dla położenia środkowego jest bliska, ale nie zawsze równa 0. Kontroler, którego aktualnie używam działa poprawnie przy progu ±0.01. Nie tylko z tego powodu w grach zwykle pojawia się opcja odcięcia (threshold / dead zone). Stick, który znajduje się na sprężynie, przy puszczeniu od krawędzi może odbić w drugą stronę.

Czas przetestować sprzęt

Mały proof-of-concept.

See the Pen Gamepad test by Tymoteusz Czech (@Tymek) on CodePen.

Do wizualizacji użyłem przekształcenia z kwadratu na koło:

Inne strony do sprawdzania pada

HTML5 Gamepad Tester – numeryczne wartości odczytywane z urządzania
Gamepad Viewer – wizualizacja urządzenia na ekranie (może wymagać dodatkowej konfiguracji)

Dodatkowy eksperyment

Na czas redagowania wpisu nie używam myszki, ani touchpada. Kursorem poruszam za pomocą gałek (stick’ów). Nie jest to może najprzyjemniejsze rozwiązanie, ale przy dobrej konfiguracji okazuje się co najmniej wykonalne.

Ustawienie tego w sensowny sposób zajęło chwilę. Przetestowałem kilka programów umożliwiających mapowanie kontrolera zanim trafiłem na antimicro.

Przemyślenia dotyczące interakcji

Interfejs użytkownika nie kończy się na tym, co zostaje wyświetlone na ekranie. Wikipedia bardzo trafnie definiuje UI, jako „przestrzeń, w której następuje interakcja człowieka z maszyną”. Do tej przestrzeni zaliczają się wszystkie interaktywne komponenty maszyny.

Wiele aplikacji internetowych mogło by wiele zyskać na wdrożeniu obsługi gamepada. Widać to było przy okazji sporej ilości eksperymentalnych stron korzystających z telefonu jako kontrolera. Choć klawiatura ma więcej przycisków, a myszka oferuje większą precyzję #pcmasterrace, trzymanie pada w rękach zawsze będzie o wiele wygodniejsze.

 

Materiał sponsorowany

przez wujka, który mi pada pożyczył.


Warto pisać Open Source

Często wymieniane są zalety korzystania z otwartego oprogramowania. Chyba nie muszę ich powtarzać, skoro ponad 90% osób czytających ten artykuł użyje do tego przeglądarki internetowej z silnikiem na darmowej licencji. Jednak ktoś taki silnik musiał napisać. Jakie korzyści dla twórcy przynosi taka praca? Długo kompletowałem listę powodów, dlaczego warto tworzyć oprogramowanie open-source.

Bezcenna praktyka

Dla początkujących programistów publikowanie na przykład w serwisie GitHub zmusza do nauki obsługi repozytoriów kodu, oraz narzędzi do automatycznego budowania i testowania aplikacji. To umiejętności potrzebne każdemu, kto chce zajmować się wytwarzaniem oprogramowania.

Pisanie „dla siebie”

Dużo programów powstaje przy okazji. Podczas nauki i pracy, nawet przy tworzeniu oprogramowania na sprzedaż. Najlepszym powodem jest wtedy „dlaczego nie?”. Może się okazać, że ktoś (za darmo!) ulepszy program, który napisaliśmy na własny użytek.

Jakość kodu

Muszę przyznać, że całkiem inaczej planuję i piszę programy, jeśli mam zamiar je później udostępnić. Kod napisany tak, jakby miało się przekazać innej osobie dalsze jego rozwijanie po upływie pewnego czasu dużo łatwiej rozszyfrować.

Reputacja i wiarygodność

Repozytoria na GitHubie pozwalają na weryfikację praktycznych możliwości autora. Nawet drobne zaangażowanie w projekty innych osób udowadnia umiejętność zrozumienia cudzego kodu. Wydaje mi się, że dla firmy technologicznej prawdziwym kapitałem nie są produkty, a raczej wykwalifikowana kadra, która jest w stanie je tworzyć i rozwijać.

Sprawy finansowe

Wbrew pozorom na darmowych programach i usługach można zarobić. Wiele osób twierdzi inaczej, na przykład traktując Open Source Software jak pracę za darmo. Skupię się na tym argumencie, żeby innych durnych twierdzeń nie przytaczać. Załóżmy, że to prawda. Kogo więc stać na tak czasochłonne hobby? Na pewno nie są to osoby, które ze swoimi umiejętnościami ledwo potrafią zarobić na życie.


Walidacja numeru telefonu

Weryfikacja danych wprowadzanych przez użytkownika bywa równie ważna, co trudna. Łatwo się o tym przekonać szukając odpowiedniego wzorca dla adresu e-mail. Niby każdy wie, jak to powinno wyglądać: login@domena.TLD, a jednak odpowiednie wyrażenie potrafi mieć kilka tysięcy znaków.

Niedawno potrzebowałem sprawdzić numery telefonów. Szybkie wyszukiwanie w Google nie dało żadnych dobrych odpowiedzi, więc chciałbym podzielić się tym, czego dowiedziałem się rozgrzebując temat.

Ludzie kontra standardy

Miałem sporo przemyśleń podczas rejestrowania karty stałego klienta w Decathlonie. Formularz był wyjątkowo nieintuicyjny. Oczywiście, niedopuszczenie do wprowadzenia złych danych jest niezwykle ważne przy programowaniu. Z drugiej strony, jedną z podstaw projektowania, jest zwrócenie uwagi na łatwość użycia. Wymaganie konkretnego formatu danych, zwłaszcza bez jasnego zakomunikowania ograniczeń, jest frustrujące dla użytkownika.

Wracając do numeru telefonu – każdy ma swój preferowany zapis:

123-456-789 vs. 12 345 67 89 vs. (+48) 123 456 789

Odstępy, prefiks, nawiasy, to dopiero początek problemów.

Co kraj, to obyczaj

Można napisać dość proste wyrażenie regularne obsługujące tylko polskie numery, ale co z resztą świata? Tu zaczynają się schody. Na szczęście ktoś zrobił to już za nas, więc nie przedłużając przejdę do rozwiązań.

Proponowane rozwiązania

Własne wyrażenie regularne

Tak. Wiem, że to dziwna sugestia. Wszystko zależy jednak od wymagań konkretnego projektu.
Wyrażenia regularne nie są tak trudne, jakby się wydawać mogło. Jeśli nie wiesz jak je ugryźć, polecam regexone.com. Poza tym, niczego się nie nauczysz kopiując przypadkowy kod z cudzego bloga. Sam trafiłem na naprawdę tragiczne wpisy na ten temat w internecie.

Jeśli nie chcesz słuchać dobrej rady, proszę bardzo. Luźna wersja dla polskiego numeru telefonu:

/^(?:\(?\+?48)?(?:[-\.\(\)\s]*(\d)){9}\)?$/


Trzeba później usunąć wszystkie spacje i dozwolone w tym zapisie znaki specjalne (()-. itd.)

libphonenumber

Pod adresem https://github.com/googlei18n/libphonenumber można znaleźć świetną bibliotekę do weryfikacji numeru telefonu. Oficjalnie całość dostępna jest w trzech językach programowania: C++, Java i JavaScript. Istnieją także porty na C#, objective-c, Pythona, Ruby i na całe szczęście: PHP.

Uwagi

W tym wpisie nie wspomniałem o numerach wewnętrznych, które znacznie komplikują zabawę. libphonenumber ich nie obsługuje.

Żadna weryfikacja nie zastąpi wysłania kodu SMS 😉


Dokumentacja offline

Masz laptopa? Ja tak. Zdarza mi się też podróżować, lub ogólnie jechać gdzieś jako pasażer przez ponad godzinę. Pisząc ten post jestem w autobusie do mojej rodzinnej miejscowości. Czas w podróży warto spożytkować na coś produktywnego, na przykład na programowanie, lub ewentualnie sen. Zakładając, że wybieramy programowanie i mamy ograniczony dostęp do internetu, bardzo przydatna może okazać się kopia dokumentacji. Oto gdzie można zdobyć dokumentacje dostępne offline:

DevDocs

Strona internetowa umożliwiająca szybkie i wygodne przeszukiwanie dokumentacji języków programowania, frameworków itd. Tego rozwiązania używam na co dzień. Zdecydowaną wadą jest to, że jeśli wyczyścimy pamięć przeglądarki, przepadnie też dokumentacja offline.

Zeal

Odpowiednik Dash (z OS X) dla systemów Windows i Linux. Świetna opcja, jeśli potrzebujesz czegoś konkretnego i pewnego, zainstalowanego na dysku. Ogromną zaletą jest posiadanie dokumentacji do WordPressa i Javy. Sam trochę przesadziłem z ilością wybranych pakietów (prawie 30) i zajmują one aktualnie ponad 3,5GB. Wpisując tekst w wyszukiwarkę warto poprzedzić interesującą nas komendę nazwą języka i dwukropkiem.


Frameworki CSS i Material Design Lite

Od jakiegoś czasu dostaję pytania w sprawie „frejmłorków”. W sieci można znaleźć mnóstwo blogów na ten temat. Pisanie własnego eseju, albo porównanie funkcji wydaje mi się bezcelowe. W tej chwili pewno straciłem połowę publiczności, więc nie chcąc stracić reszty zacznę od podsumowania współczesnych (jak na początek 2016) rozwiązań:

  • Dla początkujących polecam Bootstrap 3. Jest łatwy do opanowania, między innymi dzięki ogromnej popularności i wynikającemu z niej wsparciu społeczności.
  • Aktualnie najnowocześniejszym rozwiązaniem jest Foundation 6, którego zaletami jest świetne działanie na urządzeniach mobilnych i poręczny kod SCSS.
  • W wielu przypadkach okaże się, że nie potrzebujesz bardzo zaawansowanych narzędzi. Istnieje mnóstwo małych i praktycznych frameworków, wśród których popularnością wyróżnia się Skeleton.

Co to jest „framework”?

Z angielskiego chodzi tu o strukturę, „ramę”, od której zaczyna się pracę. Framework CSS powinien zawierać:

  • Reset (normalizację) stylów przeglądarki
  • Układ (layout) ułatwiający pozycjonowanie treści (grid system)
  • Ujednolicenie podstawowych elementów (typografii, formularzy itp.)

W poprzedniej sekcji specjalnie nie nazwałem Bootstrapa ani Foundation frameworkami CSS. Dlaczego? Bo nimi nie są! Można to porównać do nazywania Drupala albo WordPressa frameworkiem PHP. Bardziej adekwatną nazwą jest front-end framework, jako że front-end (fasada – wszystko co serwis wyświetla użytkownikowi) dotyczy także skryptów i struktury strony. Słyszałem też bardzo adekwatną nazwę „UI Toolkit” (zestaw narzędzi dla interfejsu użytkownika).

Google Material Design

Ciągnąc wyjaśnienia dalej, Material Design nie jest ani frameworkiem CSS, ani frameworkiem front-endowym. Czym w takim razie jest? To ciekawy zestaw zasad projektowania, dostępny pod adresem www.google.com/design/spec/material-design/. Cała specyfikacja jest zaskakująco uniwersalna i intuicyjna.

Material Design Lite

Material Design Lite – wybór kolorkówOficjalna implementacja Material Design dostępna jest na getmdl.io. Najbardziej precyzyjny opis z jakim się spotkałem, to „a library of components & templates” – biblioteka komponentów i szablonów. Terminologia bywa myląca, ale nie przejmuj się – Antyweb nazwał MDL uniwersalnym frameworkiem dla webmasterów xD.

W przypadku Bootstrapa i Foundation największą zaletą jest modułowość. Znając podstawy preprocesora SASS można łatwo wybrać potrzebne elementy (na przykład framework CSS) i dostosować wygląd. Material Design Lite nie jest pod tym względem zbyt praktyczny. Nie polecam tworzenia i ręcznego kompilowania własnej wersji. Próbowałem. Realistycznie mamy jedynie możliwość dobrania dwóch głównych kolorów. Większa ingerencja wiąże się raczej z nadpisywaniem kodu CSS, czego nie polecam. Zastanawiałem się nad użyciem MDL do mojego kolejnego projektu, ale się rozmyśliłem. Może innym razem.

Alternatywy

Na szczęście istnieje wiele innych wersji, poza tą oficjalną. Wszystkim, którzy czekali na „Bootstrapa od Google” pewno spodoba się Materialize. Poza tym znalazłem motywy/nakładki na wcześniej wspominane popularne frameworki front-endowe, jednak przed ich użyciem stanowczo polecam przeglądnięcie oryginalnych wytycznych.

Podsumowanie

wybór narzędzia


Obliczenia na dacie

Na studiach informatycznych i innych związanych z programowaniem zwykle pojawia się ten koszmarny przykład: obliczenie różnicy pomiędzy dwoma datami. Dlaczego koszmarny? Bo zakłada się przy tym, że „koń i woźnica mają średnio po 3 nogi”. Słyszałem o przypadku w stylu „miesiąc ma 30 a rok 370 dni”.

Zasady gry

Celem jest podanie ilości lat, miesięcy i dni jakie upłynęły między dwoma wydarzeniami. W implementacjach użyję języka JavaScript, ponieważ blog miał być związany z technologiami internetowymi. Mam nadzieję, że kod będzie czytelny dla osób uczących się podstaw programowania w C/C++. Nie chcę też dawać możliwości użycia go na zasadzie kopiuj-wklej.

Struktura danych

Programy składają się nie tylko z algorytmów, ale i struktur danych. Tu pojawia się pierwszy problem. Wbudowane typy nie nadają się do takich obliczeń. Tak jak w przypadku C/C++ typy zmiennych w strukturze time_t, w JavaScript sposób działania metod obiektu Date bardzo utrudnia operacje matematyczne. W swoich programach użyłem własnej klasy Tm, zawierającej 3 publiczne pola: rok, miesiąc i dzień. Kompletną implementację można pobrać na końcu wpisu.

Tm = {
	year: {number},
	month: {number},
	day: {number}
}

 

Implementacja

Zobacz CodePen yeyxWP autorstwa Tymoteusza (@Tymek) na CodePen.io.

 

Problemy z naszym kalendarzem

Program zadziała jedynie współczesnego kalendarza, więc może być niedokładny (przez datę zmiany kalendarza w Rosji) nawet dla obliczania wieku wciąż żyjących osób, a co dopiero wydarzeń historycznych!

Dało by się uprościć obliczenia? Oczywiście! Znów zmieńmy kalendarz. Brzmi jak szalony pomysł, ale Kalendarz Światowy ma swoich zwolenników. Do propozycji którą znalazłem mam kilka zastrzeżeń. Po pierwsze, sądząc po stronie internetowej organizacji, chyba nikt aktualnie nie zajmuje się tą inicjatywą. Po drugie, „Worldsday” brzmi trochę jak „New World Order”, a po trzecie i najważniejsze, kto zgodzi się na piątek trzynastego 4 razy w roku! 😛

Kalendarz nie jest jedynym problemem w naszym mierzeniu czasu. Polecam dziesięciominutowy filmik: The Problem with Time & Timezones – Computerphile.

 

Zakończenie

Obliczanie różnicy między datami jest dla Ciebie za łatwe? Szukasz wyzwań?

<MDW> Santon: Algorytm obliczania daty tłustego czwartku jest bardziej skomplikowany niż algorytm kompresji JPEG 🙂
bash.org.pl/4859546/

Kompresję JPEG znam tylko w założeniach, a jeśli chodzi o algorytm obliczania daty tłustego czwartku, wziąłem lekcję z załączonego wcześniej filmu. Zmodyfikowałem gotową implementację.

Dziękuję za uwagę. W następnym materiale postaram się napisać coś bez kodu źródłowego, podejmując temat wizualnego projektowania stron internetowych.