1+ /**
2+ * CSS-JS-BOOSTER
3+ *
4+ * A polyfill for box-sizing: border-box for IE6 & IE7.
5+ *
6+ * JScript
7+ *
8+ * This program is free software: you can redistribute it and/or modify
9+ * it under the terms of the GNU Lesser General Public License as published
10+ * by the Free Software Foundation, either version 3 of the License, or
11+ * (at your option) any later version.
12+ *
13+ * This program is distributed in the hope that it will be useful,
14+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+ * GNU Lesser General Public License for more details.
17+ *
18+ * See <http://www.gnu.org/licenses/lgpl-3.0.txt>
19+ *
20+ * @category JScript
21+ * @package box-sizing-polyfill
22+ * @author Christian Schepp Schaefer <
[email protected] > <http://twitter.com/derSchepp>
23+ * @copyright 2010 Christian Schepp Schaefer
24+ * @license http://www.gnu.org/copyleft/lesser.html The GNU LESSER GENERAL PUBLIC LICENSE, Version 3.0
25+ * @link http://github.com/Schepp/box-sizing-polyfill
26+ *
27+ * PREFACE:
28+ *
29+ * This box-sizing polyfill is based on previous work done by Erik Arvidsson,
30+ * which he published in 2002 on http://webfx.eae.net/dhtml/boxsizing/boxsizing.html.
31+ *
32+ * USAGE:
33+ *
34+ * Add the behavior/HTC after every `box-sizing: border-box;` that you assign:
35+ *
36+ * box-sizing: border-box;
37+ * *behavior: url(/scripts/boxsizing.htc);`
38+ *
39+ * If you prefix the `behavior` property with a star, like seen above, it will only be seen by
40+ * IE6 & IE7, not by IE8+ (it's a hack) which is better for the performance on those newer browsers.
41+ *
42+ * The URL to the HTC file must be relative to your HTML(!) document, not relative to your CSS.
43+ * That's why I'd advise you to use absolute paths like in the example.
44+ *
45+ */
46+ <component lightWeight="true">
47+ <attach event="onpropertychange" onevent="checkPropertyChange()" />
48+ <attach event="ondetach" onevent="restore()" />
49+ <attach event="onresize" for="window" onevent="restore();init()" />
50+ <script type="text/javascript">
51+ //<![CDATA[
52+
53+ var viewportwidth = (typeof window.innerWidth != 'undefined' ? window.innerWidth : element.document.documentElement.clientWidth);
54+ // Shortcut for the document object
55+ var doc = element.document;
56+
57+ /*
58+ * init gets called once at the start and then never again,
59+ * triggers box-sizing calculations and updates width and height
60+ */
61+ function init(){
62+ // check for IE8+
63+ if(typeof(element.style.boxSizing) == "undefined"){
64+ updateBorderBoxWidth();
65+ updateBorderBoxHeight();
66+ }
67+ }
68+
69+ /*
70+ * restore gets called when the behavior is being detached (see event binding at the top),
71+ * resets everything like it was before applying the behavior
72+ */
73+ function restore(){
74+ // check for IE8+
75+ if(typeof(element.style.boxSizing) == "undefined"){
76+ element.runtimeStyle.width = "";
77+ element.runtimeStyle.height = "";
78+ }
79+ }
80+
81+ /*
82+ * checkPropertyChange gets called as soon as an element property changes
83+ * (see event binding at the top), it then checks if any property influencing its
84+ * dimensions was changed and if yes recalculates width and height
85+ */
86+ function checkPropertyChange(){
87+ // check for IE8+
88+ if(typeof(element.style.boxSizing) == "undefined"){
89+ var pn = event.propertyName;
90+ var undef;
91+ if(pn == "style.boxSizing" && element.style.boxSizing == ""){
92+ element.style.removeAttribute("boxSizing");
93+ element.runtimeStyle.boxSizing = undef;
94+ }
95+ switch (pn){
96+ case "style.width":
97+ case "style.borderLeftWidth":
98+ case "style.borderLeftStyle":
99+ case "style.borderRightWidth":
100+ case "style.borderRightStyle":
101+ case "style.paddingLeft":
102+ case "style.paddingRight":
103+ updateBorderBoxWidth();
104+ break;
105+
106+ case "style.height":
107+ case "style.borderTopWidth":
108+ case "style.borderTopStyle":
109+ case "style.borderBottomWidth":
110+ case "style.borderBottomStyle":
111+ case "style.paddingTop":
112+ case "style.paddingBottom":
113+ updateBorderBoxHeight();
114+ break;
115+
116+ case "className":
117+ case "style.boxSizing":
118+ updateBorderBoxWidth();
119+ updateBorderBoxHeight();
120+ break;
121+ }
122+ }
123+ }
124+
125+ /*
126+ * Helper function, taken from Dean Edward's IE7 framework,
127+ * added by Schepp on 12.06.2010.
128+ * http://code.google.com/p/ie7-js/
129+ *
130+ * Allows us to convert from relative to pixel-values.
131+ */
132+ function getPixelValue(value){
133+ var PIXEL = /^\d+(px)?$/i;
134+ if (PIXEL.test(value)) return parseInt(value);
135+ var style = element.style.left;
136+ var runtimeStyle = element.runtimeStyle.left;
137+ element.runtimeStyle.left = element.currentStyle.left;
138+ element.style.left = value || 0;
139+ value = parseInt(element.style.pixelLeft);
140+ element.style.left = style;
141+ element.runtimeStyle.left = runtimeStyle;
142+
143+ return value;
144+ }
145+
146+ function getPixelWidth(object, value){
147+ // For Pixel Values
148+ var PIXEL = /^\d+(px)?$/i;
149+ if (PIXEL.test(value)) return parseInt(value);
150+
151+ // For Percentage Values
152+ var PERCENT = /^[\d\.]+%$/i;
153+ if (PERCENT.test(value)){
154+ try{
155+ parentWidth = getPixelWidth(object.parentElement,(object.parentElement.currentStyle.width != "auto" ? object.parentElement.currentStyle.width : "100%"));
156+ value = (parseFloat(value) / 100) * parentWidth;
157+ }
158+ catch(e){
159+ value = (parseFloat(value) / 100) * element.document.documentElement.clientWidth;
160+ }
161+ return parseInt(value);
162+ }
163+
164+ // For EM Values
165+ var style = object.style.left;
166+ var runtimeStyle = object.runtimeStyle.left;
167+ object.runtimeStyle.left = object.currentStyle.left;
168+ object.style.left = value || 0;
169+ value = parseInt(object.style.pixelLeft);
170+ object.style.left = style;
171+ object.runtimeStyle.left = runtimeStyle;
172+
173+ return value;
174+ }
175+
176+
177+ /*
178+ * getBorderWidth & friends
179+ * Border width getters
180+ */
181+ function getBorderWidth(sSide){
182+ if(element.currentStyle["border" + sSide + "Style"] == "none"){
183+ return 0;
184+ }
185+ var n = getPixelValue(element.currentStyle["border" + sSide + "Width"]);
186+ return n || 0;
187+ }
188+ function getBorderLeftWidth() { return getBorderWidth("Left"); }
189+ function getBorderRightWidth() { return getBorderWidth("Right"); }
190+ function getBorderTopWidth() { return getBorderWidth("Top"); }
191+ function getBorderBottomWidth() { return getBorderWidth("Bottom"); }
192+
193+
194+ /*
195+ * getPadding & friends
196+ * Padding width getters
197+ */
198+ function getPadding(sSide) {
199+ var n = getPixelValue(element.currentStyle["padding" + sSide]);
200+ return n || 0;
201+ }
202+ function getPaddingLeft() { return getPadding("Left"); }
203+ function getPaddingRight() { return getPadding("Right"); }
204+ function getPaddingTop() { return getPadding("Top"); }
205+ function getPaddingBottom() { return getPadding("Bottom"); }
206+
207+
208+
209+ /*
210+ * getBoxSizing
211+ * Get the box-sizing value for the current element
212+ */
213+ function getBoxSizing(){
214+ var s = element.style;
215+ var cs = element.currentStyle
216+ if(typeof s.boxSizing != "undefined" && s.boxSizing != ""){
217+ return s.boxSizing;
218+ }
219+ if(typeof s["box-sizing"] != "undefined" && s["box-sizing"] != ""){
220+ return s["box-sizing"];
221+ }
222+ if(typeof cs.boxSizing != "undefined" && cs.boxSizing != ""){
223+ return cs.boxSizing;
224+ }
225+ if(typeof cs["box-sizing"] != "undefined" && cs["box-sizing"] != ""){
226+ return cs["box-sizing"];
227+ }
228+ return getDocumentBoxSizing();
229+ }
230+
231+
232+ /*
233+ * getDocumentBoxSizing
234+ * Get the default document box sizing (check for quirks mode)
235+ */
236+ function getDocumentBoxSizing(){
237+ if(doc.compatMode == null || doc.compatMode == "BackCompat"){
238+ return "border-box";
239+ }
240+ return "content-box"
241+ }
242+
243+
244+ /*
245+ * setBorderBoxWidth & friends
246+ * Width and height setters
247+ */
248+ function setBorderBoxWidth(n){
249+ element.runtimeStyle.width = Math.max(0, n - getBorderLeftWidth() -
250+ getPaddingLeft() - getPaddingRight() - getBorderRightWidth()) + "px";
251+ }
252+ function setBorderBoxHeight(n){
253+ element.runtimeStyle.height = Math.max(0, n - getBorderTopWidth() -
254+ getPaddingTop() - getPaddingBottom() - getBorderBottomWidth()) + "px";
255+ }
256+ function setContentBoxWidth(n){
257+ element.runtimeStyle.width = Math.max(0, n + getBorderLeftWidth() +
258+ getPaddingLeft() + getPaddingRight() + getBorderRightWidth()) + "px";
259+ }
260+ function setContentBoxHeight(n){
261+ element.runtimeStyle.height = Math.max(0, n + getBorderTopWidth() +
262+ getPaddingTop() + getPaddingBottom() + getBorderBottomWidth()) + "px";
263+ }
264+
265+
266+ /*
267+ * updateBorderBoxWidth & updateBorderBoxHeight
268+ *
269+ */
270+ function updateBorderBoxWidth() {
271+ if(getDocumentBoxSizing() == getBoxSizing()){
272+ return;
273+ }
274+ var csw = element.currentStyle.width;
275+ if(csw != "auto"){
276+ csw = getPixelWidth(element,csw);
277+ if(getBoxSizing() == "border-box"){
278+ setBorderBoxWidth(parseInt(csw));
279+ }
280+ else{
281+ setContentBoxWidth(parseInt(csw));
282+ }
283+ }
284+ }
285+
286+ function updateBorderBoxHeight() {
287+ if(getDocumentBoxSizing() == getBoxSizing()){
288+ return;
289+ }
290+ var csh = element.currentStyle.height;
291+ if(csh != "auto"){
292+ csh = getPixelValue(csh);
293+ if(getBoxSizing() == "border-box"){
294+ setBorderBoxHeight(parseInt(csh));
295+ }
296+ else{
297+ setContentBoxHeight(parseInt(csh));
298+ }
299+ }
300+ }
301+
302+
303+ // Run the calculations
304+ init();
305+
306+ //]]>
307+ </script>
308+ </component>
0 commit comments