Техноблог

О фронтенде, технологиях, вебе, программировании и дизайне.

Применение Optional в Java

Техноблог возвращается из стазиса. Теперь я верчусь в мире Java и заметки тоже будут про этот мир. Буду писать про всякие интересные штуки, которые обнаруживаю. Возможно, они миллион раз были где-то описаны, но мне это не важно, так как заметки скорее для себя, но может быть они ещё кому-то будут интересны.

Представим, что вам по цепочке вызовов нужно достать какое-то значение:

final Any thing = holder.getValue().getData().getObject().getAnythingElse();

При этом, в любом звене этой цепочки может вернуться null и случится аппокалипсис NullPointerException. Но он нам не нужен, а если вернулся null, нужно просто вернуть какое-нибудь дефолтное значение.

Можно обернуть всё это горой if-ов:

if(null != holder ) {
    if(null != holder.getValue()) {
        if(null != holder.getValue().getData()) {
            ...
        }
    }
}

Можно попробовать завернуть в try-catch (никогда так не делайте):

try {
    final Any thing = holder.getValue().getData().getObject().getAnythingElse();
} catch (NullPointerException e) {
    final Any thing = "Default Value";
}

Но красивым, и, на мой взгляд, лучшим решением будет использовать Optional:

final Any thing =
    Optional.ofNullable(holder)
        .map(Valuer::getValue)
        .map(Wrapper::getData)
        .map(Some::getObject)
        <...>
    .orElse("Default Value");

Каждый map проверит значение, возвращённое методом, на null и вернётся или нужное нам значение или заданное в блоке orElse.

2018   java   фп

Псевдопротокол tel:

Мобильные браузеры определяют телефон по тапу на нём и предлагают совершить звонок — это удобно. Но это работает, только если в вёрстке телефон сделан единым текстом. Однако часто дизайнеры оформляют телефон так:

В данном случае случае телефон придётся разбить на два блока, и единого текста, как не пытайся, не выйдет. Мобильный браузер, скорее всего, не определит телефон.

На помощь приходит псевдопротокол tel. Оборачиваем телефон в ссылку с этим протоколом:

<a href="tel:+7 (123) 456-78-90">
	<span class="code">+7 123</span>
	<span class="number">456-78-90</span>
</a>

Теперь по тапу на ссылку браузер определит телефон.

Быстрый способ получить svg из векторного слоя в фотошопе

Данный способ работает только в Photoshop CC.

Первым делом создаём в домашней папке пользователя файл generator.json, со следующим содержимым:

{
  "generator-assets":  { 
    "svg-enabled": true
  }
}

Файл можно скачать (generator.json), для ускорения процесса.

Ставим галку в меню File → Generate → Image Assets.

Затем переименовываем нужный слой, даём ему любое имя, заканчивающиеся на .svg (например pic.svg).

И вуаля. Рядом с psd файлом получаем папку, в которой будет лежать готовый svg.

Можно переименовывать даже группу слоёв.

Фотошоп довольно умно сгенерирует единый svg файл, учитывая все эффекты слоёв.

Фишка инпута для файлов, о которой не все знают

Оказывается, при указании файла в браузере совсем необязательно мучится со стандартным диалоговым окном выбора файлов.

Достаточно всего лишь перетащить нужный файл прямо на инпут.

К сожалению, это волшебство никак не распространяется на лейб для инпута. Поэтому, если вы каким-либо образом пытаетесь оформить стандартный инпут, растяните его по размерам блока и скройте с помощью прозрачности.

CSS Шрифт

Большинство веб-сервисов для подготовки кастомных шрифтов к вёрстке конвертируют шрифт в 4-5 разных форматов, при том что конвертировать имеет смысл только в один формат, в woff. Woff лёгок, и поддерживается всеми современными браузерами. При этом woff имеет смысл кодировать в base64 и вставить непосредственно в css файл с помощью data:uri.

