Spec-Zone.ru › Web Extensions

find.find()

Поиск текста во вкладке.

Вы можете использовать эту функцию для поиска текста на обычных веб-страницах HTTP(S). Она ищет в одной вкладке: вы можете указать ID конкретной вкладки для поиска, или по умолчанию будет использоваться активная вкладка. Она ищет во всех фреймах вкладки.

Вы можете сделать поиск регистрозависимым и ограничить его поиском только целых слов.

По умолчанию функция возвращает только количество найденных совпадений. Передав в функцию параметры includeRangeData и includeRectData, вы можете получить больше информации о расположении совпадений во вкладке.

Функция сохраняет результаты во внутренней памяти, поэтому при последующих вызовах расширения функции find.highlightResults() результаты этого поиска будут выделены до следующего вызова find().

Эта функция — асинхронная и возвращает Promise.

Синтаксис

browser.find.find(
  queryphrase,       // string
  options            // optional object
)

Параметры

options Необязательно

object. Объект, определяющий дополнительные параметры. Может содержать следующие свойства (все необязательные):

caseSensitive

boolean. Если true значение true, поиск будет регистрозависимым. По умолчанию false.

entireWord

boolean. Совпадение только целых слов: «Tok» не будет совпадать внутри «Tokyo». По умолчанию false.

includeRangeData

boolean. Включить данные о диапазонах в ответ, которые описывают, где в DOM страницы было найдено совпадение. По умолчанию false.

includeRectData

boolean. Включить данные о прямоугольниках в ответ, которые описывают, где на отрисованной странице было найдено совпадение. По умолчанию false.

matchDiacritics

boolean. Если true, поиск различает буквы с диакритическими знаками и их базовые буквы. Например, при значении true, поиск «résumé» не находит совпадение для «resume». По умолчанию false.

tabId

integer. ID вкладки для поиска. По умолчанию активная вкладка.

queryphrase

string. Текст для поиска.

Возвращаемое значение

A Promise, который будет выполнен с объектом, содержащим до трех свойств:

count

integer. Количество найденных результатов.

rangeData Необязательно

array. Если includeRangeData было указано в параметре options, это свойство будет включено. Оно предоставляется как массив объектов RangeData, по одному на каждое совпадение. Каждый объект RangeData описывает, где в дереве DOM было найдено совпадение. Это позволит, например, расширению получить текст, окружающий каждое совпадение, чтобы отобразить контекст совпадений.

Элементы соответствуют элементам, заданным в rectData, поэтому rangeData[i] описывает то же совпадение, что и rectData[i].

Каждый объект RangeData содержит следующие свойства:

endOffset

Позиция конца совпадения в текстовом узле.

endTextNodePos

Позиция текстового узла, в котором совпадение закончилось.

framePos

Индекс фрейма, содержащего совпадение. 0 соответствует родительскому окну. Обратите внимание, что порядок объектов в массиве rangeData будет последовательно соответствовать порядку индексов фреймов: например, framePos для первой последовательности объектов rangeData будет 0, framePos для следующей последовательности будет 1 и так далее.

startOffset

Позиция начала совпадения в текстовом узле.

startTextNodePos

Позиция текстового узла, в котором совпадение началось.

rectData Необязательно

array. Если includeRectData было задано в параметре options, это свойство будет включено. Это массив объектов RectData. Содержит прямоугольники для всех совпадений в поиске, относительно верхнего левого угла области просмотра. Расширения могут использовать это для предоставления пользовательского выделения результатов.

Каждый объект RectData содержит данные прямоугольника для одного совпадения. Он имеет два свойства:

rectsAndTexts

Объект, содержащий два массива:

  • rectList: массив объектов, каждый из которых имеет четыре целочисленные свойства: top, left, bottom, right. Эти свойства описывают прямоугольник относительно верхнего левого угла области просмотра.
  • textList: массив строк, соответствующий массиву rectList. Элемент по индексу textList[i] содержит часть совпадения, ограниченную прямоугольником по индексу rectList[i].

Например, рассмотрим часть веб-страницы, которая выглядит так:

Text reading "this domain is established to be used for illustrative examples in documents. You may use this domain in examples without prior coordination or asking for permission." and a "More information" link.

Если вы ищете «You may», совпадение должно быть описано двумя прямоугольниками:

This domain is established to be used for illustrative examples in documents. You may use this domain in examples without prior coordination or asking for permission.". The words "you may" are highlighted.

В этом случае, в объекте RectData , описывающем это совпадение, rectsAndTexts.rectList и rectsAndTexts.textList будут содержать по 2 элемента.

  • textList[0] будет содержать «You », а rectList[0] — его прямоугольник.
  • textList[1] будет содержать «may», а rectList[1] — его прямоугольник.
text

Полный текст совпадения, «You may» в приведённом примере.

Совместимость с браузерами

Рабочие столы Мобильные устройства
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox for Android Opera Android Safari на IOS Samsung Internet
find Нет Нет 57 ? Нет Нет ? ? Нет ? Нет ?
options Нет Нет 57 ? Нет Нет ? ? Нет ? Нет ?

Примеры

Базовые примеры

Поиск «banana» в активной вкладке, вывод количества совпадений и выделение их:

function found(results) {
  console.log(`There were: ${results.count} matches.`);
  if (results.count > 0) {
    browser.find.highlightResults();
  }
}

browser.find.find("banana").then(found);

Поиск «banana» во всех вкладках (обратите внимание, что это требует «tabs» разрешения или соответствующих разрешений на доступ к хосту, так как это обращение к tab.url):

async function findInAllTabs(allTabs) {
  for (const tab of allTabs) {
    const results = await browser.find.find("banana", { tabId: tab.id });
    console.log(`In page "${tab.url}": ${results.count} matches.`);
  }
}

browser.tabs.query({}).then(findInAllTabs);

Использование rangeData

В этом примере расширение использует rangeData для получения контекста, в котором было найдено совпадение. Контекст — это весь textContent узла, в котором было найдено совпадение. Если совпадение охватывает несколько узлов, контекст представляет собой конкатенацию textContent всех охваченных узлов.

Обратите внимание, что для простоты в этом примере не обрабатываются страницы, содержащие фреймы. Чтобы поддержать эту функциональность, вам необходимо разбить rangeData на группы, по одной на каждый фрейм, и выполнить скрипт в каждом фрейме.

Скрипт фонового расширения:

// background.js

async function getContexts(matches) {
  // get the active tab ID
  const activeTabArray = await browser.tabs.query({
    active: true,
    currentWindow: true,
  });
  const tabId = activeTabArray[0].id;

  // execute the content script in the active tab
  await browser.tabs.executeScript(tabId, { file: "get-context.js" });
  // ask the content script to get the contexts for us
  const contexts = await browser.tabs.sendMessage(tabId, {
    ranges: matches.rangeData,
  });
  for (const context of contexts) {
    console.log(context);
  }
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.find.find("example", { includeRangeData: true }).then(getContexts);
});

Скрипт содержимого:

/**
 * Get all the text nodes into a single array
 */
function getNodes() {
  const walker = document.createTreeWalker(
    document,
    window.NodeFilter.SHOW_TEXT,
    null,
    false
  );
  const nodes = [];
  while ((node = walker.nextNode())) {
    nodes.push(node);
  }

  return nodes;
}

/**
 * Gets all text nodes in the document, then for each match, return the
 * complete text content of nodes that contained the match.
 * If a match spanned more than one node, concatenate the textContent
 * of each node.
 */
function getContexts(ranges) {
  const contexts = [];
  const nodes = getNodes();

  for (const range of ranges) {
    let context = nodes[range.startTextNodePos].textContent;
    let pos = range.startTextNodePos;
    while (pos < range.endTextNodePos) {
      pos++;
      context += nodes[pos].textContent;
    }
    contexts.push(context);
  }
  return contexts;
}

browser.runtime.onMessage.addListener((message, sender, sendResponse) => {
  sendResponse(getContexts(message.ranges));
});

Использование rectData

В этом примере расширение использует rectData для «затемнения» совпадений, добавив черные DIV'ы поверх их прямоугольников:

Three search results with some texted redacted by black rectangles.

Обратите внимание, что во многих случаях это не лучший способ затемнения страниц.

Скрипт фонового расширения:

// background.js

async function redact(matches) {
  // get the active tab ID
  const activeTabArray = await browser.tabs.query({
    active: true,
    currentWindow: true,
  });
  const tabId = activeTabArray[0].id;

  // execute the content script in the active tab
  await browser.tabs.executeScript(tabId, { file: "redact.js" });
  // ask the content script to redact matches for us
  await browser.tabs.sendMessage(tabId, { rects: matches.rectData });
}

browser.browserAction.onClicked.addListener((tab) => {
  browser.find.find("banana", { includeRectData: true }).then(redact);
});

Скрипт содержимого:

// redact.js

/**
 * Add a black DIV where the rect is.
 */
function redactRect(rect) {
  const redaction = document.createElement("div");
  redaction.style.backgroundColor = "black";
  redaction.style.position = "absolute";
  redaction.style.top = `${rect.top}px`;
  redaction.style.left = `${rect.left}px`;
  redaction.style.width = `${rect.right - rect.left}px`;
  redaction.style.height = `${rect.bottom - rect.top}px`;
  document.body.appendChild(redaction);
}

/**
 * Go through every rect, redacting them.
 */
function redactAll(rectData) {
  for (const match of rectData) {
    for (const rect of match.rectsAndTexts.rectList) {
      redactRect(rect);
    }
  }
}

browser.runtime.onMessage.addListener((message) => {
  redactAll(message.rects);
});

Примеры расширений

  • find-across-tabs

© 2005–2023 MDN contributors.
Licensed under the Creative Commons Attribution-ShareAlike License v2.5 or later.
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/find/find

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API