misc/class
lib/jquery_pnotify, lib/moment, lib/lodash, misc/notification, site/engine, misc/social
if( $.browser.msie && $.browser.version <= 8 ) include('lib/respond'); $._social.__cfg = {"init":[{"service":"basic"},{"fb_app_id":"1997094873850041","service":"fb"},{"vk_app_id":"2978320","service":"vk"},{"service":"twi"}],"like":[{"service":"fb"},{"service":"vk"},{"via":"","channel":"","hash_tag":"","service":"twi"}]}; window._SiteEngine = new classes.SiteEngine( { user_id: 0, controller: 'content_tape', action: 'view', content_css_version: '1459538664', social_enabled: 0} );

Faiwer

Блог web-программиста

V8 & unicode RegExp-ы

22 марта 2016

Не так давно в V8 движок добавили поддержку флага /u (т.е. поддержку unicode) для регулярных выражений. В nodeJS можно подключить флагом --harmony_unicode_regexps. Вот небольшой обзор по новым возможностям. При установленном флаге . понимает иероглифы, их же стало можно использовать в описании регулярного выражения без экранирования, появилась поддержка i флага.

Но! Они недобавили самого вкусного ― \p{L}. При помощи модификатора \p можно кратко описать многие вещи (см. раздел Unicode Categories). К примеру можно описать в пару символом регулярку, которая будет проверять принадлежность символа к алфавиту какого-либо языка. Например, /^\p{L}[\p{L}\d-_ ]+$/u отлично подойдёт для валидации имени пользователя, не поставив в незавидное положение ни грузин, ни китайцев, ни русских. Но отлично отфильтрует рандомный бред с клавиатуры.

Надеюсь, что это временно. А пока можно воспользоваться, к примеру, XRegExp-ом.

Подключаем HTTPS к Nginx за счёт Let’s Encrypt

21 марта 2016

Небольшая заметка про подключение letsencrypt на сайт с nginx сервером. За основу взял хабра-статью от @questor-а. Наша задача добавить поддержку https на сайт малой кровью. letsencrypt позволяет нам это сделать, взяв на себя всю чёрную работу по подготовке, выдаче, загрузке и обновлению сертификатов (подробнее). Всё нижеописанное я привожу для linux debian-like систем.

Принцип работы

Для подключения HTTPS необходимы сертификаты (для шифрования и аутентификации). Причём эти сертификаты должны быть выданными доверенными серверами, список которых вшит в браузеры. Обычно это дело было платным, но с недавних пор, появилось несколько доступных и бесплатных альтернатив. Одна из которых это Let’s Encrypt.

Let’s Encrypt выпускает сертификаты бесплатно и в автоматическом режиме на 3 месяца. Для работы с ним подготовлено ПО с открытым кодом и есть открытое API для взаимодействия вручную. Мы воспользуемся готовым рекомендованным ПО.

Принцип работы этого ПО заключается в том, что сервер запрашивает у letsencrypt-центра выпуск новых сертификатов для указанных доменным имён. Для этого letsencrypt-центр ломится на ваш сервер по конкретным URL-ам с этими доменными именами, и убеждается в том, что они принадлежат вам. Затем выпускает новые сертификаты и передаёт их на сервер сайта. ПО складирует их в указанной директории. Вам остаётся лишь подключить их к nginx и настроить автоматическое обновление по cron-у.

Подготовка, подключение и обновление под катом.

подробности…

Resize изображений на стороне браузера

21 марта 2016

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

Для начала нам потребуется <input type="file"/>. Без него нам не открыть диалог для выбора файла. Чтобы вызвать его вручную необходимо в обработчике вида onclick (onkeydown и пр. отпадают из-за Firefox) вызвать file.click(). Вызвать диалог в произвольный момент времени не получится.

Отслеживаем изменение выбора файла по onchange. Сам же файл достаём из file.files[index]. Если наш <input/> работает не в multiple режиме, то index, соответственно, равен 0. Присмотревшись к свойствам этого объекта мы увидим его mime тип, размер, имя файла. Но не содержимое.

Для получения содержимого воспользуемся FileReader-ом.

const reader = new FileReader();
reader.onload = e => { e.target.result; /* base64 string */ };
reader.readAsDataURL(file);

