1 /**
  2  * @fileOverview style for ie
  3  * @author lifesinger@gmail.com,yiminghe@gmail.com
  4  */
  5 KISSY.add('dom/style-ie', function (S, DOM, UA, Style) {
  6 
  7     var HUNDRED = 100;
  8 
  9     // only for ie
 10     if (!UA['ie']) {
 11         return DOM;
 12     }
 13 
 14     var doc = S.Env.host.document,
 15         docElem = doc.documentElement,
 16         OPACITY = 'opacity',
 17         STYLE = 'style',
 18         FILTER = "filter",
 19         CURRENT_STYLE = 'currentStyle',
 20         RUNTIME_STYLE = 'runtimeStyle',
 21         LEFT = 'left',
 22         PX = 'px',
 23         CUSTOM_STYLES = Style._CUSTOM_STYLES,
 24         RE_NUMPX = /^-?\d+(?:px)?$/i,
 25         RE_NUM = /^-?\d/,
 26         backgroundPosition = "backgroundPosition",
 27         ropacity = /opacity=([^)]*)/,
 28         ralpha = /alpha\([^)]*\)/i;
 29 
 30     // odd backgroundPosition
 31     CUSTOM_STYLES[backgroundPosition] = {
 32         get:function (elem, computed) {
 33             if (computed) {
 34                 return elem[CURRENT_STYLE][backgroundPosition + "X"] +
 35                     " " +
 36                     elem[CURRENT_STYLE][backgroundPosition + "Y"];
 37             } else {
 38                 return elem[STYLE][backgroundPosition];
 39             }
 40         }
 41     };
 42 
 43     // use alpha filter for IE opacity
 44     try {
 45         if (docElem.style[OPACITY] == null) {
 46 
 47             CUSTOM_STYLES[OPACITY] = {
 48 
 49                 get:function (elem, computed) {
 50                     // 没有设置过 opacity 时会报错,这时返回 1 即可
 51                     // 如果该节点没有添加到 dom ,取不到 filters 结构
 52                     // val = elem[FILTERS]['DXImageTransform.Microsoft.Alpha'][OPACITY];
 53                     return ropacity.test((
 54                         computed && elem[CURRENT_STYLE] ?
 55                             elem[CURRENT_STYLE][FILTER] :
 56                             elem[STYLE][FILTER]) || "") ?
 57                         ( parseFloat(RegExp.$1) / HUNDRED ) + "" :
 58                         computed ? "1" : "";
 59                 },
 60 
 61                 set:function (elem, val) {
 62                     val = parseFloat(val);
 63 
 64                     var style = elem[STYLE],
 65                         currentStyle = elem[CURRENT_STYLE],
 66                         opacity = isNaN(val) ? "" : "alpha(" + OPACITY + "=" + val * HUNDRED + ")",
 67                         filter = S.trim(currentStyle && currentStyle[FILTER] || style[FILTER] || "");
 68 
 69                     // ie  has layout
 70                     style.zoom = 1;
 71 
 72                     // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute
 73                     if (val >= 1 && S.trim(filter.replace(ralpha, "")) === "") {
 74 
 75                         // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
 76                         // if "filter:" is present at all, clearType is disabled, we want to avoid this
 77                         // style.removeAttribute is IE Only, but so apparently is this code path...
 78                         style.removeAttribute(FILTER);
 79 
 80                         // if there there is no filter style applied in a css rule, we are done
 81                         if (currentStyle && !currentStyle[FILTER]) {
 82                             return;
 83                         }
 84                     }
 85 
 86                     // otherwise, set new filter values
 87                     // 如果 >=1 就不设,就不能覆盖外部样式表定义的样式,一定要设
 88                     style.filter = ralpha.test(filter) ?
 89                         filter.replace(ralpha, opacity) :
 90                         filter + (filter ? ", " : "") + opacity;
 91                 }
 92             };
 93         }
 94     }
 95     catch (ex) {
 96         S.log('IE filters ActiveX is disabled. ex = ' + ex);
 97     }
 98 
 99     /*
100      border fix
101      ie 不设置数值,则 computed style 不返回数值,只返回 thick? medium ...
102      (default is "medium")
103      */
104     var IE8 = UA['ie'] == 8,
105         BORDER_MAP = {
106         },
107         BORDERS = ["", "Top", "Left", "Right", "Bottom"];
108     BORDER_MAP['thin'] = IE8 ? '1px' : '2px';
109     BORDER_MAP['medium'] = IE8 ? '3px' : '4px';
110     BORDER_MAP['thick'] = IE8 ? '5px' : '6px';
111 
112     S.each(BORDERS, function (b) {
113         var name = "border" + b + "Width",
114             styleName = "border" + b + "Style";
115 
116         /**
117          * @ignore
118          */
119         CUSTOM_STYLES[name] = {
120             get:function (elem, computed) {
121                 // 只有需要计算样式的时候才转换,否则取原值
122                 var currentStyle = computed ? elem[CURRENT_STYLE] : 0,
123                     current = currentStyle && String(currentStyle[name]) || undefined;
124                 // look up keywords if a border exists
125                 if (current && current.indexOf("px") < 0) {
126                     // 边框没有隐藏
127                     if (BORDER_MAP[current] && currentStyle[styleName] !== "none") {
128                         current = BORDER_MAP[current];
129                     } else {
130                         // otherwise no border
131                         current = 0;
132                     }
133                 }
134                 return current;
135             }
136         };
137     });
138 
139     // getComputedStyle for IE
140     if (!(doc.defaultView || { }).getComputedStyle && docElem[CURRENT_STYLE]) {
141 
142         DOM._getComputedStyle = function (elem, name) {
143             name = DOM._cssProps[name] || name;
144             // currentStyle maybe null
145             // http://msdn.microsoft.com/en-us/library/ms535231.aspx
146             var ret = elem[CURRENT_STYLE] && elem[CURRENT_STYLE][name];
147 
148             // 当 width/height 设置为百分比时,通过 pixelLeft 方式转换的 width/height 值
149             // 一开始就处理了! CUSTOM_STYLE["height"],CUSTOM_STYLE["width"] ,cssHook 解决@2011-08-19
150             // 在 ie 下不对,需要直接用 offset 方式
151             // borderWidth 等值也有问题,但考虑到 borderWidth 设为百分比的概率很小,这里就不考虑了
152 
153             // From the awesome hack by Dean Edwards
154             // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
155             // If we're not dealing with a regular pixel number
156             // but a number that has a weird ending, we need to convert it to pixels
157             if ((!RE_NUMPX.test(ret) && RE_NUM.test(ret))) {
158                 // Remember the original values
159                 var style = elem[STYLE],
160                     left = style[LEFT],
161                     rsLeft = elem[RUNTIME_STYLE] && elem[RUNTIME_STYLE][LEFT];
162 
163                 // Put in the new values to get a computed value out
164                 if (rsLeft) {
165                     elem[RUNTIME_STYLE][LEFT] = elem[CURRENT_STYLE][LEFT];
166                 }
167                 style[LEFT] = name === 'fontSize' ? '1em' : (ret || 0);
168                 ret = style['pixelLeft'] + PX;
169 
170                 // Revert the changed values
171                 style[LEFT] = left;
172                 if (rsLeft) {
173                     elem[RUNTIME_STYLE][LEFT] = rsLeft;
174                 }
175             }
176             return ret === "" ? "auto" : ret;
177         };
178     }
179     return DOM;
180 }, {
181     requires:["./base", "ua", "./style"]
182 });
183 /**
184  * NOTES:
185  *
186  * yiminghe@gmail.com: 2011.12.21 backgroundPosition in ie
187  *  - currentStyle['backgroundPosition'] undefined
188  *  - currentStyle['backgroundPositionX'] ok
189  *  - currentStyle['backgroundPositionY'] ok
190  *
191  *
192  * yiminghe@gmail.com: 2011.05.19 opacity in ie
193  *  - 如果节点是动态创建,设置opacity,没有加到 dom 前,取不到 opacity 值
194  *  - 兼容:border-width 值,ie 下有可能返回 medium/thin/thick 等值,其它浏览器返回 px 值。
195  *
196  *  - opacity 的实现,参考自 jquery
197  *
198  */
199