@qooxdoo/framework
Version:
The JS Framework for Coders
251 lines (210 loc) • 6.58 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)
************************************************************************ */
/**
* Contains methods to control and query the element's clip property
*
* @require(qx.lang.normalize.String)
*/
qx.Bootstrap.define("qx.bom.element.Clip",
{
/*
*****************************************************************************
STATICS
*****************************************************************************
*/
statics :
{
/**
* Compiles the given clipping into a CSS compatible string. This
* is a simple square which describes the visible area of an DOM element.
* Changing the clipping does not change the dimensions of
* an element.
*
* @param map {Map} Map which contains <code>left</code>, <code>top</code>
* <code>width</code> and <code>height</code> of the clipped area.
* @return {String} CSS compatible string
*/
compile : function(map)
{
if (!map) {
return "clip:auto;";
}
var left = map.left;
var top = map.top;
var width = map.width;
var height = map.height;
var right, bottom;
if (left == null)
{
right = (width == null ? "auto" : width + "px");
left = "auto";
}
else
{
right = (width == null ? "auto" : left + width + "px");
left = left + "px";
}
if (top == null)
{
bottom = (height == null ? "auto" : height + "px");
top = "auto";
}
else
{
bottom = (height == null ? "auto" : top + height + "px");
top = top + "px";
}
return "clip:rect(" + top + "," + right + "," + bottom + "," + left + ");";
},
/**
* Gets the clipping of the given element.
*
* @param element {Element} DOM element to query
* @param mode {Number} Choose one of the modes {@link qx.bom.element.Style#COMPUTED_MODE},
* {@link qx.bom.element.Style#CASCADED_MODE}, {@link qx.bom.element.Style#LOCAL_MODE}.
* The computed mode is the default one.
* @return {Map} Map which contains <code>left</code>, <code>top</code>
* <code>width</code> and <code>height</code> of the clipped area.
* Each one could be null or any integer value.
*/
get : function(element, mode)
{
var clip = qx.bom.element.Style.get(element, "clip", mode, false);
var left, top, width, height;
var right, bottom;
if (typeof clip === "string" && clip !== "auto" && clip !== "")
{
clip = clip.trim();
// Do not use "global" here. This will break Firefox because of
// an issue that the lastIndex will not be reset on separate calls.
if (/\((.*)\)/.test(clip))
{
var result = RegExp.$1;
// Process result
// Some browsers store values space-separated, others comma-separated.
// Handle both cases by means of feature-detection.
if (/,/.test(result)) {
var split = result.split(",");
}
else
{
var split = result.split(" ");
}
top = split[0].trim();
right = split[1].trim();
bottom = split[2].trim();
left = split[3].trim();
// Normalize "auto" to null
if (left === "auto") {
left = null;
}
if (top === "auto") {
top = null;
}
if (right === "auto") {
right = null;
}
if (bottom === "auto") {
bottom = null;
}
// Convert to integer values
if (top != null) {
top = parseInt(top, 10);
}
if (right != null) {
right = parseInt(right, 10);
}
if (bottom != null) {
bottom = parseInt(bottom, 10);
}
if (left != null) {
left = parseInt(left, 10);
}
// Compute width and height
if (right != null && left != null) {
width = right - left;
} else if (right != null) {
width = right;
}
if (bottom != null && top != null) {
height = bottom - top;
} else if (bottom != null) {
height = bottom;
}
}
else
{
throw new Error("Could not parse clip string: " + clip);
}
}
// Return map when any value is available.
return {
left : left || null,
top : top || null,
width : width || null,
height : height || null
};
},
/**
* Sets the clipping of the given element. This is a simple
* square which describes the visible area of an DOM element.
* Changing the clipping does not change the dimensions of
* an element.
*
* @param element {Element} DOM element to modify
* @param map {Map} A map with one or more of these available keys:
* <code>left</code>, <code>top</code>, <code>width</code>, <code>height</code>.
*/
set : function(element, map)
{
if (!map)
{
element.style.clip = "rect(auto,auto,auto,auto)";
return;
}
var left = map.left;
var top = map.top;
var width = map.width;
var height = map.height;
var right, bottom;
if (left == null)
{
right = (width == null ? "auto" : width + "px");
left = "auto";
}
else
{
right = (width == null ? "auto" : left + width + "px");
left = left + "px";
}
if (top == null)
{
bottom = (height == null ? "auto" : height + "px");
top = "auto";
}
else
{
bottom = (height == null ? "auto" : top + height + "px");
top = top + "px";
}
element.style.clip = "rect(" + top + "," + right + "," + bottom + "," + left + ")";
},
/**
* Resets the clipping of the given DOM element.
*
* @param element {Element} DOM element to modify
*/
reset : function(element) {
element.style.clip = "rect(auto, auto, auto, auto)";
}
}
});