1 /****************************************************************************
  2  Copyright (c) 2008-2010 Ricardo Quesada
  3  Copyright (c) 2011-2012 cocos2d-x.org
  4  Copyright (c) 2013-2014 Chukong Technologies 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 /**
 28  * the dollar sign, classic like jquery, this selector add extra methods to HTMLElement without touching its prototype</br>
 29  * it is also chainable like jquery
 30  * @param {HTMLElement|String} x pass in a css selector in string or the whole HTMLElement
 31  * @class
 32  * @return {cc.$}
 33  */
 34 cc.$ = function (x) {
 35     /** @lends cc.$# */
 36     var parent = (this == cc) ? document : this;
 37 
 38     var el = (x instanceof HTMLElement) ? x : parent.querySelector(x);
 39 
 40     if (el) {
 41         /**
 42          * find and return the child wth css selector (same as jquery.find)
 43          * @lends cc.$#
 44          * @function
 45          * @param {HTMLElement|String} x pass in a css selector in string or the whole HTMLElement
 46          * @return {cc.$}
 47          */
 48         el.find = el.find || cc.$;
 49         /**
 50          * check if a DOMNode has a specific class
 51          * @lends cc.$#
 52          * @function
 53          * @param {String} cls
 54          * @return {Boolean}
 55          */
 56         el.hasClass = el.hasClass || function (cls) {
 57             return this.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'));
 58         };
 59         /**
 60          * add a class to a DOMNode, returns self to allow chaining
 61          * @lends cc.$#
 62          * @function
 63          * @param {String} cls
 64          * @return {cc.$}
 65          */
 66         el.addClass = el.addClass || function (cls) {
 67             if (!this.hasClass(cls)) {
 68                 if (this.className) {
 69                     this.className += " ";
 70                 }
 71                 this.className += cls;
 72             }
 73             return this;
 74         };
 75         /**
 76          * remove a specific class from a DOMNode, returns self to allow chaining
 77          * @lends cc.$#
 78          * @function
 79          * @param {String} cls
 80          * @return {cc.$}
 81          */
 82         el.removeClass = el.removeClass || function (cls) {
 83             if (this.hasClass(cls)) {
 84                 this.className = this.className.replace(cls, '');
 85             }
 86             return this;
 87         };
 88         /**
 89          * detach it self from parent
 90          * @lends cc.$#
 91          * @function
 92          */
 93         el.remove = el.remove || function () {
 94             if (this.parentNode)
 95                 this.parentNode.removeChild(this);
 96             return this;
 97         };
 98 
 99         /**
100          * add to another element as a child
101          * @lends cc.$#
102          * @function
103          * @param {HTMLElement|cc.$} x
104          * @return {cc.$}
105          */
106         el.appendTo = el.appendTo || function (x) {
107             x.appendChild(this);
108             return this;
109         };
110 
111         /**
112          * add to another element as a child and place on the top of the children list
113          * @lends cc.$#
114          * @function
115          * @param {HTMLElement|cc.$} x
116          * @return {cc.$}
117          */
118         el.prependTo = el.prependTo || function (x) {
119             ( x.childNodes[0]) ? x.insertBefore(this, x.childNodes[0]) : x.appendChild(this);
120             return this;
121         };
122 
123         /**
124          * helper function for updating the css transform
125          * @lends cc.$#
126          * @function
127          * @return {cc.$}
128          */
129         el.transforms = el.transforms || function () {
130             this.style[cc.$.trans] = cc.$.translate(this.position) + cc.$.rotate(this.rotation) + cc.$.scale(this.scale) + cc.$.skew(this.skew);
131             return this;
132         };
133 
134         el.position = el.position || {x: 0, y: 0};
135         el.rotation = el.rotation || 0;
136         el.scale = el.scale || {x: 1, y: 1};
137         el.skew = el.skew || {x: 0, y: 0};
138 
139         /**
140          * move the element
141          * @memberOf cc.$#
142          * @name translates
143          * @function
144          * @param {Number} x in pixel
145          * @param {Number} y in pixel
146          * @return {cc.$}
147          */
148         el.translates = function (x, y) {
149             this.position.x = x;
150             this.position.y = y;
151             this.transforms();
152             return this
153         };
154 
155         /**
156          * rotate the element
157          * @memberOf cc.$#
158          * @name rotate
159          * @function
160          * @param {Number} x in degrees
161          * @return {cc.$}
162          */
163         el.rotate = function (x) {
164             this.rotation = x;
165             this.transforms();
166             return this
167         };
168 
169         /**
170          * resize the element
171          * @memberOf cc.$#
172          * @name resize
173          * @function
174          * @param {Number} x
175          * @param {Number} y
176          * @return {cc.$}
177          */
178         el.resize = function (x, y) {
179             this.scale.x = x;
180             this.scale.y = y;
181             this.transforms();
182             return this
183         };
184 
185         /**
186          * skews the element
187          * @memberOf cc.$#
188          * @name setSkew
189          * @function
190          * @param {Number} x in degrees
191          * @param {Number} y
192          * @return {cc.$}
193          */
194         el.setSkew = function (x, y) {
195             this.skew.x = x;
196             this.skew.y = y;
197             this.transforms();
198             return this
199         };
200     }
201     return el;
202 };
203 //getting the prefix and css3 3d support
204 switch (cc.sys.browserType) {
205     case cc.sys.BROWSER_TYPE_FIREFOX:
206         cc.$.pfx = "Moz";
207         cc.$.hd = true;
208         break;
209     case cc.sys.BROWSER_TYPE_CHROME:
210     case cc.sys.BROWSER_TYPE_SAFARI:
211         cc.$.pfx = "webkit";
212         cc.$.hd = true;
213         break;
214     case cc.sys.BROWSER_TYPE_OPERA:
215         cc.$.pfx = "O";
216         cc.$.hd = false;
217         break;
218     case cc.sys.BROWSER_TYPE_IE:
219         cc.$.pfx = "ms";
220         cc.$.hd = false;
221         break;
222     default:
223         cc.$.pfx = "webkit";
224         cc.$.hd = true;
225 }
226 //cache for prefixed transform
227 cc.$.trans = cc.$.pfx + "Transform";
228 //helper function for constructing transform strings
229 cc.$.translate = (cc.$.hd) ? function (a) {
230     return "translate3d(" + a.x + "px, " + a.y + "px, 0) "
231 } : function (a) {
232     return "translate(" + a.x + "px, " + a.y + "px) "
233 };
234 cc.$.rotate = (cc.$.hd) ? function (a) {
235     return "rotateZ(" + a + "deg) ";
236 } : function (a) {
237     return "rotate(" + a + "deg) ";
238 };
239 cc.$.scale = function (a) {
240     return "scale(" + a.x + ", " + a.y + ") "
241 };
242 cc.$.skew = function (a) {
243     return "skewX(" + -a.x + "deg) skewY(" + a.y + "deg)";
244 };
245 
246 
247 /**
248  * Creates a new element, and adds cc.$ methods
249  * @param {String} x name of the element tag to create
250  * @return {cc.$}
251  */
252 cc.$new = function (x) {
253     return cc.$(document.createElement(x))
254 };
255 cc.$.findpos = function (obj) {
256     var curleft = 0;
257     var curtop = 0;
258     do {
259         curleft += obj.offsetLeft;
260         curtop += obj.offsetTop;
261     } while (obj = obj.offsetParent);
262     return {x: curleft, y: curtop};
263 };
264 
265