Pull to refresh

Получаем и отображаем favicon сайта в AdobeAIR

Reading time 2 min
Views 713
Safari умеет отображать картинки формата .ico, а вот AdobeAIR не умеет, хоть и оба используют WebKIT. Очень досадно, когда хочется около ссылки на сайт отобразить его favicon, а сделать этого не получается.

Решение нашел, хоть и не идеальное. Решил использовать сервис для получения favicon с сайта в png, получать оттуда ответ и кешировать его у себя локально.



Для загрузки изображений мы будем использовать air.URLLoader.

Получилась такая функция:

function getFavicon( url ) {
    // тут мы из строки с url вытаскиваем только нужную нам часть - название домена 
    var domain = id.match(/(\w+):\/\/([^\/:]+)(:\d*)?([^# ]*)/i); 
    if (domain != null) { 
        var domname = domain[2]; 
         
        // проверяем, есть ли у нас в кеше уже такая иконка 
        var file = air.File.applicationStorageDirectory.resolvePath("favicons/" + domname + '.png'); 
        if ( file.exists ) 
            // и, если есть, возвращаем ссылку на нее 
            return file.url; 
         
        // а вот если нет, шлем запрос на sectorprime 
        var fav = "http://www.sectorprime.com/cgi-bin/fav2png.pl?fav=" + domname; 
        air.trace('загружаем favicon ' + domname); 
         
        var request = new air.URLRequest(fav); 
         
        var loader = new air.URLLoader</a>(); 
        // важно! получать данные будем в бинарном виде 
        loader.dataFormat = air.URLLoaderDataFormat.BINARY; 
         
        loader.addEventListener(air.Event.COMPLETE, function( e ) { 
            // эта функция отработается сразу после того, как мы получим ответ на запрос 
            var loader = e.target; 
             
            // создаем поток для записи в файл 
            var fileStream = new air.FileStream(); 
            fileStream.open(file, air.FileMode.WRITE);  
            // и записываем в него все, что получили 
            fileStream.writeBytes(loader.data); 
            fileStream.close(); 
 
        } ); 
         
        // собственно, запускаем процесс загрузки 
        loader.load(request); 
    } 
 
    // а вот эта иконка будет выдаваться у нас по-умолчанию 
    return "/images/icon_item.png";
}


В первый раз мы не отобразим иконку, зато начнем ее качать. При вызове функции в следующий раз иконка возьмется из локального кеша (если уже успела скачаться). Почему не сразу? — чтобы не тормозить выполнение скрипта ожиданием.

Очистка кеша иконок можно сделать примерно такой функцией:

var favdir = air.File.applicationStorageDirectory.resolvePath("favicons"); 
             
// выясняем, существует ли такая папка вообще 
if ( ( favdir.exists ) && ( favdir.isDirectory ) ) 
    // если существует, то удаляем папку вместе с содержимым 
    favdir.deleteDirectory(true);


Недостатки такого решения:
  • Иконка выдается не сразу;
  • Сервис выдает какую-то левую стрелку для тех сайтов, у которых недоступна favicon.


Если у кого-то есть предложения по совершенствованию функции, пишите, я буду рад любым комментариям.

Кросспост из личного блога.
Tags:
Hubs:
+5
Comments 1
Comments Comments 1

Articles