/**
-
box-sizing Polyfill
*
-
A polyfill for box-sizing: border-box for IE6 & IE7.
*
-
JScript
*
-
This program is free software: you can redistribute it and/or modify
-
it under the terms of the GNU Lesser General Public License as published
-
by the Free Software Foundation, either version 3 of the License, or
-
(at your option) any later version.
*
-
This program is distributed in the hope that it will be useful,
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-
GNU Lesser General Public License for more details.
*
*
-
@category JScript
-
@package box-sizing-polyfill
-
@author Christian Schepp Schaefer <schaepp@gmx.de> <twitter.com/derSchepp>
-
@copyright 2012 Christian Schepp Schaefer
-
@license www.gnu.org/copyleft/lesser.html The GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0
*
-
PREFACE:
*
-
This box-sizing polyfill is based on previous work done by Erik Arvidsson,
-
which he published in 2002 on webfx.eae.net/dhtml/boxsizing/boxsizing.html.
*
-
USAGE:
*
-
Add the behavior/HTC after every ‘box-sizing: border-box;` that you assign:
*
-
box-sizing: border-box;
-
*behavior: url(/scripts/boxsizing.htc);‘
*
-
Prefix the ‘behavior` property with a star, like seen above, so it will only be seen by
-
IE6 & IE7, not by IE8+ who already implement box-sizing.
*
-
The URL to the HTC file must be relative to your HTML(!) document, not relative to your CSS.
-
That’s why I’d advise you to use absolute paths like in the example.
* */ <component lightWeight=“true”> <attach event=“onpropertychange” onevent=“checkPropertyChange()” /> <attach event=“ondetach” onevent=“restore()” /> <attach event=“onresize” for=“window” onevent=“update()” /> <script type=“text/javascript”> //<![CDATA[
var viewportwidth = (typeof window.innerWidth != ‘undefined’ ? window.innerWidth : element.document.documentElement.clientWidth);
// Shortcut for the document object var doc = element.document;
// Buffer for multiple resize events var resizetimeout = null;
// Don’t apply box-sizing to certain elements var apply = false; switch(element.nodeName){
case '#comment': case 'HTML': case 'HEAD': case 'TITLE': case 'SCRIPT': case 'STYLE': case 'LINK': case 'META': break; default: apply = true; break;
}
/*
-
update gets called during resize events, then waits until there are no further resize events, and finally triggers a recalculation
*/ function update(){
if(resizetimeout !== null){ window.clearTimeout(resizetimeout); } resizetimeout = window.setTimeout(function(){ restore(); init(); resizetimeout = null; },100);
}
/*
-
restore gets called when the behavior is being detached (see event binding at the top),
-
resets everything like it was before applying the behavior
*/ function restore(){
if(apply){ element.runtimeStyle.removeAttribute("width"); element.runtimeStyle.removeAttribute("height"); }
}
/*
-
init gets called once at the start and then never again,
-
triggers box-sizing calculations and updates width and height
*/ function init(){
if(apply){ updateBorderBoxWidth(); updateBorderBoxHeight(); }
}
/*
-
checkPropertyChange gets called as soon as an element property changes
-
(see event binding at the top), it then checks if any property influencing its
-
dimensions was changed and if yes recalculates width and height
*/ function checkPropertyChange(){
if(apply){ var pn = event.propertyName; if(pn === "style.boxSizing" && element.style.boxSizing === ""){ element.style.removeAttribute("boxSizing"); element.runtimeStyle.removeAttribute("boxSizing"); element.runtimeStyle.removeAttribute("width"); element.runtimeStyle.removeAttribute("height"); } switch (pn){ case "style.width": case "style.borderLeftWidth": case "style.borderLeftStyle": case "style.borderRightWidth": case "style.borderRightStyle": case "style.paddingLeft": case "style.paddingRight": updateBorderBoxWidth(); break; case "style.height": case "style.borderTopWidth": case "style.borderTopStyle": case "style.borderBottomWidth": case "style.borderBottomStyle": case "style.paddingTop": case "style.paddingBottom": updateBorderBoxHeight(); break; case "className": case "style.boxSizing": updateBorderBoxWidth(); updateBorderBoxHeight(); break; } }
}
/*
* Helper function, taken from Dean Edward's IE7 framework, * added by Schepp on 12.06.2010. * http://code.google.com/p/ie7-js/ * * Allows us to convert from relative to pixel-values. */
function getPixelValue(value){
var PIXEL = /^\d+(px)?$/i; if (PIXEL.test(value)) return parseInt(value); var style = element.style.left; var runtimeStyle = element.runtimeStyle.left; element.runtimeStyle.left = element.currentStyle.left; element.style.left = value || 0; value = parseInt(element.style.pixelLeft); element.style.left = style; element.runtimeStyle.left = runtimeStyle; return value;
}
function getPixelWidth(object, value){
// For Pixel Values var PIXEL = /^\d+(px)?$/i; if (PIXEL.test(value)) return parseInt(value); // For Percentage Values var PERCENT = /^[\d\.]+%$/i; if (PERCENT.test(value)){ try{ parentWidth = getPixelWidth(object.parentElement,(object.parentElement.currentStyle.width != "auto" ? object.parentElement.currentStyle.width : "100%")); value = (parseFloat(value) / 100) * parentWidth; } catch(e){ value = (parseFloat(value) / 100) * element.document.documentElement.clientWidth; } return parseInt(value); } // For EM Values var style = object.style.left; var runtimeStyle = object.runtimeStyle.left; object.runtimeStyle.left = object.currentStyle.left; object.style.left = value || 0; value = parseInt(object.style.pixelLeft); object.style.left = style; object.runtimeStyle.left = runtimeStyle; return value;
}
function getPixelHeight(object, value){
// For Pixel Values var PIXEL = /^\d+(px)?$/i; if (PIXEL.test(value)) return parseInt(value); // For Percentage Values var PERCENT = /^[\d\.]+%$/i; if (PERCENT.test(value)){ try{ if(object.parentElement.currentStyle.height != "auto"){ switch(object.parentElement.nodeName){ default: parentHeight = getPixelHeight(object.parentElement,object.parentElement.currentStyle.height); if(parentHeight !== "auto"){ value = (parseFloat(value) / 100) * parentHeight; } else { value = "auto"; } break; case 'HTML': parentHeight = element.document.documentElement.clientHeight; if(parentHeight !== "auto"){ value = (parseFloat(value) / 100) * parentHeight; } else { value = "auto"; } break; } if(value !== "auto") value = parseInt(value); } else { value = "auto"; } } catch(e){ value = "auto"; } return value; } // For EM Values var style = object.style.left; var runtimeStyle = object.runtimeStyle.left; object.runtimeStyle.left = object.currentStyle.left; object.style.left = value || 0; value = parseInt(object.style.pixelLeft); object.style.left = style; object.runtimeStyle.left = runtimeStyle; return value;
}
/*
* getBorderWidth & friends * Border width getters */
function getBorderWidth(sSide){
if(element.currentStyle["border" + sSide + "Style"] == "none"){ return 0; } var n = getPixelValue(element.currentStyle["border" + sSide + "Width"]); return n || 0;
} function getBorderLeftWidth() { return getBorderWidth(“Left”); } function getBorderRightWidth() { return getBorderWidth(“Right”); } function getBorderTopWidth() { return getBorderWidth(“Top”); } function getBorderBottomWidth() { return getBorderWidth(“Bottom”); }
/*
* getPadding & friends * Padding width getters */
function getPadding(sSide) {
var n = getPixelValue(element.currentStyle["padding" + sSide]); return n || 0;
} function getPaddingLeft() { return getPadding(“Left”); } function getPaddingRight() { return getPadding(“Right”); } function getPaddingTop() { return getPadding(“Top”); } function getPaddingBottom() { return getPadding(“Bottom”); }
/*
* getBoxSizing * Get the box-sizing value for the current element */
function getBoxSizing(){
var s = element.style; var cs = element.currentStyle if(typeof s.boxSizing != "undefined" && s.boxSizing != ""){ return s.boxSizing; } if(typeof s["box-sizing"] != "undefined" && s["box-sizing"] != ""){ return s["box-sizing"]; } if(typeof cs.boxSizing != "undefined" && cs.boxSizing != ""){ return cs.boxSizing; } if(typeof cs["box-sizing"] != "undefined" && cs["box-sizing"] != ""){ return cs["box-sizing"]; } return getDocumentBoxSizing();
}
/*
* getDocumentBoxSizing * Get the default document box sizing (check for quirks mode) */
function getDocumentBoxSizing(){
if(doc.compatMode === null || doc.compatMode === "BackCompat"){ return "border-box"; } return "content-box"
}
/*
* setBorderBoxWidth & friends * Width and height setters */
function setBorderBoxWidth(n){
element.runtimeStyle.width = Math.max(0, n - getBorderLeftWidth() - getPaddingLeft() - getPaddingRight() - getBorderRightWidth()) + "px";
} function setBorderBoxHeight(n){
element.runtimeStyle.height = Math.max(0, n - getBorderTopWidth() - getPaddingTop() - getPaddingBottom() - getBorderBottomWidth()) + "px";
} function setContentBoxWidth(n){
element.runtimeStyle.width = Math.max(0, n + getBorderLeftWidth() + getPaddingLeft() + getPaddingRight() + getBorderRightWidth()) + "px";
} function setContentBoxHeight(n){
element.runtimeStyle.height = Math.max(0, n + getBorderTopWidth() + getPaddingTop() + getPaddingBottom() + getBorderBottomWidth()) + "px";
}
/*
* updateBorderBoxWidth & updateBorderBoxHeight * */
function updateBorderBoxWidth() {
if(getDocumentBoxSizing() == getBoxSizing()){ return; } var csw = element.currentStyle.width; if(csw != "auto"){ csw = getPixelWidth(element,csw); if(getBoxSizing() == "border-box"){ setBorderBoxWidth(parseInt(csw)); } else{ setContentBoxWidth(parseInt(csw)); } }
}
function updateBorderBoxHeight() {
if(getDocumentBoxSizing() == getBoxSizing()){ return; } var csh = element.currentStyle.height; if(csh != "auto"){ csh = getPixelHeight(element,csh); if(csh !== "auto"){ if(getBoxSizing() == "border-box"){ setBorderBoxHeight(parseInt(csh)); } else{ setContentBoxHeight(parseInt(csh)); } } }
}
// Run the calculations init();
//]]> </script> </component>