I'm working on a firefox addon using the Add-on SDK, in that addon i have content scripts communicating with the main addon script using the port.on() and port.emit() as described here in the Add-on SDK documentation.
My addon also makes use of the YouTube iFrame Player API. The API works great, if not for this one issue: it seems that once I create a new instance of YT.Player() (using the YouTube API) the port.on()/port.emit() communication of the Add-on between my main addon script and my content script stops working...
if I try to do this in my content script
addon.port.emit('anything');
before creating an instance of YT.Player(), then my main addon script can receives it just fine:
....
worker.port.on('anything',function(){
// works just fine...
});
....
but if I try to do the same thing after instantiating the YT.Player() the main addon script won't fire 'on' any of the port.emit events fired. It's as though introducing an instance of YT.Player() somehow sabotages the communication.
when I use the debugger I can confirm that 'addon.port' still exists ( it just won't work ). using the debugger I also stepped through the minified API code as it creates the instance of YT.Player, and it's about 94 or so 'steps' in that the communication stops working, when it reaches this bit of obfuscated code in the API library (line 82)
;function N(a,b,c){this.b=b;this.h=this.a=null;this.g=this[t]||(this[t]=++ca);this.c=0;this.B=!1;this.w=[];this.f=null;this.s=c;this.v={};b=document;if(a=r(a)?b.getElementById(a):a)if("iframe"!=a.tagName.toLowerCase()&&(b=yb(this,a),this.h=a,(c=a.parentNode)&&c.replaceChild(b,a),a=b),this.a=a,this.a.id||(b=a=this.a,b=b[t]||(b[t]=++ca),a.id="widget"+b),L[this.a.id]=this,window.postMessage){this.f=new H;zb(this);a=O(this.b,"events");for(var d in a)a.hasOwnProperty(d)&&this.addEventListener(d,a[d]);for(var e in ub)Ab(this,
//... which cleaned-up looks like...
function N(a, b, c) {
this.b = b;
this.h = this.a = null;
this.g = this[t] || (this[t] = ++ca);
this.c = 0;
this.B = !1;
this.w = [];
this.f = null;
this.s = c;
this.v = {};
b = document;
if (a = r(a) ? b.getElementById(a) : a)
if ("iframe" != a.tagName.toLowerCase() &&
(b = yb(this, a), this.h = a, (c = a.parentNode) && c.replaceChild(b, a), a = b),
this.a = a,
this.a.id ||
(b = a = this.a, b = b[t] ||
(b[t] = ++ca), a.id = "widget" + b),
L[this.a.id] = this, window.postMessage) {
this.f = new H;
zb(this);
a = O(this.b, "events");
for (var d in a) a.hasOwnProperty(d) && this.addEventListener(d, a[d]);
for (var e in ub) Ab(this,e)
}
}
any idea what might be going on? or any suggestions on how I might further debug this situation... I'm at a complete loss :(
UPDATE:
after further debugging i've narrowed down the exact point when the addon port.emit/port.on communication stops working, it is indeed when the line above in the YouTube API library runs ( during the YT.Player() instantiation process ). specifically it's inside the second if statement when this runs:
c.replaceChild(b, a)
where I've identified c to be the document.body, a ( the element being replaced ) is the element I originally passed to the YT.Player() constructor as the element I want to place the instance of the YouTube player in, and b (the element replacing a) is an iframe (created in this process), so to recap, when the instantiation process replaces the element which i originally passed into it as the desired parent container for the player, which looks something like this:
<div id="player"></div>
with the new iframe, which looks like this:
<iframe width="600" height="345" frameborder="0" id="player" allowfullscreen="1" title="YouTube video player" src="http://www.youtube.com/embed/[YT-VIDEO-ID]?autoplay=1&controls=0&enablejsapi=1&origin=resource%3A%2F%2F[ADDON-SCRIPT-ID]&widgetid=1">
...that's when it seems to break
UPDATE 2:
i've posted a new question here, which gets down to this specific issue of the iframe...