Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Firefox плагин для сортировки комментариев на DOU

Підписуйтеся на Telegram-канал «DOU #tech», щоб не пропустити нові технічні статті

Привет, ребята!

Так, как я очень люблю DOU, как и многие другие, я решила написать плагин под Firefox 29+ (и новее) для сортировки комментариев на DOU и поделится им с сообществом. Плагин может быть особенно полезен в длинных топиках, когда хочется сразу полистать последние комментарии, не делая обход всего дерева. Установить его можно по ссылке: addons.mozilla.org/...​/addon/dou-sort-comments. Исходный код плагина доступен здесь: github.com/...​irinkav/dou-sort-comments. Во время разработки плагина пользовалась отличным руководством на официальном сайте Mozilla Firefox: developer.mozilla.org/...​-US/Add-ons/SDK/Tutorials.


Функции

  • Сортировка комментариев включить/выключить

Техническая комплектация решения

  • Платформа: Firefox 29+
  • API: Firefox Add-on SDK
  • Язык: JavaScript
  • Дополнительные библиотеки: jQuery v1.11.1

Описание решения

  • dou-sort-comments/lib/main.js — основной скрипт, с которого начинается запуск плагина Firefox’ом. В этом скрипте описано следующее:
    • следим за загрузками страниц (pageMod.PageMod)
    • интересуемся любыми страницами, размещенными на доменах *.dou.ua и *.developers.org.ua (include: [«*.dou.ua», «*.developers.org.ua»])
    • ждем окончания загрузки страницы со всеми CSS/JS/images перед отправкой сообщения типа loaded (contentScriptWhen: «end»)
    • подключаем внешние библиотеки к плагину
      contentScriptFile: [self.data.url("jquery-min.js"), self.data.url("my-script.js")]
      где,

      jquery-min.js (dou-sort-comments/data/jquery-min.js) — многими известная библиотека для работы с HTML страничками. Её я использую для сортировки комментариев на странице

      my-script.js (dou-sort-comments/data/my-script.js) — мой скрипт, в котором находится обработчик сообщений о том, что страница выгружена пользователю
    • чтоб послать сообщение о том, что страница полностью загружена типа loaded (из main.js) в слушателсь из my-script.js, я использую следующий код:
      worker.port.emit("loaded");
  • dou-sort-comments/data/my-script.js — простенький обработчик сообщений типа loaded, так что проблем с его пониманием не должно быть.
  • Сортировку комментариев на страничке реализовала с использованием jQuery sort API. Код находится в dou-sort-comments/data/my-script.js в функции с названием sort
  • Для того, чтоб отслеживать изменения динамического контента использовала подход, основанный на MutationObserver’е
  • На случай, если будут приходить какие-либо AJAX ответы, которые могут изменить DOM страницы, решила использовать подход на основе debounce’а, который заключается в том, что сколько бы не было запросов на протяжении (в моем случае 300 мс), функция будет выполнена лишь один раз за установленное время (в моем случае 300 мс), в результате чего выиграем в производительности, потому как сортировку по DOM’у нужно будет делать всего 1 раз за 300 мс. Об этом подходе (debounce) можно прочитать здесь: Function Debouncing, откуда я стянула код для debounce’инга обращений за вызовом функции сортировки и в исходном коде не забыла сделать на это ссылку