Об этом ещё в 2012 году писал Артём Поликарпов. С тех пор, как я прочитал совет Артёма, я подготавливал все шрифты вручную, т. е. конвертировал файл сначала в woff, затем кодировал в base64, затем создавал css-файл и вставлял в него всё полученное. И мечтал о сервисе, который делал бы за меня всё это автоматически. Но, к сожалению, так и не нашёл такого, и поэтому сделал сам. Собственно вот:

Открыть в новой вкладке

Плюсы шрифта в css:

  • нужно подключить всего один файл;
  • меньше запросов к серверу;
  • текст не прыгает при загрузке шрифта.

Минусы:

  • не поддерживается ИЕ ниже 9-го.

От поддержки 8-го ИЕ я отказался (рекомендую и вам), по нескольким причинам:

  • шрифт в формате eot (специальный формат для ИЕ), у меня не работал практически никогда, и как сделать, чтоб заработал, я понятия не имел;
  • человеку с ИЕ 8 будет не до вашего кастомного шрифта, из-за которого этот браузер начнёт ещё больше тормозить, да ещё и сайт из-за него грузится дольше будет, поэтому имеет смысл подобрать стандартный шрифт.

Ссылки по теме:
Ещё один способ устранить ВОШ

О скриншотах веб-страниц

Есть вещь, которая мне совершенно непонятна в современных браузерах. А именно отсутствие человеческой возможности сделать скриншот страницы в полный рост.

Сейчас эта задача решается какими-то сторонними расширениями и плагинами, которые работают ужасно абсолютно все. Лично я пользуюсь вот этим для хрома и плачу каждый раз, когда использую его.

Самое интересное то, что браузер итак уже отрендерил страницу, на которой я нахожусь. Значит её изображение уже есть где-то у него в памяти. Неужели разработчикам так сложно добавить где-нибудь в настройках браузера незаметную кнопку «Сохранить изображение страницы»? Загадка.

UPD: Нашёл расширение получше: Joxi. И сервис, который вообще всё за тебя делает: S-shot.

Швейцарский нож jQuery-разработчика — jQuery Helpers

Каждый веб-разработчик, работающий с jQuery, со временем начинает собирать удачные решения и ходы, для того, чтобы применять их в будущих проектах. Со временем таких решений накапливается много, некоторые из них перерастают в плагины, а некоторые небольшие, но полезные куски кода копируются из проекта в проект. Похожим образом получилось и у меня. И сейчас я хочу поделиться с вами своими наработками. Надеюсь, для кого-то из вас они тоже окажутся полезными :-)

Можно посмотреть на Гитхабе или сразу скачать.

makeActive
cycle
genHtml
appendCount, prependCount
onlyDigits
parseInt, parseFloat
breakdown
cleaner
dataObject
popup
transmit
src, href
disable, enable
hash, pathname
run
removeSpaces
reverse
ending

makeActive (’classname’ || object{classname, selector})

Часто возникает ситуация, когда нужно назначить класс таким образом, чтобы элемент был единственным его обладателем в ряду соседних элементов. Эту проблему помогает решить makeActive. По умолчанию назначается класс active. Нужный класс можно передать строкой :

$(this).makeActive('my_class_name');

Или передать объект, заключающий в себе название класса и селектор соседних элементов:

$(this).makeActive({
	className: 'my_class_name',
	selector: 'div'
});

Пример:

$('div').click(function(){
    $(this).makeActive();
});

cycle (’next’ || ’prev’)

Не знаю как вам, а мне иногда катастрофически не хватает циклических next / prev в jQuery. Эту проблему я решил, написав хелпер cycle, который принимает next или prev в качестве строки.

Пример:

$('#prev').click(function(){
    $('.wrap div.active').cycle('prev').makeActive();
});

$('#next').click(function(){
    $('.wrap div.active').cycle('next').makeActive();
});

genHtml (code, count)

Иногда бывает задача создать определённое количество html элементов, например для пагинации слайдера.

Конструкции вроде:

$('.slide').each(function(i){
	var $li = $('<li>').append('<a><span>'+ (i+1) +'</span></a>');
	$pagination.append($li);
});

меня всегда бесили. Поэтому был написан хелпер genHtml, который принимает тег строкой и количество.

appendCount, prependCount

Вставляют нужное количество html элементов на страницу, используя genHtml. Синтаксис такой же как у genHtml.

onlyDigits

Иногда требуется текстовый инпут, в который физически можно ввести только цифры. К великому сожалению, стандартные средства html не предлагают такого функционала (даже <input type="number" /> в котором это было бы логично). Для этого существует хелпер onlyDigits.

$('input').onlyDigits();

parseInt, parseFloat

Вызываются у блока с числом или инпута и возвращают число сразу с типом number.

breakdown

С помощью этого хелпера, можно разбить число пробелами по разрядам.

$('#num').breakdown();

cleaner

В современных приложениях реализована такая удобная, особенно на мобильных устройствах, штука, как крестик для очистки инпута от введённых в него данных. В браузеры, к сожалению, перекочёвывать она не сильно спешит. Насколько я знаю, такой крестик есть только в интернет экплорере, но последний не предоставляет возможностей для оформления этого элемента.

Для этих целей был написан хелпер cleaner. Он добавляет рядом с инпутом <a class="clean" />, который можно оформить с помощью css как душе угодно.
Желательно перед использованием обернуть инпут в какой-нибудь див, а крестик прижать вправо абсолютным позиционированием. А после этого добавить инпуту паддинг справа, чтобы текст не заезжал на крестик. Да, к сожалению всё это не так удобно, как мне хотелось бы, но работаю над упрощением. Для стандартного использования написан css-код, который желательно просто копировать в основной файл стилей своего проекта и изменять.

dataObject

Данный хелпер позволяет доставать javascript-объекты из атрибутов data-*. Используется также, как и стандартный метод .data() в jQuery, только вместо строки возвращает объект.

Иногда нужен простой попап, который бы закрывался при клике за его пределами. Для этого был написан хелпер popup. При вызове он добавляет элементу класс shown, и удаляет при закрытии (я использую добавление класса, а не show/hide, чтобы управлять анимацией появления при помощи css). Метод может принимать объект, с атрибутами link и close. link — ссылка, при клике на которую будет показан попап. close — элемент внутри попапа (крестик), при клике на который попап будет закрыт.

transmit (’method’, [options array])

Все мы постоянно пишем колбеки для разных событий, и почти всегда используем анонимные функции для этого. Но конструкции вроде этой:

$(window).load(function(){
	$('#object').click();
});

мне кажутся нелогичными и трудночитаемыми, когда намного логичней было бы так:

$(window).load($('#object').click);

Но jQuery перезаписывает контекст у колбеков. И конечно в 99% случаев это удобно, но не в данном.
Хелпер transmit частично решает эту проблему, позволяя писать так:

$(window).load($('#object').transmit('click'));

src, href

Возвращают/изменяют значение атрибутов src и href у элементов на странице. Мне не хватало таких методов как val() у инпутов, только для ссылок.

disable, enable

disable — добавляет атрибут disabled у элементов, enable — убирает.

hash, pathname

Возвращают/изменяют соответствующие части href у ссылок на странице.

run

Запускает функцию в контексте текущей выборки, а не для каждого элемента отдельно, в отличии от each.

removeSpaces

Удаляет пробелы между элементами. Служит, в основном, для решения проблем с инлайн-блоками.

reverse()

Разворачивает порядок следования jQuery объектов.

ending (end1, end2, end3, count)

Хелпер для формирования окончаний у слов во множественном числе.

Для определения возможностей браузера я рекомендую использовать Modernizr. Но в своей работе я сталкивался с тем, что не все нужные мне тесты были реализованы в нём. Поэтому я написал парочку своих, расширив jQuery.support, и оформив всё в файл jquery.support.js.

jQuery.support.calc

