API 0.9.5
Foundation/CPJSONPConnection.j
Go to the documentation of this file.
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
 All Classes Files Functions Variables Defines