1/*
2 * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3 * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com)
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1.  Redistributions of source code must retain the above copyright
10 *     notice, this list of conditions and the following disclaimer.
11 * 2.  Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 *     its contributors may be used to endorse or promote products derived
16 *     from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#import "config.h"
31#import "AppleScriptController.h"
32
33#import <WebKit/WebView.h>
34#import <WebKit/WebViewPrivate.h>   // for aeDescByEvaluatingJavaScriptFromString, which is pending API review
35
36@implementation AppleScriptController
37
38+ (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
39{
40    if (aSelector == @selector(doJavaScript:))
41        return NO;
42    return YES;
43}
44
45+ (NSString *)webScriptNameForSelector:(SEL)aSelector
46{
47    if (aSelector == @selector(doJavaScript:))
48        return @"doJavaScript";
49
50    return nil;
51}
52
53- (id)initWithWebView:(WebView *)wv
54{
55    self = [super init];
56    webView = wv;
57    return self;
58}
59
60static id convertAEDescToObject(NSAppleEventDescriptor *aeDesc)
61{
62    id value = nil;
63
64    DescType descType = [aeDesc descriptorType];
65    switch (descType) {
66        case typeUnicodeText:
67            value = [NSString stringWithFormat:@"\"%@\"", [aeDesc stringValue]];
68            break;
69        case typeLongDateTime:
70            if ([[aeDesc data] length] == sizeof(LongDateTime)) {
71                LongDateTime d;
72                [[aeDesc data] getBytes:&d];
73                value = [NSString stringWithFormat:@"%016llX", (unsigned long long)d];
74            }
75            break;
76        case typeAEList:
77            value = [NSMutableString stringWithString:@"("];
78            int numItems = [aeDesc numberOfItems];
79            for (int i = 0; i < numItems; ++i) {
80                if (i != 0)
81                    [(NSMutableString*)value appendString:@", "];
82                id obj = convertAEDescToObject([aeDesc descriptorAtIndex:(i + 1)]);
83                [(NSMutableString*)value appendString:[obj description]];
84            }
85            [(NSMutableString*)value appendString:@")"];
86            break;
87        case typeType: {
88            OSType type = [aeDesc typeCodeValue];
89
90            char typeStr[5];
91            typeStr[0] = type >> 24;
92            typeStr[1] = type >> 16;
93            typeStr[2] = type >> 8;
94            typeStr[3] = type;
95            typeStr[4] = 0;
96
97            value = [NSString stringWithFormat:@"'%s'", typeStr];
98            break;
99        }
100    }
101
102    if (!value)
103        value = [aeDesc stringValue];
104    if (!value)
105        value = [aeDesc data];
106
107    return value;
108}
109
110- (NSString *)doJavaScript:(NSString *)aString
111{
112    NSAppleEventDescriptor *aeDesc = [webView aeDescByEvaluatingJavaScriptFromString:aString];
113    if (!aeDesc)
114        return @"(null)";
115
116    DescType descType = [aeDesc descriptorType];
117    char descTypeStr[5];
118    descTypeStr[0] = descType >> 24;
119    descTypeStr[1] = descType >> 16;
120    descTypeStr[2] = descType >> 8;
121    descTypeStr[3] = descType;
122    descTypeStr[4] = 0;
123
124    return [NSString stringWithFormat:@"%@ ('%s')", convertAEDescToObject(aeDesc), descTypeStr];
125}
126
127@end
128