2013-12-10 55 views
0

未能在background.js:断言在Chrome扩展和重复

function checkForValidUrl(tabId, changeInfo, tab) { 
    if(changeInfo.status === "loading") { 
    if (tab.url.indexOf('google.com') > -1 || tab.url.indexOf('amazon.com') > -1) { 
    chrome.pageAction.show(tabId); 
} 
} 
}; 
chrome.tabs.onUpdated.addListener(checkForValidUrl); 
chrome.pageAction.onClicked.addListener(function(tab){ 

if (tab.url.indexOf('google.com') > -1){ 

    chrome.tabs.query({active: true, currentWindow: true}, function(tabs) { 
     chrome.tabs.sendMessage(tab.id, {google_go: "go"}); 
    }); 

    chrome.tabs.create({url: "http://facebook.com", "active":true}); 
    chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 
     chrome.runtime.onConnect.addListener(function(port) { 
      console.assert(port.name == "facebook_chanel"); 
      port.onMessage.addListener(function(msg) { 
       if (msg.facebook_go == "go") 
       port.postMessage(request); 
      }); 
      }); 
     }); 
} 

在facebook.js:

$(document).ready(function(){ 
    var port = chrome.runtime.connect({name: "facebook_chanel"}); 
    port.postMessage({facebook_go: "go"}); 
    port.onMessage.addListener(function(msg) { 

     console.log(msg); 

    }); 

}); 

我去得谷歌。按pageAction,我看到标签与脸书,看到一个对象在控制台。在html/background.html控制台(铬)我看到的错误Assertion failed:

console.assert(port.name == "facebook_chanel"); 

我再次去谷歌,按pageAction,我在新的Facebook页面一个老看和2个新的对象

如何解决?谢谢。

UPDATE

background.js

chrome.tabs.create({url: "http://facebook.com", "active":true}, function(tab){ 
     chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { 
       chrome.tabs.query({active: true, currentWindow: true}, function(tab) { 
        chrome.tabs.sendMessage(tab[0].id, request); 
       }); 

     }); 
    }); 

facebook.js

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse) { 
    console.log(request); 
    }); 

它的正确方法吗?但我有明确的控制台,最新的错误?

+0

你为什么不用'console.log(port.name)'来看它是否真的是'facebook_chanel '? – thefourtheye

+0

'console.log(port.name)'返回'facebook_chanel'。我使用这里的代码http://developer.chrome.com/extensions/messaging.html(长期连接) – tim

+0

只是评论说'assert'声明并尝试 – thefourtheye

回答

1

现在还不是很清楚你试图达到什么目的,为什么你选择使用持久端口(而不是单一消息)和页面动作,但从我明白的话来说,上下文菜单可能是更好的/更干净的方法

因此,下面是一个示例扩展的源代码,该示例扩展注册了用于选择某些文本(即选择/突出显示某些文本并右键单击)的上下文菜单,然后打开Facebook选项卡并将所选文本发送给进一步处理(通过FB选项卡的内容脚本)。

如果您仍需要一个页面的动作,而不是一个菜单,改变这样的代码:

  1. 在背景页chrome.pageAction.onClicked添加监听器。
  2. 向原始标签注入一些代码(例如google.com)以检索广告返回当前选择(使用chrome.tabs.executeScript())。
  3. 处理获取的选定文本,如下面的代码所示。

manifest.json的:

{ 
    "manifest_version": 2, 

    "name": "Test Extension", 
    "version": "0.0", 
    "offline_enabled": false, 

    "background": { 
     "persistent": false, 
     "scripts": [ 
      "background.js" 
     ] 
    }, 

    "content_scripts": [{ 
     "matches": ["*://*.facebook.com/"], 
     "js":   ["content.js"], 
     "run_at":  "document_end", 
     "all_frames": false 
    }], 

    "permissions": [ 
     "contextMenus" 
    ] 
} 

content.js:

chrome.runtime.onMessage.addListener(function(msg) { 

    /* Input validation */ 
    if (!msg.source || !msg.text) { 
     console.error('Bad message format: ', msg); 
     return; 
    } 

    /* Handle the selected text */ 
    switch (msg.source) { 
    case 'Amazon': 
    case 'Google': 
     alert('Selected on ' + msg.source + ':\n' + msg.text); 
     break; 
    default: 
     alert('Unknown source: ' + msg.source); 
     break; 
    } 

}); 

背景。JS:

var contextMenuID = 'copyToFB'; 
var googleRegex = /^https?:\/\/(?:[^\.]+\.)?google\..+/; 
var amazonRegex = /^https?:\/\/(?:[^\.]+\.)?amazon\..+/; 

/* `onUpdated` listener factory (for when FB has loaded) */ 
var listenerFactory = function(trgTabID, msgSrc, selectedText) { 
    return function(tabId, info, tab) { 
     if ((trgTabID === tabId) && (info.status === 'complete')) { 
      chrome.tabs.onUpdated.removeListener(arguments.callee); 
      chrome.tabs.sendMessage(trgTabID, { 
       source: msgSrc, 
       text: selectedText 
      }); 
     } 
    } 
}; 

chrome.contextMenus.create({ 
    type:  'normal', 
    id:  contextMenuID, 
    title: 'Copy to Facebook', 
    contexts: ['selection'], 
    // For some reason documentsUrlPatterns 
    // does not seem to work (at least on Windows). 
    // Theoratically, you should be able to limit the 
    // context-menu on specific sites only 
    //documentUrlPatterns: [ 
     //'*://*.google.*/*', 
     //'*://*.amazon.*/*' 
    //], 
    enabled: true 
}); 

chrome.contextMenus.onClicked.addListener(function(info, tab) { 
    console.log('Context menu clicked: ', info.menuItemId); 
    if (info.menuItemId === contextMenuID) { 
     var selectedText = info.selectionText; 
     console.log('Selected text: ', selectedText); 
     if (!selectedText) { 
      alert('Nothing to copy to Facebook !'); 
      return; 
     } 

     var url = info.frameUrl ? info.frameUrl : info.pageUrl; 
     if (googleRegex.test(url)) { 
      console.log('Google.com URL: ', url); 

      /* Handle text selected on `google.com` */ 
      chrome.tabs.create({ 
       url: 'http://facebook.com/', 
       active: true 
      }, function(tab) { 
       chrome.tabs.onUpdated.addListener(
         listenerFactory(tab.id, 'Google', selectedText)); 
      }); 
     } else if (amazonRegex.test(url)) { 
      console.log('Amazon.com URL: ', url); 

      /* Handle text selected on `amazon.com` */ 
      chrome.tabs.create({ 
       url: 'http://facebook.com/', 
       active: true 
      }, function(tab) { 
       chrome.tabs.onUpdated.addListener(
         listenerFactory(tab.id, 'Amazon', selectedText)); 
      }); 
     } else { 
      console.log('Non-matching URL: ', url); 
     } 
    } 
}); 

最后说明:

  • 因为documentUrlPatterns似乎不工作(至少在Windows上),上下文菜单显示在每一页上(当您选择一些文字)。您可以添加额外的侦听器(例如chrome.tabs.onActivated等),以在用户不在其中一个允许的URL上时删除或禁用上下文菜单。

  • 这可能是一个好主意,跟踪一个操作FB选项卡,而不是每次创建一个新的。 (或者你也可以寻找一个已经打开的(例如用户)FB标签)。

+0

对不起,但我不需要任何上下文菜单。在google.js中解析所有信息,在后台我可以看到请求,我从google.js发送,然后发送给facebook.js,它可以在页面中添加请求。但在facebook.js控制台很明显,很奇怪,我不知道为什么。 – tim