diff options
Diffstat (limited to 'Source/WebKit2/UIProcess/mac')
-rw-r--r-- | Source/WebKit2/UIProcess/mac/BackingStoreMac.mm | 93 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/ChunkedUpdateDrawingAreaProxyMac.mm | 108 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/LayerBackedDrawingAreaProxyMac.mm | 92 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/TextCheckerMac.mm | 328 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebContextMac.mm | 93 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.h | 69 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm | 232 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm | 142 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm | 113 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h | 66 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm | 109 | ||||
-rw-r--r-- | Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm | 127 |
12 files changed, 1572 insertions, 0 deletions
diff --git a/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm b/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm new file mode 100644 index 0000000..979f755 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/BackingStoreMac.mm @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "BackingStore.h" + +#include "CGUtilities.h" +#include "ShareableBitmap.h" +#include "UpdateInfo.h" +#include <WebCore/GraphicsContext.h> + +using namespace WebCore; + +namespace WebKit { + +void BackingStore::paint(PlatformGraphicsContext context, const IntRect& rect) +{ + ASSERT(m_bitmapContext); + + paintBitmapContext(context, m_bitmapContext.get(), rect.location(), rect); +} + +void BackingStore::incorporateUpdate(const UpdateInfo& updateInfo) +{ + ASSERT(m_size == updateInfo.viewSize); + + RefPtr<ShareableBitmap> bitmap = ShareableBitmap::create(updateInfo.updateRectBounds.size(), updateInfo.bitmapHandle); + if (!bitmap) + return; + + if (!m_bitmapContext) { + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); + + m_bitmapContext.adoptCF(CGBitmapContextCreate(0, m_size.width(), m_size.height(), 8, m_size.width() * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + + // We want the origin to be in the top left corner so flip the backing store context. + CGContextTranslateCTM(m_bitmapContext.get(), 0, m_size.height()); + CGContextScaleCTM(m_bitmapContext.get(), 1, -1); + } + + scroll(updateInfo.scrollRect, updateInfo.scrollDelta); + + IntPoint updateRectLocation = updateInfo.updateRectBounds.location(); + + GraphicsContext graphicsContext(m_bitmapContext.get()); + + // Paint all update rects. + for (size_t i = 0; i < updateInfo.updateRects.size(); ++i) { + IntRect updateRect = updateInfo.updateRects[i]; + IntRect srcRect = updateRect; + srcRect.move(-updateRectLocation.x(), -updateRectLocation.y()); + + bitmap->paint(graphicsContext, updateRect.location(), srcRect); + } +} + +void BackingStore::scroll(const IntRect& scrollRect, const IntSize& scrollDelta) +{ + if (scrollDelta.isZero()) + return; + + CGContextSaveGState(m_bitmapContext.get()); + + CGContextClipToRect(m_bitmapContext.get(), scrollRect); + + CGPoint destination = CGPointMake(scrollRect.x() + scrollDelta.width(), scrollRect.y() + scrollDelta.height()); + paintBitmapContext(m_bitmapContext.get(), m_bitmapContext.get(), destination, scrollRect); + + CGContextRestoreGState(m_bitmapContext.get()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/ChunkedUpdateDrawingAreaProxyMac.mm b/Source/WebKit2/UIProcess/mac/ChunkedUpdateDrawingAreaProxyMac.mm new file mode 100644 index 0000000..909745b --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/ChunkedUpdateDrawingAreaProxyMac.mm @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "ChunkedUpdateDrawingAreaProxy.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include "UpdateChunk.h" +#include "WKAPICast.h" +#include "WKView.h" +#include "WebPageProxy.h" + +using namespace WebCore; + +namespace WebKit { + +WebPageProxy* ChunkedUpdateDrawingAreaProxy::page() +{ + return toImpl([m_webView pageRef]); +} + +void ChunkedUpdateDrawingAreaProxy::ensureBackingStore() +{ + if (m_bitmapContext) + return; + + RetainPtr<CGColorSpaceRef> colorSpace(AdoptCF, CGColorSpaceCreateDeviceRGB()); + const IntSize& viewSize = size(); + m_bitmapContext.adoptCF(CGBitmapContextCreate(0, viewSize.width(), viewSize.height(), 8, viewSize.width() * 4, colorSpace.get(), kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host)); + + // Flip the bitmap context coordinate system. + CGContextTranslateCTM(m_bitmapContext.get(), 0, viewSize.height()); + CGContextScaleCTM(m_bitmapContext.get(), 1, -1); +} + +void ChunkedUpdateDrawingAreaProxy::invalidateBackingStore() +{ + m_bitmapContext = 0; +} + +bool ChunkedUpdateDrawingAreaProxy::platformPaint(const IntRect& rect, CGContextRef context) +{ + if (!m_bitmapContext) + return false; + + CGContextSaveGState(context); + + // Use the copy blend mode when drawing a background. + if (page()->drawsBackground()) + CGContextSetBlendMode(context, kCGBlendModeCopy); + + // Flip the destination. + CGContextScaleCTM(context, 1, -1); + CGContextTranslateCTM(context, 0, -m_size.height()); + + RetainPtr<CGImageRef> image(AdoptCF, CGBitmapContextCreateImage(m_bitmapContext.get())); + CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image.get()), CGImageGetHeight(image.get())), image.get()); + + CGContextRestoreGState(context); + return true; +} + +void ChunkedUpdateDrawingAreaProxy::drawUpdateChunkIntoBackingStore(UpdateChunk* updateChunk) +{ + ensureBackingStore(); + + RetainPtr<CGImageRef> image(updateChunk->createImage()); + IntRect updateChunkRect = updateChunk->rect(); + + CGContextSaveGState(m_bitmapContext.get()); + + // Use the copy blend mode to replace existing content. + CGContextSetBlendMode(m_bitmapContext.get(), kCGBlendModeCopy); + + // Flip the destination. + CGContextScaleCTM(m_bitmapContext.get(), 1, -1); + CGContextTranslateCTM(m_bitmapContext.get(), 0, -(updateChunkRect.y() + updateChunkRect.bottom())); + + CGContextDrawImage(m_bitmapContext.get(), updateChunkRect, image.get()); + + CGContextRestoreGState(m_bitmapContext.get()); + + [m_webView setNeedsDisplayInRect:NSRectFromCGRect(updateChunkRect)]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/LayerBackedDrawingAreaProxyMac.mm b/Source/WebKit2/UIProcess/mac/LayerBackedDrawingAreaProxyMac.mm new file mode 100644 index 0000000..846eb25 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/LayerBackedDrawingAreaProxyMac.mm @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "LayerBackedDrawingAreaProxy.h" + +#include "DrawingAreaMessageKinds.h" +#include "DrawingAreaProxyMessageKinds.h" +#include <QuartzCore/QuartzCore.h> +#include "WKAPICast.h" +#include "WKView.h" +#include "WKViewInternal.h" +#include "WebKitSystemInterface.h" +#include "WebPageProxy.h" + +using namespace WebCore; + +namespace WebKit { + +WebPageProxy* LayerBackedDrawingAreaProxy::page() +{ + return toImpl([m_webView pageRef]); +} + +void LayerBackedDrawingAreaProxy::platformSetSize() +{ + [m_compositingRootLayer.get() setBounds:CGRectMake(0, 0, size().width(), size().height())]; +} + +void LayerBackedDrawingAreaProxy::attachCompositingContext(uint32_t contextID) +{ +#if HAVE(HOSTED_CORE_ANIMATION) + m_compositingRootLayer = WKMakeRenderLayer(contextID); + + // Turn off default animations. + NSNull *nullValue = [NSNull null]; + NSDictionary *actions = [NSDictionary dictionaryWithObjectsAndKeys: + nullValue, @"anchorPoint", + nullValue, @"bounds", + nullValue, @"contents", + nullValue, @"contentsRect", + nullValue, @"opacity", + nullValue, @"position", + nullValue, @"sublayerTransform", + nullValue, @"sublayers", + nullValue, @"transform", + nil]; + [m_compositingRootLayer.get() setStyle:[NSDictionary dictionaryWithObject:actions forKey:@"actions"]]; + + [m_compositingRootLayer.get() setAnchorPoint:CGPointZero]; + [m_compositingRootLayer.get() setBounds:CGRectMake(0, 0, size().width(), size().height())]; + + // FIXME: this fixes the layer jiggle when resizing the window, but breaks layer flipping because + // CA doesn't propagate the kCALayerFlagFlippedAbove through the remote layer. + // [m_compositingRootLayer.get() setGeometryFlipped:YES]; + +#ifndef NDEBUG + [m_compositingRootLayer.get() setName:@"Compositing root layer"]; +#endif + + [m_webView _startAcceleratedCompositing:m_compositingRootLayer.get()]; +#endif +} + +void LayerBackedDrawingAreaProxy::detachCompositingContext() +{ + [m_webView _stopAcceleratedCompositing]; + m_compositingRootLayer = 0; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/TextCheckerMac.mm b/Source/WebKit2/UIProcess/mac/TextCheckerMac.mm new file mode 100644 index 0000000..c89011e --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/TextCheckerMac.mm @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "TextChecker.h" + +#include "TextCheckerState.h" +#include <wtf/RetainPtr.h> + +#ifndef BUILDING_ON_SNOW_LEOPARD +#import <AppKit/NSTextChecker.h> +#endif + +static const NSString * const WebAutomaticSpellingCorrectionEnabled = @"WebAutomaticSpellingCorrectionEnabled"; +static const NSString * const WebContinuousSpellCheckingEnabled = @"WebContinuousSpellCheckingEnabled"; +static const NSString * const WebGrammarCheckingEnabled = @"WebGrammarCheckingEnabled"; +static const NSString * const WebSmartInsertDeleteEnabled = @"WebSmartInsertDeleteEnabled"; +static const NSString * const WebAutomaticQuoteSubstitutionEnabled = @"WebAutomaticQuoteSubstitutionEnabled"; +static const NSString * const WebAutomaticDashSubstitutionEnabled = @"WebAutomaticDashSubstitutionEnabled"; +static const NSString * const WebAutomaticLinkDetectionEnabled = @"WebAutomaticLinkDetectionEnabled"; +static const NSString * const WebAutomaticTextReplacementEnabled = @"WebAutomaticTextReplacementEnabled"; + +using namespace WebCore; + +namespace WebKit { + +TextCheckerState textCheckerState; + +static void initializeState() +{ + static bool didInitializeState; + if (didInitializeState) + return; + + textCheckerState.isContinuousSpellCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebContinuousSpellCheckingEnabled] && TextChecker::isContinuousSpellCheckingAllowed(); + textCheckerState.isGrammarCheckingEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebGrammarCheckingEnabled]; + textCheckerState.isAutomaticSpellingCorrectionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticSpellingCorrectionEnabled]; + textCheckerState.isAutomaticQuoteSubstitutionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticQuoteSubstitutionEnabled]; + textCheckerState.isAutomaticDashSubstitutionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticDashSubstitutionEnabled]; + textCheckerState.isAutomaticLinkDetectionEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticLinkDetectionEnabled]; + textCheckerState.isAutomaticTextReplacementEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebAutomaticTextReplacementEnabled]; + +#if !defined(BUILDING_ON_SNOW_LEOPARD) + if (![[NSUserDefaults standardUserDefaults] objectForKey:WebAutomaticSpellingCorrectionEnabled]) + textCheckerState.isAutomaticSpellingCorrectionEnabled = [NSSpellChecker isAutomaticSpellingCorrectionEnabled]; +#endif + + didInitializeState = true; +} + +const TextCheckerState& TextChecker::state() +{ + initializeState(); + return textCheckerState; +} + +bool TextChecker::isContinuousSpellCheckingAllowed() +{ + static bool allowContinuousSpellChecking = true; + static bool readAllowContinuousSpellCheckingDefault = false; + + if (!readAllowContinuousSpellCheckingDefault) { + if ([[NSUserDefaults standardUserDefaults] objectForKey:@"NSAllowContinuousSpellChecking"]) + allowContinuousSpellChecking = [[NSUserDefaults standardUserDefaults] boolForKey:@"NSAllowContinuousSpellChecking"]; + + readAllowContinuousSpellCheckingDefault = true; + } + + return allowContinuousSpellChecking; +} + +void TextChecker::setContinuousSpellCheckingEnabled(bool isContinuousSpellCheckingEnabled) +{ + if (state().isContinuousSpellCheckingEnabled == isContinuousSpellCheckingEnabled) + return; + + textCheckerState.isContinuousSpellCheckingEnabled = isContinuousSpellCheckingEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isContinuousSpellCheckingEnabled forKey:WebContinuousSpellCheckingEnabled]; + + // FIXME: preflight the spell checker. +} + +void TextChecker::setGrammarCheckingEnabled(bool isGrammarCheckingEnabled) +{ + if (state().isGrammarCheckingEnabled == isGrammarCheckingEnabled) + return; + + textCheckerState.isGrammarCheckingEnabled = isGrammarCheckingEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isGrammarCheckingEnabled forKey:WebGrammarCheckingEnabled]; + [[NSSpellChecker sharedSpellChecker] updatePanels]; + + // We call preflightSpellChecker() when turning continuous spell checking on, but we don't need to do that here + // because grammar checking only occurs on code paths that already preflight spell checking appropriately. +} + +void TextChecker::setAutomaticSpellingCorrectionEnabled(bool isAutomaticSpellingCorrectionEnabled) +{ + if (state().isAutomaticSpellingCorrectionEnabled == isAutomaticSpellingCorrectionEnabled) + return; + + textCheckerState.isAutomaticSpellingCorrectionEnabled = isAutomaticSpellingCorrectionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticSpellingCorrectionEnabled forKey:WebAutomaticSpellingCorrectionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticQuoteSubstitutionEnabled(bool isAutomaticQuoteSubstitutionEnabled) +{ + if (state().isAutomaticQuoteSubstitutionEnabled == isAutomaticQuoteSubstitutionEnabled) + return; + + textCheckerState.isAutomaticQuoteSubstitutionEnabled = isAutomaticQuoteSubstitutionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticQuoteSubstitutionEnabled forKey:WebAutomaticQuoteSubstitutionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticDashSubstitutionEnabled(bool isAutomaticDashSubstitutionEnabled) +{ + if (state().isAutomaticDashSubstitutionEnabled == isAutomaticDashSubstitutionEnabled) + return; + + textCheckerState.isAutomaticDashSubstitutionEnabled = isAutomaticDashSubstitutionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticDashSubstitutionEnabled forKey:WebAutomaticDashSubstitutionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticLinkDetectionEnabled(bool isAutomaticLinkDetectionEnabled) +{ + if (state().isAutomaticLinkDetectionEnabled == isAutomaticLinkDetectionEnabled) + return; + + textCheckerState.isAutomaticLinkDetectionEnabled = isAutomaticLinkDetectionEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticLinkDetectionEnabled forKey:WebAutomaticLinkDetectionEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +void TextChecker::setAutomaticTextReplacementEnabled(bool isAutomaticTextReplacementEnabled) +{ + if (state().isAutomaticTextReplacementEnabled == isAutomaticTextReplacementEnabled) + return; + + textCheckerState.isAutomaticTextReplacementEnabled = isAutomaticTextReplacementEnabled; + [[NSUserDefaults standardUserDefaults] setBool:isAutomaticTextReplacementEnabled forKey:WebAutomaticTextReplacementEnabled]; + + [[NSSpellChecker sharedSpellChecker] updatePanels]; +} + +static bool smartInsertDeleteEnabled; + +bool TextChecker::isSmartInsertDeleteEnabled() +{ + static bool readSmartInsertDeleteEnabledDefault; + + if (!readSmartInsertDeleteEnabledDefault) { + smartInsertDeleteEnabled = [[NSUserDefaults standardUserDefaults] boolForKey:WebSmartInsertDeleteEnabled]; + + readSmartInsertDeleteEnabledDefault = true; + } + + return smartInsertDeleteEnabled; +} + +void TextChecker::setSmartInsertDeleteEnabled(bool flag) +{ + if (flag == isSmartInsertDeleteEnabled()) + return; + + smartInsertDeleteEnabled = flag; + + [[NSUserDefaults standardUserDefaults] setBool:flag forKey:WebSmartInsertDeleteEnabled]; +} + +int64_t TextChecker::uniqueSpellDocumentTag() +{ + return [NSSpellChecker uniqueSpellDocumentTag]; +} + +void TextChecker::closeSpellDocumentWithTag(int64_t tag) +{ + [[NSSpellChecker sharedSpellChecker] closeSpellDocumentWithTag:tag]; +} + +Vector<TextCheckingResult> TextChecker::checkTextOfParagraph(int64_t spellDocumentTag, const UChar* text, int length, uint64_t checkingTypes) +{ + Vector<TextCheckingResult> results; + + RetainPtr<NSString> textString(AdoptNS, [[NSString alloc] initWithCharactersNoCopy:const_cast<UChar*>(text) length:length freeWhenDone:NO]); + NSArray *incomingResults = [[NSSpellChecker sharedSpellChecker] checkString:textString .get() + range:NSMakeRange(0, length) + types:checkingTypes | NSTextCheckingTypeOrthography + options:nil + inSpellDocumentWithTag:spellDocumentTag + orthography:NULL + wordCount:NULL]; + for (NSTextCheckingResult *incomingResult in incomingResults) { + NSRange resultRange = [incomingResult range]; + NSTextCheckingType resultType = [incomingResult resultType]; + ASSERT(resultRange.location != NSNotFound); + ASSERT(resultRange.length > 0); + if (resultType == NSTextCheckingTypeSpelling && (checkingTypes & NSTextCheckingTypeSpelling)) { + TextCheckingResult result; + result.type = TextCheckingTypeSpelling; + result.location = resultRange.location; + result.length = resultRange.length; + results.append(result); + } else if (resultType == NSTextCheckingTypeGrammar && (checkingTypes & NSTextCheckingTypeGrammar)) { + TextCheckingResult result; + NSArray *details = [incomingResult grammarDetails]; + result.type = TextCheckingTypeGrammar; + result.location = resultRange.location; + result.length = resultRange.length; + for (NSDictionary *incomingDetail in details) { + ASSERT(incomingDetail); + GrammarDetail detail; + NSValue *detailRangeAsNSValue = [incomingDetail objectForKey:NSGrammarRange]; + ASSERT(detailRangeAsNSValue); + NSRange detailNSRange = [detailRangeAsNSValue rangeValue]; + ASSERT(detailNSRange.location != NSNotFound); + ASSERT(detailNSRange.length > 0); + detail.location = detailNSRange.location; + detail.length = detailNSRange.length; + detail.userDescription = [incomingDetail objectForKey:NSGrammarUserDescription]; + NSArray *guesses = [incomingDetail objectForKey:NSGrammarCorrections]; + for (NSString *guess in guesses) + detail.guesses.append(String(guess)); + result.details.append(detail); + } + results.append(result); + } else if (resultType == NSTextCheckingTypeLink && (checkingTypes & NSTextCheckingTypeLink)) { + TextCheckingResult result; + result.type = TextCheckingTypeLink; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [[incomingResult URL] absoluteString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeQuote && (checkingTypes & NSTextCheckingTypeQuote)) { + TextCheckingResult result; + result.type = TextCheckingTypeQuote; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeDash && (checkingTypes & NSTextCheckingTypeDash)) { + TextCheckingResult result; + result.type = TextCheckingTypeDash; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeReplacement && (checkingTypes & NSTextCheckingTypeReplacement)) { + TextCheckingResult result; + result.type = TextCheckingTypeReplacement; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } else if (resultType == NSTextCheckingTypeCorrection && (checkingTypes & NSTextCheckingTypeCorrection)) { + TextCheckingResult result; + result.type = TextCheckingTypeCorrection; + result.location = resultRange.location; + result.length = resultRange.length; + result.replacement = [incomingResult replacementString]; + results.append(result); + } + } + + return results; +} + +void TextChecker::updateSpellingUIWithMisspelledWord(const String& misspelledWord) +{ + [[NSSpellChecker sharedSpellChecker] updateSpellingPanelWithMisspelledWord:misspelledWord]; +} + +void TextChecker::getGuessesForWord(int64_t spellDocumentTag, const String& word, const String& context, Vector<String>& guesses) +{ +#if !defined(BUILDING_ON_SNOW_LEOPARD) + NSString* language = nil; + NSOrthography* orthography = nil; + NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker]; + if (context.length()) { + [checker checkString:context range:NSMakeRange(0, context.length()) types:NSTextCheckingTypeOrthography options:0 inSpellDocumentWithTag:spellDocumentTag orthography:&orthography wordCount:0]; + language = [checker languageForWordRange:NSMakeRange(0, context.length()) inString:context orthography:orthography]; + } + NSArray* stringsArray = [checker guessesForWordRange:NSMakeRange(0, word.length()) inString:word language:language inSpellDocumentWithTag:spellDocumentTag]; +#else + NSArray* stringsArray = [[NSSpellChecker sharedSpellChecker] guessesForWord:word]; +#endif + + for (NSString *guess in stringsArray) + guesses.append(guess); +} + +void TextChecker::learnWord(const String& word) +{ + [[NSSpellChecker sharedSpellChecker] learnWord:word]; +} + +void TextChecker::ignoreWord(int64_t spellDocumentTag, const String& word) +{ + [[NSSpellChecker sharedSpellChecker] ignoreWord:word inSpellDocumentWithTag:spellDocumentTag]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/WebContextMac.mm b/Source/WebKit2/UIProcess/mac/WebContextMac.mm new file mode 100644 index 0000000..ce4c3e6 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebContextMac.mm @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "WebContext.h" + +#include "WebKitSystemInterface.h" +#include "WebProcessCreationParameters.h" +#include <WebCore/FileSystem.h> +#include <sys/param.h> + +using namespace WebCore; + +NSString *WebKitLocalCacheDefaultsKey = @"WebKitLocalCache"; + +namespace WebKit { + +String WebContext::applicationCacheDirectory() +{ + NSString *appName = [[NSBundle mainBundle] bundleIdentifier]; + if (!appName) + appName = [[NSProcessInfo processInfo] processName]; + + ASSERT(appName); + + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSString *cacheDir = [defaults objectForKey:WebKitLocalCacheDefaultsKey]; + + if (!cacheDir || ![cacheDir isKindOfClass:[NSString class]]) { +#ifdef BUILDING_ON_TIGER + cacheDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"]; +#else + char cacheDirectory[MAXPATHLEN]; + size_t cacheDirectoryLen = confstr(_CS_DARWIN_USER_CACHE_DIR, cacheDirectory, MAXPATHLEN); + + if (cacheDirectoryLen) + cacheDir = [[NSFileManager defaultManager] stringWithFileSystemRepresentation:cacheDirectory length:cacheDirectoryLen - 1]; +#endif + } + + return [cacheDir stringByAppendingPathComponent:appName]; +} + + +void WebContext::platformInitializeWebProcess(WebProcessCreationParameters& parameters) +{ + // We want to use a PDF view in the UI process for PDF MIME types. + HashSet<String, CaseFoldingHash> mimeType = pdfAndPostScriptMIMETypes(); + parameters.mimeTypesWithCustomRepresentation.appendRange(mimeType.begin(), mimeType.end()); + + RetainPtr<CFStringRef> cachePath(AdoptCF, WKCopyFoundationCacheDirectory()); + if (!cachePath) + cachePath = reinterpret_cast<CFStringRef>(NSHomeDirectory()); + + NSURLCache *urlCache = [NSURLCache sharedURLCache]; + + parameters.nsURLCachePath = fileSystemRepresentation([(NSString *)cachePath.get() stringByStandardizingPath]); + parameters.nsURLCacheMemoryCapacity = [urlCache memoryCapacity]; + parameters.nsURLCacheDiskCapacity = [urlCache diskCapacity]; + +#if USE(ACCELERATED_COMPOSITING) && HAVE(HOSTED_CORE_ANIMATION) + mach_port_t renderServerPort = WKInitializeRenderServer(); + if (renderServerPort != MACH_PORT_NULL) + parameters.acceleratedCompositingPort = CoreIPC::MachPort(renderServerPort, MACH_MSG_TYPE_COPY_SEND); +#endif + + // FIXME: This should really be configurable; we shouldn't just blindly allow read access to the UI process bundle. + parameters.uiProcessBundleResourcePath = fileSystemRepresentation([[NSBundle mainBundle] resourcePath]); +} + +} // namespace WebKit + diff --git a/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.h b/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.h new file mode 100644 index 0000000..ee4fa3d --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#ifndef WebContextMenuProxyMac_h +#define WebContextMenuProxyMac_h + +#include "WebContextMenuProxy.h" +#include <wtf/RetainPtr.h> + +#ifdef __OBJC__ +@class NSPopUpButtonCell; +@class WKView; +#else +class NSPopUpButtonCell; +class WKView; +#endif + +namespace WebKit { + +class WebPageProxy; + +class WebContextMenuProxyMac : public WebContextMenuProxy { +public: + static PassRefPtr<WebContextMenuProxyMac> create(WKView* webView, WebPageProxy* page) + { + return adoptRef(new WebContextMenuProxyMac(webView, page)); + } + ~WebContextMenuProxyMac(); + + virtual void showContextMenu(const WebCore::IntPoint&, const Vector<WebContextMenuItemData>&); + virtual void hideContextMenu(); + + void contextMenuItemSelected(const WebContextMenuItemData&); + +private: + WebContextMenuProxyMac(WKView*, WebPageProxy*); + + void populate(const Vector<WebContextMenuItemData>&); + + RetainPtr<NSPopUpButtonCell> m_popup; + WKView* m_webView; + WebPageProxy* m_page; +}; + +} // namespace WebKit + +#endif // WebContextMenuProxyMac_h diff --git a/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm new file mode 100644 index 0000000..d76b997 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebContextMenuProxyMac.mm @@ -0,0 +1,232 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "WebContextMenuProxyMac.h" + +#include "PageClientImpl.h" +#include "WebContextMenuItemData.h" +#include "WKView.h" + +#include <WebCore/IntRect.h> +#include <WebKitSystemInterface.h> + +using namespace WebCore; + +@interface WebUserDataWrapper : NSObject { + RefPtr<WebKit::APIObject> _webUserData; +} +- (id)initWithUserData:(WebKit::APIObject*)userData; +- (WebKit::APIObject*)userData; +@end + +@implementation WebUserDataWrapper + +- (id)initWithUserData:(WebKit::APIObject*)userData +{ + self = [super init]; + if (!self) + return nil; + + _webUserData = userData; + return self; +} + +- (WebKit::APIObject*)userData +{ + return _webUserData.get(); +} + +@end + +@interface WKMenuTarget : NSObject { + WebKit::WebContextMenuProxyMac* _menuProxy; +} ++ (WKMenuTarget*)sharedMenuTarget; +- (WebKit::WebContextMenuProxyMac*)menuProxy; +- (void)setMenuProxy:(WebKit::WebContextMenuProxyMac*)menuProxy; +- (void)forwardContextMenuAction:(id)sender; +@end + +@implementation WKMenuTarget + ++ (WKMenuTarget*)sharedMenuTarget +{ + static WKMenuTarget* target = [[WKMenuTarget alloc] init]; + return target; +} + +- (WebKit::WebContextMenuProxyMac*)menuProxy +{ + return _menuProxy; +} + +- (void)setMenuProxy:(WebKit::WebContextMenuProxyMac*)menuProxy +{ + _menuProxy = menuProxy; +} + +- (void)forwardContextMenuAction:(id)sender +{ + WebKit::WebContextMenuItemData item(ActionType, static_cast<ContextMenuAction>([sender tag]), [sender title], [sender isEnabled], [sender state] == NSOnState); + + if (id representedObject = [sender representedObject]) { + ASSERT([representedObject isKindOfClass:[WebUserDataWrapper class]]); + item.setUserData([static_cast<WebUserDataWrapper *>(representedObject) userData]); + } + + _menuProxy->contextMenuItemSelected(item); +} + +@end + +namespace WebKit { + +WebContextMenuProxyMac::WebContextMenuProxyMac(WKView* webView, WebPageProxy* page) + : m_webView(webView) + , m_page(page) +{ +} + +WebContextMenuProxyMac::~WebContextMenuProxyMac() +{ + if (m_popup) + [m_popup.get() setControlView:nil]; +} + +void WebContextMenuProxyMac::contextMenuItemSelected(const WebContextMenuItemData& item) +{ + m_page->contextMenuItemSelected(item); +} + +static void populateNSMenu(NSMenu* menu, const Vector<RetainPtr<NSMenuItem> >& menuItemVector) +{ + for (unsigned i = 0; i < menuItemVector.size(); ++i) { + NSInteger oldState = [menuItemVector[i].get() state]; + [menu addItem:menuItemVector[i].get()]; + [menuItemVector[i].get() setState:oldState]; + } +} + +static Vector<RetainPtr<NSMenuItem> > nsMenuItemVector(const Vector<WebContextMenuItemData>& items) +{ + Vector<RetainPtr<NSMenuItem> > result; + + unsigned size = items.size(); + result.reserveCapacity(size); + for (unsigned i = 0; i < size; i++) { + switch (items[i].type()) { + case ActionType: + case CheckableActionType: { + NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:nsStringFromWebCoreString(items[i].title()) action:@selector(forwardContextMenuAction:) keyEquivalent:@""]; + [menuItem setTag:items[i].action()]; + [menuItem setEnabled:items[i].enabled()]; + [menuItem setState:items[i].checked() ? NSOnState : NSOffState]; + + if (items[i].userData()) { + WebUserDataWrapper *wrapper = [[WebUserDataWrapper alloc] initWithUserData:items[i].userData()]; + [menuItem setRepresentedObject:wrapper]; + [wrapper release]; + } + + result.append(RetainPtr<NSMenuItem>(AdoptNS, menuItem)); + break; + } + case SeparatorType: + result.append([NSMenuItem separatorItem]); + break; + case SubmenuType: { + NSMenu* menu = [[NSMenu alloc] initWithTitle:nsStringFromWebCoreString(items[i].title())]; + [menu setAutoenablesItems:NO]; + populateNSMenu(menu, nsMenuItemVector(items[i].submenu())); + + NSMenuItem* menuItem = [[NSMenuItem alloc] initWithTitle:nsStringFromWebCoreString(items[i].title()) action:@selector(forwardContextMenuAction:) keyEquivalent:@""]; + [menuItem setEnabled:items[i].enabled()]; + [menuItem setSubmenu:menu]; + [menu release]; + + result.append(RetainPtr<NSMenuItem>(AdoptNS, menuItem)); + + break; + } + default: + ASSERT_NOT_REACHED(); + } + } + + WKMenuTarget* target = [WKMenuTarget sharedMenuTarget]; + for (unsigned i = 0; i < size; ++i) + [result[i].get() setTarget:target]; + + return result; +} + +void WebContextMenuProxyMac::populate(const Vector<WebContextMenuItemData>& items) +{ + if (m_popup) + [m_popup.get() removeAllItems]; + else { + m_popup.adoptNS([[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]); + [m_popup.get() setUsesItemFromMenu:NO]; + [m_popup.get() setAutoenablesItems:NO]; + } + + NSMenu* menu = [m_popup.get() menu]; + populateNSMenu(menu, nsMenuItemVector(items)); +} + +void WebContextMenuProxyMac::showContextMenu(const IntPoint& menuLocation, const Vector<WebContextMenuItemData>& items) +{ + populate(items); + [[WKMenuTarget sharedMenuTarget] setMenuProxy:this]; + + NSRect menuRect = NSMakeRect(menuLocation.x(), menuLocation.y(), 0, 0); + + [m_popup.get() attachPopUpWithFrame:menuRect inView:m_webView]; + + NSMenu* menu = [m_popup.get() menu]; + + // These values were borrowed from AppKit to match their placement of the menu. + NSRect titleFrame = [m_popup.get() titleRectForBounds:menuRect]; + if (titleFrame.size.width <= 0 || titleFrame.size.height <= 0) + titleFrame = menuRect; + float vertOffset = roundf((NSMaxY(menuRect) - NSMaxY(titleFrame)) + NSHeight(titleFrame)); + NSPoint location = NSMakePoint(NSMinX(menuRect), NSMaxY(menuRect) - vertOffset); + + RetainPtr<NSView> dummyView(AdoptNS, [[NSView alloc] initWithFrame:menuRect]); + [m_webView addSubview:dummyView.get()]; + location = [dummyView.get() convertPoint:location fromView:m_webView]; + + WKPopupMenu(menu, location, roundf(NSWidth(menuRect)), dummyView.get(), -1, nil); + + [m_popup.get() dismissPopUp]; + [dummyView.get() removeFromSuperview]; +} + +void WebContextMenuProxyMac::hideContextMenu() +{ + [m_popup.get() dismissPopUp]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm new file mode 100644 index 0000000..e129094 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebInspectorProxyMac.mm @@ -0,0 +1,142 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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 "WebInspectorProxy.h" + +#if ENABLE(INSPECTOR) + +#import "WKAPICast.h" +#import "WKView.h" +#import "WebPageProxy.h" +#import <WebKitSystemInterface.h> +#import <wtf/text/WTFString.h> + +using namespace WebCore; +using namespace WebKit; + +// The height needed to match a typical NSToolbar. +static const CGFloat windowContentBorderThickness = 55; + +// WebInspectorProxyObjCAdapter is a helper ObjC object used as a delegate or notification observer +// for the sole purpose of getting back into the C++ code from an ObjC caller. + +@interface WebInspectorProxyObjCAdapter : NSObject <NSWindowDelegate> { + WebInspectorProxy* _inspectorProxy; // Not retained to prevent cycles +} + +- (id)initWithWebInspectorProxy:(WebInspectorProxy*)inspectorProxy; + +@end + +@implementation WebInspectorProxyObjCAdapter + +- (id)initWithWebInspectorProxy:(WebInspectorProxy*)inspectorProxy +{ + ASSERT_ARG(inspectorProxy, inspectorProxy); + + if (!(self = [super init])) + return nil; + + _inspectorProxy = inspectorProxy; // Not retained to prevent cycles + + return self; +} + +- (void)windowWillClose:(NSNotification *)notification +{ + _inspectorProxy->close(); +} + +@end + +namespace WebKit { + +WebPageProxy* WebInspectorProxy::platformCreateInspectorPage() +{ + ASSERT(m_page); + ASSERT(!m_inspectorView); + + m_inspectorView.adoptNS([[WKView alloc] initWithFrame:NSZeroRect contextRef:toAPI(page()->context()) pageGroupRef:toAPI(inspectorPageGroup())]); + ASSERT(m_inspectorView); + + return toImpl(m_inspectorView.get().pageRef); +} + +void WebInspectorProxy::platformOpen() +{ + ASSERT(!m_inspectorWindow); + + m_inspectorProxyObjCAdapter.adoptNS([[WebInspectorProxyObjCAdapter alloc] initWithWebInspectorProxy:this]); + + // FIXME: support opening in docked mode here. + + NSUInteger styleMask = (NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask | NSTexturedBackgroundWindowMask); + NSWindow *window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, initialWindowWidth, initialWindowHeight) styleMask:styleMask backing:NSBackingStoreBuffered defer:NO]; + [window setAutorecalculatesContentBorderThickness:NO forEdge:NSMaxYEdge]; + [window setContentBorderThickness:windowContentBorderThickness forEdge:NSMaxYEdge]; + [window setDelegate:m_inspectorProxyObjCAdapter.get()]; + [window setMinSize:NSMakeSize(minimumWindowWidth, minimumWindowHeight)]; + [window setReleasedWhenClosed:NO]; + + // Center the window initially before setting the frame autosave name so that the window will be in a good + // position if there is no saved frame yet. + [window center]; + [window setFrameAutosaveName:@"Web Inspector 2"]; + + WKNSWindowMakeBottomCornersSquare(window); + + NSView *contentView = [window contentView]; + [m_inspectorView.get() setFrame:[contentView bounds]]; + [m_inspectorView.get() setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; + [contentView addSubview:m_inspectorView.get()]; + + [window makeKeyAndOrderFront:nil]; + + m_inspectorWindow.adoptNS(window); +} + +void WebInspectorProxy::platformClose() +{ + // FIXME: support closing in docked mode here. + + [m_inspectorWindow.get() setDelegate:nil]; + [m_inspectorWindow.get() orderOut:nil]; + + m_inspectorWindow = 0; + m_inspectorView = 0; + m_inspectorProxyObjCAdapter = 0; +} + +String WebInspectorProxy::inspectorPageURL() const +{ + NSString *path = [[NSBundle bundleWithIdentifier:@"com.apple.WebCore"] pathForResource:@"inspector" ofType:@"html" inDirectory:@"inspector"]; + ASSERT(path); + + return [[NSURL fileURLWithPath:path] absoluteString]; +} + +} // namespace WebKit + +#endif // ENABLE(INSPECTOR) diff --git a/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm new file mode 100644 index 0000000..36905fb --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebPageProxyMac.mm @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "WebPageProxy.h" + +#include <WebCore/Language.h> +#include <wtf/text/StringConcatenate.h> + +@interface NSApplication (Details) +- (void)speakString:(NSString *)string; +@end + +using namespace WebCore; + +namespace WebKit { + +#if defined(__ppc__) || defined(__ppc64__) +#define PROCESSOR "PPC" +#elif defined(__i386__) || defined(__x86_64__) +#define PROCESSOR "Intel" +#else +#error Unknown architecture +#endif + +static inline int callGestalt(OSType selector) +{ + SInt32 value = 0; + Gestalt(selector, &value); + return value; +} + +// Uses underscores instead of dots because if "4." ever appears in a user agent string, old DHTML libraries treat it as Netscape 4. +static String macOSXVersionString() +{ + // Can't use -[NSProcessInfo operatingSystemVersionString] because it has too much stuff we don't want. + int major = callGestalt(gestaltSystemVersionMajor); + ASSERT(major); + + int minor = callGestalt(gestaltSystemVersionMinor); + int bugFix = callGestalt(gestaltSystemVersionBugFix); + if (bugFix) + return String::format("%d_%d_%d", major, minor, bugFix); + if (minor) + return String::format("%d_%d", major, minor); + return String::format("%d", major); +} + +static String userVisibleWebKitVersionString() +{ + // If the version is 4 digits long or longer, then the first digit represents + // the version of the OS. Our user agent string should not include this first digit, + // so strip it off and report the rest as the version. <rdar://problem/4997547> + NSString *fullVersion = [[NSBundle bundleForClass:NSClassFromString(@"WKView")] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]; + NSRange nonDigitRange = [fullVersion rangeOfCharacterFromSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]]; + if (nonDigitRange.location == NSNotFound && [fullVersion length] >= 4) + return [fullVersion substringFromIndex:1]; + if (nonDigitRange.location != NSNotFound && nonDigitRange.location >= 4) + return [fullVersion substringFromIndex:1]; + return fullVersion; +} + +String WebPageProxy::standardUserAgent(const String& applicationNameForUserAgent) +{ + DEFINE_STATIC_LOCAL(String, osVersion, (macOSXVersionString())); + DEFINE_STATIC_LOCAL(String, webKitVersion, (userVisibleWebKitVersionString())); + + // FIXME: We should upate the user agent if the default language changes. + String language = defaultLanguage(); + + if (applicationNameForUserAgent.isEmpty()) + return makeString("Mozilla/5.0 (Macintosh; U; " PROCESSOR " Mac OS X ", osVersion, "; ", language, ") AppleWebKit/", webKitVersion, " (KHTML, like Gecko)"); + return makeString("Mozilla/5.0 (Macintosh; U; " PROCESSOR " Mac OS X ", osVersion, "; ", language, ") AppleWebKit/", webKitVersion, " (KHTML, like Gecko) ", applicationNameForUserAgent); +} + +void WebPageProxy::getIsSpeaking(bool& isSpeaking) +{ + isSpeaking = [NSApp isSpeaking]; +} + +void WebPageProxy::speak(const String& string) +{ + NSString *convertedString = string; + [NSApp speakString:convertedString]; +} + +void WebPageProxy::stopSpeaking() +{ + [NSApp stopSpeaking:nil]; +} + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h new file mode 100644 index 0000000..85339d6 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#ifndef WebPopupMenuProxyMac_h +#define WebPopupMenuProxyMac_h + +#include "WebPopupMenuProxy.h" +#include <wtf/RetainPtr.h> + +#ifdef __OBJC__ +@class NSPopUpButtonCell; +@class WKView; +#else +class NSPopUpButtonCell; +class WKView; +#endif + +namespace WebKit { + +class WebPageProxy; + +class WebPopupMenuProxyMac : public WebPopupMenuProxy { +public: + static PassRefPtr<WebPopupMenuProxyMac> create(WKView* webView, WebPopupMenuProxy::Client* client) + { + return adoptRef(new WebPopupMenuProxyMac(webView, client)); + } + ~WebPopupMenuProxyMac(); + + virtual void showPopupMenu(const WebCore::IntRect&, const Vector<WebPopupItem>&, const PlatformPopupMenuData&, int32_t selectedIndex); + virtual void hidePopupMenu(); + +private: + WebPopupMenuProxyMac(WKView*, WebPopupMenuProxy::Client* client); + + void populate(const Vector<WebPopupItem>&); + + RetainPtr<NSPopUpButtonCell> m_popup; + WKView* m_webView; +}; + +} // namespace WebKit + +#endif // WebPopupMenuProxyMac_h diff --git a/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm new file mode 100644 index 0000000..481e8c5 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebPopupMenuProxyMac.mm @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "WebPopupMenuProxyMac.h" + +#include "PageClientImpl.h" +#include "PlatformPopupMenuData.h" +#include "WKView.h" +#include "WebPopupItem.h" +#include <WebKitSystemInterface.h> + +using namespace WebCore; + +namespace WebKit { + +WebPopupMenuProxyMac::WebPopupMenuProxyMac(WKView* webView, WebPopupMenuProxy::Client* client) + : WebPopupMenuProxy(client) + , m_webView(webView) +{ +} + +WebPopupMenuProxyMac::~WebPopupMenuProxyMac() +{ + if (m_popup) + [m_popup.get() setControlView:nil]; +} + +void WebPopupMenuProxyMac::populate(const Vector<WebPopupItem>& items) +{ + if (m_popup) + [m_popup.get() removeAllItems]; + else { + m_popup.adoptNS([[NSPopUpButtonCell alloc] initTextCell:@"" pullsDown:NO]); + [m_popup.get() setUsesItemFromMenu:NO]; + [m_popup.get() setAutoenablesItems:NO]; + } + + int size = items.size(); + + for (int i = 0; i < size; i++) { + if (items[i].m_type == WebPopupItem::Seperator) + [[m_popup.get() menu] addItem:[NSMenuItem separatorItem]]; + else { + [m_popup.get() addItemWithTitle:nsStringFromWebCoreString(items[i].m_text)]; + NSMenuItem* menuItem = [m_popup.get() lastItem]; + [menuItem setEnabled:items[i].m_isEnabled]; + [menuItem setToolTip:nsStringFromWebCoreString(items[i].m_toolTip)]; + } + } +} + +void WebPopupMenuProxyMac::showPopupMenu(const IntRect& rect, const Vector<WebPopupItem>& items, const PlatformPopupMenuData&, int32_t selectedIndex) +{ + populate(items); + + [m_popup.get() attachPopUpWithFrame:rect inView:m_webView]; + [m_popup.get() selectItemAtIndex:selectedIndex]; + + NSMenu* menu = [m_popup.get() menu]; + + // These values were borrowed from AppKit to match their placement of the menu. + const int popOverHorizontalAdjust = -10; + NSRect titleFrame = [m_popup.get() titleRectForBounds:rect]; + if (titleFrame.size.width <= 0 || titleFrame.size.height <= 0) + titleFrame = rect; + float vertOffset = roundf((NSMaxY(rect) - NSMaxY(titleFrame)) + NSHeight(titleFrame)); + NSPoint location = NSMakePoint(NSMinX(rect) + popOverHorizontalAdjust, NSMaxY(rect) - vertOffset); + + RetainPtr<NSView> dummyView(AdoptNS, [[NSView alloc] initWithFrame:rect]); + [m_webView addSubview:dummyView.get()]; + location = [dummyView.get() convertPoint:location fromView:m_webView]; + + WKPopupMenu(menu, location, roundf(NSWidth(rect)), dummyView.get(), selectedIndex, [NSFont menuFontOfSize:0]); + + [m_popup.get() dismissPopUp]; + [dummyView.get() removeFromSuperview]; + + m_client->valueChangedForPopupMenu(this, [m_popup.get() indexOfSelectedItem]); +} + +void WebPopupMenuProxyMac::hidePopupMenu() +{ + [m_popup.get() dismissPopUp]; +} + + +} // namespace WebKit diff --git a/Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm b/Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm new file mode 100644 index 0000000..b954bd2 --- /dev/null +++ b/Source/WebKit2/UIProcess/mac/WebPreferencesMac.mm @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * + * 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 INC. AND ITS CONTRIBUTORS ``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 INC. OR ITS 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. + */ + +#include "WebPreferences.h" + +#include "PageClientImpl.h" +#include <wtf/text/StringConcatenate.h> + +namespace WebKit { + +static inline NSString* makeKey(const String& identifier, const String& baseKey) +{ + return nsStringFromWebCoreString(makeString(identifier, ".WebKit2", baseKey)); +} + +static void setStringValueIfInUserDefaults(const String& identifier, const String& key, WebPreferencesStore& store) +{ + id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(identifier, key)]; + if (!object) + return; + if (![object isKindOfClass:[NSString class]]) + return; + + store.setStringValueForKey(key, (NSString *)object); +} + +static void setBoolValueIfInUserDefaults(const String& identifier, const String& key, WebPreferencesStore& store) +{ + id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(identifier, key)]; + if (!object) + return; + if (![object respondsToSelector:@selector(boolValue)]) + return; + + store.setBoolValueForKey(key, [object boolValue]); +} + +static void setUInt32ValueIfInUserDefaults(const String& identifier, const String& key, WebPreferencesStore& store) +{ + id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(identifier, key)]; + if (!object) + return; + if (![object respondsToSelector:@selector(intValue)]) + return; + + store.setUInt32ValueForKey(key, [object intValue]); +} + +static void setDoubleValueIfInUserDefaults(const String& identifier, const String& key, WebPreferencesStore& store) +{ + id object = [[NSUserDefaults standardUserDefaults] objectForKey:makeKey(identifier, key)]; + if (!object) + return; + if (![object respondsToSelector:@selector(doubleValue)]) + return; + + store.setDoubleValueForKey(key, [object doubleValue]); +} + +void WebPreferences::platformInitializeStore() +{ + if (!m_identifier) + return; + +#define INITIALIZE_PREFERENCE_FROM_NSUSERDEFAULTS(KeyUpper, KeyLower, TypeName, Type, DefaultValue) \ + set##TypeName##ValueIfInUserDefaults(m_identifier, WebPreferencesKey::KeyLower##Key(), m_store); + + FOR_EACH_WEBKIT_PREFERENCE(INITIALIZE_PREFERENCE_FROM_NSUSERDEFAULTS) + +#undef INITIALIZE_PREFERENCE_FROM_NSUSERDEFAULTS +} + +void WebPreferences::platformUpdateStringValueForKey(const String& key, const String& value) +{ + if (!m_identifier) + return; + + [[NSUserDefaults standardUserDefaults] setObject:nsStringFromWebCoreString(value) forKey:makeKey(m_identifier, key)]; +} + +void WebPreferences::platformUpdateBoolValueForKey(const String& key, bool value) +{ + if (!m_identifier) + return; + + [[NSUserDefaults standardUserDefaults] setBool:value forKey:makeKey(m_identifier, key)]; +} + +void WebPreferences::platformUpdateUInt32ValueForKey(const String& key, uint32_t value) +{ + if (!m_identifier) + return; + + [[NSUserDefaults standardUserDefaults] setInteger:value forKey:makeKey(m_identifier, key)]; +} + +void WebPreferences::platformUpdateDoubleValueForKey(const String& key, double value) +{ + if (!m_identifier) + return; + + [[NSUserDefaults standardUserDefaults] setDouble:value forKey:makeKey(m_identifier, key)]; +} + +} // namespace WebKit |