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