Commit b6682be2 authored by Thibaut Frain's avatar Thibaut Frain

Links in iframed gadgets are opened in top window (using base element)

parent f7b2f00f
...@@ -147,6 +147,14 @@ ...@@ -147,6 +147,14 @@
return this; return this;
}; };
// Set aq_parent on gadget_instance which call acquire on parent_gadget
function setAqParent(gadget_instance, parent_gadget) {
gadget_instance.__aq_parent = function (method_name, argument_list) {
return acquire.apply(parent_gadget, [gadget_instance, method_name,
argument_list]);
};
}
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// RenderJSEmbeddedGadget // RenderJSEmbeddedGadget
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -166,7 +174,7 @@ ...@@ -166,7 +174,7 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// privateDeclarePublicGadget // privateDeclarePublicGadget
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
function privateDeclarePublicGadget(url, options) { function privateDeclarePublicGadget(url, options, parent_gadget) {
var gadget_instance; var gadget_instance;
if (options.element === undefined) { if (options.element === undefined) {
options.element = document.createElement("div"); options.element = document.createElement("div");
...@@ -194,6 +202,7 @@ ...@@ -194,6 +202,7 @@
template_node_list[i].cloneNode(true) template_node_list[i].cloneNode(true)
); );
} }
setAqParent(gadget_instance, parent_gadget);
// Load dependencies if needed // Load dependencies if needed
return RSVP.all([ return RSVP.all([
gadget_instance.getRequiredJSList(), gadget_instance.getRequiredJSList(),
...@@ -237,12 +246,11 @@ ...@@ -237,12 +246,11 @@
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// privateDeclareIframeGadget // privateDeclareIframeGadget
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
function privateDeclareIframeGadget(url, options) { function privateDeclareIframeGadget(url, options, parent_gadget) {
var gadget_instance, var gadget_instance,
iframe, iframe,
node, node,
iframe_loading_deferred = RSVP.defer(); iframe_loading_deferred = RSVP.defer();
if (options.element === undefined) { if (options.element === undefined) {
throw new Error("DOM element is required to create Iframe Gadget " + throw new Error("DOM element is required to create Iframe Gadget " +
url); url);
...@@ -262,12 +270,12 @@ ...@@ -262,12 +270,12 @@
} }
gadget_instance = new RenderJSIframeGadget(); gadget_instance = new RenderJSIframeGadget();
setAqParent(gadget_instance, parent_gadget);
iframe = document.createElement("iframe"); iframe = document.createElement("iframe");
// gadget_instance.element.setAttribute("seamless", "seamless"); // gadget_instance.element.setAttribute("seamless", "seamless");
iframe.setAttribute("src", url); iframe.setAttribute("src", url);
gadget_instance.__path = url; gadget_instance.__path = url;
gadget_instance.__element = options.element; gadget_instance.__element = options.element;
// Attach it to the DOM // Attach it to the DOM
options.element.appendChild(iframe); options.element.appendChild(iframe);
...@@ -348,7 +356,6 @@ ...@@ -348,7 +356,6 @@
// transform url to absolute url if it is relative // transform url to absolute url if it is relative
url = renderJS.getAbsoluteURL(url, this.__path); url = renderJS.getAbsoluteURL(url, this.__path);
// Change the global variable to update the loading queue // Change the global variable to update the loading queue
queue = new RSVP.Queue() queue = new RSVP.Queue()
// Wait for previous gadget loading to finish first // Wait for previous gadget loading to finish first
...@@ -369,16 +376,11 @@ ...@@ -369,16 +376,11 @@
throw new Error("Unsupported sandbox options '" + throw new Error("Unsupported sandbox options '" +
options.sandbox + "'"); options.sandbox + "'");
} }
return method(url, options); return method(url, options, parent_gadget);
}) })
// Set the HTML context // Set the HTML context
.push(function (gadget_instance) { .push(function (gadget_instance) {
var i; var i;
// Define __aq_parent to reach parent gadget
gadget_instance.__aq_parent = function (method_name, argument_list) {
return acquire.apply(parent_gadget, [gadget_instance, method_name,
argument_list]);
};
// Drop the current loading klass info used by selector // Drop the current loading klass info used by selector
gadget_loading_klass = undefined; gadget_loading_klass = undefined;
// Trigger calling of all ready callback // Trigger calling of all ready callback
...@@ -711,7 +713,6 @@ ...@@ -711,7 +713,6 @@
notifyDeclareMethod, notifyDeclareMethod,
gadget_ready = false; gadget_ready = false;
// Create the gadget class for the current url // Create the gadget class for the current url
if (gadget_model_dict.hasOwnProperty(url)) { if (gadget_model_dict.hasOwnProperty(url)) {
throw new Error("bootstrap should not be called twice"); throw new Error("bootstrap should not be called twice");
...@@ -745,6 +746,12 @@ ...@@ -745,6 +746,12 @@
); );
}; };
tmp_constructor.prototype.__acquired_method_dict = {};
// Allow acquisition of getTopURL returning the top gadget path
tmp_constructor.allowPublicAcquisition('getTopURL', function () {
return root_gadget.__path;
});
} else { } else {
// Create the communication channel // Create the communication channel
embedded_channel = Channel.build({ embedded_channel = Channel.build({
...@@ -831,9 +838,8 @@ ...@@ -831,9 +838,8 @@
}); });
}); });
}; };
tmp_constructor.prototype.__acquired_method_dict = {};
} }
tmp_constructor.prototype.__acquired_method_dict = {};
gadget_loading_klass = tmp_constructor; gadget_loading_klass = tmp_constructor;
function init() { function init() {
...@@ -871,6 +877,19 @@ ...@@ -871,6 +877,19 @@
function ready_wrapper() { function ready_wrapper() {
return root_gadget; return root_gadget;
} }
if (window.top !== window.self) {
tmp_constructor.ready(function () {
var base = document.createElement('base');
return root_gadget.__aq_parent('getTopURL', [])
.then(function (topURL) {
base.href = topURL;
base.target = "_top";
document.head.appendChild(base);
});
});
}
queue.push(ready_wrapper); queue.push(ready_wrapper);
for (i = 0; i < tmp_constructor.__ready_list.length; i += 1) { for (i = 0; i < tmp_constructor.__ready_list.length; i += 1) {
// Put a timeout? // Put a timeout?
......
...@@ -8,6 +8,14 @@ ...@@ -8,6 +8,14 @@
gk.ready(function (g) { gk.ready(function (g) {
ready_called = true; ready_called = true;
}) })
.declareMethod('getBaseHref', function () {
return document.querySelector('base')
.getAttribute('href');
})
.declareMethod('getBaseTarget', function () {
return document.querySelector('base')
.getAttribute('target');
})
.declareMethod('wasReadyCalled', function () { .declareMethod('wasReadyCalled', function () {
return ready_called; return ready_called;
}) })
......
...@@ -2427,11 +2427,17 @@ ...@@ -2427,11 +2427,17 @@
test('Can take a scope options', function () { test('Can take a scope options', function () {
// Subclass RenderJSGadget to not pollute its namespace // Subclass RenderJSGadget to not pollute its namespace
var gadget = new RenderJSGadget(), var gadget = new RenderJSGadget(),
url = "./embedded.html"; url = "./embedded.html",
topURL = "http://example.org/topGadget";
gadget.__sub_gadget_dict = {}; gadget.__sub_gadget_dict = {};
document.getElementById("qunit-fixture").textContent = ""; document.getElementById("qunit-fixture").textContent = "";
gadget.__acquired_method_dict = {
getTopURL: function () {return topURL; }
};
stop(); stop();
gadget.declareGadget(url, { gadget.declareGadget(url, {
sandbox: 'iframe', sandbox: 'iframe',
...@@ -2459,11 +2465,16 @@ ...@@ -2459,11 +2465,16 @@
port: parsed.port, port: parsed.port,
path: parsed.path}).toString(), path: parsed.path}).toString(),
gadget_path = "./embedded.html", gadget_path = "./embedded.html",
absolute_path = parent_path + "embedded.html"; absolute_path = parent_path + "embedded.html",
topURL = "http://example.org/topGadget";
document.getElementById("qunit-fixture").textContent = ""; document.getElementById("qunit-fixture").textContent = "";
parent_gadget.__path = parent_path; parent_gadget.__path = parent_path;
parent_gadget.__acquired_method_dict = {
getTopURL: function () {return topURL; }
};
stop(); stop();
parent_gadget.declareGadget(gadget_path, { parent_gadget.declareGadget(gadget_path, {
sandbox: 'iframe', sandbox: 'iframe',
...@@ -2471,7 +2482,9 @@ ...@@ -2471,7 +2482,9 @@
}) })
.then(function (new_gadget) { .then(function (new_gadget) {
equal(new_gadget.__path, absolute_path); equal(new_gadget.__path, absolute_path);
deepEqual(new_gadget.__acquired_method_dict, undefined); equal(Object.keys(new_gadget.__acquired_method_dict).length, 1);
equal(typeof new_gadget.__acquired_method_dict.getTopURL,
'function');
ok(new_gadget instanceof RenderJSIframeGadget); ok(new_gadget instanceof RenderJSIframeGadget);
equal( equal(
new_gadget.__element.innerHTML, new_gadget.__element.innerHTML,
...@@ -2487,10 +2500,15 @@ ...@@ -2487,10 +2500,15 @@
test('Initialize sub_gadget_dict private property', function () { test('Initialize sub_gadget_dict private property', function () {
// Check that declare gadget returns the gadget // Check that declare gadget returns the gadget
var gadget = new RenderJSGadget(), var gadget = new RenderJSGadget(),
url = "./embedded.html"; url = "./embedded.html",
topURL = "http://example.org/topGadget";
document.getElementById("qunit-fixture").textContent = ""; document.getElementById("qunit-fixture").textContent = "";
gadget.__acquired_method_dict = {
getTopURL: function () {return topURL; }
};
stop(); stop();
gadget.declareGadget(url, { gadget.declareGadget(url, {
sandbox: 'iframe', sandbox: 'iframe',
...@@ -2509,7 +2527,8 @@ ...@@ -2509,7 +2527,8 @@
// Check that declare gadget returns the gadget // Check that declare gadget returns the gadget
var gadget = new RenderJSGadget(), var gadget = new RenderJSGadget(),
acquire_called = false, acquire_called = false,
url = "./embedded.html"; url = "./embedded.html",
topURL = "http://example.org/topGadget";
gadget.__aq_parent = function (method_name, argument_list) { gadget.__aq_parent = function (method_name, argument_list) {
acquire_called = true; acquire_called = true;
...@@ -2525,6 +2544,10 @@ ...@@ -2525,6 +2544,10 @@
throw new renderJS.AcquisitionError("Can not handle " + method_name); throw new renderJS.AcquisitionError("Can not handle " + method_name);
}; };
gadget.__acquired_method_dict = {
getTopURL: function () {return topURL; }
};
stop(); stop();
gadget.declareGadget(url, { gadget.declareGadget(url, {
sandbox: 'iframe', sandbox: 'iframe',
...@@ -2605,6 +2628,18 @@ ...@@ -2605,6 +2628,18 @@
"acquireMethodRequestedWithAcquisitionError", "acquireMethodRequestedWithAcquisitionError",
error error
); );
})
.push(function () {
return new_gadget.getBaseHref();
})
.push(function (href) {
equal(href, topURL);
})
.push(function () {
return new_gadget.getBaseTarget();
})
.push(function (target) {
equal(target, "_top");
}); });
}) })
.fail(function (error) { .fail(function (error) {
...@@ -2739,7 +2774,8 @@ ...@@ -2739,7 +2774,8 @@
.then(function (root_gadget) { .then(function (root_gadget) {
// Check instance // Check instance
equal(root_gadget.__path, window.location.href); equal(root_gadget.__path, window.location.href);
deepEqual(root_gadget.__acquired_method_dict, {}); equal(typeof root_gadget.__acquired_method_dict, 'object');
equal(Object.keys(root_gadget.__acquired_method_dict).length, 1);
equal(root_gadget.__title, document.title); equal(root_gadget.__title, document.title);
deepEqual(root_gadget.__interface_list, []); deepEqual(root_gadget.__interface_list, []);
deepEqual(root_gadget.__required_css_list, deepEqual(root_gadget.__required_css_list,
...@@ -2788,6 +2824,8 @@ ...@@ -2788,6 +2824,8 @@
ok(root_gadget.__aq_parent !== undefined); ok(root_gadget.__aq_parent !== undefined);
ok(root_gadget.hasOwnProperty("__sub_gadget_dict")); ok(root_gadget.hasOwnProperty("__sub_gadget_dict"));
deepEqual(root_gadget.__sub_gadget_dict, {}); deepEqual(root_gadget.__sub_gadget_dict, {});
equal(root_gadget.__acquired_method_dict.getTopURL(),
window.location.href);
}) })
.fail(function (e) { .fail(function (e) {
ok(false, e); ok(false, e);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment