Skip to content
Browse files

When calculating em unit size on elements that don't accept children,…

… insert the length calc element into the parent and perform an additional calculation based on the specified font-size. Prevents error trying to insert into the childless element. Fixes #99.
  • Loading branch information...
1 parent 65b832d commit 89231378716d8cd1b9203352606032c9b52ec432 Jason Johnston committed Apr 27, 2011
Showing with 127 additions and 22 deletions.
  1. +2 −16 sources/BorderRenderer.js
  2. +18 −6 sources/Length.js
  3. +17 −0 sources/PIE_open.js
  4. +90 −0 tests/lengths.html
View
18 sources/BorderRenderer.js
@@ -11,20 +11,6 @@ PIE.BorderRenderer = PIE.RendererBase.newRenderer( {
boxName: 'border',
/**
- * Lookup table of elements which cannot take custom children.
- */
- childlessElements: {
- 'TABLE':1, //can obviously have children but not custom ones
- 'INPUT':1,
- 'TEXTAREA':1,
- 'SELECT':1,
- 'OPTION':1,
- 'IMG':1,
- 'HR':1,
- 'FIELDSET':1 //can take children but wrapping its children messes up its <legend>
- },
-
- /**
* Values of the type attribute for input elements displayed as buttons
*/
inputButtonTypes: {
@@ -105,8 +91,8 @@ PIE.BorderRenderer = PIE.RendererBase.newRenderer( {
isIE6 = PIE.ieVersion === 6,
sides, side, i;
- if( ( isIE6 && tag in this.childlessElements ) || tag === 'BUTTON' ||
- ( tag === 'INPUT' && el.type in this.inputButtonTypes ) ) {
+ if( ( isIE6 && ( tag in PIE.childlessElements || tag === 'FIELDSET' ) ) ||
+ tag === 'BUTTON' || ( tag === 'INPUT' && el.type in this.inputButtonTypes ) ) {
rs.borderWidth = '';
sides = this.styleInfos.borderInfo.sides;
for( i = sides.length; i--; ) {
View
24 sources/Length.js
@@ -24,6 +24,9 @@ PIE.Length = (function() {
}
parent.removeChild( lengthCalcEl );
+ // All calcs from here on will use 1em
+ lengthCalcEl.style.width = '1em';
+
function Length( val ) {
this.val = val;
@@ -98,18 +101,27 @@ PIE.Length = (function() {
* however if the font-size is set using non-pixel units then we get that value
* rather than a pixel conversion. To get around this, we keep a floating element
* with width:1em which we insert into the target element and then read its offsetWidth.
- * But if the font-size *is* specified in pixels, then we use that directly to avoid
- * the expensive DOM manipulation.
- * @param el
+ * For elements that won't accept a child we insert into the parent node and perform
+ * additional calculation. If the font-size *is* specified in pixels, then we use that
+ * directly to avoid the expensive DOM manipulation.
+ * @param {Element} el
+ * @return {number}
*/
getEmPixels: function( el ) {
var fs = el.currentStyle.fontSize,
- px;
+ px, parent, me;
if( fs.indexOf( 'px' ) > 0 ) {
return parseFloat( fs );
- } else {
- lengthCalcEl.style.width = '1em';
+ }
+ else if( el.tagName in PIE.childlessElements ) {
+ me = this;
+ parent = el.parentNode;
+ return PIE.getLength( fs ).pixels( parent, function() {
+ return me.getEmPixels( parent );
+ } );
+ }
+ else {
el.appendChild( lengthCalcEl );
px = lengthCalcEl.offsetWidth;
if( lengthCalcEl.parentNode === el ) { //not sure how this could be false but it sometimes is
View
17 sources/PIE_open.js
@@ -8,6 +8,23 @@ if( !PIE ) {
tableCellTags: {
'TD': 1,
'TH': 1
+ },
+
+ /**
+ * Lookup table of elements which cannot take custom children.
+ */
+ childlessElements: {
+ 'TABLE':1,
+ 'THEAD':1,
+ 'TBODY':1,
+ 'TFOOT':1,
+ 'TR':1,
+ 'INPUT':1,
+ 'TEXTAREA':1,
+ 'SELECT':1,
+ 'OPTION':1,
+ 'IMG':1,
+ 'HR':1
}
};
View
90 tests/lengths.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+
+ <style type="text/css">
+
+ html, body {
+ font: 10px sans-serif;
+ }
+ div, input {
+ font-family: sans-serif;
+ }
+
+ .section {
+ clear: both;
+ padding: 20px;
+ }
+ h2 {
+ font-size: 14px;
+ }
+
+ .tester {
+ behavior: url(../build/PIE.htc);
+ float: left;
+ margin: 0 10px;
+ padding: 10px;
+ border: 0;
+ background: #CCC;
+ }
+
+ input::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+ }
+ </style>
+
+</head>
+<body>
+
+<div class="section">
+ <h2>font-size: 10px;</h2>
+
+ <div class="tester" style="border-radius: 15px; font-size: 10px;">
+ div, border-radius: 10px;
+ </div>
+
+ <div class="tester" style="border-radius: 1.5em; font-size: 10px;">
+ div, border-radius: 1.5em;
+ </div>
+
+ <input class="tester" type="button" style="border-radius: 15px; font-size: 10px;" value="input, border-radius: 15px;" />
+
+ <input class="tester" type="button" style="border-radius: 1.5em; font-size: 10px;" value="input, border-radius: 1.5em;" />
+</div>
+
+<div class="section" style="font-size: 20px;">
+ <h2>font-size: .5em;</h2>
+
+ <div class="tester" style="border-radius: 15px; font-size: .5em;">
+ div, border-radius: 10px;
+ </div>
+
+ <div class="tester" style="border-radius: 1.5em; font-size: .5em;">
+ div, border-radius: 1.5em;
+ </div>
+
+ <input class="tester" type="button" style="border-radius: 15px; font-size: .5em;" value="input, border-radius: 15px;" />
+
+ <input class="tester" type="button" style="border-radius: 1.5em; font-size: .5em;" value="input, border-radius: 1.5em;" />
+</div>
+
+<div class="section" style="font-size: 20px;">
+ <h2>font-size: 50%;</h2>
+
+ <div class="tester" style="border-radius: 15px; font-size: 50%;">
+ div, border-radius: 10px;
+ </div>
+
+ <div class="tester" style="border-radius: 1.5em; font-size: 50%;">
+ div, border-radius: 1.5em;
+ </div>
+
+ <input class="tester" type="button" style="border-radius: 15px; font-size: 50%;" value="input, border-radius: 15px;" />
+
+ <input class="tester" type="button" style="border-radius: 1.5em; font-size: 50%;" value="input, border-radius: 1.5em;" />
+</div>
+
+</body>
+</html>

0 comments on commit 8923137

Please sign in to comment.
Something went wrong with that request. Please try again.