@qooxdoo/framework
Version:
The JS Framework for Coders
214 lines (191 loc) • 6.24 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2004-2008 1&1 Internet AG, Germany, http://www.1und1.de
License:
MIT: https://opensource.org/licenses/MIT
See the LICENSE file in the project's top-level directory for details.
Authors:
* Sebastian Werner (wpbasti)
* Andreas Ecker (ecker)
* Jonathan Weiß (jonathan_rass)
* Christian Hagendorn (Chris_schmidt)
************************************************************************ */
/**
* Cross browser abstractions to work with iframes.
*
* @require(qx.event.handler.Iframe)
*/
qx.Class.define("qx.bom.Iframe", {
/*
*****************************************************************************
STATICS
*****************************************************************************
*/
statics: {
/**
* @type {Map} Default attributes for creation {@link #create}.
*/
DEFAULT_ATTRIBUTES: {
frameBorder: 0,
frameSpacing: 0,
marginWidth: 0,
marginHeight: 0,
hspace: 0,
vspace: 0,
border: 0,
allowTransparency: true
},
/**
* Creates an DOM element.
*
* Attributes may be given directly with this call. This is critical
* for some attributes e.g. name, type, ... in many clients.
*
* @param attributes {Map?null} Map of attributes to apply
* @param win {Window?null} Window to create the element for
* @return {Element} The created iframe node
*/
create(attributes, win) {
// Work on a copy to not modify given attributes map
var attributes = attributes ? qx.lang.Object.clone(attributes) : {};
var initValues = qx.bom.Iframe.DEFAULT_ATTRIBUTES;
for (var key in initValues) {
if (!(key in attributes)) {
attributes[key] = initValues[key];
}
}
var elem = qx.dom.Element.create("iframe", attributes, win);
if (!("onload" in attributes)) {
elem.onload = function () {
qx.event.handler.Iframe.onevent(elem);
};
}
return elem;
},
/**
* Get the DOM window object of an iframe.
*
* @param iframe {Element} DOM element of the iframe.
* @return {Window?null} The DOM window object of the iframe or null.
* @signature function(iframe)
*/
getWindow(iframe) {
try {
return iframe.contentWindow;
} catch (ex) {
return null;
}
},
/**
* Get the DOM document object of an iframe.
*
* @param iframe {Element} DOM element of the iframe.
* @return {Document} The DOM document object of the iframe.
*/
getDocument(iframe) {
if ("contentDocument" in iframe) {
try {
return iframe.contentDocument;
} catch (ex) {
return null;
}
}
try {
var win = this.getWindow(iframe);
return win ? win.document : null;
} catch (ex) {
return null;
}
},
/**
* Get the HTML body element of the iframe.
*
* @param iframe {Element} DOM element of the iframe.
* @return {Element} The DOM node of the <code>body</code> element of the iframe.
*/
getBody(iframe) {
try {
var doc = this.getDocument(iframe);
return doc ? doc.getElementsByTagName("body")[0] : null;
} catch (ex) {
return null;
}
},
/**
* Sets iframe's source attribute to given value
*
* @param iframe {Element} DOM element of the iframe.
* @param source {String} URL to be set.
* @signature function(iframe, source)
*/
setSource(iframe, source) {
try {
// the guru says ...
// it is better to use 'replace' than 'src'-attribute, since 'replace'
// does not interfere with the history (which is taken care of by the
// history manager), but there has to be a loaded document
if (this.getWindow(iframe) && qx.dom.Hierarchy.isRendered(iframe)) {
/*
Some gecko users might have an exception here:
Exception... "Component returned failure code: 0x805e000a
[nsIDOMLocation.replace]" nsresult: "0x805e000a (<unknown>)"
*/
try {
// Webkit on Mac can't set the source when the iframe is still
// loading its current page
if (
qx.core.Environment.get("engine.name") == "webkit" &&
qx.core.Environment.get("os.name") == "osx"
) {
var contentWindow = this.getWindow(iframe);
if (contentWindow) {
contentWindow.stop();
}
}
this.getWindow(iframe).location.replace(source);
} catch (ex) {
iframe.src = source;
}
} else {
iframe.src = source;
}
// This is a programmer provided source. Remember URL for this source
// for later comparison with current URL. The current URL can diverge
// if the end-user navigates in the Iframe.
this.__rememberUrl(iframe);
} catch (ex) {
qx.log.Logger.warn("Iframe source could not be set!");
}
},
/**
* Returns the current (served) URL inside the iframe
*
* @param iframe {Element} DOM element of the iframe.
* @return {String} Returns the location href or null (if a query is not possible/allowed)
*/
queryCurrentUrl(iframe) {
var doc = this.getDocument(iframe);
try {
if (doc && doc.location) {
return doc.location.href;
}
} catch (ex) {}
return "";
},
/**
* Remember actual URL of iframe.
*
* @param iframe {Element} DOM element of the iframe.
*/
__rememberUrl(iframe) {
// URL can only be detected after load. Retrieve and store URL once.
var callback = function () {
qx.bom.Event.removeNativeListener(iframe, "load", callback);
iframe.$$url = qx.bom.Iframe.queryCurrentUrl(iframe);
};
qx.bom.Event.addNativeListener(iframe, "load", callback);
}
}
});