Хобрук: Ваш путь к мастерству в программировании

Как заставить расширение Chrome работать для каждого нового добавленного Iframe?

Я создал расширение Chrome в качестве решения для переопределения всплывающих окон helpText на страницах консоли SalesForce. Пузырьки helpText отображают текст без возможности связывания URL-адресов. Это выглядит так:

введите здесь описание изображения

Расширение использует всплывающее окно helpText (которое в окне консоли SalesForce находится внутри iFrame) и делает URL-адрес доступным для щелчка. Он также добавляет перенос слов и помечает ссылки синим цветом.

Решение отлично работает, когда страница загружается с начальным iFrame (или iFrame), то есть при первом открытии консоли SalesForce (https://eu3.salesforce.com/console).
Когда в консоли SalesForce создается новая вкладка, мой скрипт ввода не запускается.

введите здесь описание изображения

Не могли бы вы помочь понять, как внедрить скрипт в каждую новую вкладку, которую создает консоль SalesForce?

Расширение следующим образом:

manifest.js:

    {
   "browser_action": {
      "default_icon": "icons/icon16.png"
   },
   "content_scripts": [ {
      "all_frames": true,
      "js": [ "js/jquery/jquery.js", "src/inject/inject.js" ],
      "matches": [ "https://*.salesforce.com/*", "http://*.salesforce.com/*" ]
   } ],
   "default_locale": "en",
   "description": "This extension Fix SalesForce help bubbles",
   "icons": {
      "128": "icons/icon128.png",
      "16": "icons/icon16.png",
      "48": "icons/icon48.png"
   },
   "manifest_version": 2,
   "name": "--Fix SalesForce bubble text--",
   "permissions": [ "https://*.salesforce.com/*", "http://*.salesforce.com/*" ],
   "update_url": "https://clients2.google.com/service/update2/crx",
   "version": "5"
}

А это inject.js:

chrome.extension.sendMessage({}, function(response) {
  var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
      clearInterval(readyStateCheckInterval);

      var frame = jQuery('#servicedesk iframe.x-border-panel');
      frame = frame.contents();

      function linkify(inputText) {
        var replacedText, replacePattern1, replacePattern2, replacePattern3;
        var originalText = inputText;

        //URLs starting with http://, https://, file:// or ftp://
        replacePattern1 = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim;
        replacedText = inputText.replace(replacePattern1, '<a href="$1" style="color: blue;" target="_blank">$1</a>');

        //URLs starting with "www." (without // before it, or it'd re-link the ones done above).
        replacePattern2 = /(^|[^\/f])(www\.[\S]+(\b|$))/gim;

        replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" style="color: blue;" target="_blank">$2</a>');

        //Change email addresses to mailto:: links.
        replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
        replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>');

        //If there are hrefs in the original text, let's split
        // the text up and only work on the parts that don't have urls yet.
        var count = originalText.match(/<a href/g) || [];

        if(count.length > 0){
          var combinedReplacedText;
          //Keep delimiter when splitting
          var splitInput = originalText.split(/(<\/a>)/g);

          for (i = 0 ; i < splitInput.length ; i++){
            if(splitInput[i].match(/<a href/g) == null){
              splitInput[i] = splitInput[i].replace(replacePattern1, '<a href="$1" target="_blank">$1</a>').replace(replacePattern2, '$1<a href="http://$2" style="color: blue;" target="_blank">$2</a>').replace(replacePattern3, '<a href="mailto:$1">$1</a>');
            }
          }
          combinedReplacedText = splitInput.join('');
          return combinedReplacedText;
        } else {
          return replacedText;
        }
      }

      var helpOrbReady = setInterval(function() {
        var helpOrb = frame.find('.helpOrb');
        if (helpOrb) {
          clearInterval(helpOrbReady)
        } else {
          return;
        }

        helpOrb.on('mouseout', function(event) {
          event.stopPropagation();
          event.preventDefault();
          setTimeout(function() {
            var helpText = frame.find('.helpText')
            helpText.css('display', 'block');
            helpText.css('opacity', '1');
            helpText.css('word-wrap', 'break-word');

            var text = helpText.html()
            text = text.substr(text.indexOf('http'))
            text = text.substr(0, text.indexOf(' '))

            var newHtml = helpText.html()
            helpText.html(linkify(newHtml))
          }, 500); });
      }, 1000);
    }
  }, 1000);
});

  • Частью этикета Stack Overflow является включение рассматриваемого кода (но только соответствующих частей!). Причиной этого является цель Stack Overflow: не помочь вам, а помочь всем, у кого есть такая же проблема. Ссылка может стать мертвой, цитата здесь не может. Это, а также тот факт, что извлечение кода — это множество шагов, которые большинство людей не хотят выполнять. 02.06.2014

Ответы:


1

Возможно (я не проверял это, но это звучит правдоподобно из нескольких вопросов, которые я видел здесь), что Chrome не вставляет код, указанный в манифесте, автоматически во вновь созданные элементы <iframe>.

В этом случае вам придется использовать фоновый скрипт, чтобы повторно внедрить ваш скрипт:

chrome.runtime.onMessage.addListener( function(request, sender, sendResponse) {
  if(request.reinject) {
    chrome.tabs.executeScript(
      sender.tab.id,
      { file: "js/jquery/jquery.js", "all_frames": true },
      function(){
        chrome.tabs.executeScript(
          sender.tab.id,
          { file: "js/inject/inject.js", "all_frames": true }
        );
      }
    );
});

Скрипт контента:

// Before everything: include guard, ensure injected only once
if(injected) return;
var injected = true;

function onNewIframe(){
  chrome.runtime.sendMessage({reinject: true});
}

Теперь у меня есть много вопросов о вашем коде, которые не имеют прямого отношения к вашему вопросу.

02.06.2014
  • Почему вы звонили executeScript дважды? 20.09.2017
  • @serv-inc Поскольку исходный вопрос требовал внедрения двух файлов (jQuery и inject.js) в качестве сценариев содержимого. Функция не может принимать несколько скриптов одновременно. 20.09.2017
  • Новые материалы

    Я собираюсь научить вас Python шаг за шагом
    Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

    Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
    Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..

    React on Rails
    Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

    Что такое гибкие методологии разработки программного обеспечения
    Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...

    Ториго  — революция в игре Го
    Наш следующий вызов против ИИ и для ИИ. Сможет ли он победить людей в обновленной игре Го? Обратите внимание, что в следующей статье AI означает искусственный интеллект, а Goban  —..

    Простое развертывание моделей с помощью Mlflow — Упаковка классификатора обзоров продуктов NLP от HuggingFace
    Как сохранить свои модели машинного обучения в формате с открытым исходным кодом с помощью MLFlow, чтобы позже получить возможность легкого развертывания. Сегодня модели упаковки имеют несколько..

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