Определяет, поддерживает  ли браузер css-функцию calc. Актуально для старых версий оперы и 8-го экслорера.

jQuery.support.flash

Определяет, установлен ли Flash на компьютере пользователя.

jQuery.support.mobile

Детектит мобильные браузеры.

jQuery.support.preserve3d

Проверяет, поддерживается ли браузером 3D представления. Актуально, если вы хотите использовать в своём проекте transform-style: preserve-3d;.

Хелперы собираются в один файл с помощью Гранта. Если проект получит развитие, в дальнейшем будет добавлена страница онлайн-сборки, где вы сможете собрать jQuery Helpers, выбрав только необходимые вашему проекту хелперы.

UPD: Произошла какая-то фигня, и я не заметил, как публикнул недописанный черновик. Но это даже хорошо, т. к. я бы ещё месяц его мусолил. Так что кто увидел — тссс.

finalReject — наипростейшая заглушка для старых версий IE

finalReject — Плагин, отображающий, в устаревших версиях Internet Explorer, заглушку с предложением обновить браузер. Заглушка накладывается поверх сайта в виде попапа, и в случае чего может быть закрыта пользователем. При этом, после закрытия, она не исчезает навсегда, а прикрепляется к верхней части окна браузера, и продолжает отображаться в минимизированном виде.

Полная заглушка выглядит вот так:

Установка плагина предельно проста. Достаточно скачать архив по ссылке и распаковать папку reject в корень сайта. Или в любое другое место на сайте.

Подключается плагин самым нативным способом: с помощью условных комментариев. Например для отображения заглушки во всех версиях IE ниже 9, достаточно добавить в блок <head> следующий код:

<!--[if lt IE 9]>
	<link rel="stylesheet" href="/reject/reject.css" media="all" />
	<script type="text/javascript" src="/reject/reject.min.js"></script>
<![endif]-->

В 7-9 версиях Internet Explorer плагин отображается и работает так, как задумано. В 6-й не совсем, но тоже адекватно.

Страница плагина на Гитхабе. Буду рад вашим старам, и пулл реквестам :-)

На какое-то время, эта заметка в блоге будет являться официальной страницей плагина, пока я не придумаю что-нибудь поинтересней.

UPD: Теперь finalReject можно установить с помощью bower:

$ bower install final-reject --save

UPD2: Можно ничего не скачивать и не устанавливать, а просто добавить в <head> код:

<!--[if lt IE 9]>
	<link rel="stylesheet" href="https://rawgit.com/codefucker/finalReject/master/reject/reject.css" media="all" />
	<script type="text/javascript" src="https://rawgit.com/codefucker/finalReject/master/reject/reject.min.js"></script>
<![endif]-->

UPD3: Текст заглушки можно изменить с помощью аттрибута data-text:

<!--[if lt IE 9]>
	<link rel="stylesheet" href="https://rawgit.com/codefucker/finalReject/master/reject/reject.css" media="all" />
	<script type="text/javascript" src="https://rawgit.com/codefucker/finalReject/master/reject/reject.min.js" data-text="Unfortunately, the browser you use, outdated and can not properly display the site. Please download any of the following browsers:"></script>
<![endif]-->
2014   finalReject   IE   javascript   plugin

Как подружить Sublime Text 2 и SASS на Windows

Если ты не знаешь что такое SASS, можешь почитать тут. Вкратце: очень крутая штука.

Для начала, для того, чтобы получить возможность компилировать sass/scss файлы необходимо установить Ruby. Во время установки обязательно проследи чтобы стояла галочка, добавляющая Ruby в Path.

После установки запусти командную строку (cmd). Это можно сделать нажав Win + R и набрав cmd. В командной строке набери «gem install sass». Должно появится что-то вроде этого:

SASS установлен. Теперь ты можешь компилировать sass/scss файлы, используя командную строку:

Но гораздо удобней делать это через текстовый редактор, например Sublime Text

