<commit_before>/*
 * CPJSONPConnection.j
 * Foundation
 *
 * Created by <NAME>.
 * Copyright 2008, 280 North, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
 
@import <Foundation/CPObject.j>


CPJSONPConnectionCallbacks = {};

CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";

/*! 
    @ingroup foundation
    @brief Allows cross domain connections using JSONP protocol.

    Important note: CPJSONPConnection is <strong>only</strong> for JSONP APIs.
    If aren't sure you <strong>need</strong>
    <a href="http://ajaxian.com/archives/jsonp-json-with-padding">JSON<strong>P</strong></a>,
    you most likely don't want to use CPJSONPConnection, but rather the more standard
    CPURLConnection. CPJSONPConnection is designed for cross-domain
    connections, and if you are making requests to the same domain (as most web
    applications do), you do not need it.
*/
@implementation CPJSONPConnection : CPObject
{
    CPURLRequest    _request;
    id              _delegate;
    
    CPString        _callbackParameter;
    DOMElement      _scriptTag;
}

/*! @deprecated */
+ (CPJSONPConnection)sendRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate 
{
    return [self connectionWithRequest:aRequest callback:callbackParameter delegate:aDelegate];
}

+ (CPJSONPConnection)connectionWithRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate
{
    return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES];;
}

- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate 
{
    return [self initWithRequest:aRequest callback:aString delegate:aDelegate startImmediately: NO];
}

- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately
{
    self = [super init];
    
    _request = aRequest;
    _delegate = aDelegate;
    
    _callbackParameter = aString;
    
    if (!_callbackParameter && [[_request URL] absoluteString].indexOf(CPJSONPCallbackReplacementString) < 0)
         [CPException raise:CPInvalidArgumentException reason:@"JSONP source specified without callback parameter or CPJSONPCallbackReplacementString in URL."];

    if(shouldStartImmediately)
        [self start];
        
    return self;
}

