2 * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #import "TextInputController.h"
31 #import <AppKit/NSInputManager.h>
32 #import <WebKit/WebDocument.h>
33 #import <WebKit/WebFrame.h>
34 #import <WebKit/WebFrameView.h>
35 #import <WebKit/WebView.h>
37 @implementation NSMutableAttributedString (TextInputController)
39 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
41 if (aSelector == @selector(string)
42 || aSelector == @selector(getLength)
43 || aSelector == @selector(attributeNamesAtIndex:)
44 || aSelector == @selector(valueOfAttribute:atIndex:)
45 || aSelector == @selector(addAttribute:value:)
46 || aSelector == @selector(addAttribute:value:from:length:)
47 || aSelector == @selector(addColorAttribute:red:green:blue:alpha:)
48 || aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:)
49 || aSelector == @selector(addFontAttribute:fontName:size:)
50 || aSelector == @selector(addFontAttribute:fontName:size:from:length:))
55 + (NSString *)webScriptNameForSelector:(SEL)aSelector
57 if (aSelector == @selector(getLength))
59 if (aSelector == @selector(attributeNamesAtIndex:))
60 return @"getAttributeNamesAtIndex";
61 if (aSelector == @selector(valueOfAttribute:atIndex:))
62 return @"getAttributeValueAtIndex";
63 if (aSelector == @selector(addAttribute:value:))
64 return @"addAttribute";
65 if (aSelector == @selector(addAttribute:value:from:length:))
66 return @"addAttributeForRange";
67 if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:))
68 return @"addColorAttribute";
69 if (aSelector == @selector(addColorAttribute:red:green:blue:alpha:from:length:))
70 return @"addColorAttributeForRange";
71 if (aSelector == @selector(addFontAttribute:fontName:size:))
72 return @"addFontAttribute";
73 if (aSelector == @selector(addFontAttribute:fontName:size:from:length:))
74 return @"addFontAttributeForRange";
81 return (int)[self length];
84 - (NSArray *)attributeNamesAtIndex:(int)index
86 NSDictionary *attributes = [self attributesAtIndex:(unsigned)index effectiveRange:nil];
87 return [attributes allKeys];
90 - (id)valueOfAttribute:(NSString *)attrName atIndex:(int)index
92 return [self attribute:attrName atIndex:(unsigned)index effectiveRange:nil];
95 - (void)addAttribute:(NSString *)attrName value:(id)value
97 [self addAttribute:attrName value:value range:NSMakeRange(0, [self length])];
100 - (void)addAttribute:(NSString *)attrName value:(id)value from:(int)from length:(int)length
102 [self addAttribute:attrName value:value range:NSMakeRange((unsigned)from, (unsigned)length)];
105 - (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha
107 [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange(0, [self length])];
110 - (void)addColorAttribute:(NSString *)attrName red:(float)red green:(float)green blue:(float)blue alpha:(float)alpha from:(int)from length:(int)length
112 [self addAttribute:attrName value:[NSColor colorWithDeviceRed:red green:green blue:blue alpha:alpha] range:NSMakeRange((unsigned)from, (unsigned)length)];
115 - (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize
117 [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange(0, [self length])];
120 - (void)addFontAttribute:(NSString *)attrName fontName:(NSString *)fontName size:(float)fontSize from:(int)from length:(int)length
122 [self addAttribute:attrName value:[NSFont fontWithName:fontName size:fontSize] range:NSMakeRange((unsigned)from, (unsigned)length)];
127 @implementation TextInputController
129 + (BOOL)isSelectorExcludedFromWebScript:(SEL)aSelector
131 if (aSelector == @selector(insertText:)
132 || aSelector == @selector(doCommand:)
133 || aSelector == @selector(setMarkedText:selectedFrom:length:)
134 || aSelector == @selector(unmarkText)
135 || aSelector == @selector(hasMarkedText)
136 || aSelector == @selector(conversationIdentifier)
137 || aSelector == @selector(substringFrom:length:)
138 || aSelector == @selector(attributedSubstringFrom:length:)
139 || aSelector == @selector(markedRange)
140 || aSelector == @selector(selectedRange)
141 || aSelector == @selector(firstRectForCharactersFrom:length:)
142 || aSelector == @selector(characterIndexForPointX:Y:)
143 || aSelector == @selector(validAttributesForMarkedText)
144 || aSelector == @selector(attributedStringWithString:))
149 + (NSString *)webScriptNameForSelector:(SEL)aSelector
151 if (aSelector == @selector(insertText:))
152 return @"insertText";
153 else if (aSelector == @selector(doCommand:))
155 else if (aSelector == @selector(setMarkedText:selectedFrom:length:))
156 return @"setMarkedText";
157 else if (aSelector == @selector(substringFrom:length:))
158 return @"substringFromRange";
159 else if (aSelector == @selector(attributedSubstringFrom:length:))
160 return @"attributedSubstringFromRange";
161 else if (aSelector == @selector(firstRectForCharactersFrom:length:))
162 return @"firstRectForCharacterRange";
163 else if (aSelector == @selector(characterIndexForPointX:Y:))
164 return @"characterIndexForPoint";
165 else if (aSelector == @selector(attributedStringWithString:))
166 return @"makeAttributedString"; // just a factory method, doesn't call into NSTextInput
171 - (id)initWithWebView:(WebView *)wv
178 - (NSObject <NSTextInput> *)textInput
180 NSView <NSTextInput> *view = [[[webView mainFrame] frameView] documentView];
181 return [view conformsToProtocol:@protocol(NSTextInput)] ? view : nil;
184 - (void)insertText:(id)aString
186 NSObject <NSTextInput> *textInput = [self textInput];
189 [textInput insertText:aString];
192 - (void)doCommand:(NSString *)aCommand
194 NSObject <NSTextInput> *textInput = [self textInput];
197 [textInput doCommandBySelector:NSSelectorFromString(aCommand)];
200 - (void)setMarkedText:(NSString *)aString selectedFrom:(int)from length:(int)length
202 NSObject <NSTextInput> *textInput = [self textInput];
205 [textInput setMarkedText:aString selectedRange:NSMakeRange(from, length)];
210 NSObject <NSTextInput> *textInput = [self textInput];
213 [textInput unmarkText];
216 - (BOOL)hasMarkedText
218 NSObject <NSTextInput> *textInput = [self textInput];
221 return [textInput hasMarkedText];
226 - (long)conversationIdentifier
228 NSObject <NSTextInput> *textInput = [self textInput];
231 return [textInput conversationIdentifier];
236 - (NSString *)substringFrom:(int)from length:(int)length
238 NSObject <NSTextInput> *textInput = [self textInput];
241 return [[textInput attributedSubstringFromRange:NSMakeRange(from, length)] string];
246 - (NSMutableAttributedString *)attributedSubstringFrom:(int)from length:(int)length
248 NSObject <NSTextInput> *textInput = [self textInput];
250 NSMutableAttributedString *ret = [[[NSMutableAttributedString alloc] init] autorelease];
253 [ret setAttributedString:[textInput attributedSubstringFromRange:NSMakeRange(from, length)]];
258 - (NSArray *)markedRange
260 NSObject <NSTextInput> *textInput = [self textInput];
263 NSRange range = [textInput markedRange];
264 return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
270 - (NSArray *)selectedRange
272 NSObject <NSTextInput> *textInput = [self textInput];
275 NSRange range = [textInput selectedRange];
276 return [NSArray arrayWithObjects:[NSNumber numberWithUnsignedInt:range.location], [NSNumber numberWithUnsignedInt:range.length], nil];
283 - (NSArray *)firstRectForCharactersFrom:(int)from length:(int)length
285 NSObject <NSTextInput> *textInput = [self textInput];
288 NSRect rect = [textInput firstRectForCharacterRange:NSMakeRange(from, length)];
289 return [NSArray arrayWithObjects:
290 [NSNumber numberWithFloat:rect.origin.x],
291 [NSNumber numberWithFloat:rect.origin.y],
292 [NSNumber numberWithFloat:rect.size.width],
293 [NSNumber numberWithFloat:rect.size.height],
300 - (int)characterIndexForPointX:(float)x Y:(float)y
302 NSObject <NSTextInput> *textInput = [self textInput];
305 return [textInput characterIndexForPoint:NSMakePoint(x, y)];
310 - (NSArray *)validAttributesForMarkedText
312 NSObject <NSTextInput> *textInput = [self textInput];
315 return [textInput validAttributesForMarkedText];
320 - (NSMutableAttributedString *)attributedStringWithString:(NSString *)aString
322 NSMutableAttributedString *ret = [[[NSMutableAttributedString alloc] init] autorelease];
323 [ret setAttributedString:[[[NSAttributedString alloc] initWithString:aString] autorelease]];