Bug 1015894 - Use window.realFrameElement into b2g/components/ContentPermissionPrompt.js to dispatch the permission request to the correct iframe. r=ochameau

This commit is contained in:
Vivien Nicolas 2014-06-04 20:11:06 +02:00
parent 34a46b6121
commit d1f8d19075
3 changed files with 34 additions and 6 deletions

View File

@ -420,7 +420,24 @@ ContentPermissionPrompt.prototype = {
if (isApp) {
details.manifestURL = DOMApplicationRegistry.getManifestURLByLocalId(principal.appId);
}
SystemAppProxy.dispatchEvent(details);
// request.element is defined for OOP content, while request.window
// is defined for In-Process content.
// In both cases the message needs to be dispatched to the top-level
// <iframe mozbrowser> container in the system app.
// So the above code iterates over window.realFrameElement in order
// to crosss mozbrowser iframes boundaries and find the top-level
// one in the system app.
// window.realFrameElement will be |null| if the code try to cross
// content -> chrome boundaries.
let targetElement = request.element;
let targetWindow = request.window || targetElement.ownerDocument.defaultView;
while (targetWindow.realFrameElement) {
targetElement = targetWindow.realFrameElement;
targetWindow = targetElement.ownerDocument.defaultView;
}
SystemAppProxy.dispatchEvent(details, targetElement);
},
classID: Components.ID("{8c719f03-afe0-4aac-91ff-6c215895d467}"),

View File

@ -58,7 +58,10 @@ let SystemAppProxy = {
* @param noPending Set to true to emit this event even before the system
* app is ready.
*/
_sendCustomEvent: function systemApp_sendCustomEvent(type, details, noPending) {
_sendCustomEvent: function systemApp_sendCustomEvent(type,
details,
noPending,
target) {
let content = this._frame ? this._frame.contentWindow : null;
// If the system app isn't ready yet,
@ -80,14 +83,14 @@ let SystemAppProxy = {
}
event.initCustomEvent(type, true, false, payload);
content.dispatchEvent(event);
(target || content).dispatchEvent(event);
return event;
},
// Now deprecated, use sendCustomEvent with a custom event name
dispatchEvent: function systemApp_sendChromeEvent(details) {
return this._sendCustomEvent('mozChromeEvent', details);
dispatchEvent: function systemApp_sendChromeEvent(details, target) {
return this._sendCustomEvent('mozChromeEvent', details, false, target);
},
// Listen for dom events on the system app

View File

@ -8,6 +8,7 @@ Services.scriptloader.loadSubScript("resource://gre/modules/SystemAppProxy.jsm",
const { SystemAppProxy } = scope;
let frame;
let customEventTarget;
let index = -1;
function next() {
@ -47,6 +48,10 @@ function listener(event) {
} else if (n == 4) {
assert.equal(event.type, "mozChromeEvent");
assert.equal(event.detail.name, "fourth");
} else if (n == 5) {
assert.equal(event.type, "mozChromeEvent");
assert.equal(event.detail.name, "fifth");
assert.equal(event.target, customEventTarget);
next(); // call checkEventListening();
} else {
@ -79,6 +84,8 @@ let steps = [
frame = doc.createElement("iframe");
doc.documentElement.appendChild(frame);
customEventTarget = frame.contentDocument.body;
// Ensure that events are correctly sent to the frame.
// `listener` is going to call next()
frame.contentWindow.addEventListener("mozChromeEvent", listener);
@ -118,7 +125,8 @@ let steps = [
// they should be dispatched right away
SystemAppProxy._sendCustomEvent("custom", { name: "third" });
SystemAppProxy.dispatchEvent({ name: "fourth" });
// Once this 4th event is received, we will run checkEventListening
SystemAppProxy._sendCustomEvent("custom", { name: "fifth" }, false, customEventTarget);
// Once this 5th event is received, we will run checkEventListening
},
function checkEventListening() {