- (void)start
{
    try
    {
        CPJSONPConnectionCallbacks["callback"+[self UID]] = function(data)
        {
            [_delegate connection:self didReceiveData:data];
            [self removeScriptTag];
    
            [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
        };

        var head = document.getElementsByTagName("head").item(0),
            source = [[_request URL] absoluteString];

        if (_callbackParameter)
        {
            source += (source.indexOf('?') < 0) ? "?" : "&";
            source += _callbackParameter+"=CPJSONPConnectionCallbacks.callback"+[self UID];
        }
        else if (source.indexOf(CPJSONPCallbackReplacementString) >= 0)
        {
            source = [source stringByReplacingOccurrencesOfString:CPJSONPCallbackReplacementString withString:"CPJSONPConnectionCallbacks.callback"+[self UID]];
        }
        else
            return;
        
        _scriptTag = document.createElement("script");
        _scriptTag.setAttribute("type", "text/javascript");
        _scriptTag.setAttribute("charset", "utf-8");
        _scriptTag.setAttribute("src", source);
        
        head.appendChild(_scriptTag);
    }
    catch (exception)
    {
        [_delegate connection: self didFailWithError: exception];
        [self removeScriptTag];
    }
}

- (void)removeScriptTag
{
    var head = document.getElementsByTagName("head").item(0);
    
    if(_scriptTag && _scriptTag.parentNode == head)
        head.removeChild(_scriptTag);

    CPJSONPConnectionCallbacks["callback"+[self UID]] = nil;
    delete CPJSONPConnectionCallbacks["callback"+[self UID]];
}

- (void)cancel
{
    [self removeScriptTag];
}

@end<commit_msg>Added connectionDidFinsihLoading delegate to CPJSONPConnection<commit_after>/*
 * CPJSONPConnection.j
 * Foundation
 *
 * Created by <NAME>.
 * Copyright 2008, 280 North, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
 
@import <Foundation/CPObject.j>


CPJSONPConnectionCallbacks = {};

CPJSONPCallbackReplacementString = @"${JSONP_CALLBACK}";

/*! 
    @ingroup foundation
    @brief Allows cross domain connections using JSONP protocol.

    Important note: CPJSONPConnection is <strong>only</strong> for JSONP APIs.
    If aren't sure you <strong>need</strong>
    <a href="http://ajaxian.com/archives/jsonp-json-with-padding">JSON<strong>P</strong></a>,
    you most likely don't want to use CPJSONPConnection, but rather the more standard
    CPURLConnection. CPJSONPConnection is designed for cross-domain
    connections, and if you are making requests to the same domain (as most web
    applications do), you do not need it.
*/
@implementation CPJSONPConnection : CPObject
{
    CPURLRequest    _request;
    id              _delegate;
    
    CPString        _callbackParameter;
    DOMElement      _scriptTag;
}

/*! @deprecated */
+ (CPJSONPConnection)sendRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate 
{
    return [self connectionWithRequest:aRequest callback:callbackParameter delegate:aDelegate];
}

+ (CPJSONPConnection)connectionWithRequest:(CPURLRequest)aRequest callback:(CPString)callbackParameter delegate:(id)aDelegate
{
    return [[[self class] alloc] initWithRequest:aRequest callback:callbackParameter delegate:aDelegate startImmediately:YES];;
}

- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate 
{
    return [self initWithRequest:aRequest callback:aString delegate:aDelegate startImmediately: NO];
}

- (id)initWithRequest:(CPURLRequest)aRequest callback:(CPString)aString delegate:(id)aDelegate startImmediately:(BOOL)shouldStartImmediately
{
    self = [super init];
    
    _request = aRequest;
    _delegate = aDelegate;
    
    _callbackParameter = aString;
    
    if (!_callbackParameter && [[_request URL] absoluteString].indexOf(CPJSONPCallbackReplacementString) < 0)
         [CPException raise:CPInvalidArgumentException reason:@"JSONP source specified without callback parameter or CPJSONPCallbackReplacementString in URL."];

    if(shouldStartImmediately)
        [self start];
        
    return self;
}

- (void)start
{
    try
    {
        CPJSONPConnectionCallbacks["callback"+[self UID]] = function(data)
        {
            if ([_delegate respondsToSelector:@selector(connection:didReceiveData:)])
                [_delegate connection:self didReceiveData:data];

            if ([_delegate respondsToSelector:@selector(connectionDidFinishLoading:)])
                    [_delegate connectionDidFinishLoading:self];
    
            [self removeScriptTag];
    
            [[CPRunLoop currentRunLoop] limitDateForMode:CPDefaultRunLoopMode];
        };

        var head = document.getElementsByTagName("head").item(0),
            source = [[_request URL] absoluteString];

        if (_callbackParameter)
        {
            source += (source.indexOf('?') < 0) ? "?" : "&";
            source += _callbackParameter+"=CPJSONPConnectionCallbacks.callback"+[self UID];
        }
        else if (source.indexOf(CPJSONPCallbackReplacementString) >= 0)
        {
            source = [source stringByReplacingOccurrencesOfString:CPJSONPCallbackReplacementString withString:"CPJSONPConnectionCallbacks.callback"+[self UID]];
        }
        else
            return;
        
        _scriptTag = document.createElement("script");
        _scriptTag.setAttribute("type", "text/javascript");
        _scriptTag.setAttribute("charset", "utf-8");
        _scriptTag.setAttribute("src", source);
        
        head.appendChild(_scriptTag);
    }
    catch (exception)
    {
        if ([_delegate respondsToSelector:@selector(connection:didFailWithError:)])
            [_delegate connection: self didFailWithError: exception];

        [self removeScriptTag];
    }
}

- (void)removeScriptTag
{
    var head = document.getElementsByTagName("head").item(0);
    
    if(_scriptTag && _scriptTag.parentNode == head)
        head.removeChild(_scriptTag);

    CPJSONPConnectionCallbacks["callback"+[self UID]] = nil;
    delete CPJSONPConnectionCallbacks["callback"+[self UID]];
}

- (void)cancel
{
    [self removeScriptTag];
}

@end
{'fraction_non_alphanumeric': 0.09729458917835672, 'fraction_numerical': 0.0052104208416833666, 'mean_word_length': 3.705799151343706, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7223436', 'n_tokens_mistral': 2796, 'n_tokens_neox': 2673, 'n_words': 712}