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: 'tag', content_css_version: '1459538664', social_enabled: 0} );

Faiwer

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

Поиск по метке: Chrome

Тернистый путь расширений в Chrome

2 ноября 2017

Довольно часто я сталкиваюсь с тем, что сторонние сайты работают не совсем так, как я бы хотел. И будучи web-программистом я пытаюсь на это дело как-то повлиять. Но одно дело, скажем, стили сайту подправить, и совсем другое вмешаться в его работу JavaScript-ом. Эта заметка о втором.

Итак. На этот раз жертвой пал puzzle-english. Ресурс для изучения английского. Среди прочего там есть возможно уникальная возможность тренировать аудирование на небольших заранее заготовленных фразах, записанных от нескольких дикторов. Предлагается на выбор по 3-5 слов на каждое произнесённое слово. Итого ты или кликаешь по кнопкам мышью, собирая фразу, или с клавиатуры клавишами цифр. Всё бы ничего, если бы не отсутствие поддержки чисел с num-панели. Поддерживаются только те, что над буквами. Что, лично для меня, страшно неудобно. Ну что ж, приступим.

Для начала я решил узнать как оно там вообще работает. Посмотрел все eventListener-ы на document и нашёл нужный методом перебора при debug-е. Он слушает keydown и несколько неуклюже обрабатывает event.which, поддерживая только один диапазон для чисел. Поиграл с ним и понял, что при "патченном" which num-цифры работают прекрасно. Написал небольшой скрипт в консоли примерно следующего толку и решил что дело в шляпе:

document.addEventListener('keydown',  evt =>
{
	if(evt.which > 96 && evt.which < 105)
	{
		const which = evt.which - 48;

		$.event.trigger(
		{
			type: 'keydown',
			which,
			originalEvent: { target: document.body }
		});
	}
});

Забыл упомянуть, puzzle-english агрессивно использует jQuery. Чем я не применул воспользоваться. Там ведь свои обёртки и свои рецепты. Обернул этот код расширением и... Обломался. Chrome не позволяет использовать со страницы жертвы ничего кроме DOM. Т.е. доступа к jQuery нет, доступа к любым кастомным window-полям тоже нет. Ничего нет. 

Ну не беда, подумал я и решил организовать keydown средствами браузера. Что у нас там есть? document.createEvent и initKeyboardEvent. Поковырялся — работает плохо. Да ещё и deprecated. Ок, а как ещё можно? Ага, у нас есть класс KeyboadEvent. Ok:

new KeyboardEvent('keydown', { which: 50 });

Ага. Нифига. В документации одно, в браузере другое. Плевал он на which и прочие поля. Что пишут нам интернеты? Ух, дичь какая... Зато работает:

window.evt = evt = document.createEvent("KeyboardEvent");
evt.initKeyboardEvent('keydown',
	true, false, null, 0, false,
	0, false, which, 0);
evt.__defineGetter__('which', () => which);
document.dispatchEvent(evt);

Правда только из консоли. Почему? Потому что браузер заменяет отправленные из расширения события их копиями в основной тред. В целях безопасности. И того мы снова теряем which.

Что в итоге? В итоге вспомнил, что там ещё мышью можно было кликать. Стало быть можно эмулировать клик. Просто вызвав у DOMElement-а метод click. С этим уже граблей не было.

В общем мораль такова: расширения скованы цепями. Попытки сделать что-то просто — могут упереться в открытые баги или просто запреты. Так и живём ;)

For-of и браузеры

28 января 2016

Оказывается, браузеры по-разному относятся к итерированию цикла for-of. Судите сами:

for(const a of []) ; // chrome: ok, ff: syntax error

На что ругается Firefox? Говорит, что a указана, как константа, а используется как переменная. Но почему?

for(let a of [1, 2])
  setTimeout(() => alert(a));
  • Chrome: 1, 2
  • Firefox: 2, 2

Всё просто. Chrome каждую итерацию пересоздаёт scope, а Firefox довольствуется одним. И если с const ошибка вылезет сразу (правда только в Firefox). То в случае чего-нибудь асинхронного ждите трудно-вылавливаемые баги, которые проявятся только в Firefox-е. В спеку мне лезть лень, но код генерируемый babel-ем ближе к Chrome-варианту. Кто прав?

Нечёткий поиск по именам файлов в ChromeDevTools

24 сентября 2014

Случайно обнаружил, что ChromeDevTools поддерживают нечёткий поиск по именам файлов на вкладке Sources. Поиск доступен также как и в SublimeText2 по комбинации Ctrl + P. Enjoy! :)