@qooxdoo/framework
Version:
The JS Framework for Coders
536 lines (472 loc) • 15.6 kB
JavaScript
/* ************************************************************************
qooxdoo - the new era of web development
http://qooxdoo.org
Copyright:
2004-2011 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:
* Martin Wittemann (martinwittemann)
************************************************************************ */
/**
* Internal class which contains the checks used by {@link qx.core.Environment}.
* All checks in here are marked as internal which means you should never use
* them directly.
*
* This class should contain all checks about HTML.
*
* @internal
*/
qx.Bootstrap.define("qx.bom.client.Html",
{
statics:
{
/**
* Whether the client supports Web Workers.
*
* @internal
* @return {Boolean} <code>true</code> if webworkers are supported
*/
getWebWorker : function() {
return window.Worker != null;
},
/**
* Whether the client supports File Readers
*
* @internal
* @return {Boolean} <code>true</code> if FileReaders are supported
*/
getFileReader : function() {
return window.FileReader != null;
},
/**
* Whether the client supports Geo Location.
*
* @internal
* @return {Boolean} <code>true</code> if geolocation supported
*/
getGeoLocation : function() {
return "geolocation" in navigator;
},
/**
* Whether the client supports audio.
*
* @internal
* @return {Boolean} <code>true</code> if audio is supported
*/
getAudio : function() {
return !!document.createElement('audio').canPlayType;
},
/**
* Whether the client can play ogg audio format.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getAudioOgg : function() {
if (!qx.bom.client.Html.getAudio()) {
return "";
}
var a = document.createElement("audio");
return a.canPlayType("audio/ogg");
},
/**
* Whether the client can play mp3 audio format.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getAudioMp3 : function() {
if (!qx.bom.client.Html.getAudio()) {
return "";
}
var a = document.createElement("audio");
return a.canPlayType("audio/mpeg");
},
/**
* Whether the client can play wave audio wave format.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getAudioWav : function() {
if (!qx.bom.client.Html.getAudio()) {
return "";
}
var a = document.createElement("audio");
return a.canPlayType("audio/x-wav");
},
/**
* Whether the client can play au audio format.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getAudioAu : function() {
if (!qx.bom.client.Html.getAudio()) {
return "";
}
var a = document.createElement("audio");
return a.canPlayType("audio/basic");
},
/**
* Whether the client can play aif audio format.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getAudioAif : function() {
if (!qx.bom.client.Html.getAudio()) {
return "";
}
var a = document.createElement("audio");
return a.canPlayType("audio/x-aiff");
},
/**
* Whether the client supports video.
*
* @internal
* @return {Boolean} <code>true</code> if video is supported
*/
getVideo : function() {
return !!document.createElement('video').canPlayType;
},
/**
* Whether the client supports ogg video.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getVideoOgg : function() {
if (!qx.bom.client.Html.getVideo()) {
return "";
}
var v = document.createElement("video");
return v.canPlayType('video/ogg; codecs="theora, vorbis"');
},
/**
* Whether the client supports mp4 video.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getVideoH264 : function() {
if (!qx.bom.client.Html.getVideo()) {
return "";
}
var v = document.createElement("video");
return v.canPlayType('video/mp4; codecs="avc1.42E01E, mp4a.40.2"');
},
/**
* Whether the client supports webm video.
*
* @internal
* @return {String} "" or "maybe" or "probably"
*/
getVideoWebm : function() {
if (!qx.bom.client.Html.getVideo()) {
return "";
}
var v = document.createElement("video");
return v.canPlayType('video/webm; codecs="vp8, vorbis"');
},
/**
* Whether the client supports local storage.
*
* @internal
* @return {Boolean} <code>true</code> if local storage is supported
*/
getLocalStorage : function() {
try {
// write once to make sure to catch safari's private mode [BUG #7718]
window.localStorage.setItem("$qx_check", "test");
window.localStorage.removeItem("$qx_check");
return true;
} catch (exc) {
// Firefox Bug: localStorage doesn't work in file:/// documents
// see https://bugzilla.mozilla.org/show_bug.cgi?id=507361
return false;
}
},
/**
* Whether the client supports session storage.
*
* @internal
* @return {Boolean} <code>true</code> if session storage is supported
*/
getSessionStorage : function() {
try {
// write once to make sure to catch safari's private mode [BUG #7718]
window.sessionStorage.setItem("$qx_check", "test");
window.sessionStorage.removeItem("$qx_check");
return true;
} catch (exc) {
// Firefox Bug: Local execution of window.sessionStorage throws error
// see https://bugzilla.mozilla.org/show_bug.cgi?id=357323
return false;
}
},
/**
* Whether the client supports user data to persist data. This is only
* relevant for IE < 8.
*
* @internal
* @return {Boolean} <code>true</code> if the user data is supported.
*/
getUserDataStorage : function() {
var el = document.createElement("div");
el.style["display"] = "none";
document.getElementsByTagName("head")[0].appendChild(el);
var supported = false;
try {
el.addBehavior("#default#userdata");
el.load("qxtest");
supported = true;
} catch (e) {}
document.getElementsByTagName("head")[0].removeChild(el);
return supported;
},
/**
* Whether the browser supports CSS class lists.
* https://developer.mozilla.org/en-US/docs/DOM/element.classList
*
* @internal
* @return {Boolean} <code>true</code> if class list is supported.
*/
getClassList : function() {
return !!(document.documentElement.classList &&
qx.Bootstrap.getClass(document.documentElement.classList) === "DOMTokenList"
);
},
/**
* Checks if XPath could be used.
*
* @internal
* @return {Boolean} <code>true</code> if xpath is supported.
*/
getXPath : function() {
return !!document.evaluate;
},
/**
* Checks if XUL could be used.
*
* @internal
* @return {Boolean} <code>true</code> if XUL is supported.
*/
getXul : function() {
try {
document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "label");
return true;
} catch (e) {
return false;
}
},
/**
* Checks if SVG could be used
*
* @internal
* @return {Boolean} <code>true</code> if SVG is supported.
*/
getSvg : function() {
return document.implementation && document.implementation.hasFeature &&
(document.implementation.hasFeature("org.w3c.dom.svg", "1.0") ||
document.implementation.hasFeature(
"http://www.w3.org/TR/SVG11/feature#BasicStructure",
"1.1"
)
);
},
/**
* Checks if VML is supported
*
* @internal
* @return {Boolean} <code>true</code> if VML is supported.
*/
getVml : function() {
var el = document.createElement("div");
document.body.appendChild(el);
el.innerHTML = '<v:shape id="vml_flag1" adj="1" />';
el.firstChild.style.behavior = "url(#default#VML)";
var hasVml = typeof el.firstChild.adj == "object";
document.body.removeChild(el);
return hasVml;
},
/**
* Checks if canvas could be used
*
* @internal
* @return {Boolean} <code>true</code> if canvas is supported.
*/
getCanvas : function() {
return !!window.CanvasRenderingContext2D;
},
/**
* Asynchronous check for using data urls.
*
* @internal
* @param callback {Function} The function which should be executed as
* soon as the check is done.
*/
getDataUrl : function(callback) {
var data = new Image();
data.onload = data.onerror = function() {
// wrap that into a timeout because IE might execute it synchronously
window.setTimeout(function() {
callback.call(null, (data.width == 1 && data.height == 1));
}, 0);
};
data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
},
/**
* Checks if dataset could be used
*
* @internal
* @return {Boolean} <code>true</code> if dataset is supported.
*/
getDataset : function() {
return !!document.documentElement.dataset;
},
/**
* Check for element.contains
*
* @internal
* @return {Boolean} <code>true</code> if element.contains is supported
*/
getContains : function()
{
// "object" in IE6/7/8, "function" in IE9
return (typeof document.documentElement.contains !== "undefined");
},
/**
* Check for element.compareDocumentPosition
*
* @internal
* @return {Boolean} <code>true</code> if element.compareDocumentPosition is supported
*/
getCompareDocumentPosition : function()
{
return (typeof document.documentElement.compareDocumentPosition === "function");
},
/**
* Check for element.textContent. Legacy IEs do not support this, use
* innerText instead.
*
* @internal
* @return {Boolean} <code>true</code> if textContent is supported
*/
getTextContent : function()
{
var el = document.createElement("span");
return (typeof el.textContent !== "undefined");
},
/**
* Whether the client supports the fullscreen API.
*
* @internal
* @return {Boolean} <code>true</code> if fullscreen is supported
*/
getFullScreen : function() {
return document.fullscreenEnabled ||
document.webkitFullscreenEnabled ||
document.mozFullScreenEnabled ||
document.msFullscreenEnabled || false;
},
/**
* Check for a console object.
*
* @internal
* @return {Boolean} <code>true</code> if a console is available.
*/
getConsole : function()
{
return typeof window.console !== "undefined";
},
/**
* Check for the <code>naturalHeight</code> and <code>naturalWidth</code>
* image element attributes.
*
* @internal
* @return {Boolean} <code>true</code> if both attributes are supported
*/
getNaturalDimensions : function()
{
var img = document.createElement("img");
return typeof img.naturalHeight === "number" &&
typeof img.naturalWidth === "number";
},
/**
* Check for HTML5 history manipulation support.
* @internal
* @return {Boolean} <code>true</code> if the HTML5 history API is supported
*/
getHistoryState : function()
{
return (typeof window.onpopstate !== "undefined" &&
typeof window.history.replaceState !== "undefined" &&
typeof window.history.pushState !== "undefined");
},
/**
* Returns the name of the native object/function used to access the
* document's text selection.
*
* @return {String|null} <code>getSelection</code> if the standard window.getSelection
* function is available; <code>selection</code> if the MS-proprietary
* document.selection object is available; <code>null</code> if no known
* text selection API is available.
*/
getSelection : function()
{
if (typeof window.getSelection === "function") {
return "getSelection";
}
if (typeof document.selection === "object") {
return "selection";
}
return null;
},
/**
* Check for the isEqualNode DOM method.
*
* @return {Boolean} <code>true</code> if isEqualNode is supported by DOM nodes
*/
getIsEqualNode : function() {
return typeof document.documentElement.isEqualNode === "function";
}
},
defer : function (statics) {
qx.core.Environment.add("html.webworker", statics.getWebWorker);
qx.core.Environment.add("html.filereader", statics.getFileReader);
qx.core.Environment.add("html.geolocation", statics.getGeoLocation);
qx.core.Environment.add("html.audio", statics.getAudio);
qx.core.Environment.add("html.audio.ogg", statics.getAudioOgg);
qx.core.Environment.add("html.audio.mp3", statics.getAudioMp3);
qx.core.Environment.add("html.audio.wav", statics.getAudioWav);
qx.core.Environment.add("html.audio.au", statics.getAudioAu);
qx.core.Environment.add("html.audio.aif", statics.getAudioAif);
qx.core.Environment.add("html.video", statics.getVideo);
qx.core.Environment.add("html.video.ogg", statics.getVideoOgg);
qx.core.Environment.add("html.video.h264", statics.getVideoH264);
qx.core.Environment.add("html.video.webm", statics.getVideoWebm);
qx.core.Environment.add("html.storage.local", statics.getLocalStorage);
qx.core.Environment.add("html.storage.session", statics.getSessionStorage);
qx.core.Environment.add("html.storage.userdata", statics.getUserDataStorage);
qx.core.Environment.add("html.classlist", statics.getClassList);
qx.core.Environment.add("html.xpath", statics.getXPath);
qx.core.Environment.add("html.xul", statics.getXul);
qx.core.Environment.add("html.canvas", statics.getCanvas);
qx.core.Environment.add("html.svg", statics.getSvg);
qx.core.Environment.add("html.vml", statics.getVml);
qx.core.Environment.add("html.dataset", statics.getDataset);
qx.core.Environment.addAsync("html.dataurl", statics.getDataUrl);
qx.core.Environment.add("html.element.contains", statics.getContains);
qx.core.Environment.add("html.element.compareDocumentPosition", statics.getCompareDocumentPosition);
qx.core.Environment.add("html.element.textcontent", statics.getTextContent);
qx.core.Environment.add("html.console", statics.getConsole);
qx.core.Environment.add("html.image.naturaldimensions", statics.getNaturalDimensions);
qx.core.Environment.add("html.history.state", statics.getHistoryState);
qx.core.Environment.add("html.selection", statics.getSelection);
qx.core.Environment.add("html.node.isequalnode", statics.getIsEqualNode);
qx.core.Environment.add("html.fullscreen", statics.getFullScreen);
}
});