diff options
author | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-26 18:48:44 +0000 |
---|---|---|
committer | pinkerton@google.com <pinkerton@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-26 18:48:44 +0000 |
commit | 8be5f2bcf41943a8b38326a3a51acf5554cd5f80 (patch) | |
tree | 817e6ec82169189d001ac336a92d730e998f86c0 /webkit/port/bridge | |
parent | 3200e976b0a204ecf57e9b27a3b0249cce5eeb3b (diff) | |
download | chromium_src-8be5f2bcf41943a8b38326a3a51acf5554cd5f80.zip chromium_src-8be5f2bcf41943a8b38326a3a51acf5554cd5f80.tar.gz chromium_src-8be5f2bcf41943a8b38326a3a51acf5554cd5f80.tar.bz2 |
Forking webkit sources for clipboard/drag impl on Mac. It's almost exactly
the same as before except removing anything that uses the objc DOM bindings,
which we don't have. So it's like one change in each file, more or less.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1391 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/port/bridge')
-rw-r--r-- | webkit/port/bridge/mac/FrameMac.mm | 726 |
1 files changed, 726 insertions, 0 deletions
diff --git a/webkit/port/bridge/mac/FrameMac.mm b/webkit/port/bridge/mac/FrameMac.mm new file mode 100644 index 0000000..8604f8d --- /dev/null +++ b/webkit/port/bridge/mac/FrameMac.mm @@ -0,0 +1,726 @@ +/* + * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved. + * Copyright (C) 2006 Alexey Proskuryakov (ap@nypop.com) + * Copyright (C) 2007 Trolltech ASA + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "Frame.h" + +#import "AXObjectCache.h" +#import "BeforeUnloadEvent.h" +#import "BlockExceptions.h" +#import "CSSHelper.h" +#import "Cache.h" +#import "Chrome.h" +#import "ClipboardEvent.h" +#import "ClipboardMac.h" +#import "ColorMac.h" +#import "Cursor.h" +#if USE(JAVASCRIPTCORE_BINDINGS) +#import "DOMInternal.h" +#endif +#import "DocumentLoader.h" +#import "EditCommand.h" +#import "EditorClient.h" +#import "Event.h" +#import "EventNames.h" +#import "FloatRect.h" +#import "FoundationExtras.h" +#import "FrameLoadRequest.h" +#import "FrameLoader.h" +#import "FrameLoaderClient.h" +#import "FrameLoaderTypes.h" +#import "FramePrivate.h" +#import "FrameView.h" +#import "GraphicsContext.h" +#import "HTMLDocument.h" +#import "HTMLFormElement.h" +#import "HTMLGenericFormElement.h" +#import "HTMLInputElement.h" +#import "HTMLNames.h" +#import "HTMLTableCellElement.h" +#import "HitTestRequest.h" +#import "HitTestResult.h" +#import "KeyboardEvent.h" +#import "Logging.h" +#import "MouseEventWithHitTestResults.h" +#import "Page.h" +#import "PlatformKeyboardEvent.h" +#import "PlatformScrollBar.h" +#import "PlatformWheelEvent.h" +#import "Plugin.h" +#import "RegularExpression.h" +#import "RenderImage.h" +#import "RenderListItem.h" +#import "RenderPart.h" +#import "RenderTableCell.h" +#import "RenderTheme.h" +#import "RenderView.h" +#import "ResourceHandle.h" +#import "Settings.h" +#import "SimpleFontData.h" +#import "SystemTime.h" +#import "TextResourceDecoder.h" +#import "UserStyleSheetLoader.h" +#import "WebCoreFrameBridge.h" +#import "WebCoreSystemInterface.h" +#import "WebCoreViewFactory.h" +#import "WebDashboardRegion.h" +#import "visible_units.h" +#import <Carbon/Carbon.h> +#if USE(JAVASCRIPTCORE_BINDINGS) +#import "kjs_proxy.h" +#import "kjs_window.h" +#import "WebScriptObjectPrivate.h" +#import <JavaScriptCore/NP_jsobject.h> +#import <JavaScriptCore/npruntime_impl.h> +#else +#include <../../../../../webkit/glue/webplugin_impl.h> +#include <../../../../../port/bindings/v8/v8_npobject.h> +#endif + +#undef _webcore_TIMING + +@interface NSObject (WebPlugIn) +- (id)objectForWebScript; +- (NPObject *)createPluginScriptableObject; +@end + +@interface NSView (WebCoreHTMLDocumentView) +- (void)drawSingleRect:(NSRect)rect; +@end + +using namespace std; + +#if USE(JAVASCRIPTCORE_BINDINGS) +using namespace KJS::Bindings; +using KJS::JSLock; +#endif + +namespace WebCore { + +using namespace EventNames; +using namespace HTMLNames; + +void Frame::setBridge(WebCoreFrameBridge* bridge) +{ + if (d->m_bridge == bridge) + return; + + if (!bridge) { + [d->m_bridge clearFrame]; + HardRelease(d->m_bridge); + d->m_bridge = nil; + return; + } + HardRetain(bridge); + HardRelease(d->m_bridge); + d->m_bridge = bridge; +} + +WebCoreFrameBridge* Frame::bridge() const +{ + return d->m_bridge; +} + +// Either get cached regexp or build one that matches any of the labels. +// The regexp we build is of the form: (STR1|STR2|STRN) +RegularExpression* regExpForLabels(NSArray* labels) +{ + // All the ObjC calls in this method are simple array and string + // calls which we can assume do not raise exceptions + + + // Parallel arrays that we use to cache regExps. In practice the number of expressions + // that the app will use is equal to the number of locales is used in searching. + static const unsigned int regExpCacheSize = 4; + static NSMutableArray* regExpLabels = nil; + static Vector<RegularExpression*> regExps; + static RegularExpression wordRegExp = RegularExpression("\\w"); + + RegularExpression* result; + if (!regExpLabels) + regExpLabels = [[NSMutableArray alloc] initWithCapacity:regExpCacheSize]; + CFIndex cacheHit = [regExpLabels indexOfObject:labels]; + if (cacheHit != NSNotFound) + result = regExps.at(cacheHit); + else { + DeprecatedString pattern("("); + unsigned int numLabels = [labels count]; + unsigned int i; + for (i = 0; i < numLabels; i++) { + DeprecatedString label = DeprecatedString::fromNSString((NSString*)[labels objectAtIndex:i]); + + bool startsWithWordChar = false; + bool endsWithWordChar = false; + if (label.length() != 0) { + startsWithWordChar = wordRegExp.search(label.at(0)) >= 0; + endsWithWordChar = wordRegExp.search(label.at(label.length() - 1)) >= 0; + } + + if (i != 0) + pattern.append("|"); + // Search for word boundaries only if label starts/ends with "word characters". + // If we always searched for word boundaries, this wouldn't work for languages + // such as Japanese. + if (startsWithWordChar) { + pattern.append("\\b"); + } + pattern.append(label); + if (endsWithWordChar) { + pattern.append("\\b"); + } + } + pattern.append(")"); + result = new RegularExpression(pattern, false); + } + + // add regexp to the cache, making sure it is at the front for LRU ordering + if (cacheHit != 0) { + if (cacheHit != NSNotFound) { + // remove from old spot + [regExpLabels removeObjectAtIndex:cacheHit]; + regExps.remove(cacheHit); + } + // add to start + [regExpLabels insertObject:labels atIndex:0]; + regExps.insert(0, result); + // trim if too big + if ([regExpLabels count] > regExpCacheSize) { + [regExpLabels removeObjectAtIndex:regExpCacheSize]; + RegularExpression* last = regExps.last(); + regExps.removeLast(); + delete last; + } + } + return result; +} + +NSString* Frame::searchForNSLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell) +{ + RenderTableCell* cellRenderer = static_cast<RenderTableCell*>(cell->renderer()); + + if (cellRenderer && cellRenderer->isTableCell()) { + RenderTableCell* cellAboveRenderer = cellRenderer->table()->cellAbove(cellRenderer); + + if (cellAboveRenderer) { + HTMLTableCellElement* aboveCell = + static_cast<HTMLTableCellElement*>(cellAboveRenderer->element()); + + if (aboveCell) { + // search within the above cell we found for a match + for (Node* n = aboveCell->firstChild(); n; n = n->traverseNextNode(aboveCell)) { + if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { + // For each text chunk, run the regexp + DeprecatedString nodeString = n->nodeValue().deprecatedString(); + int pos = regExp->searchRev(nodeString); + if (pos >= 0) + return nodeString.mid(pos, regExp->matchedLength()).getNSString(); + } + } + } + } + } + // Any reason in practice to search all cells in that are above cell? + return nil; +} + +NSString* Frame::searchForLabelsBeforeElement(NSArray* labels, Element* element) +{ + RegularExpression* regExp = regExpForLabels(labels); + // We stop searching after we've seen this many chars + const unsigned int charsSearchedThreshold = 500; + // This is the absolute max we search. We allow a little more slop than + // charsSearchedThreshold, to make it more likely that we'll search whole nodes. + const unsigned int maxCharsSearched = 600; + // If the starting element is within a table, the cell that contains it + HTMLTableCellElement* startingTableCell = 0; + bool searchedCellAbove = false; + + // walk backwards in the node tree, until another element, or form, or end of tree + int unsigned lengthSearched = 0; + Node* n; + for (n = element->traversePreviousNode(); + n && lengthSearched < charsSearchedThreshold; + n = n->traversePreviousNode()) + { + if (n->hasTagName(formTag) + || (n->isHTMLElement() + && static_cast<HTMLElement*>(n)->isGenericFormElement())) + { + // We hit another form element or the start of the form - bail out + break; + } else if (n->hasTagName(tdTag) && !startingTableCell) { + startingTableCell = static_cast<HTMLTableCellElement*>(n); + } else if (n->hasTagName(trTag) && startingTableCell) { + NSString* result = searchForLabelsAboveCell(regExp, startingTableCell); + if (result && [result length] > 0) + return result; + searchedCellAbove = true; + } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) { + // For each text chunk, run the regexp + DeprecatedString nodeString = n->nodeValue().deprecatedString(); + // add 100 for slop, to make it more likely that we'll search whole nodes + if (lengthSearched + nodeString.length() > maxCharsSearched) + nodeString = nodeString.right(charsSearchedThreshold - lengthSearched); + int pos = regExp->searchRev(nodeString); + if (pos >= 0) + return nodeString.mid(pos, regExp->matchedLength()).getNSString(); + + lengthSearched += nodeString.length(); + } + } + + // If we started in a cell, but bailed because we found the start of the form or the + // previous element, we still might need to search the row above us for a label. + if (startingTableCell && !searchedCellAbove) { + NSString* result = searchForLabelsAboveCell(regExp, startingTableCell); + if (result && [result length] > 0) + return result; + } + + return nil; +} + +NSString* Frame::matchLabelsAgainstElement(NSArray* labels, Element* element) +{ + DeprecatedString name = element->getAttribute(nameAttr).deprecatedString(); + // Make numbers and _'s in field names behave like word boundaries, e.g., "address2" + name.replace(RegularExpression("\\d"), " "); + name.replace('_', ' '); + + RegularExpression* regExp = regExpForLabels(labels); + // Use the largest match we can find in the whole name string + int pos; + int length; + int bestPos = -1; + int bestLength = -1; + int start = 0; + do { + pos = regExp->search(name, start); + if (pos != -1) { + length = regExp->matchedLength(); + if (length >= bestLength) { + bestPos = pos; + bestLength = length; + } + start = pos+1; + } + } while (pos != -1); + + if (bestPos != -1) + return name.mid(bestPos, bestLength).getNSString(); + return nil; +} + +NSImage* Frame::imageFromRect(NSRect rect) const +{ +#if !PLATFORM(SKIA) + NSView* view = d->m_view->getDocumentView(); + if (!view) + return nil; + if (![view respondsToSelector:@selector(drawSingleRect:)]) + return nil; + + NSImage* resultImage; + BEGIN_BLOCK_OBJC_EXCEPTIONS; + + NSRect bounds = [view bounds]; + + // Round image rect size in window coordinate space to avoid pixel cracks at HiDPI (4622794) + rect = [view convertRect:rect toView:nil]; + rect.size.height = roundf(rect.size.height); + rect.size.width = roundf(rect.size.width); + rect = [view convertRect:rect fromView:nil]; + + resultImage = [[[NSImage alloc] initWithSize:rect.size] autorelease]; + + if (rect.size.width != 0 && rect.size.height != 0) { + [resultImage setFlipped:YES]; + [resultImage lockFocus]; + CGContextRef context = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + CGContextSaveGState(context); + CGContextTranslateCTM(context, bounds.origin.x - rect.origin.x, bounds.origin.y - rect.origin.y); + + // Note: Must not call drawRect: here, because drawRect: assumes that it's called from AppKit's + // display machinery. It calls getRectsBeingDrawn:count:, which can only be called inside + // when a real AppKit display is underway. + [view drawSingleRect:rect]; + + CGContextRestoreGState(context); + [resultImage unlockFocus]; + [resultImage setFlipped:NO]; + } + + return resultImage; + + END_BLOCK_OBJC_EXCEPTIONS; +#endif + return nil; +} + +NSImage* Frame::selectionImage(bool forceBlackText) const +{ + d->m_paintRestriction = forceBlackText ? PaintRestrictionSelectionOnlyBlackText : PaintRestrictionSelectionOnly; + d->m_doc->updateLayout(); + NSImage* result = imageFromRect(selectionRect()); + d->m_paintRestriction = PaintRestrictionNone; + return result; +} + +NSImage* Frame::snapshotDragImage(Node* node, NSRect* imageRect, NSRect* elementRect) const +{ + RenderObject* renderer = node->renderer(); + if (!renderer) + return nil; + + renderer->updateDragState(true); // mark dragged nodes (so they pick up the right CSS) + d->m_doc->updateLayout(); // forces style recalc - needed since changing the drag state might + // imply new styles, plus JS could have changed other things + IntRect topLevelRect; + NSRect paintingRect = renderer->paintingRootRect(topLevelRect); + + d->m_elementToDraw = node; // invoke special sub-tree drawing mode + NSImage* result = imageFromRect(paintingRect); + renderer->updateDragState(false); + d->m_doc->updateLayout(); + d->m_elementToDraw = 0; + + if (elementRect) + *elementRect = topLevelRect; + if (imageRect) + *imageRect = paintingRect; + return result; +} + +NSDictionary* Frame::fontAttributesForSelectionStart() const +{ + Node* nodeToRemove; + RenderStyle* style = styleForSelectionStart(nodeToRemove); + if (!style) + return nil; + + NSMutableDictionary* result = [NSMutableDictionary dictionary]; + + if (style->backgroundColor().isValid() && style->backgroundColor().alpha() != 0) + [result setObject:nsColor(style->backgroundColor()) forKey:NSBackgroundColorAttributeName]; + + if (style->font().primaryFont()->getNSFont()) + [result setObject:style->font().primaryFont()->getNSFont() forKey:NSFontAttributeName]; + + if (style->color().isValid() && style->color() != Color::black) + [result setObject:nsColor(style->color()) forKey:NSForegroundColorAttributeName]; + + ShadowData* shadow = style->textShadow(); + if (shadow) { + NSShadow* s = [[NSShadow alloc] init]; + [s setShadowOffset:NSMakeSize(shadow->x, shadow->y)]; + [s setShadowBlurRadius:shadow->blur]; + [s setShadowColor:nsColor(shadow->color)]; + [result setObject:s forKey:NSShadowAttributeName]; + } + + int decoration = style->textDecorationsInEffect(); + if (decoration & LINE_THROUGH) + [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSStrikethroughStyleAttributeName]; + + int superscriptInt = 0; + switch (style->verticalAlign()) { + case BASELINE: + case BOTTOM: + case BASELINE_MIDDLE: + case LENGTH: + case MIDDLE: + case TEXT_BOTTOM: + case TEXT_TOP: + case TOP: + break; + case SUB: + superscriptInt = -1; + break; + case SUPER: + superscriptInt = 1; + break; + } + if (superscriptInt) + [result setObject:[NSNumber numberWithInt:superscriptInt] forKey:NSSuperscriptAttributeName]; + + if (decoration & UNDERLINE) + [result setObject:[NSNumber numberWithInt:NSUnderlineStyleSingle] forKey:NSUnderlineStyleAttributeName]; + + if (nodeToRemove) { + ExceptionCode ec = 0; + nodeToRemove->remove(ec); + ASSERT(ec == 0); + } + + return result; +} + +NSWritingDirection Frame::baseWritingDirectionForSelectionStart() const +{ + NSWritingDirection result = NSWritingDirectionLeftToRight; + + Position pos = selectionController()->selection().visibleStart().deepEquivalent(); + Node* node = pos.node(); + if (!node || !node->renderer() || !node->renderer()->containingBlock()) + return result; + RenderStyle* style = node->renderer()->containingBlock()->style(); + if (!style) + return result; + + switch (style->direction()) { + case LTR: + result = NSWritingDirectionLeftToRight; + break; + case RTL: + result = NSWritingDirectionRightToLeft; + break; + } + + return result; +} + +void Frame::issuePasteCommand() +{ + [d->m_bridge issuePasteCommand]; +} + +const short enableRomanKeyboardsOnly = -23; +void Frame::setUseSecureKeyboardEntry(bool enable) +{ + if (enable == IsSecureEventInputEnabled()) + return; + if (enable) { + EnableSecureEventInput(); +#ifdef BUILDING_ON_TIGER + KeyScript(enableRomanKeyboardsOnly); +#else + CFArrayRef inputSources = TISCreateASCIICapableInputSourceList(); + TSMSetDocumentProperty(TSMGetActiveDocument(), kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources); + CFRelease(inputSources); +#endif + } else { + DisableSecureEventInput(); +#ifdef BUILDING_ON_TIGER + KeyScript(smKeyEnableKybds); +#else + TSMRemoveDocumentProperty(TSMGetActiveDocument(), kTSMDocumentEnabledInputSourcesPropertyTag); +#endif + } +} + +NSMutableDictionary* Frame::dashboardRegionsDictionary() +{ + Document* doc = document(); + if (!doc) + return nil; + + const Vector<DashboardRegionValue>& regions = doc->dashboardRegions(); + size_t n = regions.size(); + + // Convert the Vector<DashboardRegionValue> into a NSDictionary of WebDashboardRegions + NSMutableDictionary* webRegions = [NSMutableDictionary dictionaryWithCapacity:n]; + for (size_t i = 0; i < n; i++) { + const DashboardRegionValue& region = regions[i]; + + if (region.type == StyleDashboardRegion::None) + continue; + + NSString *label = region.label; + WebDashboardRegionType type = WebDashboardRegionTypeNone; + if (region.type == StyleDashboardRegion::Circle) + type = WebDashboardRegionTypeCircle; + else if (region.type == StyleDashboardRegion::Rectangle) + type = WebDashboardRegionTypeRectangle; + NSMutableArray *regionValues = [webRegions objectForKey:label]; + if (!regionValues) { + regionValues = [[NSMutableArray alloc] initWithCapacity:1]; + [webRegions setObject:regionValues forKey:label]; + [regionValues release]; + } + + WebDashboardRegion *webRegion = [[WebDashboardRegion alloc] initWithRect:region.bounds clip:region.clip type:type]; + [regionValues addObject:webRegion]; + [webRegion release]; + } + + return webRegions; +} + +void Frame::dashboardRegionsChanged() +{ + NSMutableDictionary *webRegions = dashboardRegionsDictionary(); + [d->m_bridge dashboardRegionsChanged:webRegions]; +} + +void Frame::willPopupMenu(NSMenu * menu) +{ + [d->m_bridge willPopupMenu:menu]; +} + +FloatRect Frame::customHighlightLineRect(const AtomicString& type, const FloatRect& lineRect, Node* node) +{ + return [d->m_bridge customHighlightRect:type forLine:lineRect representedNode:node]; +} + +void Frame::paintCustomHighlight(const AtomicString& type, const FloatRect& boxRect, const FloatRect& lineRect, bool text, bool line, Node* node) +{ + [d->m_bridge paintCustomHighlight:type forBox:boxRect onLine:lineRect behindText:text entireLine:line representedNode:node]; +} + +DragImageRef Frame::dragImageForSelection() +{ + if (!selectionController()->isRange()) + return nil; + return selectionImage(); +} + +#if USE(JAVASCRIPTCORE_BINDINGS) +KJS::Bindings::Instance* Frame::createScriptInstanceForWidget(WebCore::Widget* widget) +{ + NSView* aView = widget->getView(); + if (!aView) + return 0; + + void* nativeHandle = aView; + CreateRootObjectFunction createRootObject = RootObject::createRootObject(); + RefPtr<RootObject> rootObject = createRootObject(nativeHandle); + + if ([aView respondsToSelector:@selector(objectForWebScript)]) { + id objectForWebScript = [aView objectForWebScript]; + if (objectForWebScript) + return Instance::createBindingForLanguageInstance(Instance::ObjectiveCLanguage, objectForWebScript, rootObject.release()); + return 0; + } else if ([aView respondsToSelector:@selector(createPluginScriptableObject)]) { +#if USE(NPOBJECT) + NPObject* npObject = [aView createPluginScriptableObject]; + if (npObject) { + Instance* instance = Instance::createBindingForLanguageInstance(Instance::CLanguage, npObject, rootObject.release()); + + // -createPluginScriptableObject returns a retained NPObject. The caller is expected to release it. + _NPN_ReleaseObject(npObject); + return instance; + } +#endif + return 0; + } + + jobject applet; + + // Get a pointer to the actual Java applet instance. + if ([d->m_bridge respondsToSelector:@selector(getAppletInView:)]) + applet = [d->m_bridge getAppletInView:aView]; + else + applet = [d->m_bridge pollForAppletInView:aView]; + + if (applet) { + // Wrap the Java instance in a language neutral binding and hand + // off ownership to the APPLET element. + Instance* instance = Instance::createBindingForLanguageInstance(Instance::JavaLanguage, applet, rootObject.release()); + return instance; + } + + return 0; +} + +WebScriptObject* Frame::windowScriptObject() +{ + if (!scriptProxy()->isEnabled()) + return 0; + + if (!d->m_windowScriptObject) { + KJS::JSLock lock; + KJS::JSObject* win = KJS::Window::retrieveWindow(this); + KJS::Bindings::RootObject *root = bindingRootObject(); + d->m_windowScriptObject = [WebScriptObject scriptObjectForJSObject:toRef(win) originRootObject:root rootObject:root]; + } + + return d->m_windowScriptObject.get(); +} + +void Frame::clearPlatformScriptObjects() +{ + if (d->m_windowScriptObject) { + KJS::Bindings::RootObject* root = bindingRootObject(); + [d->m_windowScriptObject.get() _setOriginRootObject:root andRootObject:root]; + } +} + +#else + +#warning Untested V8 code! + +JSInstance Frame::createScriptInstanceForWidget(Widget* widget) +{ + // As in FrameWin.cpp, without the kjs branch. This should be shared! + + ASSERT(widget != 0); + + if (widget->isFrameView()) + return JSInstanceHolder::EmptyInstance(); + + // Note: We have to trust that the widget passed to us here + // is a WebPluginImpl. There isn't a way to dynamically verify + // it, since the derived class (Widget) has no identifier. + WebPluginContainer* container = static_cast<WebPluginContainer*>(widget); + if (!container) + return JSInstanceHolder::EmptyInstance(); + + NPObject *npObject = container->GetPluginScriptableObject(); + if (!npObject) + return JSInstanceHolder::EmptyInstance(); + + JSInstance instance = CreateV8ObjectForNPObject(npObject, nil); + // GetPluginScriptableObject returns a retained NPObject. + // The caller is expected to release it. + NPN_ReleaseObject(npObject); + return instance; +} + +void Frame::clearPlatformScriptObjects() +{ + // no-op as in FrameWin.cpp +} + +#endif + +void Frame::setUserStyleSheetLocation(const KURL& url) +{ + delete d->m_userStyleSheetLoader; + d->m_userStyleSheetLoader = 0; + if (d->m_doc && d->m_doc->docLoader()) + d->m_userStyleSheetLoader = new UserStyleSheetLoader(d->m_doc, url.string()); +} + +void Frame::setUserStyleSheet(const String& styleSheet) +{ + delete d->m_userStyleSheetLoader; + d->m_userStyleSheetLoader = 0; + if (d->m_doc) + d->m_doc->setUserStyleSheet(styleSheet); +} + +} // namespace WebCore |