3

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

在此处输入图像描述

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

当页面加载初始 iFrame(或 iFrame)时,该解决方案工作正常,这意味着当您第一次打开 SalesForce 控制台时(https://eu3.salesforce.com/console)。
在 SalesForce 控制台上创建新选项卡时,我的注入脚本不会运行。

在此处输入图像描述

您能否协助了解如何在每个新的 Tab SalesForce Console 正在创建的标签上注入脚本?

扩展如下:

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

1 回答 1

2

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

现在,我对您的代码有很多问题,这些问题与您的问题没有直接关系。

  • 为什么是毫无意义的sendMessage包装?甚至没有人在听,所以你的代码基本上返回一个错误集。
  • 为什么所有的间隔?使用事件而不是轮询。
    • 如果您正在等待文档准备好,jQuery 提供$(document).ready(...)
    • 如果您正在等待 DOM 修改,请学习使用 DOM Mutation Observers,如此处或此处所记录和概述顺便说一句,这将是调用.onNewIframe()
于 2014-06-02T16:17:53.850 回答