WebCore:
[WebKit-https.git] / WebCore / bridge / mac / WebCoreFrameBridge.mm
1 /*
2  * Copyright (C) 2004, 2005, 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2005, 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  * 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  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
25  */
26
27 #import "config.h"
28 #import "WebCoreFrameBridge.h"
29
30 #import "Cache.h"
31 #import "DOMInternal.h"
32 #import "DocumentFragment.h"
33 #import "DocumentType.h"
34 #import "FrameTree.h"
35 #import "GraphicsContext.h"
36 #import "HTMLFormElement.h"
37 #import "HTMLInputElement.h"
38 #import "AccessibilityObjectCache.h"
39 #import "CharsetNames.h"
40 #import "KWQEditCommand.h"
41 #import "FloatRect.h"
42 #import "FoundationExtras.h"
43 #import "KWQLoader.h"
44 #import "KWQPageState.h"
45 #import "RenderTreeAsText.h"
46 #import "FrameMac.h"
47 #import "Page.h"
48 #import "SelectionController.h"
49 #import "WebCorePageBridge.h"
50 #import "WebCoreSettings.h"
51 #import "WebCoreViewFactory.h"
52 #import "WebCoreWidgetHolder.h"
53 #import "csshelper.h"
54 #import "DeleteSelectionCommand.h"
55 #import "HTMLDocument.h"
56 #import "html_imageimpl.h"
57 #import "htmlediting.h"
58 #import "HTMLNames.h"
59 #import "kjs_proxy.h"
60 #import "kjs_window.h"
61 #import "markup.h"
62 #import "ModifySelectionListLevelCommand.h"
63 #import "MoveSelectionCommand.h"
64 #import "RenderCanvas.h"
65 #import "render_frames.h"
66 #import "RenderImage.h"
67 #import "ReplaceSelectionCommand.h"
68 #import "TypingCommand.h"
69 #import "TextIterator.h"
70 #import "visible_units.h"
71 #import "xml_tokenizer.h"
72 #import <JavaScriptCore/date_object.h>
73 #import <JavaScriptCore/runtime_root.h>
74
75 @class NSView;
76
77 using namespace std;
78 using namespace WebCore;
79 using namespace HTMLNames;
80
81 using KJS::BooleanType;
82 using KJS::DateInstance;
83 using KJS::ExecState;
84 using KJS::GetterSetterType;
85 using KJS::Identifier;
86 using KJS::Interpreter;
87 using KJS::JSLock;
88 using KJS::JSObject;
89 using KJS::JSType;
90 using KJS::JSValue;
91 using KJS::List;
92 using KJS::NullType;
93 using KJS::NumberType;
94 using KJS::ObjectType;
95 using KJS::SavedBuiltins;
96 using KJS::SavedProperties;
97 using KJS::StringType;
98 using KJS::UString;
99 using KJS::UndefinedType;
100 using KJS::UnspecifiedType;
101 using KJS::Window;
102
103 using KJS::Bindings::RootObject;
104
105 NSString *WebCorePageCacheStateKey = @"WebCorePageCacheState";
106
107 @interface WebCoreFrameBridge (WebCoreBridgeInternal)
108 - (RootObject *)executionContextForView:(NSView *)aView;
109 - (RenderObject::NodeInfo)nodeInfoAtPoint:(NSPoint)point allowShadowContent:(BOOL)allow;
110 @end
111
112 static RootObject *rootForView(void *v)
113 {
114     NSView *aView = (NSView *)v;
115     WebCoreFrameBridge *aBridge = [[WebCoreViewFactory sharedFactory] bridgeForView:aView];
116     RootObject *root = 0;
117
118     if (aBridge)
119         root = [aBridge executionContextForView:aView];
120
121     return root;
122 }
123
124 static pthread_t mainThread = 0;
125
126 static void updateRenderingForBindings (ExecState *exec, JSObject *rootObject)
127 {
128     if (pthread_self() != mainThread)
129         return;
130         
131     if (!rootObject)
132         return;
133         
134     Window *window = static_cast<Window*>(rootObject);
135     if (!window)
136         return;
137         
138     Document *doc = static_cast<Document*>(window->frame()->document());
139     if (doc)
140         doc->updateRendering();
141 }
142
143 static BOOL hasCaseInsensitivePrefix(NSString *string, NSString *prefix)
144 {
145     return [string rangeOfString:prefix options:(NSCaseInsensitiveSearch | NSAnchoredSearch)].location !=
146         NSNotFound;
147 }
148
149 static BOOL isCaseSensitiveEqual(NSString *a, NSString *b)
150 {
151     return [a caseInsensitiveCompare:b] == NSOrderedSame;
152 }
153
154 static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsValue)
155 {
156     NSAppleEventDescriptor* aeDesc = 0;
157     switch (jsValue->type()) {
158         case BooleanType:
159             aeDesc = [NSAppleEventDescriptor descriptorWithBoolean:jsValue->getBoolean()];
160             break;
161         case StringType:
162             aeDesc = [NSAppleEventDescriptor descriptorWithString:String(jsValue->getString())];
163             break;
164         case NumberType: {
165             Float64 value = jsValue->getNumber();
166             aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeIEEE64BitFloatingPoint bytes:&value length:sizeof(value)];
167             break;
168         }
169         case ObjectType: {
170             JSObject* object = jsValue->getObject();
171             if (object->inherits(&DateInstance::info)) {
172                 DateInstance* date = static_cast<DateInstance*>(object);
173                 double ms = 0;
174                 int tzOffset = 0;
175                 if (date->getTime(ms, tzOffset)) {
176                     CFAbsoluteTime utcSeconds = ms / 1000 - kCFAbsoluteTimeIntervalSince1970;
177                     LongDateTime ldt;
178                     if (noErr == UCConvertCFAbsoluteTimeToLongDateTime(utcSeconds, &ldt))
179                         aeDesc = [NSAppleEventDescriptor descriptorWithDescriptorType:typeLongDateTime bytes:&ldt length:sizeof(ldt)];
180                 }
181             }
182             if (!aeDesc) {
183                 JSValue* primitive = object->toPrimitive(exec);
184                 if (exec->hadException()) {
185                     exec->clearException();
186                     return [NSAppleEventDescriptor nullDescriptor];
187                 }
188                 return aeDescFromJSValue(exec, primitive);
189             }
190             break;
191         }
192         default:
193             LOG_ERROR("Unknown JavaScript type: %d", jsValue->type());
194             // no break;
195         case UnspecifiedType:
196         case UndefinedType:
197         case NullType:
198         case GetterSetterType:
199             aeDesc = [NSAppleEventDescriptor nullDescriptor];
200             break;
201     }
202     
203     return aeDesc;
204 }
205
206 @implementation WebCoreFrameBridge
207
208 static bool initializedObjectCacheSize = false;
209 static bool initializedKJS = false;
210
211 static inline WebCoreFrameBridge *bridge(Frame *frame)
212 {
213     if (!frame)
214         return nil;
215     return Mac(frame)->bridge();
216 }
217
218 - (WebCoreFrameBridge *)firstChild
219 {
220     return bridge(m_frame->tree()->firstChild());
221 }
222
223 - (WebCoreFrameBridge *)lastChild
224 {
225     return bridge(m_frame->tree()->lastChild());
226 }
227
228 - (unsigned)childCount
229 {
230     return m_frame->tree()->childCount();
231 }
232
233 - (WebCoreFrameBridge *)previousSibling;
234 {
235     return bridge(m_frame->tree()->previousSibling());
236 }
237
238 - (WebCoreFrameBridge *)nextSibling;
239 {
240     return bridge(m_frame->tree()->nextSibling());
241 }
242
243 - (BOOL)isDescendantOfFrame:(WebCoreFrameBridge *)ancestor
244 {
245     return m_frame->tree()->isDescendantOf(ancestor->m_frame);
246 }
247
248 - (WebCoreFrameBridge *)traverseNextFrameStayWithin:(WebCoreFrameBridge *)stayWithin
249 {
250     return bridge(m_frame->tree()->traverseNext(stayWithin->m_frame));
251 }
252
253 - (void)appendChild:(WebCoreFrameBridge *)child
254 {
255     m_frame->tree()->appendChild(adoptRef(child->m_frame));
256 }
257
258 - (void)removeChild:(WebCoreFrameBridge *)child
259 {
260     m_frame->tree()->removeChild(child->m_frame);
261 }
262
263 - (WebCoreFrameBridge *)childFrameNamed:(NSString *)name
264 {
265     return bridge(m_frame->tree()->child(name));
266 }
267
268 - (WebCoreFrameBridge *)nextFrameWithWrap:(BOOL)wrapFlag
269 {
270     return bridge(m_frame->tree()->traverseNextWithWrap(wrapFlag));
271 }
272
273 - (WebCoreFrameBridge *)previousFrameWithWrap:(BOOL)wrapFlag
274 {
275     return bridge(m_frame->tree()->traversePreviousWithWrap(wrapFlag));
276 }
277
278 - (NSString *)domain
279 {
280     Document *doc = m_frame->document();
281     if (doc && doc->isHTMLDocument())
282         return doc->domain();
283     return nil;
284 }
285
286 // FIXME: this is not getting called any more! security regression...
287 - (BOOL)_shouldAllowAccessFrom:(WebCoreFrameBridge *)source
288 {
289     // if no source frame, allow access
290     if (source == nil)
291         return YES;
292
293     //   - allow access if the two frames are in the same window
294     if ([self page] == [source page])
295         return YES;
296
297     //   - allow if the request is made from a local file.
298     NSString *sourceDomain = [self domain];
299     if ([sourceDomain length] == 0)
300         return YES;
301
302     //   - allow access if this frame or one of its ancestors
303     //     has the same origin as source
304     for (WebCoreFrameBridge *ancestor = self; ancestor; ancestor = [ancestor parent]) {
305         NSString *ancestorDomain = [ancestor domain];
306         if (ancestorDomain != nil && 
307             isCaseSensitiveEqual(sourceDomain, ancestorDomain))
308             return YES;
309         
310         ancestor = [ancestor parent];
311     }
312
313     //   - allow access if this frame is a toplevel window and the source
314     //     can access its opener. Note that we only allow one level of
315     //     recursion here.
316     if ([self parent] == nil) {
317         NSString *openerDomain = [[self opener] domain];
318         if (openerDomain != nil && isCaseSensitiveEqual(sourceDomain, openerDomain))
319             return YES;
320     }
321     
322     // otherwise deny access
323     return NO;
324 }
325
326 - (BOOL)canTargetLoadInFrame:(WebCoreFrameBridge *)targetFrame
327 {
328     // This method prevents this exploit:
329     // <rdar://problem/3715785> multiple frame injection vulnerability reported by Secunia, affects almost all browsers
330     
331     // don't mess with navigation within the same page/frameset
332     if ([self page] == [targetFrame page])
333         return YES;
334
335     // Normally, domain should be called on the DOMDocument since it is a DOM method, but this fix is needed for
336     // Jaguar as well where the DOM API doesn't exist.
337     NSString *thisDomain = [self domain];
338     if ([thisDomain length] == 0) {
339         // Allow if the request is made from a local file.
340         return YES;
341     }
342     
343     WebCoreFrameBridge *parentBridge = [targetFrame parent];
344     // Allow if target is an entire window.
345     if (!parentBridge)
346         return YES;
347     
348     NSString *parentDomain = [parentBridge domain];
349     // Allow if the domain of the parent of the targeted frame equals this domain.
350     if (parentDomain && isCaseSensitiveEqual(thisDomain, parentDomain))
351         return YES;
352
353     return NO;
354 }
355
356 - (WebCoreFrameBridge *)findFrameNamed:(NSString *)name
357 {
358     return bridge(m_frame->tree()->find(name));
359 }
360
361 + (NSArray *)supportedMIMETypes
362 {
363     return [NSArray arrayWithObjects:
364         @"text/html",
365         @"text/xml",
366         @"text/xsl",
367         @"application/xml",
368         @"application/xhtml+xml",
369         @"application/rss+xml",
370         @"application/atom+xml",
371         @"application/x-webarchive",
372         @"multipart/x-mixed-replace",
373 #if SVG_SUPPORT
374         @"image/svg+xml",
375 #endif
376         nil];
377 }
378
379 + (WebCoreFrameBridge *)bridgeForDOMDocument:(DOMDocument *)document
380 {
381     return bridge([document _document]->frame());
382 }
383
384 - (id)initMainFrameWithPage:(WebCorePageBridge *)page
385 {
386     if (!initializedKJS) {
387         mainThread = pthread_self();
388         RootObject::setFindRootObjectForNativeHandleFunction(rootForView);
389         KJS::Bindings::Instance::setDidExecuteFunction(updateRenderingForBindings);
390         initializedKJS = true;
391     }
392     
393     if (!(self = [super init]))
394         return nil;
395
396     m_frame = new FrameMac([page impl], 0);
397     m_frame->setBridge(self);
398     _shouldCreateRenderers = YES;
399
400     // FIXME: This is one-time initialization, but it gets the value of the setting from the
401     // current WebView. That's a mismatch and not good!
402     if (!initializedObjectCacheSize) {
403         Cache::setSize([self getObjectCacheSize]);
404         initializedObjectCacheSize = true;
405     }
406     
407     return self;
408 }
409
410 - (id)initSubframeWithRenderer:(RenderPart *)renderer
411 {
412     if (!(self = [super init]))
413         return nil;
414     
415     m_frame = new FrameMac(renderer->node()->document()->frame()->page(), renderer);
416     m_frame->setBridge(self);
417     _shouldCreateRenderers = YES;
418     return self;
419 }
420
421 - (WebCorePageBridge *)page
422 {
423     return m_frame->page()->bridge();
424 }
425
426 - (void)initializeSettings:(WebCoreSettings *)settings
427 {
428     m_frame->setSettings([settings settings]);
429 }
430
431 - (void)fini
432 {
433     if (_keyboardUIModeAccessed) {
434         [[NSDistributedNotificationCenter defaultCenter] 
435             removeObserver:self name:KeyboardUIModeDidChangeNotification object:nil];
436         [[NSNotificationCenter defaultCenter] 
437             removeObserver:self name:WebPreferencesChangedNotification object:nil];
438     }
439
440     [self removeFromFrame];
441 }
442
443 - (void)dealloc
444 {
445     [self fini];
446     [super dealloc];
447 }
448
449 - (void)finalize
450 {
451     // FIXME: This work really should not be done at deallocation time.
452     // We need to do it at some well-defined time instead.
453     [self fini];
454     [super finalize];
455 }
456
457 - (WebCoreFrameBridge *)parent
458 {
459     return bridge(m_frame->tree()->parent());
460 }
461
462 - (void)provisionalLoadStarted
463 {
464     m_frame->provisionalLoadStarted();
465 }
466
467 - (void)openURL:(NSURL *)URL reload:(BOOL)reload contentType:(NSString *)contentType refresh:(NSString *)refresh lastModified:(NSDate *)lastModified pageCache:(NSDictionary *)pageCache
468 {
469     if (pageCache) {
470         KWQPageState *state = [pageCache objectForKey:WebCorePageCacheStateKey];
471         m_frame->openURLFromPageCache(state);
472         [state invalidate];
473         return;
474     }
475         
476     // arguments
477     ResourceRequest request(m_frame->resourceRequest());
478     request.reload = reload;
479     if (contentType)
480         request.m_responseMIMEType = contentType;
481     m_frame->setResourceRequest(request);
482
483     // opening the URL
484     if (m_frame->didOpenURL(URL)) {
485         // things we have to set up after calling didOpenURL
486         if (refresh) {
487             m_frame->addMetaData("http-refresh", refresh);
488         }
489         if (lastModified) {
490             NSString *modifiedString = [lastModified descriptionWithCalendarFormat:@"%a %b %d %Y %H:%M:%S" timeZone:nil locale:nil];
491             m_frame->addMetaData("modified", modifiedString);
492         }
493     }
494 }
495
496 - (void)setEncoding:(NSString *)encoding userChosen:(BOOL)userChosen
497 {
498     m_frame->setEncoding(DeprecatedString::fromNSString(encoding), userChosen);
499 }
500
501 - (void)addData:(NSData *)data
502 {
503     Document *doc = m_frame->document();
504     
505     // Document may be nil if the part is about to redirect
506     // as a result of JS executing during load, i.e. one frame
507     // changing another's location before the frame's document
508     // has been created. 
509     if (doc) {
510         doc->setShouldCreateRenderers([self shouldCreateRenderers]);
511         m_frame->addData((const char *)[data bytes], [data length]);
512     }
513 }
514
515 - (void)closeURL
516 {
517     m_frame->closeURL();
518 }
519
520 - (void)stopLoading
521 {
522     m_frame->stopLoading();
523 }
524
525 - (void)didNotOpenURL:(NSURL *)URL pageCache:(NSDictionary *)pageCache
526 {
527     m_frame->didNotOpenURL(KURL(URL).url());
528
529     // We might have made a page cache item, but now we're bailing out due to an error before we ever
530     // transitioned to the new page (before WebFrameState==commit).  The goal here is to restore any state
531     // so that the existing view (that wenever got far enough to replace) can continue being used.
532     Document *doc = m_frame->document();
533     if (doc)
534         doc->setInPageCache(NO);
535
536     KWQPageState *state = [pageCache objectForKey:WebCorePageCacheStateKey];
537     [state invalidate];
538 }
539
540 - (BOOL)canLoadURL:(NSURL *)URL fromReferrer:(NSString *)referrer hideReferrer:(BOOL *)hideReferrer
541 {
542     BOOL referrerIsWebURL = hasCaseInsensitivePrefix(referrer, @"http:") || hasCaseInsensitivePrefix(referrer, @"https:");
543     BOOL referrerIsLocalURL = hasCaseInsensitivePrefix(referrer, @"file:") || hasCaseInsensitivePrefix(referrer, @"applewebdata:");
544     BOOL URLIsFileURL = [URL scheme] != NULL && [[URL scheme] compare:@"file" options:(NSCaseInsensitiveSearch|NSLiteralSearch)] == NSOrderedSame;
545     BOOL referrerIsSecureURL = hasCaseInsensitivePrefix(referrer, @"https:");
546     BOOL URLIsSecureURL = [URL scheme] != NULL && [[URL scheme] compare:@"https" options:(NSCaseInsensitiveSearch|NSLiteralSearch)] == NSOrderedSame;
547
548     
549     *hideReferrer = !referrerIsWebURL || (referrerIsSecureURL && !URLIsSecureURL);
550     return !URLIsFileURL || referrerIsLocalURL;
551 }
552
553 - (void)saveDocumentState
554 {
555     Document* doc = m_frame->document();
556     if (doc) {
557         DeprecatedStringList list = doc->docState();
558         NSMutableArray* documentState = [[NSMutableArray alloc] init];
559         DeprecatedStringList::const_iterator end = list.constEnd();
560         for (DeprecatedStringList::const_iterator i = list.constBegin(); i != end; ++i) {
561             const DeprecatedString& s = *i;
562             [documentState addObject:[NSString stringWithCharacters:(const unichar *)s.unicode() length:s.length()]];
563         }
564         [self saveDocumentState:documentState];
565         [documentState release];
566     }
567 }
568
569 - (void)restoreDocumentState
570 {
571     Document *doc = m_frame->document();
572     if (doc) {
573         NSArray *documentState = [self documentState];
574         
575         DeprecatedStringList s;
576         for (unsigned i = 0; i < [documentState count]; i++) {
577             NSString *string = [documentState objectAtIndex: i];
578             s.append(DeprecatedString::fromNSString(string));
579         }
580             
581         doc->setRestoreState(s);
582     }
583 }
584
585 - (void)scrollToAnchorWithURL:(NSURL *)URL
586 {
587     m_frame->scrollToAnchor(KURL(URL).url().latin1());
588 }
589
590 - (BOOL)scrollOverflowInDirection:(WebScrollDirection)direction granularity:(WebScrollGranularity)granularity
591 {
592     if (!m_frame)
593         return NO;
594     return m_frame->scrollOverflow((KWQScrollDirection)direction, (KWQScrollGranularity)granularity);
595 }
596
597 - (BOOL)sendScrollWheelEvent:(NSEvent *)event
598 {
599     return m_frame ? m_frame->wheelEvent(event) : NO;
600 }
601
602 - (BOOL)saveDocumentToPageCache
603 {
604     Document *doc = m_frame->document();
605     if (!doc)
606         return NO;
607     if (!doc->view())
608         return NO;
609
610     m_frame->clearTimers();
611
612     JSLock lock;
613
614     SavedProperties *windowProperties = new SavedProperties;
615     m_frame->saveWindowProperties(windowProperties);
616
617     SavedProperties *locationProperties = new SavedProperties;
618     m_frame->saveLocationProperties(locationProperties);
619     
620     SavedBuiltins *interpreterBuiltins = new SavedBuiltins;
621     m_frame->saveInterpreterBuiltins(*interpreterBuiltins);
622
623     KWQPageState *pageState = [[KWQPageState alloc] initWithDocument:doc
624                                                                  URL:m_frame->url()
625                                                     windowProperties:windowProperties
626                                                   locationProperties:locationProperties
627                                                  interpreterBuiltins:interpreterBuiltins
628                                                       pausedTimeouts:m_frame->pauseTimeouts()];
629
630     BOOL result = [self saveDocumentToPageCache:pageState];
631
632     [pageState release];
633
634     return result;
635 }
636
637 - (BOOL)canCachePage
638 {
639     return m_frame->canCachePage();
640 }
641
642 - (void)clear
643 {
644     m_frame->clear();
645 }
646
647 - (void)end
648 {
649     m_frame->end();
650 }
651
652 - (void)stop
653 {
654     m_frame->stop();
655 }
656
657 - (void)clearFrame
658 {
659     m_frame = 0;
660 }
661
662 - (void)handleFallbackContent
663 {
664     // this needs to be callable even after teardown of the frame
665     if (!m_frame)
666         return;
667     m_frame->handleFallbackContent();
668 }
669
670 - (void)createFrameViewWithNSView:(NSView *)view marginWidth:(int)mw marginHeight:(int)mh
671 {
672     // If we own the view, delete the old one - otherwise the render m_frame will take care of deleting the view.
673     [self removeFromFrame];
674
675     FrameView* frameView = new FrameView(m_frame);
676     m_frame->setView(frameView);
677     frameView->deref();
678
679     frameView->setView(view);
680     if (mw >= 0)
681         frameView->setMarginWidth(mw);
682     if (mh >= 0)
683         frameView->setMarginHeight(mh);
684 }
685
686 - (void)scrollToAnchor:(NSString *)anchor
687 {
688     m_frame->gotoAnchor(anchor);
689 }
690
691 - (BOOL)isSelectionEditable
692 {
693     return m_frame->selection().isContentEditable();
694 }
695
696 - (BOOL)isSelectionRichlyEditable
697 {
698     return m_frame->selection().isContentRichlyEditable();
699 }
700
701 - (WebSelectionState)selectionState
702 {
703     switch (m_frame->selection().state()) {
704         case WebCore::Selection::NONE:
705             return WebSelectionStateNone;
706         case WebCore::Selection::CARET:
707             return WebSelectionStateCaret;
708         case WebCore::Selection::RANGE:
709             return WebSelectionStateRange;
710     }
711     
712     ASSERT_NOT_REACHED();
713     return WebSelectionStateNone;
714 }
715
716 - (NSString *)_stringWithDocumentTypeStringAndMarkupString:(NSString *)markupString
717 {
718     return m_frame->documentTypeString() + markupString;
719 }
720
721 - (NSArray *)nodesFromList:(DeprecatedPtrList<Node> *)nodeList
722 {
723     NSMutableArray *nodes = [NSMutableArray arrayWithCapacity:nodeList->count()];
724     for (DeprecatedPtrListIterator<Node> i(*nodeList); i.current(); ++i)
725         [nodes addObject:[DOMNode _nodeWith:i.current()]];
726
727     return nodes;
728 }
729
730 - (NSString *)markupStringFromNode:(DOMNode *)node nodes:(NSArray **)nodes
731 {
732     // FIXME: This is never "for interchange". Is that right? See the next method.
733     DeprecatedPtrList<Node> nodeList;
734     NSString *markupString = createMarkup([node _node], IncludeNode, nodes ? &nodeList : 0).getNSString();
735     if (nodes)
736         *nodes = [self nodesFromList:&nodeList];
737
738     return [self _stringWithDocumentTypeStringAndMarkupString:markupString];
739 }
740
741 - (NSString *)markupStringFromRange:(DOMRange *)range nodes:(NSArray **)nodes
742 {
743     // FIXME: This is always "for interchange". Is that right? See the previous method.
744     DeprecatedPtrList<Node> nodeList;
745     NSString *markupString = createMarkup([range _range], nodes ? &nodeList : 0, AnnotateForInterchange).getNSString();
746     if (nodes)
747         *nodes = [self nodesFromList:&nodeList];
748
749     return [self _stringWithDocumentTypeStringAndMarkupString:markupString];
750 }
751
752 - (NSString *)selectedString
753 {
754     String text = m_frame->selectedText();
755     text.replace(QChar('\\'), m_frame->backslashAsCurrencySymbol());
756     return [[(NSString*)text copy] autorelease];
757 }
758
759 - (NSString *)stringForRange:(DOMRange *)range
760 {
761     String text = plainText([range _range]);
762     text.replace(QChar('\\'), m_frame->backslashAsCurrencySymbol());
763     return [[(NSString*)text copy] autorelease];
764 }
765
766 - (void)selectAll
767 {
768     m_frame->selectAll();
769 }
770
771 - (void)deselectAll
772 {
773     [self deselectText];
774     Document *doc = m_frame->document();
775     if (doc) {
776         doc->setFocusNode(0);
777     }
778 }
779
780 - (void)deselectText
781 {
782     // FIXME: 6498 Should just be able to call m_frame->selection().clear()
783     m_frame->setSelection(SelectionController());
784 }
785
786 - (BOOL)isFrameSet
787 {
788     return m_frame->isFrameSet();
789 }
790
791 - (void)reapplyStylesForDeviceType:(WebCoreDeviceType)deviceType
792 {
793     m_frame->setMediaType(deviceType == WebCoreDeviceScreen ? "screen" : "print");
794     Document *doc = m_frame->document();
795     if (doc)
796         doc->setPrinting(deviceType == WebCoreDevicePrinter);
797     return m_frame->reparseConfiguration();
798 }
799
800 static BOOL nowPrinting(WebCoreFrameBridge *self)
801 {
802     Document *doc = self->m_frame->document();
803     return doc && doc->printing();
804 }
805
806 // Set or unset the printing mode in the view.  We only toy with this if we're printing.
807 - (void)_setupRootForPrinting:(BOOL)onOrOff
808 {
809     if (nowPrinting(self)) {
810         RenderCanvas *root = static_cast<RenderCanvas *>(m_frame->document()->renderer());
811         if (root) {
812             root->setPrintingMode(onOrOff);
813         }
814     }
815 }
816
817 - (void)forceLayoutAdjustingViewSize:(BOOL)flag
818 {
819     [self _setupRootForPrinting:YES];
820     m_frame->forceLayout();
821     if (flag) {
822         [self adjustViewSize];
823     }
824     [self _setupRootForPrinting:NO];
825 }
826
827 - (void)forceLayoutWithMinimumPageWidth:(float)minPageWidth maximumPageWidth:(float)maxPageWidth adjustingViewSize:(BOOL)flag
828 {
829     [self _setupRootForPrinting:YES];
830     m_frame->forceLayoutWithPageWidthRange(minPageWidth, maxPageWidth);
831     if (flag) {
832         [self adjustViewSize];
833     }
834     [self _setupRootForPrinting:NO];
835 }
836
837 - (void)sendResizeEvent
838 {
839     m_frame->sendResizeEvent();
840 }
841
842 - (void)sendScrollEvent
843 {
844     m_frame->sendScrollEvent();
845 }
846
847 - (void)drawRect:(NSRect)rect
848 {
849     GraphicsContext context([NSGraphicsContext currentContext]);
850     context.setUsesInactiveTextBackgroundColor(!m_frame->displaysWithFocusAttributes());
851     [self _setupRootForPrinting:YES];
852     m_frame->paint(&context, enclosingIntRect(rect));
853     [self _setupRootForPrinting:NO];
854 }
855
856 // Used by pagination code called from AppKit when a standalone web page is printed.
857 - (NSArray*)computePageRectsWithPrintWidthScaleFactor:(float)printWidthScaleFactor printHeight:(float)printHeight
858 {
859     [self _setupRootForPrinting:YES];
860     NSMutableArray* pages = [NSMutableArray arrayWithCapacity:5];
861     if (printWidthScaleFactor <= 0) {
862         LOG_ERROR("printWidthScaleFactor has bad value %.2f", printWidthScaleFactor);
863         return pages;
864     }
865     
866     if (printHeight <= 0) {
867         LOG_ERROR("printHeight has bad value %.2f", printHeight);
868         return pages;
869     }
870
871     if (!m_frame || !m_frame->document() || !m_frame->view()) return pages;
872     RenderCanvas* root = static_cast<RenderCanvas *>(m_frame->document()->renderer());
873     if (!root) return pages;
874     
875     FrameView* view = m_frame->view();
876     NSView* documentView = view->getDocumentView();
877     if (!documentView)
878         return pages;
879
880     float currPageHeight = printHeight;
881     float docHeight = root->layer()->height();
882     float docWidth = root->layer()->width();
883     float printWidth = docWidth/printWidthScaleFactor;
884     
885     // We need to give the part the opportunity to adjust the page height at each step.
886     for (float i = 0; i < docHeight; i += currPageHeight) {
887         float proposedBottom = min(docHeight, i + printHeight);
888         m_frame->adjustPageHeight(&proposedBottom, i, proposedBottom, i);
889         currPageHeight = max(1.0f, proposedBottom - i);
890         for (float j = 0; j < docWidth; j += printWidth) {
891             NSValue* val = [NSValue valueWithRect: NSMakeRect(j, i, printWidth, currPageHeight)];
892             [pages addObject: val];
893         }
894     }
895     [self _setupRootForPrinting:NO];
896     
897     return pages;
898 }
899
900 // This is to support the case where a webview is embedded in the view that's being printed
901 - (void)adjustPageHeightNew:(float *)newBottom top:(float)oldTop bottom:(float)oldBottom limit:(float)bottomLimit
902 {
903     [self _setupRootForPrinting:YES];
904     m_frame->adjustPageHeight(newBottom, oldTop, oldBottom, bottomLimit);
905     [self _setupRootForPrinting:NO];
906 }
907
908 - (NSObject *)copyRenderNode:(RenderObject *)node copier:(id <WebCoreRenderTreeCopier>)copier
909 {
910     NSMutableArray *children = [[NSMutableArray alloc] init];
911     for (RenderObject *child = node->firstChild(); child; child = child->nextSibling()) {
912         [children addObject:[self copyRenderNode:child copier:copier]];
913     }
914           
915     NSString *name = [[NSString alloc] initWithUTF8String:node->renderName()];
916     
917     RenderWidget *renderWidget = node->isWidget() ? static_cast<RenderWidget *>(node) : 0;
918     Widget *widget = renderWidget ? renderWidget->widget() : 0;
919     NSView *view = widget ? widget->getView() : nil;
920     
921     int nx, ny;
922     node->absolutePosition(nx, ny);
923     NSObject *copiedNode = [copier nodeWithName:name
924                                        position:NSMakePoint(nx,ny)
925                                            rect:NSMakeRect(node->xPos(), node->yPos(), node->width(), node->height())
926                                            view:view
927                                        children:children];
928     
929     [name release];
930     [children release];
931     
932     return copiedNode;
933 }
934
935 - (NSObject *)copyRenderTree:(id <WebCoreRenderTreeCopier>)copier
936 {
937     RenderObject *renderer = m_frame->renderer();
938     if (!renderer) {
939         return nil;
940     }
941     return [self copyRenderNode:renderer copier:copier];
942 }
943
944 - (void)removeFromFrame
945 {
946     if (m_frame)
947         m_frame->setView(0);
948 }
949
950 - (void)installInFrame:(NSView *)view
951 {
952     // If this isn't the main frame, it must have a render m_frame set, or it
953     // won't ever get installed in the view hierarchy.
954     ASSERT(self == [[self page] mainFrame] || m_frame->ownerRenderer());
955
956     m_frame->view()->setView(view);
957     // FIXME: frame tries to do this too, is it needed?
958     if (m_frame->ownerRenderer()) {
959         m_frame->ownerRenderer()->setWidget(m_frame->view());
960         // Now the render part owns the view, so we don't any more.
961     }
962
963     m_frame->view()->initScrollBars();
964 }
965
966 - (void)setActivationEventNumber:(int)num
967 {
968     m_frame->setActivationEventNumber(num);
969 }
970
971 - (void)mouseDown:(NSEvent *)event
972 {
973     m_frame->mouseDown(event);
974 }
975
976 - (void)mouseDragged:(NSEvent *)event
977 {
978     m_frame->mouseDragged(event);
979 }
980
981 - (void)mouseUp:(NSEvent *)event
982 {
983     m_frame->mouseUp(event);
984 }
985
986 - (void)mouseMoved:(NSEvent *)event
987 {
988     m_frame->mouseMoved(event);
989 }
990
991 - (BOOL)sendContextMenuEvent:(NSEvent *)event
992 {
993     return m_frame->sendContextMenuEvent(event);
994 }
995
996 - (DOMElement*)elementForView:(NSView*)view
997 {
998     // FIXME: implemented currently for only a subset of the KWQ widgets
999     if ([view conformsToProtocol:@protocol(WebCoreWidgetHolder)]) {
1000         NSView <WebCoreWidgetHolder>* widgetHolder = view;
1001         Widget* widget = [widgetHolder widget];
1002         if (widget && widget->client())
1003             return [DOMElement _elementWith:widget->client()->element(widget)];
1004     }
1005     return nil;
1006 }
1007
1008 static HTMLInputElement* inputElementFromDOMElement(DOMElement* element)
1009 {
1010     Node* node = [element _node];
1011     if (node->hasTagName(inputTag))
1012         return static_cast<HTMLInputElement*>(node);
1013     return nil;
1014 }
1015
1016 static HTMLFormElement *formElementFromDOMElement(DOMElement *element)
1017 {
1018     Node *node = [element _node];
1019     // This should not be necessary, but an XSL file on
1020     // maps.google.com crashes otherwise because it is an xslt file
1021     // that contains <form> elements that aren't in any namespace, so
1022     // they come out as generic CML elements
1023     if (node && node->hasTagName(formTag)) {
1024         return static_cast<HTMLFormElement *>(node);
1025     }
1026     return nil;
1027 }
1028
1029 - (DOMElement *)elementWithName:(NSString *)name inForm:(DOMElement *)form
1030 {
1031     HTMLFormElement *formElement = formElementFromDOMElement(form);
1032     if (formElement) {
1033         Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
1034         AtomicString targetName = name;
1035         for (unsigned int i = 0; i < elements.size(); i++) {
1036             HTMLGenericFormElement *elt = elements[i];
1037             // Skip option elements, other duds
1038             if (elt->name() == targetName)
1039                 return [DOMElement _elementWith:elt];
1040         }
1041     }
1042     return nil;
1043 }
1044
1045 - (BOOL)elementDoesAutoComplete:(DOMElement *)element
1046 {
1047     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1048     return inputElement != nil
1049         && inputElement->inputType() == HTMLInputElement::TEXT
1050         && inputElement->autoComplete();
1051 }
1052
1053 - (BOOL)elementIsPassword:(DOMElement *)element
1054 {
1055     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1056     return inputElement != nil
1057         && inputElement->inputType() == HTMLInputElement::PASSWORD;
1058 }
1059
1060 - (DOMElement *)formForElement:(DOMElement *)element;
1061 {
1062     HTMLInputElement *inputElement = inputElementFromDOMElement(element);
1063     if (inputElement) {
1064         HTMLFormElement *formElement = inputElement->form();
1065         if (formElement) {
1066             return [DOMElement _elementWith:formElement];
1067         }
1068     }
1069     return nil;
1070 }
1071
1072 - (DOMElement *)currentForm
1073 {
1074     return [DOMElement _elementWith:m_frame->currentForm()];
1075 }
1076
1077 - (NSArray *)controlsInForm:(DOMElement *)form
1078 {
1079     NSMutableArray *results = nil;
1080     HTMLFormElement *formElement = formElementFromDOMElement(form);
1081     if (formElement) {
1082         Vector<HTMLGenericFormElement*>& elements = formElement->formElements;
1083         for (unsigned int i = 0; i < elements.size(); i++) {
1084             if (elements.at(i)->isEnumeratable()) { // Skip option elements, other duds
1085                 DOMElement *de = [DOMElement _elementWith:elements.at(i)];
1086                 if (!results) {
1087                     results = [NSMutableArray arrayWithObject:de];
1088                 } else {
1089                     [results addObject:de];
1090                 }
1091             }
1092         }
1093     }
1094     return results;
1095 }
1096
1097 - (NSString *)searchForLabels:(NSArray *)labels beforeElement:(DOMElement *)element
1098 {
1099     return m_frame->searchForLabelsBeforeElement(labels, [element _element]);
1100 }
1101
1102 - (NSString *)matchLabels:(NSArray *)labels againstElement:(DOMElement *)element
1103 {
1104     return m_frame->matchLabelsAgainstElement(labels, [element _element]);
1105 }
1106
1107 - (void)getInnerNonSharedNode:(DOMNode **)innerNonSharedNode innerNode:(DOMNode **)innerNode URLElement:(DOMElement **)URLElement atPoint:(NSPoint)point allowShadowContent:(BOOL) allow
1108 {
1109     RenderObject *renderer = m_frame->renderer();
1110     if (!renderer) {
1111         *innerNonSharedNode = nil;
1112         *innerNode = nil;
1113         *URLElement = nil;
1114         return;
1115     }
1116
1117     RenderObject::NodeInfo nodeInfo = [self nodeInfoAtPoint:point allowShadowContent:allow];
1118     *innerNonSharedNode = [DOMNode _nodeWith:nodeInfo.innerNonSharedNode()];
1119     *innerNode = [DOMNode _nodeWith:nodeInfo.innerNode()];
1120     *URLElement = [DOMElement _elementWith:nodeInfo.URLElement()];
1121 }
1122
1123 - (BOOL)isPointInsideSelection:(NSPoint)point
1124 {
1125     return m_frame->isPointInsideSelection(IntPoint(point));
1126 }
1127
1128 - (NSURL *)URLWithAttributeString:(NSString *)string
1129 {
1130     Document *doc = m_frame->document();
1131     if (!doc)
1132         return nil;
1133     // FIXME: is parseURL appropriate here?
1134     DeprecatedString rel = parseURL(string).deprecatedString();
1135     return KURL(doc->completeURL(rel)).getNSURL();
1136 }
1137
1138 - (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag
1139 {
1140     return m_frame->findString(string, forward, caseFlag, wrapFlag);
1141 }
1142
1143 - (unsigned)highlightAllMatchesForString:(NSString *)string caseSensitive:(BOOL)caseFlag
1144 {
1145     return m_frame->highlightAllMatchesForString(string, caseFlag);
1146 }
1147
1148 - (void)clearHighlightedMatches
1149 {
1150     Document *doc = m_frame->document();
1151     if (!doc) {
1152         return;
1153     }
1154     doc->removeMarkers(DocumentMarker::TextMatch);
1155 }
1156
1157 - (NSString *)advanceToNextMisspelling
1158 {
1159     return m_frame->advanceToNextMisspelling();
1160 }
1161
1162 - (NSString *)advanceToNextMisspellingStartingJustBeforeSelection
1163 {
1164     return m_frame->advanceToNextMisspelling(true);
1165 }
1166
1167 - (void)unmarkAllMisspellings
1168 {
1169     Document *doc = m_frame->document();
1170     if (!doc) {
1171         return;
1172     }
1173     doc->removeMarkers(DocumentMarker::Spelling);
1174 }
1175
1176 - (void)setTextSizeMultiplier:(float)multiplier
1177 {
1178     int newZoomFactor = (int)rint(multiplier * 100);
1179     if (m_frame->zoomFactor() == newZoomFactor) {
1180         return;
1181     }
1182     m_frame->setZoomFactor(newZoomFactor);
1183 }
1184
1185 - (CFStringEncoding)textEncoding
1186 {
1187     return WebCore::TextEncoding(m_frame->encoding().latin1()).encodingID();
1188 }
1189
1190 - (NSView *)nextKeyView
1191 {
1192     Document *doc = m_frame->document();
1193     if (!doc)
1194         return nil;
1195     return m_frame->nextKeyView(doc->focusNode(), KWQSelectingNext);
1196 }
1197
1198 - (NSView *)previousKeyView
1199 {
1200     Document *doc = m_frame->document();
1201     if (!doc)
1202         return nil;
1203     return m_frame->nextKeyView(doc->focusNode(), KWQSelectingPrevious);
1204 }
1205
1206 - (NSView *)nextKeyViewInsideWebFrameViews
1207 {
1208     Document *doc = m_frame->document();
1209     if (!doc)
1210         return nil;
1211     return m_frame->nextKeyViewInFrameHierarchy(doc->focusNode(), KWQSelectingNext);
1212 }
1213
1214 - (NSView *)previousKeyViewInsideWebFrameViews
1215 {
1216     Document *doc = m_frame->document();
1217     if (!doc)
1218         return nil;
1219     return m_frame->nextKeyViewInFrameHierarchy(doc->focusNode(), KWQSelectingPrevious);
1220 }
1221
1222 - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string
1223 {
1224     return [self stringByEvaluatingJavaScriptFromString:string forceUserGesture:true];
1225 }
1226
1227 - (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture
1228 {
1229     m_frame->createEmptyDocument();
1230     JSValue* result = m_frame->executeScript(0, DeprecatedString::fromNSString(string), forceUserGesture);
1231     if (!result || !result->isString())
1232         return 0;
1233     JSLock lock;
1234     return String(result->getString());
1235 }
1236
1237 - (NSAppleEventDescriptor *)aeDescByEvaluatingJavaScriptFromString:(NSString *)string
1238 {
1239     m_frame->createEmptyDocument();
1240     JSValue* result = m_frame->executeScript(0, DeprecatedString::fromNSString(string), true);
1241     if (!result) // FIXME: pass errors
1242         return 0;
1243     JSLock lock;
1244     return aeDescFromJSValue(m_frame->jScript()->interpreter()->globalExec(), result);
1245 }
1246
1247 - (WebScriptObject *)windowScriptObject
1248 {
1249     return m_frame->windowScriptObject();
1250 }
1251
1252 - (NPObject *)windowScriptNPObject
1253 {
1254     return m_frame->windowScriptNPObject();
1255 }
1256
1257 - (DOMDocument *)DOMDocument
1258 {
1259     return [DOMDocument _documentWith:m_frame->document()];
1260 }
1261
1262 - (DOMHTMLElement *)frameElement
1263 {
1264     // Not [[self DOMDocument] _ownerElement], since our doc is not set up at the start of our own load.
1265     // FIXME: There really is no guarantee this is an HTML element.
1266     // For example, it could be something like an SVG foreign object element.
1267     // Because of that, I believe the cast here is wrong and also the public API
1268     // of WebKit might have to be changed.
1269     return (DOMHTMLElement *)[DOMElement _elementWith:m_frame->ownerElement()];
1270 }
1271
1272 - (NSAttributedString *)selectedAttributedString
1273 {
1274     // FIXME: should be a no-arg version of attributedString() that does this
1275     return m_frame->attributedString(m_frame->selection().start().node(), m_frame->selection().start().offset(), m_frame->selection().end().node(), m_frame->selection().end().offset());
1276 }
1277
1278 - (NSAttributedString *)attributedStringFrom:(DOMNode *)start startOffset:(int)startOffset to:(DOMNode *)end endOffset:(int)endOffset
1279 {
1280     return m_frame->attributedString([start _node], startOffset, [end _node], endOffset);
1281 }
1282
1283 - (NSRect)selectionRect
1284 {
1285     return m_frame->selectionRect(); 
1286 }
1287
1288 - (NSRect)visibleSelectionRect
1289 {
1290     return m_frame->visibleSelectionRect(); 
1291 }
1292
1293 - (void)centerSelectionInVisibleArea
1294 {
1295     m_frame->centerSelectionInVisibleArea(); 
1296 }
1297
1298 - (NSRect)caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity
1299 {
1300     return [node _node]->renderer()->caretRect(offset, static_cast<EAffinity>(affinity));
1301 }
1302 - (NSRect)firstRectForDOMRange:(DOMRange *)range
1303 {
1304     int extraWidthToEndOfLine = 0;
1305     IntRect startCaretRect = [[range startContainer] _node]->renderer()->caretRect([range startOffset], DOWNSTREAM, &extraWidthToEndOfLine);
1306     IntRect endCaretRect = [[range endContainer] _node]->renderer()->caretRect([range endOffset], UPSTREAM);
1307
1308     if (startCaretRect.y() == endCaretRect.y()) {
1309         // start and end are on the same line
1310         return IntRect(MIN(startCaretRect.x(), endCaretRect.x()), 
1311                      startCaretRect.y(), 
1312                      abs(endCaretRect.x() - startCaretRect.x()),
1313                      MAX(startCaretRect.height(), endCaretRect.height()));
1314     }
1315
1316     // start and end aren't on the same line, so go from start to the end of its line
1317     return IntRect(startCaretRect.x(), 
1318                  startCaretRect.y(),
1319                  startCaretRect.width() + extraWidthToEndOfLine,
1320                  startCaretRect.height());
1321 }
1322
1323 - (NSImage *)selectionImage
1324 {
1325     return m_frame->selectionImage();
1326 }
1327
1328 - (void)setName:(NSString *)name
1329 {
1330     m_frame->tree()->setName(name);
1331 }
1332
1333 - (NSString *)name
1334 {
1335     return m_frame->tree()->name();
1336 }
1337
1338 - (NSURL *)URL
1339 {
1340     return m_frame->url().getNSURL();
1341 }
1342
1343 - (NSURL *)baseURL
1344 {
1345     return m_frame->completeURL(m_frame->document()->baseURL()).getNSURL();
1346 }
1347
1348 - (NSString *)referrer
1349 {
1350     return m_frame->referrer().getNSString();
1351 }
1352
1353 - (WebCoreFrameBridge *)opener
1354 {
1355     Frame *openerPart = m_frame->opener();
1356
1357     if (openerPart)
1358         return Mac(openerPart)->bridge();
1359
1360     return nil;
1361 }
1362
1363 - (void)setOpener:(WebCoreFrameBridge *)bridge;
1364 {
1365     Frame *p = [bridge impl];
1366     
1367     if (p)
1368         p->setOpener(m_frame);
1369 }
1370
1371 + (NSString *)stringWithData:(NSData *)data textEncoding:(CFStringEncoding)textEncoding
1372 {
1373     if (textEncoding == kCFStringEncodingInvalidId)
1374         textEncoding = kCFStringEncodingWindowsLatin1;
1375
1376     return WebCore::TextEncoding(textEncoding).toUnicode((const char*)[data bytes], [data length]).getNSString();
1377 }
1378
1379 + (NSString *)stringWithData:(NSData *)data textEncodingName:(NSString *)textEncodingName
1380 {
1381     CFStringEncoding textEncoding = WebCore::TextEncoding([textEncodingName lossyCString]).encodingID();
1382     return [WebCoreFrameBridge stringWithData:data textEncoding:textEncoding];
1383 }
1384
1385 - (BOOL)needsLayout
1386 {
1387     RenderObject *renderer = m_frame->renderer();
1388     return renderer ? renderer->needsLayout() : false;
1389 }
1390
1391 - (void)setNeedsLayout
1392 {
1393     RenderObject *renderer = m_frame->renderer();
1394     if (renderer)
1395         renderer->setNeedsLayout(true);
1396 }
1397
1398 - (BOOL)interceptKeyEvent:(NSEvent *)event toView:(NSView *)view
1399 {
1400     return m_frame->keyEvent(event);
1401 }
1402
1403 - (NSString *)renderTreeAsExternalRepresentation
1404 {
1405     return externalRepresentation(m_frame->renderer()).getNSString();
1406 }
1407
1408 - (void)setSelectionFromNone
1409 {
1410     m_frame->setSelectionFromNone();
1411 }
1412
1413 - (void)setDisplaysWithFocusAttributes:(BOOL)flag
1414 {
1415     m_frame->setDisplaysWithFocusAttributes(flag);
1416 }
1417
1418 - (void)setWindowHasFocus:(BOOL)flag
1419 {
1420     m_frame->setWindowHasFocus(flag);
1421 }
1422
1423 - (void)setShouldCreateRenderers:(BOOL)f
1424 {
1425     _shouldCreateRenderers = f;
1426 }
1427
1428 - (BOOL)shouldCreateRenderers
1429 {
1430     return _shouldCreateRenderers;
1431 }
1432
1433 - (int)numPendingOrLoadingRequests
1434 {
1435     Document *doc = m_frame->document();
1436     
1437     if (doc)
1438         return KWQNumberOfPendingOrLoadingRequests (doc->docLoader());
1439     return 0;
1440 }
1441
1442 - (BOOL)doneProcessingData
1443 {
1444     Document *doc = m_frame->document();
1445     if (doc) {
1446         Tokenizer* tok = doc->tokenizer();
1447         if (tok)
1448             return !tok->processingData();
1449     }
1450     return YES;
1451 }
1452
1453 - (BOOL)shouldClose
1454 {
1455     return m_frame->shouldClose();
1456 }
1457
1458 - (NSColor *)bodyBackgroundColor
1459 {
1460     return m_frame->bodyBackgroundColor();
1461 }
1462
1463 - (NSColor *)selectionColor
1464 {
1465     RenderCanvas* root = static_cast<RenderCanvas *>(m_frame->document()->renderer());
1466     if (root) {
1467         RenderStyle *pseudoStyle = root->getPseudoStyle(RenderStyle::SELECTION);
1468         if (pseudoStyle && pseudoStyle->backgroundColor().isValid()) {
1469             return nsColor(pseudoStyle->backgroundColor());
1470         }
1471     }
1472     return m_frame->displaysWithFocusAttributes() ? [NSColor selectedTextBackgroundColor] : [NSColor secondarySelectedControlColor];
1473 }
1474
1475 - (void)adjustViewSize
1476 {
1477     FrameView *view = m_frame->view();
1478     if (view)
1479         view->adjustViewSize();
1480 }
1481
1482 - (id)accessibilityTree
1483 {
1484     AccessibilityObjectCache::enableAccessibility();
1485     if (!m_frame || !m_frame->document())
1486         return nil;
1487     RenderCanvas* root = static_cast<RenderCanvas *>(m_frame->document()->renderer());
1488     if (!root)
1489         return nil;
1490     return m_frame->document()->getAccObjectCache()->get(root);
1491 }
1492
1493 - (void)setDrawsBackground:(BOOL)drawsBackground
1494 {
1495     if (m_frame && m_frame->view())
1496         m_frame->view()->setTransparent(!drawsBackground);
1497 }
1498
1499 - (void)undoEditing:(id)arg
1500 {
1501     ASSERT([arg isKindOfClass:[KWQEditCommand class]]);
1502     [arg command]->unapply();
1503 }
1504
1505 - (void)redoEditing:(id)arg
1506 {
1507     ASSERT([arg isKindOfClass:[KWQEditCommand class]]);
1508     [arg command]->reapply();
1509 }
1510
1511 - (DOMRange *)rangeByExpandingSelectionWithGranularity:(WebBridgeSelectionGranularity)granularity
1512 {
1513     if (!m_frame->hasSelection())
1514         return nil;
1515         
1516     // NOTE: The enums *must* match the very similar ones declared in SelectionController.h
1517     SelectionController selection(m_frame->selection());
1518     selection.expandUsingGranularity(static_cast<TextGranularity>(granularity));
1519     return [DOMRange _rangeWith:selection.toRange().get()];
1520 }
1521
1522 - (DOMRange *)rangeByAlteringCurrentSelection:(WebSelectionAlteration)alteration direction:(WebBridgeSelectionDirection)direction granularity:(WebBridgeSelectionGranularity)granularity
1523 {
1524     if (!m_frame->hasSelection())
1525         return nil;
1526         
1527     // NOTE: The enums *must* match the very similar ones declared in SelectionController.h
1528     SelectionController selection(m_frame->selection());
1529     selection.modify(static_cast<SelectionController::EAlter>(alteration), 
1530                      static_cast<SelectionController::EDirection>(direction), 
1531                      static_cast<TextGranularity>(granularity));
1532     return [DOMRange _rangeWith:selection.toRange().get()];
1533 }
1534
1535 - (void)alterCurrentSelection:(WebSelectionAlteration)alteration direction:(WebBridgeSelectionDirection)direction granularity:(WebBridgeSelectionGranularity)granularity
1536 {
1537     if (!m_frame->hasSelection())
1538         return;
1539         
1540     // NOTE: The enums *must* match the very similar ones declared in SelectionController.h
1541     SelectionController selection(m_frame->selection());
1542     selection.modify(static_cast<SelectionController::EAlter>(alteration), 
1543                      static_cast<SelectionController::EDirection>(direction), 
1544                      static_cast<TextGranularity>(granularity));
1545
1546     // save vertical navigation x position if necessary; many types of motion blow it away
1547     int xPos = Frame::NoXPosForVerticalArrowNavigation;
1548     switch (granularity) {
1549         case WebBridgeSelectByLine:
1550         case WebBridgeSelectByParagraph:
1551             xPos = m_frame->xPosForVerticalArrowNavigation();
1552             break;
1553         case WebBridgeSelectByCharacter:
1554         case WebBridgeSelectByWord:
1555         case WebBridgeSelectBySentence:
1556         case WebBridgeSelectToLineBoundary:
1557         case WebBridgeSelectToParagraphBoundary:
1558         case WebBridgeSelectToSentenceBoundary:
1559         case WebBridgeSelectToDocumentBoundary:
1560             break;
1561     }
1562
1563     
1564     // setting the selection always clears saved vertical navigation x position
1565     m_frame->setSelection(selection);
1566     
1567     // altering the selection also sets the granularity back to character
1568     // NOTE: The one exception is that we need to keep word granularity
1569     // to preserve smart delete behavior when extending by word.  e.g. double-click,
1570     // then shift-option-rightarrow, then delete needs to smart delete, per TextEdit.
1571     if (!((alteration == WebSelectByExtending) &&
1572           (granularity == WebBridgeSelectByWord) && (m_frame->selectionGranularity() == WordGranularity)))
1573         m_frame->setSelectionGranularity(static_cast<TextGranularity>(WebBridgeSelectByCharacter));
1574     
1575     // restore vertical navigation x position if necessary
1576     if (xPos != Frame::NoXPosForVerticalArrowNavigation)
1577         m_frame->setXPosForVerticalArrowNavigation(xPos);
1578
1579     m_frame->selectFrameElementInParentIfFullySelected();
1580
1581     [self ensureSelectionVisible];
1582 }
1583
1584 - (DOMRange *)rangeByAlteringCurrentSelection:(WebSelectionAlteration)alteration verticalDistance:(float)verticalDistance
1585 {
1586     if (!m_frame->hasSelection())
1587         return nil;
1588         
1589     SelectionController selection(m_frame->selection());
1590     selection.modify(static_cast<SelectionController::EAlter>(alteration), static_cast<int>(verticalDistance));
1591     return [DOMRange _rangeWith:selection.toRange().get()];
1592 }
1593
1594 - (void)alterCurrentSelection:(WebSelectionAlteration)alteration verticalDistance:(float)verticalDistance
1595 {
1596     if (!m_frame->hasSelection())
1597         return;
1598         
1599     SelectionController selection(m_frame->selection());
1600     selection.modify(static_cast<SelectionController::EAlter>(alteration), static_cast<int>(verticalDistance));
1601
1602     // setting the selection always clears saved vertical navigation x position, so preserve it
1603     int xPos = m_frame->xPosForVerticalArrowNavigation();
1604     m_frame->setSelection(selection);
1605     m_frame->setSelectionGranularity(static_cast<TextGranularity>(WebBridgeSelectByCharacter));
1606     m_frame->setXPosForVerticalArrowNavigation(xPos);
1607
1608     m_frame->selectFrameElementInParentIfFullySelected();
1609
1610     [self ensureSelectionVisible];
1611 }
1612
1613 - (WebBridgeSelectionGranularity)selectionGranularity
1614 {
1615     // NOTE: The enums *must* match the very similar ones declared in SelectionController.h
1616     return static_cast<WebBridgeSelectionGranularity>(m_frame->selectionGranularity());
1617 }
1618
1619 - (void)setSelectedDOMRange:(DOMRange *)range affinity:(NSSelectionAffinity)selectionAffinity closeTyping:(BOOL)closeTyping
1620 {
1621     Node *startContainer = [[range startContainer] _node];
1622     Node *endContainer = [[range endContainer] _node];
1623     ASSERT(startContainer);
1624     ASSERT(endContainer);
1625     ASSERT(startContainer->document() == endContainer->document());
1626     
1627     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1628
1629     EAffinity affinity = static_cast<EAffinity>(selectionAffinity);
1630     
1631     // Non-collapsed ranges are not allowed to start at the end of a line that is wrapped,
1632     // they start at the beginning of the next line instead
1633     if (![range collapsed])
1634         affinity = DOWNSTREAM;
1635     
1636     // FIXME: Can we provide extentAffinity?
1637     VisiblePosition visibleStart(startContainer, [range startOffset], affinity);
1638     VisiblePosition visibleEnd(endContainer, [range endOffset], SEL_DEFAULT_AFFINITY);
1639     SelectionController selection(visibleStart, visibleEnd);
1640     m_frame->setSelection(selection, closeTyping);
1641 }
1642
1643 - (DOMRange *)selectedDOMRange
1644 {
1645     return [DOMRange _rangeWith:m_frame->selection().toRange().get()];
1646 }
1647
1648 - (NSRange)convertToNSRange:(Range *)range
1649 {
1650     if (!range || range->isDetached()) {
1651         return NSMakeRange(NSNotFound, 0);
1652     }
1653
1654     RefPtr<Range> fromStartRange(m_frame->document()->createRange());
1655     int exception = 0;
1656
1657     fromStartRange->setEnd(range->startContainer(exception), range->startOffset(exception), exception);
1658     int startPosition = TextIterator::rangeLength(fromStartRange.get());
1659
1660     fromStartRange->setEnd(range->endContainer(exception), range->endOffset(exception), exception);
1661     int endPosition = TextIterator::rangeLength(fromStartRange.get());
1662
1663     return NSMakeRange(startPosition, endPosition - startPosition);
1664 }
1665
1666 - (PassRefPtr<Range>)convertToDOMRange:(NSRange)nsrange
1667 {
1668     if (nsrange.location > INT_MAX)
1669         return 0;
1670     if (nsrange.length > INT_MAX || nsrange.location + nsrange.length > INT_MAX)
1671         nsrange.length = INT_MAX - nsrange.location;
1672
1673     return TextIterator::rangeFromLocationAndLength(m_frame->document(), nsrange.location, nsrange.length);
1674 }
1675
1676 - (DOMRange *)convertNSRangeToDOMRange:(NSRange)nsrange
1677 {
1678     return [DOMRange _rangeWith:[self convertToDOMRange:nsrange].get()];
1679 }
1680
1681 - (NSRange)convertDOMRangeToNSRange:(DOMRange *)range
1682 {
1683     return [self convertToNSRange:[range _range]];
1684 }
1685
1686 - (void)selectNSRange:(NSRange)range
1687 {
1688     m_frame->setSelection(SelectionController([self convertToDOMRange:range].get(), SEL_DEFAULT_AFFINITY));
1689 }
1690
1691 - (NSRange)selectedNSRange
1692 {
1693     return [self convertToNSRange:m_frame->selection().toRange().get()];
1694 }
1695
1696 - (NSSelectionAffinity)selectionAffinity
1697 {
1698     return static_cast<NSSelectionAffinity>(m_frame->selection().affinity());
1699 }
1700
1701 - (void)setMarkDOMRange:(DOMRange *)range
1702 {
1703     Range* r = [range _range];
1704     m_frame->setMark(Selection(startPosition(r), endPosition(r), SEL_DEFAULT_AFFINITY));
1705 }
1706
1707 - (DOMRange *)markDOMRange
1708 {
1709     return [DOMRange _rangeWith:m_frame->mark().toRange().get()];
1710 }
1711
1712 - (void)setMarkedTextDOMRange:(DOMRange *)range customAttributes:(NSArray *)attributes ranges:(NSArray *)ranges
1713 {
1714     m_frame->setMarkedTextRange([range _range], attributes, ranges);
1715 }
1716
1717 - (DOMRange *)markedTextDOMRange
1718 {
1719     return [DOMRange _rangeWith:m_frame->markedTextRange()];
1720 }
1721
1722 - (NSRange)markedTextNSRange
1723 {
1724     return [self convertToNSRange:m_frame->markedTextRange()];
1725 }
1726
1727 - (void)replaceMarkedTextWithText:(NSString *)text
1728 {
1729     if (!m_frame->hasSelection())
1730         return;
1731     
1732     int exception = 0;
1733
1734     Range *markedTextRange = m_frame->markedTextRange();
1735     if (markedTextRange && !markedTextRange->collapsed(exception))
1736         TypingCommand::deleteKeyPressed(m_frame->document(), NO);
1737     
1738     if ([text length] > 0)
1739         TypingCommand::insertText(m_frame->document(), text, YES);
1740     
1741     [self ensureSelectionVisible];
1742 }
1743
1744 - (BOOL)canDeleteRange:(DOMRange *)range
1745 {
1746     Node *startContainer = [[range startContainer] _node];
1747     Node *endContainer = [[range endContainer] _node];
1748     if (startContainer == nil || endContainer == nil)
1749         return NO;
1750     
1751     if (!startContainer->isContentEditable() || !endContainer->isContentEditable())
1752         return NO;
1753     
1754     if ([range collapsed]) {
1755         VisiblePosition start(startContainer, [range startOffset], DOWNSTREAM);
1756         if (isStartOfEditableContent(start))
1757             return NO;
1758     }
1759     
1760     return YES;
1761 }
1762
1763 // Given proposedRange, returns an extended range that includes adjacent whitespace that should
1764 // be deleted along with the proposed range in order to preserve proper spacing and punctuation of
1765 // the text surrounding the deletion.
1766 - (DOMRange *)smartDeleteRangeForProposedRange:(DOMRange *)proposedRange
1767 {
1768     Node *startContainer = [[proposedRange startContainer] _node];
1769     Node *endContainer = [[proposedRange endContainer] _node];
1770     if (startContainer == nil || endContainer == nil)
1771         return nil;
1772
1773     ASSERT(startContainer->document() == endContainer->document());
1774     
1775     m_frame->document()->updateLayoutIgnorePendingStylesheets();
1776
1777     Position start(startContainer, [proposedRange startOffset]);
1778     Position end(endContainer, [proposedRange endOffset]);
1779     Position newStart = start.upstream().leadingWhitespacePosition(DOWNSTREAM, true);
1780     if (newStart.isNull())
1781         newStart = start;
1782     Position newEnd = end.downstream().trailingWhitespacePosition(DOWNSTREAM, true);
1783     if (newEnd.isNull())
1784         newEnd = end;
1785
1786     RefPtr<Range> range = m_frame->document()->createRange();
1787     int exception = 0;
1788     range->setStart(newStart.node(), newStart.offset(), exception);
1789     range->setEnd(newStart.node(), newStart.offset(), exception);
1790     return [DOMRange _rangeWith:range.get()];
1791 }
1792
1793 // Determines whether whitespace needs to be added around aString to preserve proper spacing and
1794 // punctuation when itÕs inserted into the receiverÕs text over charRange. Returns by reference
1795 // in beforeString and afterString any whitespace that should be added, unless either or both are
1796 // nil. Both are returned as nil if aString is nil or if smart insertion and deletion are disabled.
1797 - (void)smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString
1798 {
1799     // give back nil pointers in case of early returns
1800     if (beforeString)
1801         *beforeString = nil;
1802     if (afterString)
1803         *afterString = nil;
1804         
1805     // inspect destination
1806     Node *startContainer = [[rangeToReplace startContainer] _node];
1807     Node *endContainer = [[rangeToReplace endContainer] _node];
1808
1809     Position startPos(startContainer, [rangeToReplace startOffset]);
1810     Position endPos(endContainer, [rangeToReplace endOffset]);
1811
1812     VisiblePosition startVisiblePos = VisiblePosition(startPos, VP_DEFAULT_AFFINITY);
1813     VisiblePosition endVisiblePos = VisiblePosition(endPos, VP_DEFAULT_AFFINITY);
1814     
1815     // this check also ensures startContainer, startPos, endContainer, and endPos are non-null
1816     if (startVisiblePos.isNull() || endVisiblePos.isNull())
1817         return;
1818
1819     bool addLeadingSpace = startPos.leadingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isStartOfParagraph(startVisiblePos);
1820     if (addLeadingSpace) {
1821         QChar previousChar = startVisiblePos.previous().character();
1822         if (!previousChar.isNull()) {
1823             addLeadingSpace = !m_frame->isCharacterSmartReplaceExempt(previousChar, true);
1824         }
1825     }
1826     
1827     bool addTrailingSpace = endPos.trailingWhitespacePosition(VP_DEFAULT_AFFINITY, true).isNull() && !isEndOfParagraph(endVisiblePos);
1828     if (addTrailingSpace) {
1829         QChar thisChar = endVisiblePos.character();
1830         if (!thisChar.isNull()) {
1831             addTrailingSpace = !m_frame->isCharacterSmartReplaceExempt(thisChar, false);
1832         }
1833     }
1834     
1835     // inspect source
1836     bool hasWhitespaceAtStart = false;
1837     bool hasWhitespaceAtEnd = false;
1838     unsigned pasteLength = [pasteString length];
1839     if (pasteLength > 0) {
1840         NSCharacterSet *whiteSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
1841         
1842         if ([whiteSet characterIsMember:[pasteString characterAtIndex:0]]) {
1843             hasWhitespaceAtStart = YES;
1844         }
1845         if ([whiteSet characterIsMember:[pasteString characterAtIndex:(pasteLength - 1)]]) {
1846             hasWhitespaceAtEnd = YES;
1847         }
1848     }
1849     
1850     // issue the verdict
1851     if (beforeString && addLeadingSpace && !hasWhitespaceAtStart)
1852         *beforeString = @" ";
1853     if (afterString && addTrailingSpace && !hasWhitespaceAtEnd)
1854         *afterString = @" ";
1855 }
1856
1857 - (DOMDocumentFragment *)documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString 
1858 {
1859     if (!m_frame || !m_frame->document())
1860         return 0;
1861
1862     return [DOMDocumentFragment _documentFragmentWith:createFragmentFromMarkup(m_frame->document(),
1863         DeprecatedString::fromNSString(markupString), DeprecatedString::fromNSString(baseURLString)).get()];
1864 }
1865
1866 - (DOMDocumentFragment *)documentFragmentWithText:(NSString *)text
1867 {
1868     if (!m_frame || !m_frame->document() || !text)
1869         return 0;
1870     
1871     return [DOMDocumentFragment _documentFragmentWith:createFragmentFromText(m_frame->document(), DeprecatedString::fromNSString(text)).get()];
1872 }
1873
1874 - (DOMDocumentFragment *)documentFragmentWithNodesAsParagraphs:(NSArray *)nodes
1875 {
1876     NSEnumerator *nodeEnum = [nodes objectEnumerator];
1877     DOMNode *node;
1878     DeprecatedPtrList<Node> nodeList;
1879     
1880     if (!m_frame || !m_frame->document())
1881         return 0;
1882     
1883     while ((node = [nodeEnum nextObject])) {
1884         nodeList.append([node _node]);
1885     }
1886     
1887     return [DOMDocumentFragment _documentFragmentWith:createFragmentFromNodeList(m_frame->document(), nodeList).get()];
1888 }
1889
1890 - (void)replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
1891 {
1892     if (!m_frame->hasSelection() || !fragment)
1893         return;
1894     
1895     EditCommandPtr(new ReplaceSelectionCommand(m_frame->document(), [fragment _fragment], selectReplacement, smartReplace, matchStyle)).apply();
1896     [self ensureSelectionVisible];
1897 }
1898
1899 - (void)replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
1900 {
1901     DOMDocumentFragment *fragment = [[self DOMDocument] createDocumentFragment];
1902     [fragment appendChild:node];
1903     [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO];
1904 }
1905
1906 - (void)replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
1907 {
1908     DOMDocumentFragment *fragment = [self documentFragmentWithMarkupString:markupString baseURLString:baseURLString];
1909     [self replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO];
1910 }
1911
1912 - (void)replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
1913 {
1914     [self replaceSelectionWithFragment:[self documentFragmentWithText:text] selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:YES];
1915 }
1916
1917 - (bool)canIncreaseSelectionListLevel
1918 {
1919     return ModifySelectionListLevelCommand::canIncreaseSelectionListLevel(m_frame->document());
1920 }
1921
1922 - (bool)canDecreaseSelectionListLevel
1923 {
1924     return ModifySelectionListLevelCommand::canDecreaseSelectionListLevel(m_frame->document());
1925 }
1926
1927 - (void)increaseSelectionListLevel
1928 {
1929     if (!m_frame->hasSelection())
1930         return;
1931     
1932     ModifySelectionListLevelCommand::increaseSelectionListLevel(m_frame->document());
1933     [self ensureSelectionVisible];
1934 }
1935
1936 - (void)decreaseSelectionListLevel
1937 {
1938     if (!m_frame->hasSelection())
1939         return;
1940     
1941     ModifySelectionListLevelCommand::decreaseSelectionListLevel(m_frame->document());
1942     [self ensureSelectionVisible];
1943 }
1944
1945 - (void)insertLineBreak
1946 {
1947     if (!m_frame->hasSelection())
1948         return;
1949     
1950     TypingCommand::insertLineBreak(m_frame->document());
1951     [self ensureSelectionVisible];
1952 }
1953
1954 - (void)insertParagraphSeparator
1955 {
1956     if (!m_frame->hasSelection())
1957         return;
1958     
1959     TypingCommand::insertParagraphSeparator(m_frame->document());
1960     [self ensureSelectionVisible];
1961 }
1962
1963 - (void)insertParagraphSeparatorInQuotedContent
1964 {
1965     if (!m_frame->hasSelection())
1966         return;
1967     
1968     TypingCommand::insertParagraphSeparatorInQuotedContent(m_frame->document());
1969     [self ensureSelectionVisible];
1970 }
1971
1972 - (void)insertText:(NSString *)text selectInsertedText:(BOOL)selectInsertedText
1973 {
1974     if (!m_frame->hasSelection())
1975         return;
1976     
1977     TypingCommand::insertText(m_frame->document(), text, selectInsertedText);
1978     [self ensureSelectionVisible];
1979 }
1980
1981 - (void)setSelectionToDragCaret
1982 {
1983     m_frame->setSelection(m_frame->dragCaret());
1984 }
1985
1986 - (void)moveSelectionToDragCaret:(DOMDocumentFragment *)selectionFragment smartMove:(BOOL)smartMove
1987 {
1988     Position base = m_frame->dragCaret().base();
1989     EditCommandPtr(new MoveSelectionCommand(m_frame->document(), [selectionFragment _fragment], base, smartMove)).apply();
1990 }
1991
1992 - (VisiblePosition)_visiblePositionForPoint:(NSPoint)point
1993 {
1994     RenderObject *renderer = m_frame->renderer();
1995     if (!renderer) {
1996         return VisiblePosition();
1997     }
1998     
1999     RenderObject::NodeInfo nodeInfo = [self nodeInfoAtPoint:point allowShadowContent:YES];
2000     
2001     Node *node = nodeInfo.innerNode();
2002     if (!node || !node->renderer())
2003         return VisiblePosition();
2004     
2005     return node->renderer()->positionForCoordinates((int)point.x, (int)point.y);
2006 }
2007
2008 - (void)moveDragCaretToPoint:(NSPoint)point
2009 {   
2010     SelectionController dragCaret([self _visiblePositionForPoint:point]);
2011     m_frame->setDragCaret(dragCaret);
2012 }
2013
2014 - (void)removeDragCaret
2015 {
2016     m_frame->setDragCaret(SelectionController());
2017 }
2018
2019 - (DOMRange *)dragCaretDOMRange
2020 {
2021     return [DOMRange _rangeWith:m_frame->dragCaret().toRange().get()];
2022 }
2023
2024 - (BOOL)isDragCaretRichlyEditable
2025 {
2026     return m_frame->dragCaret().isContentRichlyEditable();
2027 }
2028
2029 - (DOMRange *)editableDOMRangeForPoint:(NSPoint)point
2030 {
2031     VisiblePosition position = [self _visiblePositionForPoint:point];
2032     return position.isNull() ? nil : [DOMRange _rangeWith:SelectionController(position).toRange().get()];
2033 }
2034
2035 - (DOMRange *)characterRangeAtPoint:(NSPoint)point
2036 {
2037     VisiblePosition position = [self _visiblePositionForPoint:point];
2038     if (position.isNull())
2039         return nil;
2040     
2041     VisiblePosition previous = position.previous();
2042     if (previous.isNotNull()) {
2043         DOMRange *previousCharacterRange = [DOMRange _rangeWith:makeRange(previous, position).get()];
2044         NSRect rect = [self firstRectForDOMRange:previousCharacterRange];
2045         if (NSPointInRect(point, rect))
2046             return previousCharacterRange;
2047     }
2048
2049     VisiblePosition next = position.next();
2050     if (next.isNotNull()) {
2051         DOMRange *nextCharacterRange = [DOMRange _rangeWith:makeRange(position, next).get()];
2052         NSRect rect = [self firstRectForDOMRange:nextCharacterRange];
2053         if (NSPointInRect(point, rect))
2054             return nextCharacterRange;
2055     }
2056     
2057     return nil;
2058 }
2059
2060 - (void)deleteSelectionWithSmartDelete:(BOOL)smartDelete
2061 {
2062     if (!m_frame->hasSelection())
2063         return;
2064     
2065     EditCommandPtr(new DeleteSelectionCommand(m_frame->document(), smartDelete)).apply();
2066 }
2067
2068 - (void)deleteKeyPressedWithSmartDelete:(BOOL)smartDelete
2069 {
2070     if (!m_frame || !m_frame->document())
2071         return;
2072     
2073     TypingCommand::deleteKeyPressed(m_frame->document(), smartDelete);
2074     [self ensureSelectionVisible];
2075 }
2076
2077 - (void)forwardDeleteKeyPressedWithSmartDelete:(BOOL)smartDelete
2078 {
2079     if (!m_frame || !m_frame->document())
2080         return;
2081     
2082     TypingCommand::forwardDeleteKeyPressed(m_frame->document(), smartDelete);
2083     [self ensureSelectionVisible];
2084 }
2085
2086 - (DOMCSSStyleDeclaration *)typingStyle
2087 {
2088     if (!m_frame || !m_frame->typingStyle())
2089         return nil;
2090     return [DOMCSSStyleDeclaration _styleDeclarationWith:m_frame->typingStyle()->copy().get()];
2091 }
2092
2093 - (void)setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(WebUndoAction)undoAction
2094 {
2095     if (!m_frame)
2096         return;
2097     m_frame->computeAndSetTypingStyle([style _styleDeclaration], static_cast<EditAction>(undoAction));
2098 }
2099
2100 - (void)applyStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(WebUndoAction)undoAction
2101 {
2102     if (!m_frame)
2103         return;
2104     m_frame->applyStyle([style _styleDeclaration], static_cast<EditAction>(undoAction));
2105 }
2106
2107 - (void)applyParagraphStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(WebUndoAction)undoAction
2108 {
2109     if (!m_frame)
2110         return;
2111     m_frame->applyParagraphStyle([style _styleDeclaration], static_cast<EditAction>(undoAction));
2112 }
2113
2114 - (BOOL)selectionStartHasStyle:(DOMCSSStyleDeclaration *)style
2115 {
2116     if (!m_frame)
2117         return NO;
2118     return m_frame->selectionStartHasStyle([style _styleDeclaration]);
2119 }
2120
2121 - (NSCellStateValue)selectionHasStyle:(DOMCSSStyleDeclaration *)style
2122 {
2123     if (!m_frame)
2124         return NSOffState;
2125     switch (m_frame->selectionHasStyle([style _styleDeclaration])) {
2126         case Frame::falseTriState:
2127             return NSOffState;
2128         case Frame::trueTriState:
2129             return NSOnState;
2130         case Frame::mixedTriState:
2131             return NSMixedState;
2132     }
2133     return NSOffState;
2134 }
2135
2136 - (void)applyEditingStyleToBodyElement
2137 {
2138     if (!m_frame)
2139         return;
2140     m_frame->applyEditingStyleToBodyElement();
2141 }
2142
2143 - (void)removeEditingStyleFromBodyElement
2144 {
2145     if (!m_frame)
2146         return;
2147     m_frame->removeEditingStyleFromBodyElement();
2148 }
2149
2150 - (void)applyEditingStyleToElement:(DOMElement *)element
2151 {
2152     if (!m_frame)
2153         return;
2154     m_frame->applyEditingStyleToElement([element _element]);
2155 }
2156
2157 - (void)removeEditingStyleFromElement:(DOMElement *)element
2158 {
2159     if (!m_frame)
2160         return;
2161     m_frame->removeEditingStyleFromElement([element _element]);
2162 }
2163
2164 - (NSFont *)fontForSelection:(BOOL *)hasMultipleFonts
2165 {
2166     bool multipleFonts = false;
2167     NSFont *font = nil;
2168     if (m_frame)
2169         font = m_frame->fontForSelection(hasMultipleFonts ? &multipleFonts : 0);
2170     if (hasMultipleFonts)
2171         *hasMultipleFonts = multipleFonts;
2172     return font;
2173 }
2174
2175 - (NSDictionary *)fontAttributesForSelectionStart
2176 {
2177     return m_frame ? m_frame->fontAttributesForSelectionStart() : nil;
2178 }
2179
2180 - (NSWritingDirection)baseWritingDirectionForSelectionStart
2181 {
2182     // FIXME: remove this NSWritingDirection cast once <rdar://problem/4509035> is fixed
2183     return m_frame ? m_frame->baseWritingDirectionForSelectionStart() : (NSWritingDirection)NSWritingDirectionLeftToRight;
2184 }
2185
2186 - (void)ensureSelectionVisible
2187 {
2188     if (!m_frame->hasSelection())
2189         return;
2190     
2191     FrameView *v = m_frame->view();
2192     if (!v)
2193         return;
2194
2195     Position extent = m_frame->selection().extent();
2196     if (extent.isNull())
2197         return;
2198     
2199     RenderObject *renderer = extent.node()->renderer();
2200     if (!renderer)
2201         return;
2202     
2203     NSView *documentView = v->getDocumentView();
2204     if (!documentView)
2205         return;
2206     
2207     IntRect extentRect = renderer->caretRect(extent.offset(), m_frame->selection().affinity());
2208     RenderLayer *layer = renderer->enclosingLayer();
2209     if (layer)
2210         layer->scrollRectToVisible(extentRect, RenderLayer::gAlignToEdgeIfNeeded, RenderLayer::gAlignToEdgeIfNeeded);
2211 }
2212
2213 // [info draggingLocation] is in window coords
2214
2215 - (BOOL)eventMayStartDrag:(NSEvent *)event
2216 {
2217     return m_frame ? m_frame->eventMayStartDrag(event) : NO;
2218 }
2219
2220 static IntPoint globalPoint(NSWindow* window, NSPoint windowPoint)
2221 {
2222     NSPoint screenPoint = [window convertBaseToScreen:windowPoint];
2223     return IntPoint((int)screenPoint.x, (int)(NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - screenPoint.y));
2224 }
2225
2226 static PlatformMouseEvent createMouseEventFromDraggingInfo(NSWindow* window, id <NSDraggingInfo> info)
2227 {
2228     // FIXME: Fake modifier keys here.
2229     return PlatformMouseEvent(IntPoint([info draggingLocation]), globalPoint(window, [info draggingLocation]),
2230         LeftButton, 0, false, false, false, false);
2231 }
2232
2233 - (NSDragOperation)dragOperationForDraggingInfo:(id <NSDraggingInfo>)info
2234 {
2235     NSDragOperation op = NSDragOperationNone;
2236     if (m_frame) {
2237         RefPtr<FrameView> v = m_frame->view();
2238         if (v) {
2239             ClipboardMac::AccessPolicy policy = m_frame->baseURL().isLocalFile() ? ClipboardMac::Readable : ClipboardMac::TypesReadable;
2240             RefPtr<ClipboardMac> clipboard = new ClipboardMac(true, [info draggingPasteboard], policy);
2241             NSDragOperation srcOp = [info draggingSourceOperationMask];
2242             clipboard->setSourceOperation(srcOp);
2243
2244             PlatformMouseEvent event = createMouseEventFromDraggingInfo([self window], info);
2245             if (v->updateDragAndDrop(event, clipboard.get())) {
2246                 // *op unchanged if no source op was set
2247                 if (!clipboard->destinationOperation(&op)) {
2248                     // The element accepted but they didn't pick an operation, so we pick one for them
2249                     // (as does WinIE).
2250                     if (srcOp & NSDragOperationCopy) {
2251                         op = NSDragOperationCopy;
2252                     } else if (srcOp & NSDragOperationMove || srcOp & NSDragOperationGeneric) {
2253                         op = NSDragOperationMove;
2254                     } else if (srcOp & NSDragOperationLink) {
2255                         op = NSDragOperationLink;
2256                     } else {
2257                         op = NSDragOperationGeneric;
2258                     }
2259                 } else if (!(op & srcOp)) {
2260                     // make sure WC picked an op that was offered.  Cocoa doesn't seem to enforce this,
2261                     // but IE does.
2262                     op = NSDragOperationNone;
2263                 }
2264             }
2265             clipboard->setAccessPolicy(ClipboardMac::Numb);    // invalidate clipboard here for security
2266             return op;
2267         }
2268     }
2269     return op;
2270 }
2271
2272 - (void)dragExitedWithDraggingInfo:(id <NSDraggingInfo>)info
2273 {
2274     if (m_frame) {
2275         RefPtr<FrameView> v = m_frame->view();
2276         if (v) {
2277             // Sending an event can result in the destruction of the view and part.
2278             ClipboardMac::AccessPolicy policy = m_frame->baseURL().isLocalFile() ? ClipboardMac::Readable : ClipboardMac::TypesReadable;
2279             RefPtr<ClipboardMac> clipboard = new ClipboardMac(true, [info draggingPasteboard], policy);
2280             clipboard->setSourceOperation([info draggingSourceOperationMask]);            
2281             v->cancelDragAndDrop(createMouseEventFromDraggingInfo([self window], info), clipboard.get());
2282             clipboard->setAccessPolicy(ClipboardMac::Numb);    // invalidate clipboard here for security
2283         }
2284     }
2285 }
2286
2287 - (BOOL)concludeDragForDraggingInfo:(id <NSDraggingInfo>)info
2288 {
2289     if (m_frame) {
2290         RefPtr<FrameView> v = m_frame->view();
2291         if (v) {
2292             // Sending an event can result in the destruction of the view and part.
2293             RefPtr<ClipboardMac> clipboard = new ClipboardMac(true, [info draggingPasteboard], ClipboardMac::Readable);
2294             clipboard->setSourceOperation([info draggingSourceOperationMask]);
2295             BOOL result = v->performDragAndDrop(createMouseEventFromDraggingInfo([self window], info), clipboard.get());
2296             clipboard->setAccessPolicy(ClipboardMac::Numb);    // invalidate clipboard here for security
2297             return result;
2298         }
2299     }
2300     return NO;
2301 }
2302
2303 - (void)dragSourceMovedTo:(NSPoint)windowLoc
2304 {
2305     if (m_frame) {
2306         // FIXME: Fake modifier keys here.
2307         PlatformMouseEvent event(IntPoint(windowLoc), globalPoint([self window], windowLoc),
2308             LeftButton, 0, false, false, false, false);
2309         m_frame->dragSourceMovedTo(event);
2310     }
2311 }
2312
2313 - (void)dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)operation
2314 {
2315     if (m_frame) {
2316         // FIXME: Fake modifier keys here.
2317         PlatformMouseEvent event(IntPoint(windowLoc), globalPoint([self window], windowLoc),
2318             LeftButton, 0, false, false, false, false);
2319         m_frame->dragSourceEndedAt(event, operation);
2320     }
2321 }
2322
2323 - (BOOL)mayDHTMLCut
2324 {
2325     return m_frame->mayCut();
2326 }
2327
2328 - (BOOL)mayDHTMLCopy
2329 {
2330     return m_frame->mayCopy();
2331 }
2332
2333 - (BOOL)mayDHTMLPaste
2334 {
2335     return m_frame->mayPaste();
2336 }
2337
2338 - (BOOL)tryDHTMLCut
2339 {
2340     return m_frame->tryCut();
2341 }
2342
2343 - (BOOL)tryDHTMLCopy
2344 {
2345     return m_frame->tryCopy();
2346 }
2347
2348 - (BOOL)tryDHTMLPaste
2349 {
2350     return m_frame->tryPaste();
2351 }
2352
2353 - (DOMRange *)rangeOfCharactersAroundCaret
2354 {
2355     if (!m_frame)
2356         return nil;
2357         
2358     SelectionController selection(m_frame->selection());
2359     if (!selection.isCaret())
2360         return nil;
2361
2362     VisiblePosition caret(selection.start(), selection.affinity());
2363     VisiblePosition next = caret.next();
2364     VisiblePosition previous = caret.previous();
2365     if (previous.isNull() || next.isNull() || caret == next || caret == previous)
2366         return nil;
2367
2368     return [DOMRange _rangeWith:makeRange(previous, next).get()];
2369 }
2370
2371 - (NSMutableDictionary *)dashboardRegions
2372 {
2373     return m_frame->dashboardRegionsDictionary();
2374 }
2375
2376 // FIXME: The following 2 functions are copied from AppKit. It would be best share code.
2377
2378 // MF:!!! For now we will use static character sets for the computation, but we should eventually probably make these keys in the language dictionaries.
2379 // MF:!!! The following characters (listed with their nextstep encoding values) were in the preSmartTable in the old text objet, but aren't yet in the new text object: NS_FIGSPACE (0x80), exclamdown (0xa1), sterling (0xa3), yen (0xa5), florin (0xa6) section (0xa7), currency (0xa8), quotesingle (0xa9), quotedblleft (0xaa), guillemotleft (0xab), guilsinglleft (0xac), endash (0xb1), quotesinglbase (0xb8), quotedblbase (0xb9), questiondown (0xbf), emdash (0xd0), plusminus (0xd1).
2380 // MF:!!! The following characters (listed with their nextstep encoding values) were in the postSmartTable in the old text objet, but aren't yet in the new text object: NS_FIGSPACE (0x80), cent (0xa2), guilsinglright (0xad), registered (0xb0), dagger (0xa2), daggerdbl (0xa3), endash (0xb1), quotedblright (0xba), guillemotright (0xbb), perthousand (0xbd), onesuperior (0xc0), twosuperior (0xc9), threesuperior (0xcc), emdash (0xd0), ordfeminine (0xe3), ordmasculine (0xeb).
2381 // MF:!!! Another difference in both of these sets from the old text object is we include all the whitespace in whitespaceAndNewlineCharacterSet.
2382 #define _preSmartString @"([\"\'#$/-`{"
2383 #define _postSmartString @")].,;:?\'!\"%*-/}"
2384
2385 static NSCharacterSet *_getPreSmartSet(void)
2386 {
2387     static NSMutableCharacterSet *_preSmartSet = nil;
2388     if (!_preSmartSet) {
2389         _preSmartSet = [[NSMutableCharacterSet characterSetWithCharactersInString:_preSmartString] retain];
2390         [_preSmartSet formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
2391         // Adding CJK ranges
2392         [_preSmartSet addCharactersInRange:NSMakeRange(0x1100, 256)]; // Hangul Jamo (0x1100 - 0x11FF)
2393         [_preSmartSet addCharactersInRange:NSMakeRange(0x2E80, 352)]; // CJK & Kangxi Radicals (0x2E80 - 0x2FDF)
2394         [_preSmartSet addCharactersInRange:NSMakeRange(0x2FF0, 464)]; // Ideograph Descriptions, CJK Symbols, Hiragana, Katakana, Bopomofo, Hangul Compatibility Jamo, Kanbun, & Bopomofo Ext (0x2FF0 - 0x31BF)
2395         [_preSmartSet addCharactersInRange:NSMakeRange(0x3200, 29392)]; // Enclosed CJK, CJK Ideographs (Uni Han & Ext A), & Yi (0x3200 - 0xA4CF)
2396         [_preSmartSet addCharactersInRange:NSMakeRange(0xAC00, 11183)]; // Hangul Syllables (0xAC00 - 0xD7AF)
2397         [_preSmartSet addCharactersInRange:NSMakeRange(0xF900, 352)]; // CJK Compatibility Ideographs (0xF900 - 0xFA5F)
2398         [_preSmartSet addCharactersInRange:NSMakeRange(0xFE30, 32)]; // CJK Compatibility From (0xFE30 - 0xFE4F)
2399         [_preSmartSet addCharactersInRange:NSMakeRange(0xFF00, 240)]; // Half/Full Width Form (0xFF00 - 0xFFEF)
2400         [_preSmartSet addCharactersInRange:NSMakeRange(0x20000, 0xA6D7)]; // CJK Ideograph Exntension B
2401         [_preSmartSet addCharactersInRange:NSMakeRange(0x2F800, 0x021E)]; // CJK Compatibility Ideographs (0x2F800 - 0x2FA1D)
2402     }
2403     return _preSmartSet;
2404 }
2405
2406 static NSCharacterSet *_getPostSmartSet(void)
2407 {
2408     static NSMutableCharacterSet *_postSmartSet = nil;
2409     if (!_postSmartSet) {
2410         _postSmartSet = [[NSMutableCharacterSet characterSetWithCharactersInString:_postSmartString] retain];
2411         [_postSmartSet formUnionWithCharacterSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
2412         [_postSmartSet addCharactersInRange:NSMakeRange(0x1100, 256)]; // Hangul Jamo (0x1100 - 0x11FF)
2413         [_postSmartSet addCharactersInRange:NSMakeRange(0x2E80, 352)]; // CJK & Kangxi Radicals (0x2E80 - 0x2FDF)
2414         [_postSmartSet addCharactersInRange:NSMakeRange(0x2FF0, 464)]; // Ideograph Descriptions, CJK Symbols, Hiragana, Katakana, Bopomofo, Hangul Compatibility Jamo, Kanbun, & Bopomofo Ext (0x2FF0 - 0x31BF)
2415         [_postSmartSet addCharactersInRange:NSMakeRange(0x3200, 29392)]; // Enclosed CJK, CJK Ideographs (Uni Han & Ext A), & Yi (0x3200 - 0xA4CF)
2416         [_postSmartSet addCharactersInRange:NSMakeRange(0xAC00, 11183)]; // Hangul Syllables (0xAC00 - 0xD7AF)
2417         [_postSmartSet addCharactersInRange:NSMakeRange(0xF900, 352)]; // CJK Compatibility Ideographs (0xF900 - 0xFA5F)
2418         [_postSmartSet addCharactersInRange:NSMakeRange(0xFE30, 32)]; // CJK Compatibility From (0xFE30 - 0xFE4F)
2419         [_postSmartSet addCharactersInRange:NSMakeRange(0xFF00, 240)]; // Half/Full Width Form (0xFF00 - 0xFFEF)
2420         [_postSmartSet addCharactersInRange:NSMakeRange(0x20000, 0xA6D7)]; // CJK Ideograph Exntension B
2421         [_postSmartSet addCharactersInRange:NSMakeRange(0x2F800, 0x021E)]; // CJK Compatibility Ideographs (0x2F800 - 0x2FA1D)        
2422         [_postSmartSet formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]];
2423     }
2424     return _postSmartSet;
2425 }
2426
2427 - (BOOL)isCharacterSmartReplaceExempt:(unichar)c isPreviousCharacter:(BOOL)isPreviousCharacter
2428 {
2429     return [isPreviousCharacter ? _getPreSmartSet() : _getPostSmartSet() characterIsMember:c];
2430 }
2431
2432 #define KeyboardUIModeDidChangeNotification @"com.apple.KeyboardUIModeDidChange"
2433 #define AppleKeyboardUIMode CFSTR("AppleKeyboardUIMode")
2434 #define UniversalAccessDomain CFSTR("com.apple.universalaccess")
2435
2436 - (void)_retrieveKeyboardUIModeFromPreferences:(NSNotification *)notification
2437 {
2438     CFPreferencesAppSynchronize(UniversalAccessDomain);
2439
2440     Boolean keyExistsAndHasValidFormat;
2441     int mode = CFPreferencesGetAppIntegerValue(AppleKeyboardUIMode, UniversalAccessDomain, &keyExistsAndHasValidFormat);
2442     
2443     // The keyboard access mode is reported by two bits:
2444     // Bit 0 is set if feature is on
2445     // Bit 1 is set if full keyboard access works for any control, not just text boxes and lists
2446     // We require both bits to be on.
2447     // I do not know that we would ever get one bit on and the other off since
2448     // checking the checkbox in system preferences which is marked as "Turn on full keyboard access"
2449     // turns on both bits.
2450     _keyboardUIMode = (mode & 0x2) ? WebCoreKeyboardAccessFull : WebCoreKeyboardAccessDefault;
2451     
2452     // check for tabbing to links
2453     if ([[self _preferences] tabsToLinks]) {
2454         _keyboardUIMode |= WebCoreKeyboardAccessTabsToLinks;
2455     }
2456 }
2457
2458 - (WebCoreKeyboardUIMode)keyboardUIMode
2459 {
2460     if (!_keyboardUIModeAccessed) {
2461         _keyboardUIModeAccessed = YES;
2462         [self _retrieveKeyboardUIModeFromPreferences:nil];
2463         
2464         [[NSDistributedNotificationCenter defaultCenter] 
2465             addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) 
2466             name:KeyboardUIModeDidChangeNotification object:nil];
2467
2468         [[NSNotificationCenter defaultCenter] 
2469             addObserver:self selector:@selector(_retrieveKeyboardUIModeFromPreferences:) 
2470                    name:WebPreferencesChangedNotification object:nil];
2471     }
2472     return _keyboardUIMode;
2473 }
2474
2475 @end
2476
2477 @implementation WebCoreFrameBridge (WebCoreBridgeInternal)
2478
2479 - (RootObject *)executionContextForView:(NSView *)aView
2480 {
2481     FrameMac *frame = [self impl];
2482     RootObject *root = new RootObject(aView);    // The root gets deleted by JavaScriptCore.
2483     root->setRootObjectImp(Window::retrieveWindow(frame));
2484     root->setInterpreter(frame->jScript()->interpreter());
2485     frame->addPluginRootObject(root);
2486     return root;
2487 }
2488
2489 - (RenderObject::NodeInfo)nodeInfoAtPoint:(NSPoint)point allowShadowContent:(BOOL)allow
2490 {
2491     return m_frame->nodeInfoAtPoint(IntPoint(point), allow);
2492 }
2493
2494 @end
2495
2496 @implementation WebCoreFrameBridge (WebCoreInternalUse)
2497
2498 - (FrameMac*)impl
2499 {
2500     return m_frame;
2501 }
2502
2503 @end