Через него получаем DataURL вариант содержимого файла (асинхронно). Затем создаём новый Image, вешаем обработчик на onload, задаём этот dataURL ему как аттрибут src. В результате получаем валидный <img/> тег с загруженным готовым к использованию изображением.

Resize изображения будем осуществлять за счёт <canvas/>. У contextcanvas-а есть метод drawImage, который сделает за нас всю грязную работу. Ниже пример работы с ним (стояла задача вписать изображение в определённые рамки, но только если оно превышает эти сами рамки):

const canvas = document.createElement('canvas');

const w_ratio = img.width / width;
const h_ratio = img.height / height;
let ratio = Math.max(w_ratio, h_ratio);
if(ratio < 1)
	ratio = 1;

const w = Math.floor(img.width / ratio);
const h = Math.floor(img.height / ratio);

canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, w, h);
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, w, h);

return canvas.toDataURL('image/jpeg', 80);

Обратите внимание на то, что <canvas/> даже не обязательно цеплять к DOM-у браузера, и тем более делать его видимым. В результате получаем снова dataURL, но уже правильного вида и размера. Но что нам теперь с ним делать? 

Вариантов много. К примеру можно послать на сервер строкой, как и другие поля. Но можно воспользоваться FormData, и тогда работа с такой выдачей клиента ничем не будет отличаться от обычной:

const fd = new FormData(form);
fd.append('image', blob);

Обратите внимание на blob. Дело в том, что для маскировки под обычный input[type=file] нам нужно нашу dataURL перевести в Blob вариант. Я взял готовое решение со stackoverflow:

function dataUriToBlob(dataURI)
{
	let byteString;
	if( dataURI.split(',')[0].indexOf('base64') >= 0 )
		byteString = atob(dataURI.split(',')[1]);
	else
		byteString = window.unescape(dataURI.split(',')[1]);

	// separate out the mime component
	const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];

	// write the bytes of the string to a typed array
	const ia = new Uint8Array(byteString.length);
	for(let i = 0; i < byteString.length; i ++)
		ia[i] = byteString.charCodeAt(i);

	return new Blob([ ia ], { type: mimeString });
}

Задача решена. Относительно без крови. Однако, мы воспользовались FormData, FileReader, Blob, Uint8Array,  Canvas. Тот же самый IE9 всего этого не умеет.

Об IE9 замолвите слово

21 марта 2016

Минутка гнева… Internet Explorer 9 не умеет:

  • Placeholder
  • FormDataFileReaderBlobUint8Array
  • Flexbox

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

V8 & Async Await

17 марта 2016

Очень жду от nodeJS поддержки async/await. А т.к. nodeJS использует V8, то, получается, я жду async/await именно от V8. Мне так и не удалось найти какого-либо публичного roadmap-а от команды, которая им занимается. Что мы имеем на данный момент?

Ну для начала у нас есть страница на официальном сайте nodeJS, посвящённая ES2015. Она бегло сообщает нам о том, что можно использовать готовые возможности из ES2015 под флагом --es_staging, и посмотреть список всех доступных по --v8-options. Также можно отфильтровать все v8 флаги по in-progress. К примеру мы уже можем использовать --harmony_default_parameters и --harmony_destructuring на свой страх и риск. Я использую, работает. Там же ошибочно указано, что можно включить --harmony_modules, но эту опцию просто забыли убрать.

Затем у нас есть issue в баг-трекере v8 c несколькими сообщениями. Выясняется, что пару лет назад, кто-то уже запиливал поддержку async/await в v8, но получилось не очень. А пока вроде прогресс даже не шевелится. Отсюда же ловим ссылку на то, как какой-то энтузиаст добавил поддержку синтаксиса async/await в виде патча, который отвергли со словами, мол, парень, для начала войти в v8-team.

We have some plans for tackling that next year, but not before we have finished ES6. To be honest, we would prefer not to open that can right now, since ES6 already is producing a lot of churn.

iefserge, 2015-10-27

Полную поддержку ES6 v8 пока не получил, хотя большая часть готова. Когда дойдут у команды руки до awanc/await неизвестно. Хорошо, если это произойдёт в 2016. Остаётся надеяться, что поддержка в Edge ускорит процесс появления оного и в v8.

UPD0: Нашёл RSS с новостями V8!