1 /**
  2  * @fileOverview
  3  * twitter.enchant.js
  4  * @version 0.2 (2011/07/20)
  5  * @requires enchant.js v0.4.0 or later
  6  * @requires nineleap.enchant.js v0.3 or later
  7  *
  8  * @description
  9  * enchant.js extention for 9leap.net
 10  *
 11  * @usage
 12  * EXAMPLE: use twitter icon as a sprite
 13  *
 14  * enchant();
 15  * window.onload = function() {
 16  *    var core = new Core(320, 320);
 17  *    core.twitterRequest('account/verify_credentials');
 18  *    core.onload = function() {
 19  *         var player = core.twitterAssets['account/verify_credentials'][0].toSprite(48, 48);
 20  *         player.x = 0;
 21  *         player.y = 0;
 22  *         core.rootScene.addChild(player);
 23  *     };
 24  *     core.start();
 25  * }
 26  */
 27 (function() {
 28     enchant();
 29     /**
 30      * 依存ライブラリcheck
 31      */
 32     var parentModule;
 33     if (enchant.nineleap.memory !== undefined &&
 34         Object.getPrototypeOf(enchant.nineleap.memory) === Object.prototype) {
 35         parentModule = enchant.nineleap.memory;
 36     } else if (enchant.nineleap !== undefined &&
 37         Object.getPrototypeOf(enchant.nineleap) === Object.prototype) {
 38         parentModule = enchant.nineleap;
 39     } else {
 40         throw new Error('Cannot load nineleap.enchant.js.');
 41     }
 42 
 43     /**
 44      * @type {Object}
 45      */
 46     enchant.nineleap.twitter = {};
 47 
 48     /**
 49      * @scope enchant.nineleap.twitter.Core.prototype
 50      */
 51     enchant.nineleap.twitter.Core = enchant.Class.create(parentModule.Core, {
 52         /**
 53          * enchant.Core or enchant.nineleap.Core クラスを拡張したクラス
 54          * @param width
 55          * @param height
 56          * @constructs
 57          */
 58         initialize: function(width, height) {
 59             parentModule.Core.call(this, width, height);
 60             this._twitterRequests = [];
 61             this._twitterAssets = [];
 62             this.requireAuth = true;
 63             this.authorized = true;
 64             this.twitterQueue = 0;
 65         },
 66         start: function() {
 67             var i, l;
 68             if (this.twitterQueue !== 0) {
 69                 if (this._twitterRequests.length) {
 70                     this.twitterAssets = {};
 71                     for (i in this._twitterRequests) {
 72                         if (this._twitterRequests.hasOwnProperty(i)) {
 73                             this.twitterAssets[this._twitterRequests[i].path] = [];
 74                         }
 75                     }
 76                     for (i = 0, l = this._twitterRequests.length; i < l; i++) {
 77                         this._twitterRequests[i]._sendRequest();
 78                     }
 79                 }
 80                 return;
 81             }
 82             parentModule.Core.prototype.start.call(this);
 83         },
 84 
 85         /**
 86          * Twitterへのリクエストを送る。
 87          *
 88          * @param path {String} Twitter APIのパス
 89          * @param option {Object} Twitter APIへのリクエスト時に送信するオプション
 90          * @param checkError {Boolean} エラーで応答がない場合 (optional)
 91          */
 92         twitterRequest: function(path, option, checkError) {
 93             if (checkError == null) {
 94                 checkError = true;
 95             }
 96             if (arguments.length === 2) {
 97                 if (typeof arguments[1] === 'boolean') {
 98                     checkError = arguments[1];
 99                     option = {};
100                 } else {
101                     checkError = true;
102                 }
103             }
104             this.twitterQueue++;
105             var id = this._twitterRequests.length;
106             var request = new enchant.nineleap.twitter.TwitterRequest(id, path, option, checkError);
107             this._twitterRequests.push(request);
108         },
109 
110         _setTwitterAssets: function(resBody, path, checkError) {
111             var core = enchant.Core.instance;
112             if (!(resBody instanceof Array)) {
113                 resBody = Array.prototype.slice.call(arguments);
114                 resBody = resBody.filter(function(arg) {
115                     return (arg instanceof Object);
116                 });
117             }
118             this.twitterQueue--;
119             if (resBody[0] == null) {
120                 this.twitterAssets[path] = [];
121             } else if ('code' in resBody[0]) {
122                 if (resBody[0].code === 401 && this.requireAuth) {
123                     window.location.replace('http://9leap.net/api/login?after_login=' + window.location.href);
124                     return;
125                 } else if (resBody[0].code === 401 && !this.requireAuth) {
126                     this.authorized = false;
127                 } else if (checkError) {
128                     throw new Error(resBody[0].code + ': ' + resBody[0].error);
129                 } else {
130                     this.twitterAssets[path] = [];
131                 }
132             } else {
133                 for (var i = 0, l = resBody.length; i < l; i++) {
134                     if ('name' in resBody[i]) {
135                         this.twitterAssets[path][i] = new enchant.nineleap.twitter.TwitterUserData(resBody[i]);
136                         this._twitterAssets.push(resBody[i]['profile_image_url']);
137                         if ('status' in resBody[i]) {
138                             this.twitterAssets[path][i].status = new enchant.nineleap.twitter.TwitterStatusData(resBody[i].status);
139                         }
140                     } else {
141                         this.twitterAssets[path][i] = new enchant.nineleap.twitter.TwitterStatusData(resBody[i]);
142                         this.twitterAssets[path][i].user = new enchant.nineleap.twitter.TwitterUserData(resBody[i].user);
143                         this._twitterAssets.push(resBody[i].user['profile_image_url']);
144                     }
145                 }
146             }
147             if (this.twitterQueue === 0) {
148                 this.start();
149             }
150         }
151     });
152 
153     /**
154      * @scope enchant.nineleap.twitter.TwitterRequest.prototype
155      */
156     enchant.nineleap.twitter.TwitterRequest = enchant.Class.create({
157         /**
158          * twitter request handle class
159          * @constructs
160          * @param id
161          * @param path
162          * @param option
163          * @param checkError
164          */
165         initialize: function(id, path, option, checkError) {
166             this.path = path;
167             this.checkError = checkError;
168             var callback = '?callback=enchant.Core.instance._twitterRequests[' + id + ']._callback';
169             var src = 'http://9leap.net/api/twitter/' + path + '.json' + callback;
170             if (option) {
171                 for (var key in option) {
172                     src += '&' + key + '=' + option[key];
173                 }
174             }
175             this.script = document.createElement('script');
176             this.script.type = 'text/javascript';
177             this.script.src = src;
178         },
179         _callback: function(resBody) {
180             enchant.Core.instance._setTwitterAssets(resBody, this.path, this.checkError);
181         },
182         _sendRequest: function() {
183             document.head.appendChild(this.script);
184         }
185     });
186 
187     /**
188      * @scope enchant.nineleap.twitter.TwitterUserData.prototype
189      */
190     enchant.nineleap.twitter.TwitterUserData = enchant.Class.create({
191         /**
192          * twitter user data class
193          * @param obj
194          * @constructs
195          */
196         initialize: function(obj) {
197             for (var prop in obj) {
198                 if (obj.hasOwnProperty(prop)) {
199                     this[prop] = obj[prop];
200                 }
201             }
202         },
203         toSprite: function(width, height) {
204             if (arguments.length < 2) {
205                 width = 48;
206                 height = 48;
207             }
208             var g = enchant.Core.instance;
209             var sp = new enchant.Sprite(width, height);
210             sp.image = g.assets[this['profile_image_url']];
211             return sp;
212         }
213     });
214 
215     /**
216      * @scope enchant.nineleap.twitter.TwitterStatusData.prototype
217      */
218     enchant.nineleap.twitter.TwitterStatusData = enchant.Class.create({
219         /**
220          * twitter status data class
221          * @param obj
222          * @constructs
223          */
224         initialize: function(obj) {
225             for (var prop in obj) {
226                 if (obj.hasOwnProperty(prop)) {
227                     this[prop] = obj[prop];
228                 }
229             }
230         }
231     });
232 
233 }());
234