![]() |
API 0.9.5
|
00001 /* 00002 * CPJSONPConnection.j 00003 * Foundation 00004 * 00005 * Created by Ross Boucher. 00006 * Copyright 2008, 280 North, Inc. 00007 * 00008 * This library is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * This library is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with this library; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00021 */ 00022 00023 00024 CPJSONPConnectionCallbacks = {}; 00025 00026 CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}"; 00027 00040 @implementation CPJSONPConnection : CPObject 00041 { 00042 CPURLRequest _request; 00043 id _delegate; 00044 00045 CPString _callbackParameter; 00046 DOMElement _scriptTag; 00047 } 00048 00050 + (CPJSONPConnection)sendRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate 00051 { 00052 return [self connectionWithRequest:aRequest callback:callbackParameter delegate:aDelegate]; 00053 } 00054 00055 + (CPJSONPConnection)connectionWithRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate 00056 { 00057 return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES]; 00058 } 00059 00060 - (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate 00061 { 00062 return [self initWithRequest:aRequest callback:aString delegate:aDelegate startImmediately: NO]; 00063 } 00064 00065 - (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately 00066 { 00067 self = [super init]; 00068 00069 if (self) 00070 { 00071 _request = aRequest; 00072 _delegate = aDelegate; 00073 00074 _callbackParameter = aString; 00075 00076 if (!_callbackParameter && [[_request URL] absoluteString].indexOf(CPJSONPCallbackReplacementString) < 0) 00077 [CPException raise:CPInvalidArgumentException reason:@"JSONP source specified without callback parameter or CPJSONPCallbackReplacementString in URL."]; 00078 00079 if (shouldStartImmediately) 00080 [self start]; 00081 } 00082 00083 return self; 00084 } 00085 00086 - (void)start 00087 { 00088 try 00089 { 00090 CPJSONPConnectionCallbacks["callback"+[self UID]] = function(data) 00091 { 00092 if ([_delegate respondsToSelector:@selector(connection:didReceiveData:)]) 00093 [_delegate connection:self didReceiveData:data]; 00094 00095 if ([_delegate respondsToSelector:@selector(connectionDidFinishLoading:)]) 00096 [_delegate connectionDidFinishLoading:self]; 00097 00098 [self removeScriptTag]; 00099 00100 [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode]; 00101 }; 00102 00103 var head = document.getElementsByTagName("head").item(0), 00104 source = [[_request URL] absoluteString]; 00105 00106 if (_callbackParameter) 00107 { 00108 source += (source.indexOf('?') < 0) ? "?" : "&"; 00109 source += _callbackParameter+"=CPJSONPConnectionCallbacks.callback"+[self UID]; 00110 } 00111 else if (source.indexOf(CPJSONPCallbackReplacementString) >= 0) 00112 { 00113 source = [source stringByReplacingOccurrencesOfString:CPJSONPCallbackReplacementString withString:"CPJSONPConnectionCallbacks.callback"+[self UID]]; 00114 } 00115 else 00116 return; 00117 00118 _scriptTag = document.createElement("script"); 00119 _scriptTag.setAttribute("type", "text/javascript"); 00120 _scriptTag.setAttribute("charset", "utf-8"); 00121 _scriptTag.setAttribute("src", source); 00122 00123 head.appendChild(_scriptTag); 00124 } 00125 catch (exception) 00126 { 00127 if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)]) 00128 [_delegate connection: self didFailWithError: exception]; 00129 00130 [self removeScriptTag]; 00131 } 00132 } 00133 00134 - (void)removeScriptTag 00135 { 00136 var head = document.getElementsByTagName("head").item(0); 00137 00138 if (_scriptTag && _scriptTag.parentNode == head) 00139 head.removeChild(_scriptTag); 00140 00141 CPJSONPConnectionCallbacks["callback" + [self UID]] = nil; 00142 delete CPJSONPConnectionCallbacks["callback" + [self UID]]; 00143 } 00144 00145 - (void)cancel 00146 { 00147 [self removeScriptTag]; 00148 } 00149 00150 @end