Для начала в Sublime должен быть установлен Package Control. Если он у тебя ещё не установлен, нажми ctrl+ё, вставь в открывшуюся консоль следующие строки:

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print('Please restart Sublime Text to finish installation')

После установки перезапусти Sublime.

Теперь Package Control доступен из вкладки Preferences.

Нажми на него или используй хоткей ctrl+shift+P и набери Install Package, затем SASS Build и установи плагин.

Перезапусти Sublime.

Всё, теперь ты можешь компилировать sass/scss файлы нажав ctrl+B.

Скомпилированный файл появится рядом, с таким же именем и расширением css.

Важно! В пути до компилируемого файла не должно быть русских символов. Да, в 21-м веке это звучит странно, но у Sublime возникают с этим проблемы. Если ты знаешь как это победить, поделись в комментариях.

Если файл не компилируется, а в консоли выводится что-то вроде этого:

Traceback (most recent call last):
  File ".\sublime_plugin.py", line 337, in run_
  File ".\exec.py", line 154, in run
  File ".\exec.py", line 45, in __init__
UnicodeDecodeError: 'ascii' codec can't decode byte 0xcf in position 6: ordinal not in range(128)

то есть одно магическое действие, которое может решить проблему.

Кликни в меню Preferences → Browse Packages...

открой файл /Default/exec.py и замени строку

proc_env[k] = os.path.expandvars(v).encode(sys.getfilesystemencoding())

на

proc_env[k] = os.path.expandvars(v.decode(sys.getfilesystemencoding())).encode(sys.getfilesystemencoding())

Это должно помочь.

Чтобы сэкономить время, можешь установить плагин SublimeOnSaveBuild, и тогда компиляция будет происходить сразу после сохранения (по нажатию ctrl+S).

Для подсветки синтаксиса sass/scss файлов установи плагины в Sublime, которые так и называются SASS и SCSS, или другие, в названии которых содержится highlight.

Если тебе когда-нибудь понадобится обновить SASS, просто набери в командной строке «gem update sass».

2014   ruby   sass   scss   sublime text   windows   мануал

Как сверстать стрелку без картинок

Прочитав эту заметку, вы узнайте как сверстать вот такую симпатичную стрелочку:

«Рисуем» треугольники

Возьмём обычный бокс с бордером, для наглядности раскрасив стороны в разные цвета:

.box{
	border-style: solid;
	border-top-color: blue;
	border-right-color: green;
	border-bottom-color: yellow;
	border-left-color: red;
}
<div class="box" style="width: 200px; height: 200px; border-width: 2px"></div>

А теперь увеличим размер бордеров, одновременно уменьшив бокс:

<div class="box" style="width: 100px; height: 100px; border-width: 52px"></div>

Убёрем высоту и ширину совсем:

Треугольники готовы.

«Рисуем» стрелку

Заготовка:

.arrow{
	position: relative;
	background: #09F;
	display: inline-block;
	width: 200px;
	padding: 5px;
	color: #FFF;
}
<div class="arrow">&nbsp;</div>

Добавим знакомые нам треугольники, с помощью псевдоэлемента :after, раскрасив все в один цвет, и сделав прозрачным левый бордер:

.arrow:after{
	width: 0;
	height: 0;
	position: absolute;
	top: 0;
	right: 0;
	border: 100px solid red;
	border-left-color: transparent;
	z-index: 10;
	content: "";
}

Хитрым образом спозиционируем псевдоэлемент:

/* добавляем */
.arrow:after{
	top: 50%;
	right: -100px;
	margin-top: -100px;
}

Скроем выступы и покрасим бордеры в цвет фона:

/* добавляем */
.arrow{
	overflow: hidden;
}

.arrow:after{
	border-color: #FFF;
	border-left-color: transparent;
}

Стрелка готова, для крутости можно добавить градиент:

У метода есть 2 недостатка:

  • фон должен быть однородным,
  • по-настоящему многострочную стрелку сделать не получиться, потому-что

но вполне возможно подобрать значение правого паддинга для 2-3 строк