Создание расширения для Google Chrome Часть 1: Граббер изображений

Оглавление

Введение
Базовая структура расширения
    Минимальное расширение Chrome
Установка расширения Chrome
Добавьте значки расширений
Создание интерфейса расширения
Реализовать функцию «GRAB NOW»
    Получение необходимых разрешений
    Получение информации об активной вкладке браузера
    Захват изображений с текущей страницы
    Очистка кода
Заключение

Введение

Расширения Chrome — это небольшие программы, которые можно установить в браузер Google Chrome для расширения его возможностей. Обычно, чтобы установить расширение Chrome, пользователь должен открыть Chrome Web Store, найти нужное расширение и установить его оттуда.

В этой статье я покажу, как создать расширение Chrome с нуля. Расширение, которое мы сегодня создадим, будет использовать API Chrome для получения доступа к содержимому веб-страниц, открытых в браузере, и извлечения из них различной информации. Используя эти API, можно не только читать содержимое веб-страниц, но и записывать на них содержимое, а также взаимодействовать с этими страницами, например, автоматически нажимать кнопки или переходить по ссылкам. Эта возможность может быть использована для широкого круга задач автоматизации браузера, таких как сбор необходимой информации с веб-сайтов или автоматизация веб-серфинга, что может быть полезно для автоматизации тестирования пользовательского интерфейса.

В этой статье я проведу вас через процесс создания расширения под названием Image Grabber. Полученное расширение будет предоставлять интерфейс для подключения к веб-сайту, чтения всех изображений с него, получения их абсолютных URL-адресов и копирования этих URL-адресов в буфер обмена. В ходе этого процесса вы узнаете об основных элементах расширения Google Chrome, которые можно повторно использовать для создания расширения любого типа.

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

Это только первая часть данного руководства. Во второй части я покажу, как расширить интерфейс расширения для выбора и загрузки захваченных изображений в виде ZIP-архива, а затем объясню, как опубликовать расширение в Google Chrome WebStore. Вот ссылка на вторую часть: https://dev.to/andreygermanov/create-a-google-chrome-extension-part-2-image-grabber-47h7.

Основная структура расширения

Расширение Google Chrome — это веб-приложение, которое может содержать любое количество HTML-страниц, таблиц стилей CSS, файлов JavaScript, изображений, любых других файлов и файл manifest.json в той же папке, который определяет, как будет выглядеть и работать данное конкретное расширение.

Минимальное расширение Chrome

Минимальное расширение Chrome состоит только из файла manifest.json. Это пример базового файла manifest.json, который можно использовать в качестве шаблона при начале создания любого нового расширения Chrome:

{
    "name": "Image Grabber",
    "description": "Extract all images from current web page",
    "version": "1.0",
    "manifest_version": 3,
    "icons": {},
    "action": {},
    "permissions": [],
    "background":{}
}
Вход в полноэкранный режим Выход из полноэкранного режима

Единственными обязательными параметрами являются name, description, version и manifest_version. Значение manifest_version должно быть равно 3. Значения остальных параметров вы выбираете сами, они должны четко описывать ваше расширение и его версию. В этом примере я описал расширение Image Grabber, которое будет извлекать ссылки всех изображений с текущей страницы браузера.

Полный список опций, которые можно указать в файле manifest.json, можно посмотреть в официальной документации.

Папка с одним файлом manifest.json — это минимальное запускаемое расширение Chrome, которое можно упаковать, установить в Chrome и распространять. Это минимальное расширение будет иметь вид по умолчанию и ничего не будет делать, пока мы не определим другие параметры: icons, action, permissions и background.

Итак, давайте создадим папку image_grabber и поместим в нее файл manifest.json с содержимым по умолчанию. Затем, давайте просто установим это расширение в Chrome.

Установка расширения Chrome

Когда вы разрабатываете расширение, оно имеет вид папки с файлами. В терминах расширений Chrome она называется unpacked extension. После завершения разработки вам нужно будет упаковать папку расширения в архив с расширением .crx с помощью менеджера расширений Chrome. Этот архив затем можно использовать для загрузки в Chrome Web Store, откуда пользователи смогут установить ваше расширение в свои браузеры.

