如何为每个新的Iframe添加Chrome扩展程序? [英] How to make Chrome Extension run for each new Iframe added?

查看:104
本文介绍了如何为每个新的Iframe添加Chrome扩展程序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了Chrome扩展程序,作为覆盖SalesForce控制台页面中helpText气泡的解决方案。帮助文本气泡显示的文字无法链接网址。它看起来像这样:





扩展程序正在使用helpText泡泡(在SalesForce控制台窗口中,位于iFrame内),并使URL可点击。它还添加了自动换行并将链接标记为蓝色。



解决方案在页面加载最初的iFrame(或iFrames)时工作正常,这意味着您第一次打开SalesForce控制台时(:

  chrome.runtime.onMessage.addListener(function(request, (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 /注入.js,all_frames:true}
);
}
);
});

内容脚本:

  //在一切之前:包括guard,确保只注入一次
if(inject)return;
var injected = true;

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






现在,我有很多


  • 为什么没有意义 sendMessage 包装?没有人甚至在听,所以你的代码基本上返回一个错误集。

  • 为什么所有的间隔?使用事件而不是轮询。


    • 如果您正在等待文档准备就绪,jQuery将提供 $(document).ready(...)

    • 如果您正在等待DOM修改,请学习如何使用DOM突变观察器,如记录并按照此处此处顺便说一句,这是调用 onNewIframe()的首选方法。



I created a Chrome Extension as a solution to override the helpText bubbles in SalesForce Console pages. The helpText bubbles show up the text without the ability to link URLs. It looks like this:

The extension is taking the helpText bubble (which in the SalesForce console window, is inside an iFrame) and makes the URL click-able. It also adds word wrap and marks the links in blue.

The solution works fine when the page loads with the initial iFrame (or iFrames) on it, meaning when you open the SalesForce console the first time (https://eu3.salesforce.com/console).
When a new tab is created at the SalesForce console, my inject script doesn't run.

Can you please assist in understanding how to inject the script on each and every new Tab SalesForce Console is creating?

The Extension as follows:

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"
}

And this is the 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);
});

解决方案

It is possible (I have not tested it, but it sounds plausible from a few questions I've seen here) that Chrome does not automatically inject manifest-specified code into newly-created <iframe> elements.

In that case, you will have to use a background script to re-inject your script:

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 }
        );
      }
    );
});

Content script:

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

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


Now, I have many questions about your code, which are not directly related to your question.

  • Why the pointless sendMessage wrapper? No-one is even listening, so your code basically returns with an error set.
  • Why all the intervals? Use events instead of polling.
    • If you are waiting on document to become ready, jQuery offers $(document).ready(...)
    • If you're waiting on DOM modifications, learn to use DOM Mutation Observers, as documented and as outlined here or here. This would be, by the way, the preferred way to call onNewIframe().

这篇关于如何为每个新的Iframe添加Chrome扩展程序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