1 /****************************************************************************
  2  Copyright (c) 2010-2012 cocos2d-x.org
  3  Copyright (c) 2008-2010 Ricardo Quesada
  4  Copyright (c) 2011      Zynga Inc.
  5 
  6  http://www.cocos2d-x.org
  7 
  8  Permission is hereby granted, free of charge, to any person obtaining a copy
  9  of this software and associated documentation files (the "Software"), to deal
 10  in the Software without restriction, including without limitation the rights
 11  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 12  copies of the Software, and to permit persons to whom the Software is
 13  furnished to do so, subject to the following conditions:
 14 
 15  The above copyright notice and this permission notice shall be included in
 16  all copies or substantial portions of the Software.
 17 
 18  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 24  THE SOFTWARE.
 25  ****************************************************************************/
 26 /**
 27  * Browser detection, based on mootools<br/>
 28  * platform will print out win32, mac, etc<br/>
 29  * type is the browser type, chrome, firefox etc
 30  * @type {Object}
 31  */
 32 cc.Browser = {};
 33 (function () {
 34     cc.Browser.ua = navigator.userAgent.toLowerCase();
 35     cc.Browser.platform = navigator.platform.toLowerCase();
 36     cc.Browser.UA = cc.Browser.ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/) || [null, 'unknown', 0];
 37     cc.Browser.mode = cc.Browser.UA[1] == 'ie' && document.documentMode;
 38     cc.Browser.type = (cc.Browser.UA[1] == 'version') ? cc.Browser.UA[3] : cc.Browser.UA[1];
 39     cc.Browser.isMobile = (cc.Browser.ua.indexOf('mobile') != -1 || cc.Browser.ua.indexOf('android') != -1);
 40 })();
 41 
 42 
 43 /**
 44  * the dollar sign, classic like jquery, this selector add extra methods to HTMLElement without touching its prototype</br>
 45  * it is also chainable like jquery
 46  * @param {HTMLElement|String} x pass in a css selector in string or the whole HTMLElement
 47  * @class
 48  * @return {cc.$}
 49  */
 50 cc.$ = function (x) {
 51     /** @lends cc.$# */
 52     var parent = (this == cc) ? document : this;
 53 
 54     /**
 55      * @type {HTMLElement}
 56      */
 57     var el = (x instanceof HTMLElement) ? x : parent.querySelector(x);
 58 
 59     if (el) {
 60         /**
 61          * find and return the child wth css selector (same as jquery.find)
 62          * @param {HTMLElement|String} x pass in a css selector in string or the whole HTMLElement
 63          * @return {cc.$}
 64          */
 65         el.find = el.find || cc.$;
 66         /**
 67          * check if a DOMNode has a specific class
 68          * @param {String} cls
 69          * @return {Boolean}
 70          */
 71         el.hasClass = el.hasClass || function (cls) {
 72             return this.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
 73         };
 74         /**
 75          * add a class to a DOMNode, returns self to allow chaining
 76          * @param {String} cls
 77          * @return {cc.$}
 78          */
 79         el.addClass = el.addClass || function (cls) {
 80             if (!this.hasClass(cls)) {
 81                 if (this.className) {
 82                     this.className += " ";
 83                 }
 84                 this.className += cls;
 85             }
 86             return this;
 87         };
 88         /**
 89          * remove a specific class from a DOMNode, returns self to allow chaining
 90          * @param {String} cls
 91          * @return {cc.$}
 92          */
 93         el.removeClass = el.removeClass || function (cls) {
 94             if (this.hasClass(cls)) {
 95                 this.className = this.className.replace(cls, '');
 96             }
 97             return this;
 98         };
 99         /**
100          * detach it self from parent
101          * @function
102          */
103         el.remove = el.remove || function () {
104             if (this.parentNode)
105                 this.parentNode.removeChild(this);
106             return this;
107         };
108 
109         /**
110          * add to another element as a child
111          * @param {HTMLElement|cc.$} x
112          * @return {cc.$}
113          */
114         el.appendTo = el.appendTo || function (x) {
115             x.appendChild(this);
116             return this;
117         };
118 
119         /**
120          * add to another element as a child and place on the top of the children list
121          * @param {HTMLElement|cc.$} x
122          * @return {cc.$}
123          */
124         el.prependTo = el.prependTo || function (x) {
125             ( x.childNodes[0]) ? x.insertBefore(this, x.childNodes[0]) : x.appendChild(this);
126             return this;
127         };
128 
129         /**
130          * helper function for updating the css transform
131          * @return {cc.$}
132          */
133         el.transforms = el.transforms || function () {
134             this.style[cc.$.trans] = cc.$.translate(this.position) + cc.$.rotate(this.rotation) + cc.$.scale(this.scale) + cc.$.skew(this.skew);
135             return this;
136         };
137 
138         el.position = el.position || {x:0, y:0};
139         el.rotation = el.rotation || 0;
140         el.scale = el.scale || {x:1, y:1};
141         el.skew = el.skew || {x:0, y:0};
142 
143         /**
144          * move the element
145          * @param {Number} x in pixel
146          * @param {Number} y in pixel
147          * @return {cc.$}
148          */
149         el.translates = function (x, y) {
150             this.position.x = x;
151             this.position.y = y;
152             this.transforms();
153             return this
154         };
155 
156         /**
157          * rotate the element
158          * @param {Number} x in degrees
159          * @return {cc.$}
160          */
161         el.rotate = function (x) {
162             this.rotation = x;
163             this.transforms();
164             return this
165         };
166 
167         /**
168          * resize the element
169          * @param {Number} x
170          * @param {Number} y
171          * @return {cc.$}
172          */
173         el.resize = function (x, y) {
174             this.scale.x = x;
175             this.scale.y = y;
176             this.transforms();
177             return this
178         };
179 
180         /**
181          * skews the element
182          * @param {Number} x in degrees
183          * @param {Number} y
184          * @return {cc.$}
185          */
186         el.setSkew = function (x, y) {
187             this.skew.x = x;
188             this.skew.y = y;
189             this.transforms();
190             return this
191         };
192     }
193     return el;
194 };
195 //getting the prefix and css3 3d support
196 switch (cc.Browser.type) {
197     case "firefox":
198         cc.$.pfx = "Moz";
199         cc.$.hd = true;
200         break;
201     case "chrome":
202     case "safari":
203         cc.$.pfx = "webkit";
204         cc.$.hd = true;
205         break;
206     case "opera":
207         cc.$.pfx = "O";
208         cc.$.hd = false;
209         break;
210     case "ie":
211         cc.$.pfx = "ms";
212         cc.$.hd = false;
213 }
214 //cache for prefixed transform
215 cc.$.trans = cc.$.pfx + "Transform";
216 //helper function for constructing transform strings
217 cc.$.translate = (cc.$.hd) ? function (a) {
218     return "translate3d(" + a.x + "px, " + a.y + "px, 0) "
219 } : function (a) {
220     return "translate(" + a.x + "px, " + a.y + "px) "
221 };
222 cc.$.rotate = (cc.$.hd) ? function (a) {
223     return "rotateZ(" + a + "deg) ";
224 } : function (a) {
225     return "rotate(" + a + "deg) ";
226 };
227 cc.$.scale = function (a) {
228     return "scale(" + a.x + ", " + a.y + ") "
229 };
230 cc.$.skew = function (a) {
231     return "skewX(" + -a.x + "deg) skewY(" + a.y + "deg)";
232 };
233 
234 
235 /**
236  * Creates a new element, and adds cc.$ methods
237  * @param {String} x name of the element tag to create
238  * @return {cc.$}
239  */
240 cc.$new = function (x) {
241     return cc.$(document.createElement(x))
242 };
243 cc.$.findpos = function (obj) {
244     var curleft = 0;
245     var curtop = 0;
246     do {
247         curleft += obj.offsetLeft;
248         curtop += obj.offsetTop;
249     } while (obj = obj.offsetParent);
250     return {x:curleft, y:curtop};
251 };
252