source: Dev/trunk/src/client/dojox/html/ext-dojo/style.js @ 529

Last change on this file since 529 was 483, checked in by hendrikvanantwerpen, 11 years ago

Added Dojo 1.9.3 release.

File size: 14.3 KB
Line 
1define(["dojo/_base/kernel", "dojo/dom-style", "dojo/_base/lang", "dojo/_base/html", "dojo/_base/sniff",
2                "dojo/_base/window", "dojo/dom", "dojo/dom-construct", "dojo/dom-style", "dojo/dom-attr"],
3        function(kernel, domStyle, lang, Html, has, win, DOM, DOMConstruct, DOMStyle, DOMAttr){
4        kernel.experimental("dojox.html.ext-dojo.style");
5        var st = lang.getObject("dojox.html.ext-dojo.style", true);
6        var HtmlX = lang.getObject("dojox.html");
7        // summary:
8        //              Extensions to dojo.style adding the css3 "transform" and "transform-origin" properties on IE5.5+
9        // description:
10        //              A Package to extend the dojo.style function
11        //              Supported transformation functions:
12        //              matrix, translate, translateX, translateY, scale, scaleX, scaleY, rotate, skewX, skewY, skew
13        lang.mixin(HtmlX["ext-dojo"].style, {
14                supportsTransform: true,
15                _toPx: function(measure){
16                        var ds = Html.style, _conversion = this._conversion;
17                        if(typeof measure === "number"){
18                                return measure + "px";
19                        }else if(measure.toLowerCase().indexOf("px") != -1){
20                                return measure;
21                        }
22                        // "native" conversion in px
23                        !_conversion.parentNode && DOMConstruct.place(_conversion, win.body());
24                        ds(_conversion, "margin", measure);
25                        return ds(_conversion, "margin");
26                },
27                init: function(){
28                        var docStyle = win.doc.documentElement.style, extStyle = HtmlX["ext-dojo"].style,
29                                sget = DOMStyle.get, sset = DOMStyle.set;
30                        DOMStyle.get = function(/*DOMNode|String*/ node, /*String|Object*/ name){
31                                var tr = (name == "transform"),
32                                        to = (name == "transformOrigin");
33                                if(tr){
34                                        return extStyle.getTransform(node);
35                                }else if(to){
36                                        return extStyle.getTransformOrigin(node);
37                                }else{
38                                        return arguments.length == 2 ? sget(node, name) : sget(node);
39                                }
40                        };
41                        DOMStyle.set = function(/*DOMNode|String*/ node, /*String|Object*/ name, /*String?*/ value){
42                                var tr = (name == "transform"),
43                                        to = (name == "transformOrigin"),
44                                        n = DOM.byId(node)
45                                ;
46                                if(tr){
47                                        return extStyle.setTransform(n, value, true);
48                                }else if(to){
49                                        return extStyle.setTransformOrigin(n, value);
50                                }else{
51                                        return arguments.length == 3 ? sset(n, name, value) : sset(n, name);
52                                }
53                        };
54                        // prefixes and property names
55                        for(var i = 0, tPrefix = ["WebkitT", "MozT", "OT", "msT", "t"]; i < tPrefix.length; i++){
56                                if(typeof docStyle[tPrefix[i] + "ransform"] !== "undefined"){
57                                        this.tPropertyName = tPrefix[i] + "ransform";
58                                }
59                                if(typeof docStyle[tPrefix[i] + "ransformOrigin"] !== "undefined"){
60                                        this.toPropertyName = tPrefix[i] + "ransformOrigin";
61                                }
62                        }
63                        if(this.tPropertyName){
64                                this.setTransform = function(/*DomNode*/node, /*String*/ transform){
65                                        return sset(node, this.tPropertyName, transform);
66                                };
67                                this.getTransform = function(/*DomNode*/node){
68                                        return sget(node, this.tPropertyName);
69                                };
70                        }else if(has("ie")){
71                                this.setTransform = this._setTransformFilter;
72                                this.getTransform = this._getTransformFilter;
73                        }
74                        if(this.toPropertyName){
75                                this.setTransformOrigin = function(/*DomNode*/node, /*String*/ transformOrigin){
76                                        return sset(node, this.toPropertyName, transformOrigin);
77                                };
78                                this.getTransformOrigin = function(/*DomNode*/node){
79                                        return sget(node, this.toPropertyName);
80                                };
81                        }else if(has("ie")){
82                                this.setTransformOrigin = this._setTransformOriginFilter;
83                                this.getTransformOrigin = this._getTransformOriginFilter;
84                        }else{
85                                this.supportsTransform = false;
86                        }
87                        this._conversion = DOMConstruct.create("div", {
88                                style: {
89                                        position: "absolute",
90                                        top: "-100px",
91                                        left: "-100px",
92                                        fontSize: 0,
93                                        width: "0",
94                                        backgroundPosition: "50% 50%"
95                                }
96                        });
97                },
98                _notSupported: function(){
99                        console.warn("Sorry, this browser doesn't support transform and transform-origin");
100                },
101                _setTransformOriginFilter: function(/*DomNode*/ node, /*String*/ transformOrigin){
102                        var to = lang.trim(transformOrigin)
103                                .replace(" top", " 0")
104                                .replace("left ", "0 ")
105                                .replace(" center", "50%")
106                                .replace("center ", "50% ")
107                                .replace(" bottom", " 100%")
108                                .replace("right ", "100% ")
109                                .replace(/\s+/, " "),
110                                toAry = to.split(" "),
111                                n = DOM.byId(node),
112                                t = this.getTransform(n),
113                                validOrigin = true
114                        ;
115                        for(var i = 0; i < toAry.length; i++){
116                                validOrigin = validOrigin && /^0|(\d+(%|px|pt|in|pc|mm|cm))$/.test(toAry[i]);
117                                if(toAry[i].indexOf("%") == -1){
118                                        toAry[i] = this._toPx(toAry[i]);
119                                }
120                        }
121                        if(!validOrigin || !toAry.length || toAry.length > 2 ){
122                                return transformOrigin;
123                        }
124                        Html.attr(n, "dojo-transform-origin", toAry.join(" "));
125                        t && this.setTransform(node, t);
126                        return transformOrigin;
127                },
128                _getTransformOriginFilter: function(/*DomNode*/ node){
129                        return Html.attr(node, "dojo-transform-origin") || "50% 50%";
130                },
131                _setTransformFilter: function(/*DomNode*/ node, /*String*/ transform){
132                        // Using the Matrix Filter to implement the transform property on IE
133                        var t = transform.replace(/\s/g, ""),
134                                n = DOM.byId(node),
135                                transforms = t.split(")"),
136                                toRad = 1, toRad1 = 1,
137                                mstr = "DXImageTransform.Microsoft.Matrix",
138                                hasAttr = DOMAttr.has,
139                                attr = Html.attr,
140                                // Math functions
141                                PI = Math.PI, cos = Math.cos, sin = Math.sin, tan = Math.tan, max = Math.max, min = Math.min, abs = Math.abs,
142                                degToRad = PI/180, gradToRad = PI/200,
143
144                                // current transform
145                                ct = "", currentTransform = "",
146                                matchingTransforms = [],
147                                x0 = 0, y0 = 0, dx = 0, dy = 0, xc = 0, yc = 0, a = 0,
148
149                                // default transform, identity matrix
150                                m11 = 1, m12 = 0, m21 = 0, m22 = 1,
151
152                                // no translation
153                                tx = 0, ty = 0,
154                                props = [m11, m12, m21, m22, tx, ty],
155                                hasMatrix = false,
156                                ds = Html.style,
157                                newPosition = ds(n, "position") == "absolute" ? "absolute" : "relative",
158                                w = ds(n, "width") + ds(n, "paddingLeft") + ds(n, "paddingRight"),
159                                h = ds(n, "height") + ds(n, "paddingTop") + ds(n, "paddingBottom"),
160                                toPx = this._toPx
161                        ;
162
163                        !hasAttr(n, "dojo-transform-origin") && this.setTransformOrigin(n, "50% 50%");
164
165                        for(var i = 0, l = transforms.length; i < l; i++){
166                                matchingTransforms = transforms[i].match(/matrix|rotate|scaleX|scaleY|scale|skewX|skewY|skew|translateX|translateY|translate/);
167                                currentTransform = matchingTransforms ? matchingTransforms[0] : "";
168                                switch(currentTransform){
169                                        case "matrix":
170                                                // generic transformation
171                                                //
172                                                // matrix:
173                                                // m11        m12
174                                                //
175                                                // m21        m22
176                                                //
177                                                ct = transforms[i].replace(/matrix\(|\)/g, "");
178                                                var matrix = ct.split(",");
179                                                m11 = props[0]*matrix[0] + props[1]*matrix[2];
180                                                m12 = props[0]*matrix[1] + props[1]*matrix[3];
181                                                m21 = props[2]*matrix[0] + props[3]*matrix[2];
182                                                m22 = props[2]*matrix[1] + props[3]*matrix[3];
183                                                tx = props[4] + matrix[4];
184                                                ty = props[5] + matrix[5];
185                                        break;
186                                        case "rotate":
187                                                // rotate
188                                                //
189                                                // rotation angle:
190                                                // a (rad, deg or grad)
191                                                //
192                                                // matrix:
193                                                // cos(a)     -sin(a)
194                                                //
195                                                // sin(a)     cos(a)
196                                                //
197                                                ct = transforms[i].replace(/rotate\(|\)/g, "");
198                                                toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
199                                                a = parseFloat(ct)*toRad;
200                                                var s = sin(a),
201                                                        c = cos(a)
202                                                ;
203                                                m11 = props[0]*c + props[1]*s;
204                                                m12 = -props[0]*s + props[1]*c;
205                                                m21 = props[2]*c + props[3]*s;
206                                                m22 = -props[2]*s + props[3]*c;
207                                        break;
208                                        case "skewX":
209                                                // skewX
210                                                //
211                                                // skew angle:
212                                                // a (rad, deg or grad)
213                                                //
214                                                // matrix:
215                                                // 1          tan(a)
216                                                //
217                                                // 0          1
218                                                //
219                                                ct = transforms[i].replace(/skewX\(|\)/g, "");
220                                                toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
221                                                var ta = tan(parseFloat(ct)*toRad);
222                                                m11 = props[0];
223                                                m12 = props[0]*ta + props[1];
224                                                m21 = props[2];
225                                                m22 = props[2]*ta + props[3];
226                                        break;
227                                        case "skewY":
228                                                // skewY
229                                                //
230                                                // skew angle:
231                                                // a (rad, deg or grad)
232                                                //
233                                                // matrix:
234                                                // 1          0
235                                                //
236                                                // tan(a)     1
237                                                //
238                                                ct = transforms[i].replace(/skewY\(|\)/g, "");
239                                                toRad = ct.indexOf("deg") != -1 ? degToRad : ct.indexOf("grad") != -1 ? gradToRad : 1;
240                                                ta = tan(parseFloat(ct)*toRad);
241                                                m11 = props[0] + props[1]*ta;
242                                                m12 = props[1];
243                                                m21 = props[2] + props[3]*ta;
244                                                m22 = props[3];
245                                        break;
246                                        case "skew":
247                                                // skew
248                                                //
249                                                // skew angles:
250                                                // a0 (rad, deg or grad)
251                                                // a1 (rad, deg or grad)
252                                                //
253                                                // matrix:
254                                                // 1          tan(a0)
255                                                //
256                                                // tan(a1)    1
257                                                //
258                                                ct = transforms[i].replace(/skew\(|\)/g, "");
259                                                var skewAry = ct.split(",");
260                                                skewAry[1] = skewAry[1] || "0";
261                                                toRad = skewAry[0].indexOf("deg") != -1 ? degToRad : skewAry[0].indexOf("grad") != -1 ? gradToRad : 1;
262                                                toRad1 = skewAry[1].indexOf("deg") != -1 ? degToRad : skewAry[1].indexOf("grad") != -1 ? gradToRad : 1;
263                                                var a0 = tan(parseFloat(skewAry[0])*toRad),
264                                                        a1 = tan(parseFloat(skewAry[1])*toRad1)
265                                                ;
266                                                m11 = props[0] + props[1]*a1;
267                                                m12 = props[0]*a0 + props[1];
268                                                m21 = props[2]+ props[3]*a1;
269                                                m22 = props[2]*a0 + props[3];
270                                        break;
271                                        case "scaleX":
272                                                // scaleX
273                                                //
274                                                // scale factor:
275                                                // sx
276                                                //
277                                                // matrix:
278                                                // sx         0
279                                                //
280                                                // 0          1
281                                                //
282                                                ct = parseFloat(transforms[i].replace(/scaleX\(|\)/g, "")) || 1;
283                                                m11 = props[0]*ct;
284                                                m12 = props[1];
285                                                m21 = props[2]*ct;
286                                                m22 = props[3];
287                                        break;
288                                        case "scaleY":
289                                                // scaleY
290                                                //
291                                                // scale factor:
292                                                // sy
293                                                //
294                                                // matrix:
295                                                // 1          0
296                                                //
297                                                // 0          sy
298                                                //
299                                                ct = parseFloat(transforms[i].replace(/scaleY\(|\)/g, "")) || 1;
300                                                m11 = props[0];
301                                                m12 = props[1]*ct;
302                                                m21 = props[2];
303                                                m22 = props[3]*ct;
304                                        break;
305                                        case "scale":
306                                                // scale
307                                                //
308                                                // scale factor:
309                                                // sx, sy
310                                                //
311                                                // matrix:
312                                                // sx         0
313                                                //
314                                                // 0          sy
315                                                //
316                                                ct = transforms[i].replace(/scale\(|\)/g, "");
317                                                var scaleAry = ct.split(",");
318                                                scaleAry[1] = scaleAry[1] || scaleAry[0];
319                                                m11 = props[0]*scaleAry[0];
320                                                m12 = props[1]*scaleAry[1];
321                                                m21 = props[2]*scaleAry[0];
322                                                m22 = props[3]*scaleAry[1];
323                                        break;
324                                        case "translateX":
325                                                ct = parseInt(transforms[i].replace(/translateX\(|\)/g, "")) || 1;
326                                                m11 = props[0];
327                                                m12 = props[1];
328                                                m21 = props[2];
329                                                m22 = props[3];
330                                                tx = toPx(ct);
331                                                tx && attr(n, "dojo-transform-matrix-tx", tx);
332                                        break;
333                                        case "translateY":
334                                                ct = parseInt(transforms[i].replace(/translateY\(|\)/g, "")) || 1;
335                                                m11 = props[0];
336                                                m12 = props[1];
337                                                m21 = props[2];
338                                                m22 = props[3];
339                                                ty = toPx(ct);
340                                                ty && attr(n, "dojo-transform-matrix-ty", ty);
341                                        break;
342                                        case "translate":
343                                                ct = transforms[i].replace(/translate\(|\)/g, "");
344                                                m11 = props[0];
345                                                m12 = props[1];
346                                                m21 = props[2];
347                                                m22 = props[3];
348                                                var translateAry = ct.split(",");
349                                                translateAry[0] = parseInt(toPx(translateAry[0])) || 0;
350                                                translateAry[1] = parseInt(toPx(translateAry[1])) || 0;
351                                                tx = translateAry[0];
352                                                ty = translateAry[1];
353                                                tx && attr(n, "dojo-transform-matrix-tx", tx);
354                                                ty && attr(n, "dojo-transform-matrix-ty", ty);
355                                        break;
356                                }
357                                props = [m11, m12, m21, m22, tx, ty];
358                        }
359                        // test
360                        var Bx = min(w*m11 + h*m12, min(min(w*m11, h*m12), 0)),
361                                By = min(w*m21 + h*m22, min(min(w*m21, h*m22), 0))
362                        ;
363                        dx = -Bx;
364                        dy = -By;
365                        if(has("ie") < 8){
366                                // on IE < 8 the node must have hasLayout = true
367                                n.style.zoom = "1";
368                                if(newPosition != "absolute"){
369                                        var parentWidth = ds(node.parentNode, "width"),
370                                                tw = abs(w*m11),
371                                                th = abs(h*m12),
372                                                wMax = max(tw + th, max(max(th, tw), 0))
373                                        ;
374                                        dx -= (wMax - w) / 2 - (parentWidth > wMax ? 0 : (wMax - parentWidth) / 2);
375                                }
376                        }else if(has("ie") == 8){
377                                // IE8 bug, a filter is applied to positioned descendants
378                                // only if the parent has z-index
379                                ds(n, "zIndex") == "auto" && (n.style.zIndex = "0");
380                        }
381
382                        try{
383                                hasMatrix = !!n.filters.item(mstr);
384                        }catch(e){
385                                hasMatrix = false;
386                        }
387                        if(hasMatrix){
388                                n.filters.item(mstr).M11 = m11;
389                                n.filters.item(mstr).M12 = m12;
390                                n.filters.item(mstr).M21 = m21;
391                                n.filters.item(mstr).M22 = m22;
392                                // use 'nearest' for a faster transform
393                                n.filters.item(mstr).filterType = 'bilinear';
394                                n.filters.item(mstr).Dx = 0;
395                                n.filters.item(mstr).Dy = 0;
396                                n.filters.item(mstr).sizingMethod = 'auto expand';
397                        }else{
398                                n.style.filter +=
399                                        " progid:" + mstr + "(M11=" + m11 +
400                                        ",M12=" + m12 +
401                                        ",M21=" + m21 +
402                                        ",M22=" + m22 +
403                                        ",FilterType='bilinear',Dx=0,Dy=0,sizingMethod='auto expand')"
404                                ;
405                        }
406                        tx = parseInt(attr(n, "dojo-transform-matrix-tx") || "0");
407                        ty = parseInt(attr(n, "dojo-transform-matrix-ty") || "0");
408
409                        // transform origin
410                        var toAry = attr(n, "dojo-transform-origin").split(" ");
411
412                        for(i = 0; i < 2; i++){
413                                toAry[i] = toAry[i] || "50%";
414                        }
415                        xc = (toAry[0].toString().indexOf("%") != -1) ? w * parseInt(toAry[0]) * .01 : toAry[0];
416                        yc = (toAry[1].toString().indexOf("%") != -1) ? h * parseInt(toAry[1]) * .01 : toAry[1];
417                        if(hasAttr(n, "dojo-startX")){
418                                x0 = parseInt(attr(n, "dojo-startX"));
419                        }else{
420                                x0 = parseInt(ds(n, "left"));
421                                attr(n, "dojo-startX", newPosition == "absolute" ? x0 : "0");
422                        }
423                        if(hasAttr(n, "dojo-startY")){
424                                y0 = parseInt(attr(n, "dojo-startY"));
425                        }else{
426                                y0 = parseInt(ds(n, "top"));
427                                attr(n, "dojo-startY", newPosition == "absolute" ? y0 : "0");
428                        }
429                        ds(n, {
430                                position: newPosition,
431                                left: x0 - parseInt(dx) + parseInt(xc) - ((parseInt(xc) - tx)*m11 + (parseInt(yc) - ty)*m12) + "px",
432                                top:  y0 - parseInt(dy) + parseInt(yc) - ((parseInt(xc) - tx)*m21 + (parseInt(yc) - ty)*m22) + "px"
433                        });
434                        return transform;
435                },
436                _getTransformFilter: function(/*DomNode*/ node){
437                        try{
438                                var n = DOM.byId(node),
439                                        item = n.filters.item(0)
440                                ;
441                                return "matrix(" + item.M11 + ", " + item.M12 + ", " + item.M21 + ", " +
442                                        item.M22 + ", " + (Html.attr(node, "dojo-transform-tx") || "0") + ", " + (Html.attr(node, "dojo-transform-ty") || "0") + ")";
443                        }catch(e){
444                                return "matrix(1, 0, 0, 1, 0, 0)";
445                        }
446                },
447                setTransform: function(){
448                        this._notSupported();
449                },
450                setTransformOrigin: function(){
451                        this._notSupported();
452                }
453        });
454
455        HtmlX["ext-dojo"].style.init();
456        return Html.style;
457});
Note: See TracBrowser for help on using the repository browser.