如何在内容脚本中使用Flowplayer功能? [英] How to use Flowplayer functions in a content script?

查看:261
本文介绍了如何在内容脚本中使用Flowplayer功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个Firefox插件供个人使用,并学习更多关于JavaScript和Firefox插件SDK的信息。附加应该打开 vivo.sx URL然后自动启动播放器,但是我有两个问题。我希望你们能帮助我。



相关的附加代码:

  function vivoplay()
{
pageMod.PageMod({
include:https://vivo.sx/*,
contentScriptFile:./vivoplay.js,
onAttach:play
});

函数play(worker)//触发2次
{
console.log(Timeout);
tmr.setTimeout(sendplay,14000);
函数sendplay()
{
var a = 0;
worker.port.emit(start,a);





内容脚本

  self.port.on(start,function(a){
console.log(Load);
flowplayer()。load(); // ReferenceError:没有定义flowplayer
console.log(Loaded);
});

第一个问题是函数 play 发射2次,但应该只运行一次。这可能是 onAttach 不能正常工作。你怎么看?



更重要的问题是 ReferenceError 。我有一个Greasemonkey脚本,使用函数 flowplayer()。load(); 。我以为内容脚本就像Greasemonkey脚本一样运行。所以,我应该可以使用这个功能。那是对的吗?如何解决这个问题?

我的greasemonkey脚本
$ b $ pre $ code == UserScript ==
// @name 3. Vivo
// @namespace自动播放
// @include https://vivo.sx/*
// @version 1
// @grant none
// == / UserScript ==

window.setTimeout(Play,2000);
函数Play()
{
flowplayer()。load();
console.log(Loaded);
flowplayer()。fullscreen();
console.log(Fullscreen started);





$ b我很新,所以请耐心等待: p>

如果您需要更多的信息,请留下您的评论。 您遇到的问题是,您没有考虑到您的内容脚本正在与网页中的脚本(页面脚本)不同的上下文中执行。将内容脚本与页面脚本分离是浏览器扩展的常规体系结构,这是出于安全原因而完成的。您的内容脚本具有比授予页面脚本更高的权限。虽然技术上可以从您的内容脚本上下文中执行页面提供的功能,但出于安全原因,您绝对不应该这样做。如果您确实选择这样做,那么您的扩展程序将不会通过Mozilla的审核,以便在 AMO



虽然您可以将内容脚本中存在的函数暴露给页面脚本在页面脚本范围内创建对象,从页面脚本上下文实际执行代码的方法是添加一个< script> 元素到包含您要执行的代码的文档

<对于你的问题中的代码,这可以实现为:

  self.port.on(start,function (a){
let newScript =使用document.createElement(脚本);
//对console.log的调用不需要在页面脚本中。
//然而,newScript中的代码是异步执行的。因此,如果
// console.log(Loaded);
//在内容脚本中,它将在flowplayer()之前执行。load()实际上是
//被调用。
newScript.innerHTML ='console.log(Load);'
+'flowplayer()。load();'
+'console.log(Loaded); ;
document.head.appendChild(newScript);
});

onAttach / play 不止一次运行:

没有完整的代码和浏览器看起来像的截图,不可能确定为什么会发生这种情况。

最可能的原因是您有多个选项卡打开到匹配https://vivo.sx/*的地址。每次将内容脚本附加到页面时,都会调用 onAttach 代码。对于每个打开匹配的URL的选项卡,将附加一次。如果在加载项加载时有两个选项卡打开到匹配的URL,那么 onAttach 代码将被执行两次。


$ b $另一种可能是你多次执行 vivoplay ,导致设置多个 PageMod 这会将您的内容脚本的单独副本附加到每个选项卡。考虑到你使用这个函数的名字 vivoplay ,你可能会把它当作一个不止一次执行的播放函数。如果您在该功能中进行了组织,您不应该这样做。



显示内容过于复杂:

您的代码对于显示的内容过于复杂。您正在使用 onAttach 事件将 start 发送到内容脚本。内容脚本仅在附加时才加载/执行。因此,通过发送 start 来通知内容脚本是多余的。如果您打算将代码修改为仅发送 start 以响应其他事件(例如,用户单击按钮),这可能是合理的。但是,如果您打算始终自动启动Flowplayer,则无需向内容脚本发送 start 消息。内容脚本可以包含 setTimeout ,然后继续运行。


I am trying to write a Firefox add-on for personal use and to learn a bit more about both JavaScript and the Firefox Add-on SDK. The add-on should open a vivo.sx URL and then automatically start the player, but I have 2 issues. I hope you guys can help me.

The relevant add-on-code:

function vivoplay()
{
    pageMod.PageMod({
        include: "https://vivo.sx/*",
        contentScriptFile: "./vivoplay.js",
        onAttach: play
    });

    function play(worker)                       //Fires 2 Times
    {
        console.log("Timeout");
        tmr.setTimeout(sendplay, 14000);
        function sendplay() 
        {
            var a = 0;
            worker.port.emit("start", a);
        }
    }
}

content-script

self.port.on("start", function(a) {
    console.log("Load");
    flowplayer().load();         //ReferenceError: flowplayer is not defined
    console.log("Loaded");
});

The first problem is that the function play fires 2 times, but should only run once. It's probably the onAttach that does not work correctly. What do you think about that?

The more important problem is the ReferenceError. I have a Greasemonkey script where I use the function flowplayer().load();. I thought the content script is running like a Greasemonkey script. So, I should be able to use this function. Is that correct? How can I fix this?

my greasemonkey script

// ==UserScript==
// @name        3. Vivo
// @namespace   Autoplay
// @include     https://vivo.sx/* 
// @version     1
// @grant       none
// ==/UserScript==

window.setTimeout(Play, 2000);
function Play()
{
  flowplayer().load(); 
  console.log("Loaded");
  flowplayer().fullscreen();
  console.log("Fullscreen started");
}

I am quite new to this so please be patience with me :)

If you need more information, please leave a comment.

解决方案

The problem you are experiencing is that you are not taking into account that your content script is executing in a different context than the scripts in the webpage (page scripts). Keeping content scripts separate from page scripts is a normal architecture for browser extensions which is done for security reasons. Your content script has higher privileges than are granted to page scripts. While you technically could execute a function provided by the page from within your content script context, for security reasons, you should never do so. If you do choose to do so, your extension will not pass review by Mozilla for being listed on AMO.

While you can expose functions which exist in your content script to page scripts, and create objects in the page script scope, the way to actually execute code from within the page script context is to add a <script> element to the document containing the code you desire to execute.

For the code in your question, this could be implemented as:

self.port.on("start", function(a) {
    let newScript = document.createElement('script');
    //The calls to console.log don't need to be in the page script.
    //  However, the code in the newScript is executed asynchronously. Thus, if the
    //  console.log("Loaded"); 
    //  is in the content script it will be executed prior to flowplayer().load() actually
    //  being called.
    newScript.innerHTML = 'console.log("Load");'
                        + 'flowplayer().load();'
                        + 'console.log("Loaded");' ;
    document.head.appendChild(newScript);
});

onAttach/play running more than once:
Without your full code and a screenshot of what the browser looked like it is impossible to be certain why this would occur.

The most likely reason is that you had more than one tab open to an address that matched "https://vivo.sx/*". Your onAttach code will be called each time the content script is attached to a page. It will be attached once for each tab which is open to a matching URL. If you had two tabs open to matching URLs when the add-on was loaded, then the onAttach code will be executed twice.

Another possibility is that you have executed vivoplay more than once resulting in setting up multiple PageMods each of which would attach a separate copy of your content script to each tab. Given the name you used for this function, vivoplay, you may be treating it as a play function which you are executing more than once. With how you have things organized within that function, you should not do so.

Overly complex for what is shown:
Your code is overly complex for what is shown. You are using the onAttach event to sent start to the content script. The content script is only loaded/executed when it is attached. Thus, informing the content script that it is attached by sending start is redundant. This might be reasonable if you are intending to modify the code to only send start in response to some other event (e.g. the user clicking a button). However, if it is your intent to always auto-start the Flowplayer, then there is no need to send a start message to the content script. The content script can have the setTimeout and just go ahead and execute that code when it is run.

这篇关于如何在内容脚本中使用Flowplayer功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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