Чтобы протестировать и отладить расширение во время разработки, вы можете установить распакованное расширение в Chrome. Для этого введите chrome://extensions в строке URL браузера, чтобы открыть менеджер расширений Chrome.

Для установки и отладки расширений во время разработки включите переключатель Режим разработчика в правой части панели расширений. Появится панель управления расширениями:

Затем нажмите кнопку Load unpacked и выберите папку с расширением. Укажите ее на наше минимальное расширение image_grabber. Сразу после этого в списке установленных расширений появится панель для расширения Image Grabber:

Панель расширения Image Grabber показывает уникальный ID, описание и версию расширения. Каждый раз при изменении файла manifest.json необходимо нажать иконку Reload на панели расширений, чтобы перезагрузить обновленное расширение:

Чтобы использовать расширение в браузере, вы можете найти его в списке установленных расширений Chrome. Чтобы просмотреть этот список, нажмите кнопку Extensions с пиктограммой

в правой части URL-бара Chrome и найдите в выпадающем списке пункт «Image Grabber». Вы также можете нажать кнопку «Pin» в правой части расширения, чтобы поместить иконку расширения на панель инструментов браузера в одну строку с другими распространенными расширениями:

После Pin расширения на панели инструментов появится его значок по умолчанию:

Вот и все. Мы установили минимально работающее расширение Chrome. Однако оно выглядит как простой символ «I» на сером фоне, и при нажатии на него ничего не происходит. Давайте добавим другие недостающие части в manifest.json, чтобы изменить это.

Добавьте иконки расширений

Параметр icons в файле manifest.json имеет формат объекта Javascript, который определяет расположение иконок различных размеров. Расширение должно иметь иконки разных размеров: 16×16 px, 32×32 px, 48×48 px и 128×128 px. Иконки представляют собой изображения «.PNG», которые должны быть размещены в любом месте папки расширения. Файлы изображений могут иметь любые имена. Я создал 4 иконки соответствующих размеров в файлах 16.png, 32.png, 48.png и 128.png и поместил их в папку icons в корневой папке расширения. Затем, manifest.json следует указать на эти места с помощью параметра icons таким образом, как показано ниже:

