Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

syncing the length library with the latest from the gist.

  • Loading branch information...
commit 2a3ccec97c51b153096bddb8c4180e09fc7845de 1 parent 6c1ec3f
heygrady authored
Showing with 93 additions and 111 deletions.
  1. +90 −111 Length.js
  2. +3 −0  Length.min.js
View
201 Length.js
@@ -1,168 +1,147 @@
-(function(document, undefined){
+(function(window, document, undefined){
"use strict";
-// create an element to test with
+// create a test element
var testElem = document.createElement('test'),
- testStyle = testElem.style,
- convert = {},
- units = ['mm', 'cm', 'pt', 'pc', 'in', 'mozmm'],
- conversions = [1/25.4, 1/2.54, 1/72, 1/6],
- i = 6, //units.length,
- runit = /^(-?[\d+\.\-]+)([a-z]+|%)$/i,
- rem = /r?em/,
- rvpos = /^top|bottom/,
docElement = document.documentElement,
defaultView = document.defaultView,
getComputedStyle = defaultView && defaultView.getComputedStyle,
- defaultProp = 'left',
- marginBug,
-
- // shorten some repeated strings
- _font = 'font',
- _fontSize = _font + 'Size',
- _fontFamily = _font + 'Family',
- _fontWeight = _font + 'Weight',
- _fontStyle = _font + 'Style',
- _padding = 'padding',
- _border = 'border',
- _Top = 'Top',
- _Bottom = 'Bottom',
- _marginTop = 'margin' + _Top,
- _px = 'px',
- _toPx = 'ToPx',
- _parseFloat = parseFloat;
-
-// make sure our test element is position absolute
-testStyle.position = 'absolute';
-
-// test for the WebKit margin bug
-if( getComputedStyle ) {
- testStyle[_marginTop] = '1%';
- marginBug = getComputedStyle( testElem )[_marginTop] !== '1%';
+ computedValueBug,
+ runit = /^(-?[\d+\.\-]+)([a-z]+|%)$/i,
+ convert = {},
+ conversions = [1/25.4, 1/2.54, 1/72, 1/6],
+ units = ['mm', 'cm', 'pt', 'pc', 'in', 'mozmm'],
+ i = 6; // units.length
+
+// add the test element to the dom
+docElement.appendChild(testElem);
+
+// test for the WebKit getComputedStyle bug
+// @see http://bugs.jquery.com/ticket/10639
+if (getComputedStyle) {
+ // add a percentage margin and measure it
+ testElem.style.marginTop = '1%';
+ computedValueBug = getComputedStyle(testElem).marginTop === '1%';
}
-// loop our absolute units
+// pre-calculate absolute unit conversions
while(i--) {
- convert[units[i] + _toPx] = conversions[i] ? conversions[i] * convert.inToPx : toPx(testElem, '1' + units[i]);
+ convert[units[i] + "toPx"] = conversions[i] ? conversions[i] * convert.inToPx : toPx(testElem, '1' + units[i]);
}
+// remove the test element from the DOM and delete it
+docElement.removeChild(testElem);
+testElem = undefined;
+
// convert a value to pixels
function toPx(elem, value, prop, force) {
- prop = prop || defaultProp;
+ // use width as the default property, or specify your own
+ prop = prop || 'width';
+
var style,
- styleVal,
- styleElem,
- ret = _parseFloat(value),
+ inlineValue,
+ ret,
unit = (value.match(runit)||[])[2],
- conversion = unit === _px ? 1 : convert[unit + _toPx];
-
- // return known conversions immediately
+ conversion = unit === 'px' ? 1 : convert[unit + 'toPx'],
+ rem = /r?em/i;
+
if (conversion || rem.test(unit) && !force) {
- styleElem = unit === 'rem' ? docElement : prop === _fontSize ? elem.parentNode : elem;
- conversion = conversion || _parseFloat(curCSS(styleElem, _fontSize));
- ret = ret * conversion;
+ // calculate known conversions immediately
+ // find the correct element for absolute units or rem or fontSize + em or em
+ elem = conversion ? elem : unit === 'rem' ? docElement : prop === 'fontSize' ? elem.parentNode || elem : elem;
+
+ // use the pre-calculated conversion or fontSize of the element for rem and em
+ conversion = conversion || parseFloat(curCSS(elem, 'fontSize'));
+
+ // multiply the value by the conversion
+ ret = parseFloat(value) * conversion;
} else {
- // percentages are relative by prop on the actual element
- styleElem = unit === '%' ? elem : testElem;
- style = styleElem.style;
-
- // copy the font to the test element
- if (unit === 'ch' || unit === 'ex') {
- style[_fontSize] = curCSS(elem, _fontSize);
- style[_fontFamily] = curCSS(elem, _fontFamily);
- style[_fontWeight] = curCSS(elem, _fontWeight);
- style[_fontStyle] = curCSS(elem, _fontStyle);
- }
+ // begin "the awesome hack by Dean Edwards"
+ // @see http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
- // capture the current value
- styleVal = style[prop];
+ // remember the current style
+ style = elem.style;
+ inlineValue = style[prop];
// set the style on the target element
try {
style[prop] = value;
-
- // add the test element to the DOM
- if (styleElem === testElem) { docElement.appendChild(styleElem); }
-
- // read the computed/used value
- // if style is nothing the browser didn't accept whatever we set, return 0
- ret = !style[prop] ? 0 : _parseFloat(curCSS(styleElem, prop));
-
- // yank the test element out of the dom
- // (because people will complain if they see in in their inspector, otherwise it doens't hurt anything)
- if (elem !== testElem && styleElem === testElem) { docElement.removeChild(styleElem); }
-
- // restore the property we were testing
- style[prop] = styleVal !== undefined ? styleVal : null;
} catch(e) {
- // IE 8 and below won't accept nonsense units
- ret = 0;
+ // IE 8 and below throw an exception when setting unsupported units
+ return 0;
}
+
+ // read the computed value
+ // if style is nothing we probably set an unsupported unit
+ ret = !style[prop] ? 0 : parseFloat(curCSS(elem, prop));
+
+ // reset the style back to what it was or blank it out
+ style[prop] = inlineValue !== undefined ? inlineValue : null;
}
+ // return a number
return ret;
}
// return the computed value of a CSS property
function curCSS(elem, prop) {
var value,
- pixel = elem.style['pixel' + prop.charAt(0).toUpperCase() + prop.slice(1)],
+ pixel,
unit,
- parent,
+ rvpos = /^top|bottom/,
+ outerProp = ["paddingTop", "paddingBottom", "borderTop", "borderBottom"],
innerHeight,
- outer = [
- _padding + _Top,
- _padding + _Bottom,
- _border + _Top,
- _border + _Bottom
- ],
- i=4;
- if (pixel) {
- value = pixel + _px;
- } else if (getComputedStyle) {
+ parent,
+ i = 4; // outerProp.length
+
+ if (getComputedStyle) {
// FireFox, Chrome/Safari, Opera and IE9+
value = getComputedStyle(elem)[prop];
- } else if (prop === _fontSize) {
+ } else if (pixel = elem.style['pixel' + prop.charAt(0).toUpperCase() + prop.slice(1)]) {
+ // IE and Opera support pixel shortcuts for top, bottom, left, right, height, width
+ // WebKit supports pixel shortcuts only when an absolute unit is used
+ value = pixel + 'px';
+ } else if (prop === 'fontSize') {
// correct IE issues with font-size
// @see http://bugs.jquery.com/ticket/760
- value = toPx(elem, '1em', defaultProp, 1) + _px;
+ value = toPx(elem, '1em', 'left', 1) + 'px';
} else {
- // IE won't convert units for us
+ // IE 8 and below return the specified style
value = elem.currentStyle[prop];
}
-
- // doctor the values if we got something weird
+
+ // check the unit
unit = (value.match(runit)||[])[2];
- if (unit === '%' && marginBug) {
- // WebKit won't convert percentages for top, bottom, left, right and margin
+ if (unit === '%' && computedValueBug) {
+ // WebKit won't convert percentages for top, bottom, left, right, margin and text-indent
if (rvpos.test(prop)) {
- // Top and bottom requires measuring the innerHeigt of the parent.
+ // Top and bottom require measuring the innerHeight of the parent.
innerHeight = (parent = elem.parentNode || elem).offsetHeight;
while (i--) {
- innerHeight -= _parseFloat(curCSS(parent, outer[i]));
+ innerHeight -= parseFloat(curCSS(parent, outerProp[i]));
}
- value = _parseFloat(value) / 100 * innerHeight + _px;
+ value = parseFloat(value) / 100 * innerHeight + 'px';
} else {
- // This fixes margin, left and right
+ // This fixes margin, left, right and text-indent
// @see https://bugs.webkit.org/show_bug.cgi?id=29084
// @see http://bugs.jquery.com/ticket/10639
- value = toPx(elem, value, 'width', 1);
+ value = toPx(elem, value);
}
-
- } else if (value === 'auto' || (unit !== _px && getComputedStyle)) {
- // WebKit and Opera will return auto in some cases when a valid value can't be set on a specific property
- // Firefox will pass back an unaltered value when it is valid but can't be set for that element, like top on a static element
+ } else if ((value === 'auto' || (unit && unit !== 'px')) && getComputedStyle) {
+ // WebKit and Opera will return auto in some cases
+ // Firefox will pass back an unaltered value when it can't be set, like top on a static element
value = 0;
- }else if (unit && unit !== _px) {
- // IE might return a non-px unit, convert it using the default property
- // TODO: this will return incorrect results for percentages in some cases
- value = toPx(elem, value) + _px;
+ } else if (unit && unit !== 'px' && !getComputedStyle) {
+ // IE 8 and below won't convert units for us
+ // try to convert using a prop that will return pixels
+ // this will be accurate for everything (except font-size and some percentages)
+ value = toPx(elem, value) + 'px';
}
return value;
}
-// explose the conversion function to the window object
+// expose the conversion function to the window object
window.Length = {
toPx: toPx
-}
-}(this.document));
+};
+}(this, this.document));
View
3  Length.min.js
@@ -0,0 +1,3 @@
+(function(r,a,n){function i(b,j,c,d){var c=c||"width",e;e=(j.match(o)||[])[2];var a="px"===e?1:k[e+"toPx"],g=/r?em/i;if(a||g.test(e)&&!d)b=a?b:"rem"===e?l:"fontSize"===c?b.parentNode||b:b,a=a||parseFloat(m(b,"fontSize")),b=parseFloat(j)*a;else{d=b.style;e=d[c];try{d[c]=j}catch(f){return 0}b=!d[c]?0:parseFloat(m(b,c));d[c]=e!==n?e:null}return b}function m(b,a){var c,d,e=/^top|bottom/,f=["paddingTop","paddingBottom","borderTop","borderBottom"],h=4;c=g?g(b)[a]:(d=b.style["pixel"+a.charAt(0).toUpperCase()+
+a.slice(1)])?d+"px":"fontSize"===a?i(b,"1em","left",1)+"px":b.currentStyle[a];d=(c.match(o)||[])[2];if("%"===d&&p)if(e.test(a)){for(e=(d=b.parentNode||b).offsetHeight;h--;)e-=parseFloat(m(d,f[h]));c=parseFloat(c)/100*e+"px"}else c=i(b,c);else("auto"===c||d&&"px"!==d)&&g?c=0:d&&"px"!==d&&!g&&(c=i(b,c)+"px");return c}var f=a.createElement("test"),l=a.documentElement,g=(a=a.defaultView)&&a.getComputedStyle,p,o=/^(-?[\d+\.\-]+)([a-z]+|%)$/i,k={},a=[1/25.4,1/2.54,1/72,1/6],q="mm,cm,pt,pc,in,mozmm".split(","),
+h=6;l.appendChild(f);if(g)f.style.marginTop="1%",p="1%"===g(f).marginTop;for(;h--;)k[q[h]+"toPx"]=a[h]?a[h]*k.b:i(f,"1"+q[h]);l.removeChild(f);f=n;r.a={c:i}})(this,this.document);
Please sign in to comment.
Something went wrong with that request. Please try again.