P.S.: Если у кого будет время и желание мне помочь, то посмотрите пожалуйста мой код (можно по ссылке github.com/...​ter/data/my-script.js#L28), и объясните мне в комментариях пожалуйста, почему не отрабатывает в моем случае вызов $("a.expand-thread").trigger(’click’); в плагине, который используется для разворачивания всех комментариев топика перед сортировкой, если свёрнутые (находим их по селектору a.expand-thread) имеются. Интересен в этой проблеме тот факт, что код $("a.expand-thread").trigger(’click’); работает на ура из под firebug debug консоли, из-за чего я в некотором замешательстве... Буду очень благодарна за помощь.

Мой workaround описанной выше проблемы, который работает:

    var elements = document.getElementsByClassName("expand-thread");
    for (var idx in elements) {
        var element = elements[idx];
        if (/a/i.test(element.nodeName)) {
            element.click();
        }
    }

Спасибо за внимание!

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному0
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Коментар порушує правила спільноти і видалений модераторами.

Коментар порушує правила спільноти і видалений модераторами.

Коментар порушує правила спільноти і видалений модераторами.

Обновился плагин в соответствии с рекомендациями от Alexey Migutsky. Детали обновления доступны здесь dou.ua/...c/10383/#502837

Расширение было переработано и теперь плагин интегрируется в существующую страницу, поэтому никаких кнопок на панели инструментов Firefox’а вы не увидите, только на странице ссылку с названием Отсортировать комментарии рядом со ссылкой — Подписаться на комментарии. Производительность расширения была увеличена в ~ 61 раз! Всё по примеру того, как было сделано для Chrome’а. Статья с описанием здесь dou.ua/...ms/topic/10383

Последняя версия плагина 0.5.
Установить его можно по ссылки addons.mozilla.org/...-sort-comments

Можно было бы написать поддерживается начиная с N версии, а то, решил установить потестить, а тут — Not available for Firefox 22.0 :)

Так вроде как написано ;-)


Платформа: Firefox 29+

Даже выделено :(
Простите мои невнимательность, посмотрю в FF 30. Если что, отпишусь сюда в тему.

Отлично, еще бы для New Opera ну или хотя бы для Chrome сделать.

Спасибо, Максим, планирую в обозримом будущем для Chrome написать.

Я написала плагин под Chrome и выложила его на Chrome Web Store (официальный онлайн интернет-магазин компании Google).

О плагине можно прочитать по ссылке dou.ua/...ms/topic/10383

Ирина, хватит задротить !

п.с.: ну а вообще молодец, конечно.

попробуй
$("a.expand-thread").each(function() {
this.click();
});

Спасибо большое, Дима! Так работает.

Я пробовала такой же вариант, но только с использованием $(this).click();, но он не работает. Насколько я понимаю, то разница между this.click(); и $(this).click(); в том, что this — это чистый HTML элемент, а $(this) — HTML элемент в обёртке jQuery, тоесть функция click может вызываться не напрямую у HTML элемента. Поэтому запись element.click(); (из моего решения) равносильна записи this.click(); (вариант, предложенный тобой) в этом конкретном случае.

Дима, я хотела ещё спросить у тебя, незнаешь ли ты случаем, от чего $(this).click(); не даёт мне ожидаемое поведение? Может если у нас получится решить проблему с $(this).click(); то и получится понять природу проблемы с $("a.expand-thread").trigger(’click’);?

Я немного накопала по этой теме следующее:
В исходниках jQuery нашла определение функции click

		click: {
			// For checkbox, fire native event so checked state will be right
			trigger: function() {
				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
					this.click();
					return false;
				}
			},

			// For cross-browser consistency, don't fire native .click() on links
			_default: function( event ) {
				return jQuery.nodeName( event.target, "a" );
			}
		},
, тоесть, так как у меня элемент ссылка (а не checkbox), то будет вызван не нативный click(), из-за чего, возможно, проблема с правильной работой $(this).click(); на платформе Firefox 29+.

Как думаешь, Дима, имеет ли право эта гипотеза существовать?

то что я предложил это равносильно твоему workaround’у просто более jquery’ый стиль.

$.fn.trigger(’click’) вызовет только твои обработчики которые ты повесила на элементы. дефолтный обработчик браузера и другие обработчики из других инстансов jQuery вызваны не будут.

а просто $.fn.click он всегда был глючным и непонятно как работал. поэтому вызывать браузерный click, если он есть, более надежно.

если ты знаешь что сайт использует jQuery то можно попробовать вызвать trigger именно их jQuery чтобы вызвались обработчики с сайта, но я давно не смотрел на плагины, не смогу сказать как это сделать. если ты имеешь доступ к window сайта то возьми его $ и вызови trigger.

отдельно спасибо за:

Техническая комплектация решения
Описание решения

Лису не юзаю, но за старания, спасибо, Иринка)

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

Підписатись на коментарі