{
    "name": "Image Grabber",
    "description": "Extract all images from current web page",
    "version": "1.0",
    "manifest_version": 3,
    "icons": {
        "16":"icons/16.png",
        "32":"icons/32.png",
        "48":"icons/48.png",
        "128":"icons/128.png"
    },
    "action": {},
    "permissions": [],
    "background":{}
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Пути к файлам иконок указываются как относительные пути.

После этого нажмите кнопку Reload на панели расширения Image Grabber на вкладке chrome://extensions, чтобы применить измененный manifest.json. В результате вы должны увидеть, что значок расширения на панели инструментов изменился, как показано ниже:

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

Создание интерфейса расширения

Расширение должно что-то делать, оно должно выполнять какие-то действия, чтобы иметь смысл. Расширение позволяет выполнять действия двумя способами:

  • В фоновом режиме, при запуске расширения
  • Из интерфейса расширения, когда пользователь взаимодействует с ним с помощью кнопок или других элементов управления пользовательского интерфейса.

Расширение может использовать оба варианта одновременно.

Для запуска действий в фоновом режиме необходимо создать JS-скрипт и указать его расположение в параметре background в файле manifest.json. Этот скрипт может определять слушателей для широкого спектра событий браузера, например: когда расширение установлено, когда пользователь открывает/закрывает вкладку в браузере, когда пользователь добавляет/удаляет закладку и многие другие. Затем этот скрипт будет постоянно работать в фоновом режиме и реагировать на каждое из этих событий, выполняя Javascript-код из функций обработки событий.

Для данного расширения я не буду использовать эту функцию, поэтому параметр background в manifest.json будет пустым. Он включен только для того, чтобы файл manifest.json был полезен в качестве стартового шаблона для расширения Chrome любого типа, но в расширении Image Grabber единственным действием является «Grab images», и оно будет запускаться только из пользовательского интерфейса, когда пользователь явно нажмет кнопку «GRAB NOW».

Чтобы запускать действия из интерфейса, нам нужно определить интерфейс. Интерфейсы для расширений Chrome — это HTML-страницы, которые могут быть объединены с таблицами стилей CSS для стилизации этих страниц, и файлы Javascript, которые определяют действия, запускаемые при взаимодействии пользователя с элементами этого интерфейса. Основной интерфейс — это интерфейс, отображаемый, когда пользователь нажимает на значок расширения на панели инструментов, и он должен быть определен в параметре action файла manifest.json. В зависимости от того, как определен интерфейс, он может открываться как новая вкладка в браузере или отображаться в виде всплывающего окна под кнопкой расширения, когда пользователь нажимает на нее.

Расширение Image Grabber использует второй вариант. Оно отображает всплывающее окно с заголовком и кнопкой «GRAB NOW». Итак, давайте определим это в manifest.json:

{
    "name": "Image Grabber",
    "description": "Extract all images from current web page",
    "version": "1.0",
    "manifest_version": 3,
    "icons": {
        "16":"icons/16.png",
        "32":"icons/32.png",
        "48":"icons/48.png",
        "128":"icons/128.png"
    },
    "action": {
        "default_popup":"popup.html"
    },
    "permissions": [],
    "background":{}
}
Войти в полноэкранный режим Выход из полноэкранного режима

Итак, как определено здесь, основной интерфейс — это всплывающее окно, а содержимое этого всплывающего окна должно находиться в файле popup.html. Этот файл представляет собой обычную HTML-страницу. Итак, создайте файл popup.html в папке расширения со следующим содержимым:

<!DOCTYPE html>
<html>
    <head>
        <title>Image Grabber</title>
    </head>
    <body>
        <h1>Image Grabber</h1>
        <button id="grabBtn">GRAB NOW</button>
    </body>
</html>
Вход в полноэкранный режим Выход из полноэкранного режима

Это простая страница с заголовком «Image Grabber» и кнопкой «GRAB NOW», которая имеет идентификатор «grabBtn».

Перейдите по адресу chrome://extensions, чтобы перезагрузить расширение Image Grabber. Теперь вы можете нажать на иконку расширения, чтобы увидеть всплывающее окно с интерфейсом:

Это работает, но выглядит недостаточно идеально. Давайте придадим ему стиль с помощью CSS. Создайте следующий файл popup.css в папке расширения:

body {
    text-align:center;
    width:200px;
}

button {
    width:100%;
    color:white;
    background:linear-gradient(#01a9e1, #5bc4bc);
    border-width:0px;
    border-radius:20px;
    padding:5px;
    font-weight: bold;
    cursor:pointer;
}
Вход в полноэкранный режим Выход из полноэкранного режима

Этот CSS определяет, что body должен иметь ширину 200px. Таким образом, размер всплывающего окна должен быть определен для расширения Chrome. Если он не определен, то расширение будет использовать минимальный размер, необходимый для отображения содержимого.

Затем добавьте эту таблицу стилей popup.css в заголовок страницы popup.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Image Grabber</title>
        <link rel="stylesheet" type="text/css" href="popup.css"/>
    </head>
    <body>
        <h1>Image Grabber</h1>
        <button id="grabBtn">GRAB NOW</button>
    </body>
</html>
Вход в полноэкранный режим Выход из полноэкранного режима

Итак, когда все это готово, вы можете снова щелкнуть на значке расширения, чтобы увидеть стилизованное всплывающее окно:

Как вы могли заметить, вам не нужно перезагружать расширение каждый раз при изменении HTML или любого другого файла. Вы должны перезагружать расширение только при изменении manifest.json.

Теперь, чтобы сделать наш пользовательский интерфейс законченным, давайте добавим код Javascript для реакции на событие нажатия кнопки «GRAB NOW». Здесь есть одно важное замечание, Chrome не позволяет использовать встроенный Javascript на HTML-страницах расширений. Весь код Javascript должен быть определен только в отдельных файлах .js. Поэтому создайте файл popup.js в папке extensions со следующим кодом-заполнителем:

const grabBtn = document.getElementById("grabBtn");
grabBtn.addEventListener("click",() => {    
    alert("CLICKED");
})
Вход в полноэкранный режим Выйти из полноэкранного режима

и включите этот файл скрипта в страницу popup.html:

<!DOCTYPE html>
<html>
    <head>
        <title>Image Grabber</title>
        <link rel="stylesheet" type="text/css" href="popup.css"/>
    </head>
    <body>
        <h1>Image Grabber</h1>
        <button id="grabBtn">GRAB NOW</button>
        <script src="popup.js"></script>
    </body>
</html>
Войти в полноэкранный режим Выход из полноэкранного режима

Этот код добавляет слушателя события onClick к кнопке с идентификатором grabBtn. Теперь, если вы откроете всплывающее окно расширения и нажмете кнопку «GRAB NOW», оно должно отобразить окно оповещения с текстом «CLICKED».

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

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

Теперь давайте реализуем «бизнес-логику» этого конкретного расширения — обработчик onClick для кнопки «GRAB NOW», чтобы получить список URL-адресов изображений с текущей страницы браузера и скопировать его в буфер обмена.

Реализация функции «GRAB NOW»

Используя Javascript в расширении, вы можете делать все, что можно делать с помощью Javascript на сайте: открывать другие HTML-страницы с текущей, делать запросы к удаленным серверам, загружать данные из расширения в удаленные места и все остальное. Но в дополнение к этому, если этот скрипт выполняется в расширении Chrome, вы можете использовать API браузера Chrome для взаимодействия с объектами браузера: читать из них и изменять их. Большинство API Google Chrome доступны через пространство имен chrome. В частности, для расширения Image Grabber мы будем использовать следующие API:

Получение необходимых разрешений

По умолчанию, в целях безопасности, Chrome не разрешает доступ ко всем доступным API. Расширение должно объявить, какие разрешения ему необходимы, в параметре permissions файла manifest.json. Существует множество разрешений, все они описаны в официальной документации здесь: https://developer.chrome.com/docs/extensions/mv3/declare_permissions/. Для Image Grabber нам нужны два разрешения со следующими именами:

Чтобы получить эти разрешения, нужно добавить их имена в параметр массива permissions в manifest.json:

{
    "name": "Image Grabber",
    "description": "Extract all images from current web page",
    "version": "1.0",
    "manifest_version": 3,
    "icons": {
        "16":"icons/16.png",
        "32":"icons/32.png",
        "48":"icons/48.png",
        "128":"icons/128.png"
    },
    "action": {
        "default_popup":"popup.html",
    },
    "permissions": ["scripting", "activeTab"],
    "background":{}
}
Вход в полноэкранный режим выйти из полноэкранного режима

и перезагрузить расширение на панели chrome://extensions.

Это окончательный manifest.json для данного проекта. Теперь в нем есть все необходимые части: иконки, ссылка на основной интерфейс всплывающего окна и разрешения, которые требует этот интерфейс.

Получение информации об активной вкладке браузера

Для запроса информации о вкладках браузера мы будем использовать функцию chrome.tabs.query, которая имеет следующую сигнатуру:

chrome.tabs.query(queryObject,callback)
Войти в полноэкранный режим Выйти из полноэкранного режима
  • Объект queryObject — это объект Javascript с параметрами, определяющими критерии поиска вкладок браузера, которые нам нужно получить.
  • callback — это функция, которая вызывается после завершения запроса. Эта функция выполняется с одним параметром tabs, который представляет собой массив найденных вкладок, удовлетворяющих заданным критериям поиска. Каждый элемент массива tabs представляет собой объект Tab. Объект Tab описывает найденную вкладку и содержит уникальный идентификатор вкладки, ее заголовок и другую информацию.

Здесь я не буду полностью описывать формат queryObject и возвращаемый объект Tab. Вы можете найти эту информацию в справке по API chrome.tabs здесь: https://developer.chrome.com/docs/extensions/reference/tabs/.

Для целей расширения Image Grabber нам нужно запросить активную вкладку. Запрос для поиска такой вкладки — {active: true}.

Давайте напишем код для получения информации об активной вкладке в обработчик onClick кнопки «GRAB NOW»:

const grabBtn = document.getElementById("grabBtn");
grabBtn.addEventListener("click",() => {    
    chrome.tabs.query({active: true}, (tabs) => {
        const tab = tabs[0];
        if (tab) {
            alert(tab.id)
        } else {
            alert("There are no active tabs")
        }
    })
})
Вход в полноэкранный режим Выйти из полноэкранного режима

Этот код выполняет запрос, чтобы получить все вкладки, которые являются активными. После завершения запроса вызывается обратный вызов с массивом найденных вкладок в аргументе tabs. Активной может быть только одна вкладка, поэтому можно считать, что это первый и единственный элемент массива tabs. Если активная вкладка существует, мы показываем идентификатор этой вкладки в окне оповещения (мы заменим это оповещение разумным кодом в следующем разделе). Однако если активных вкладок нет, мы предупреждаем пользователя об этом.

Теперь, если вы откроете расширение и нажмете кнопку «GRAB NOW», оно должно показать окно предупреждения с числовым идентификатором активной вкладки.

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

Захват изображений с текущей страницы

Расширение может взаимодействовать с открытыми страницами браузера Chrome с помощью API Chrome Scripting JavaScript, расположенного в пространстве имен chrome.scripting. В частности, мы будем использовать этот API для внедрения скрипта на веб-страницу текущей вкладки, выполнения этого скрипта и возврата результата обратно в расширение. Во время работы расширение имеет доступ ко всему содержимому веб-страницы, на которую внедрен этот скрипт.

Единственная функция API chrome.scripting, которая используется для этого расширения, — executeScript. Она имеет следующую сигнатуру:

chrome.scripting.executeScript(injectSpec,callback)
Войти в полноэкранный режим Выйти из полноэкранного режима

injectSpec

Это объект типа ScriptInjection. Он определяет, куда и как внедрять скрипт. Параметр target этого объекта используется для указания «куда» внедрять скрипт — идентификатор вкладки браузера, в которую должен быть внедрен скрипт. Затем другие параметры этого объекта определяют «как» внедрить скрипт. Скрипт может быть внедрен как:

  • файл или файлы — в этом случае необходимо указать массив файлов Javascript для инъекции. Файлы должны существовать в папке расширения.
  • function — в этом случае необходимо указать функцию для инъекции. Функция должна существовать в том же файле (popup.js).

Скрипт, который нам нужно внедрить, будет использоваться для получения всех изображений целевой страницы и возврата их URL. Это небольшой скрипт, поэтому мы будем внедрять его как функцию, расположенную в том же файле popup.js. Итак, injectSpec для этого случая будет выглядеть следующим образом:

{
    target:{ tabId: tab.id, allFrames: true },
    func: grabImages,
}, 
Войти в полноэкранный режим Выйти из полноэкранного режима

Здесь мы используем id объекта tab, который мы получили в предыдущем шаге, как цель для инъекции скрипта. Также установлена опция allFrames, которая указывает, что внедряемый скрипт должен быть выполнен в каждом встроенном фрейме целевой страницы, если эта страница имеет встроенные фреймы. В качестве скрипта мы внедрим функцию grabImages, которая будет определена позже.

обратный вызов

Внедренная функция будет выполнять действия на целевой веб-странице и на всех встроенных фреймах этой страницы (каждый фрейм — это отдельная страница) и вернет результат. После этого расширение выполнит функцию обратного вызова с возвращенным результатом в качестве аргумента. Аргументом функции является массив объектов типа InjectionResult для каждого фрейма. Каждый объект содержит свойство «result», которое является фактическим результатом, который возвращает функция grabImages.

Теперь давайте соединим все части вместе:

const grabBtn = document.getElementById("grabBtn");
grabBtn.addEventListener("click",() => {    
    chrome.tabs.query({active: true}, function(tabs) {
        var tab = tabs[0];
        if (tab) {
            chrome.scripting.executeScript(
                {
                    target:{tabId: tab.id, allFrames: true},
                    func:grabImages
                },
                onResult
            )
        } else {
            alert("There are no active tabs")
        }
    })
})

function grabImages() {
    // TODO - Query all images on a target web page
    // and return an array of their URLs
}

function onResult(frames) {
    // TODO - Combine returned arrays of image URLs,
    // join them to a single string, delimited by 
    // carriage return symbol and copy to a clipboard
}
Вход в полноэкранный режим Выход из полноэкранного режима

Вот как реализована функция grabImages:

/**
 * Executed on a remote browser page to grab all images
 * and return their URLs
 * 
 *  @return Array of image URLs
 */
function grabImages() {
    const images = document.querySelectorAll("img");
    return Array.from(images).map(image=>image.src);    
}
Вход в полноэкранный режим Выход из полноэкранного режима

Эта функция будет выполняться на целевой веб-странице, поэтому document, указанный в ней, является DOM-узлом документа целевой веб-страницы. Эта функция запрашивает список всех узлов img из документа, затем преобразует этот список в массив и возвращает массив URL (image.src) этих изображений. Это очень сырая и простая функция, поэтому в качестве домашнего задания вы можете настроить ее: применить различные фильтры к этому списку, очистить URLS, удалив из них строки «query», и так далее, чтобы результирующий список выглядел идеально.

После выполнения этой функции в каждом фрейме целевой веб-страницы массивы результатов будут объединены и отправлены в функцию обратного вызова onResult, которая может выглядеть следующим образом:

/**
 * Executed after all grabImages() calls finished on 
 * remote page
 * Combines results and copy a list of image URLs 
 * to clipboard
 * 
 * @param {[]InjectionResult} frames Array 
 * of grabImage() function execution results
 */
function onResult(frames) {
    // If script execution failed on the remote end 
    // and could not return results
    if (!frames || !frames.length) { 
        alert("Could not retrieve images from specified page");
        return;
    }
    // Combine arrays of the image URLs from 
    // each frame to a single array
    const imageUrls = frames.map(frame=>frame.result)
                            .reduce((r1,r2)=>r1.concat(r2));
    // Copy to clipboard a string of image URLs, delimited by 
    // carriage return symbol  
    window.navigator.clipboard
          .writeText(imageUrls.join("n"))
          .then(()=>{
             // close the extension popup after data 
             // is copied to the clipboard
             window.close();
          });
}
Вход в полноэкранный режим Выход из полноэкранного режима

Не все вкладки, открытые в браузере, являются вкладками с веб-страницами внутри. Например, вкладка со списком расширений или вкладка с настройками браузера не являются вкладками с веб-страницами. Если вы попытаетесь запустить скрипт с объектом document на этих вкладках, он потерпит неудачу и ничего не вернет. Поэтому в начале функции onResult мы проверяем результат и продолжаем только в том случае, если он существует. Затем мы объединяем массивы URL изображений, возвращенных для каждого кадра, в один массив с помощью комбинации map/reduce и затем, используя API window.navigator.clipboard, копируем объединенный в строку массив в буфер обмена. Функция writeText является асинхронной, поэтому мы должны дождаться ее завершения, разрешив обещание, которое она возвращает. И когда оно будет разрешено, мы закроем всплывающее окно расширения.

Я объяснил только одну функцию API сценариев Chrome и только в контексте расширения Image Grabber. Вы можете посмотреть полную документацию по Chrome Scripting API, чтобы прояснить все недостающие детали: https://developer.chrome.com/docs/extensions/reference/scripting/ .

Очистка кода

Последнее, что я бы сделал с кодом, который обрабатывает событие onClick «GRAB NOW», — это выделил код, выполняющий chrome.scripting в отдельную функцию:

const grabBtn = document.getElementById("grabBtn");
grabBtn.addEventListener("click",() => {    
    // Get active browser tab
    chrome.tabs.query({active: true}, function(tabs) {
        var tab = tabs[0];
        if (tab) {
            execScript(tab);
        } else {
            alert("There are no active tabs")
        }
    })
})

/**
 * Function executes a grabImages() function on a web page,
 * opened on specified tab
 * @param tab - A tab to execute script on
 */
function execScript(tab) {
    // Execute a function on a page of the current browser tab
    // and process the result of execution
    chrome.scripting.executeScript(
        {
            target:{tabId: tab.id, allFrames: true},
            func:grabImages
        },
        onResult
    )
}
Вход в полноэкранный режим Выход из полноэкранного режима

И окончательное содержание popup.js будет следующим:

const grabBtn = document.getElementById("grabBtn");
grabBtn.addEventListener("click",() => {    
    // Get active browser tab
    chrome.tabs.query({active: true}, function(tabs) {
        var tab = tabs[0];
        if (tab) {
            execScript(tab);
        } else {
            alert("There are no active tabs")
        }
    })
})

/**
 * Execute a grabImages() function on a web page,
 * opened on specified tab and on all frames of this page
 * @param tab - A tab to execute script on
 */
function execScript(tab) {
    // Execute a function on a page of the current browser tab
    // and process the result of execution
    chrome.scripting.executeScript(
        {
            target:{tabId: tab.id, allFrames: true},
            func:grabImages
        },
        onResult
    )
}

/**
 * Executed on a remote browser page to grab all images
 * and return their URLs
 * 
 *  @return Array of image URLs
 */
function grabImages() {
    const images = document.querySelectorAll("img");
    return Array.from(images).map(image=>image.src);    
}

/**
 * Executed after all grabImages() calls finished on 
 * remote page
 * Combines results and copy a list of image URLs 
 * to clipboard
 * 
 * @param {[]InjectionResult} frames Array 
 * of grabImage() function execution results
 */
function onResult(frames) {
    // If script execution failed on remote end 
    // and could not return results
    if (!frames || !frames.length) { 
        alert("Could not retrieve images from specified page");
        return;
    }
    // Combine arrays of image URLs from 
    // each frame to a single array
    const imageUrls = frames.map(frame=>frame.result)
                            .reduce((r1,r2)=>r1.concat(r2));
    // Copy to clipboard a string of image URLs, delimited by 
    // carriage return symbol  
    window.navigator.clipboard
          .writeText(imageUrls.join("n"))
          .then(()=>{
             // close the extension popup after data 
             // is copied to the clipboard
             window.close();
          });
}
Войти в полноэкранный режим Выход из полноэкранного режима

Заключение

После этого вы можете открыть любую веб-страницу браузера с изображениями, нажать на расширение Image Grabber, чтобы открыть его всплывающий интерфейс, а затем нажать кнопку «GRAB NOW». Затем вставьте содержимое буфера обмена в любой текстовый редактор. Он должен вставить список абсолютных URL всех изображений с этой веб-страницы.

Вы можете клонировать и использовать полный исходный код этого расширения из моего репозитория GitHub: https://github.com/AndreyGermanov/image_grabber. Однако я бы рекомендовал создать это расширение с нуля, читая эту статью.

Это только первая часть руководства, связанная с этим расширением. Во второй части я буду использовать этот список URL-адресов изображений для создания дополнительного интерфейса для этого расширения, который позволит загружать все или выбранные изображения из этого списка в виде одного ZIP-архива. Это определенно полезнее, чем просто иметь список URL-адресов в буфере обмена. Кроме того, я покажу, как упаковать готовое расширение и загрузить его в Chrome Web Store, что сделает его доступным для всех желающих.

Часть 2 читайте здесь: https://dev.to/andreygermanov/create-a-google-chrome-extension-part-2-image-grabber-47h7.

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

LinkedIn: https://www.linkedin.com/in/andrey-germanov-dev/
Facebook: https://web.facebook.com/AndreyGermanovDev
Twitter: https://twitter.com/GermanovDev

Мой сайт онлайн-услуг: https://germanov.dev

Счастливого кодирования, ребята!

Оставьте комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *