source: Dev/branches/rest-dojo-ui/client/dojox/html/ext-dojo/style.js @ 256

Last change on this file since 256 was 256, checked in by hendrikvanantwerpen, 13 years ago

Reworked project structure based on REST interaction and Dojo library. As
soon as this is stable, the old jQueryUI branch can be removed (it's
kept for reference).

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