/*
 * Copyright (C) 2005-2020 Apple Inc. All rights reserved.
 *           (C) 2006, 2007 Graham Dennis (graham.dennis@gmail.com)
 *
 * 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. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "WebHTMLView.h"

#import "DOMCSSStyleDeclarationInternal.h"
#import "DOMDocumentFragmentInternal.h"
#import "DOMDocumentInternal.h"
#import "DOMNodeInternal.h"
#import "DOMRangeInternal.h"
#import "WebArchive.h"
#import "WebClipView.h"
#import "WebContextMenuClient.h"
#import "WebDOMOperationsInternal.h"
#import "WebDataSourceInternal.h"
#import "WebDefaultUIDelegate.h"
#import "WebDelegateImplementationCaching.h"
#import "WebDocumentInternal.h"
#import "WebDynamicScrollBarsViewInternal.h"
#import "WebEditingDelegate.h"
#import "WebElementDictionary.h"
#import "WebFrameInternal.h"
#import "WebFramePrivate.h"
#import "WebFrameViewInternal.h"
#import "WebHTMLRepresentationPrivate.h"
#import "WebHTMLViewInternal.h"
#import "WebImmediateActionController.h"
#import "WebKitLogging.h"
#import "WebKitNSStringExtras.h"
#import "WebKitVersionChecks.h"
#import "WebLocalizableStringsInternal.h"
#import "WebNSFileManagerExtras.h"
#import "WebNSImageExtras.h"
#import "WebNSObjectExtras.h"
#import "WebNSPrintOperationExtras.h"
#import "WebNSURLExtras.h"
#import "WebNSViewExtras.h"
#import "WebNodeHighlight.h"
#import "WebPluginController.h"
#import "WebPreferences.h"
#import "WebPreferencesPrivate.h"
#import "WebResourcePrivate.h"
#import "WebSharingServicePickerController.h"
#import "WebTextCompletionController.h"
#import "WebUIDelegatePrivate.h"
#import "WebViewInternal.h"
#import <JavaScriptCore/InitializeThreading.h>
#import <QuartzCore/QuartzCore.h>
#import <WebCore/CSSStyleDeclaration.h>
#import <WebCore/CachedImage.h>
#import <WebCore/CachedResourceClient.h>
#import <WebCore/CachedResourceLoader.h>
#import <WebCore/Chrome.h>
#import <WebCore/ColorMac.h>
#import <WebCore/CompositionHighlight.h>
#import <WebCore/ContextMenu.h>
#import <WebCore/ContextMenuController.h>
#import <WebCore/DictationAlternative.h>
#import <WebCore/DictionaryLookup.h>
#import <WebCore/Document.h>
#import <WebCore/DocumentFragment.h>
#import <WebCore/DocumentMarkerController.h>
#import <WebCore/DragController.h>
#import <WebCore/DragImage.h>
#import <WebCore/Editor.h>
#import <WebCore/EditorDeleteAction.h>
#import <WebCore/Element.h>
#import <WebCore/EventHandler.h>
#import <WebCore/FloatRect.h>
#import <WebCore/FocusController.h>
#import <WebCore/Font.h>
#import <WebCore/FontAttributeChanges.h>
#import <WebCore/FontAttributes.h>
#import <WebCore/FontCache.h>
#import <WebCore/Frame.h>
#import <WebCore/FrameLoader.h>
#import <WebCore/FrameSelection.h>
#import <WebCore/FrameView.h>
#import <WebCore/HTMLConverter.h>
#import <WebCore/HTMLNames.h>
#import <WebCore/HitTestResult.h>
#import <WebCore/Image.h>
#import <WebCore/KeyboardEvent.h>
#import <WebCore/LegacyNSPasteboardTypes.h>
#import <WebCore/LegacyWebArchive.h>
#import <WebCore/LocalizedStrings.h>
#import <WebCore/MIMETypeRegistry.h>
#import <WebCore/Page.h>
#import <WebCore/PrintContext.h>
#import <WebCore/Range.h>
#import <WebCore/RenderView.h>
#import <WebCore/RenderWidget.h>
#import <WebCore/RuntimeApplicationChecks.h>
#import <WebCore/RuntimeEnabledFeatures.h>
#import <WebCore/SharedBuffer.h>
#import <WebCore/StyleProperties.h>
#import <WebCore/StyleScope.h>
#import <WebCore/Text.h>
#import <WebCore/TextAlternativeWithRange.h>
#import <WebCore/TextIndicator.h>
#import <WebCore/TextUndoInsertionMarkupMac.h>
#import <WebCore/WebCoreJITOperations.h>
#import <WebCore/WebCoreNSFontManagerExtras.h>
#import <WebCore/WebCoreObjCExtras.h>
#import <WebCore/WebNSAttributedStringExtras.h>
#import <WebCore/markup.h>
#import <WebKitLegacy/DOM.h>
#import <WebKitLegacy/DOMExtensions.h>
#import <WebKitLegacy/DOMPrivate.h>
#import <dlfcn.h>
#import <limits>
#import <pal/spi/cf/CFUtilitiesSPI.h>
#import <pal/spi/cocoa/NSAttributedStringSPI.h>
#import <pal/spi/cocoa/NSURLFileTypeMappingsSPI.h>
#import <pal/spi/mac/NSMenuSPI.h>
#import <pal/spi/mac/NSScrollerImpSPI.h>
#import <pal/spi/mac/NSSpellCheckerSPI.h>
#import <pal/spi/mac/NSViewSPI.h>
#import <pal/spi/mac/NSWindowSPI.h>
#import <wtf/BlockObjCExceptions.h>
#import <wtf/MainThread.h>
#import <wtf/MathExtras.h>
#import <wtf/NakedPtr.h>
#import <wtf/ObjCRuntimeExtras.h>
#import <wtf/RunLoop.h>
#import <wtf/SystemTracing.h>
#import <wtf/WeakObjCPtr.h>
#import <wtf/cocoa/TypeCastsCocoa.h>
#import <wtf/cocoa/VectorCocoa.h>

#if PLATFORM(MAC)
#import "WebNSEventExtras.h"
#import "WebNSPasteboardExtras.h"
#import <AppKit/NSAccessibility.h>
#import <WebCore/PlatformEventFactoryMac.h>
#import <pal/spi/mac/NSMenuSPI.h>
#import <pal/spi/mac/NSTextInputContextSPI.h>
#endif

#if PLATFORM(IOS_FAMILY)
#import "WebUIKitDelegate.h"
#import <WebCore/GraphicsContextCG.h>
#import <WebCore/KeyEventCodesIOS.h>
#import <WebCore/PlatformEventFactoryIOS.h>
#import <WebCore/WAKClipView.h>
#import <WebCore/WAKScrollView.h>
#import <WebCore/WAKWindow.h>
#import <WebCore/WKGraphics.h>
#import <WebCore/WebCoreThreadRun.h>
#import <WebCore/WebEvent.h>
#import <pal/spi/cf/CFNotificationCenterSPI.h>
#import <pal/spi/ios/GraphicsServicesSPI.h>
#endif

#if PLATFORM(IOS_FAMILY)

@interface NSObject (Accessibility)
- (id)accessibilityHitTest:(NSPoint)point;
- (id)accessibilityFocusedUIElement;
@end

#endif

#if PLATFORM(MAC)

@class NSTextInputContext;

@interface NSApplication ()
- (BOOL)isSpeaking;
- (void)speakString:(NSString *)string;
- (void)stopSpeaking:(id)sender;
@end

@interface NSAttributedString ()
- (DOMDocumentFragment *)_documentFromRange:(NSRange)range document:(DOMDocument *)document documentAttributes:(NSDictionary *)dict subresources:(NSArray **)subresources;
@end

@interface NSObject ()
- (BOOL)handleMouseEvent:(NSEvent *)event;
- (BOOL)wantsToHandleMouseEvents;
@end

@interface NSResponder ()
- (NSTextInputContext *)inputContext;
@end

@interface NSView ()
- (BOOL)_drawnByAncestor;
- (void)_invalidateGStatesForTree;
- (void)_windowChangedKeyState;
@end

@interface NSWindow ()
@property (readonly) __kindof NSView *_borderView;

- (id)_newFirstResponderAfterResigning;
@end

using WebEvent = NSEvent;
const auto WebEventMouseDown = NSEventTypeLeftMouseDown;

@interface WebMenuTarget : NSObject {
    NakedPtr<WebCore::ContextMenuController> _menuController;
}
+ (WebMenuTarget*)sharedMenuTarget;
- (NakedPtr<WebCore::ContextMenuController>)menuController;
- (void)setMenuController:(NakedPtr<WebCore::ContextMenuController>)menuController;
- (void)forwardContextMenuAction:(id)sender;
@end

static std::optional<WebCore::ContextMenuAction> toAction(NSInteger tag)
{
    using namespace WebCore;
    if (tag >= ContextMenuItemBaseCustomTag && tag <= ContextMenuItemLastCustomTag) {
        // Just pass these through.
        return static_cast<ContextMenuAction>(tag);
    }

    switch (tag) {
    case WebMenuItemTagOpenLinkInNewWindow:
        return ContextMenuItemTagOpenLinkInNewWindow;
    case WebMenuItemTagDownloadLinkToDisk:
        return ContextMenuItemTagDownloadLinkToDisk;
    case WebMenuItemTagCopyLinkToClipboard:
        return ContextMenuItemTagCopyLinkToClipboard;
    case WebMenuItemTagOpenImageInNewWindow:
        return ContextMenuItemTagOpenImageInNewWindow;
    case WebMenuItemTagDownloadImageToDisk:
        return ContextMenuItemTagDownloadImageToDisk;
    case WebMenuItemTagCopyImageToClipboard:
        return ContextMenuItemTagCopyImageToClipboard;
    case WebMenuItemTagOpenFrameInNewWindow:
        return ContextMenuItemTagOpenFrameInNewWindow;
    case WebMenuItemTagCopy:
        return ContextMenuItemTagCopy;
    case WebMenuItemTagGoBack:
        return ContextMenuItemTagGoBack;
    case WebMenuItemTagGoForward:
        return ContextMenuItemTagGoForward;
    case WebMenuItemTagStop:
        return ContextMenuItemTagStop;
    case WebMenuItemTagReload:
        return ContextMenuItemTagReload;
    case WebMenuItemTagCut:
        return ContextMenuItemTagCut;
    case WebMenuItemTagPaste:
        return ContextMenuItemTagPaste;
    case WebMenuItemTagSpellingGuess:
        return ContextMenuItemTagSpellingGuess;
    case WebMenuItemTagNoGuessesFound:
        return ContextMenuItemTagNoGuessesFound;
    case WebMenuItemTagIgnoreSpelling:
        return ContextMenuItemTagIgnoreSpelling;
    case WebMenuItemTagLearnSpelling:
        return ContextMenuItemTagLearnSpelling;
    case WebMenuItemTagOther:
        return ContextMenuItemTagOther;
    case WebMenuItemTagSearchInSpotlight:
        return ContextMenuItemTagSearchInSpotlight;
    case WebMenuItemTagSearchWeb:
        return ContextMenuItemTagSearchWeb;
    case WebMenuItemTagLookUpInDictionary:
        return ContextMenuItemTagLookUpInDictionary;
    case WebMenuItemTagOpenWithDefaultApplication:
        return ContextMenuItemTagOpenWithDefaultApplication;
    case WebMenuItemPDFActualSize:
        return ContextMenuItemPDFActualSize;
    case WebMenuItemPDFZoomIn:
        return ContextMenuItemPDFZoomIn;
    case WebMenuItemPDFZoomOut:
        return ContextMenuItemPDFZoomOut;
    case WebMenuItemPDFAutoSize:
        return ContextMenuItemPDFAutoSize;
    case WebMenuItemPDFSinglePage:
        return ContextMenuItemPDFSinglePage;
    case WebMenuItemPDFFacingPages:
        return ContextMenuItemPDFFacingPages;
    case WebMenuItemPDFContinuous:
        return ContextMenuItemPDFContinuous;
    case WebMenuItemPDFNextPage:
        return ContextMenuItemPDFNextPage;
    case WebMenuItemPDFPreviousPage:
        return ContextMenuItemPDFPreviousPage;
    case WebMenuItemTagOpenLink:
        return ContextMenuItemTagOpenLink;
    case WebMenuItemTagIgnoreGrammar:
        return ContextMenuItemTagIgnoreGrammar;
    case WebMenuItemTagSpellingMenu:
        return ContextMenuItemTagSpellingMenu;
    case WebMenuItemTagShowSpellingPanel:
        return ContextMenuItemTagShowSpellingPanel;
    case WebMenuItemTagCheckSpelling:
        return ContextMenuItemTagCheckSpelling;
    case WebMenuItemTagCheckSpellingWhileTyping:
        return ContextMenuItemTagCheckSpellingWhileTyping;
    case WebMenuItemTagCheckGrammarWithSpelling:
        return ContextMenuItemTagCheckGrammarWithSpelling;
    case WebMenuItemTagFontMenu:
        return ContextMenuItemTagFontMenu;
    case WebMenuItemTagShowFonts:
        return ContextMenuItemTagShowFonts;
    case WebMenuItemTagBold:
        return ContextMenuItemTagBold;
    case WebMenuItemTagItalic:
        return ContextMenuItemTagItalic;
    case WebMenuItemTagUnderline:
        return ContextMenuItemTagUnderline;
    case WebMenuItemTagOutline:
        return ContextMenuItemTagOutline;
    case WebMenuItemTagStyles:
        return ContextMenuItemTagStyles;
    case WebMenuItemTagShowColors:
        return ContextMenuItemTagShowColors;
    case WebMenuItemTagSpeechMenu:
        return ContextMenuItemTagSpeechMenu;
    case WebMenuItemTagStartSpeaking:
        return ContextMenuItemTagStartSpeaking;
    case WebMenuItemTagStopSpeaking:
        return ContextMenuItemTagStopSpeaking;
    case WebMenuItemTagWritingDirectionMenu:
        return ContextMenuItemTagWritingDirectionMenu;
    case WebMenuItemTagDefaultDirection:
        return ContextMenuItemTagDefaultDirection;
    case WebMenuItemTagLeftToRight:
        return ContextMenuItemTagLeftToRight;
    case WebMenuItemTagRightToLeft:
        return ContextMenuItemTagRightToLeft;
    case WebMenuItemPDFSinglePageScrolling:
        return ContextMenuItemTagPDFSinglePageScrolling;
    case WebMenuItemPDFFacingPagesScrolling:
        return ContextMenuItemTagPDFFacingPagesScrolling;
    case WebMenuItemTagInspectElement:
        return ContextMenuItemTagInspectElement;
    case WebMenuItemTagTextDirectionMenu:
        return ContextMenuItemTagTextDirectionMenu;
    case WebMenuItemTagTextDirectionDefault:
        return ContextMenuItemTagTextDirectionDefault;
    case WebMenuItemTagTextDirectionLeftToRight:
        return ContextMenuItemTagTextDirectionLeftToRight;
    case WebMenuItemTagTextDirectionRightToLeft:
        return ContextMenuItemTagTextDirectionRightToLeft;
    case WebMenuItemTagCorrectSpellingAutomatically:
        return ContextMenuItemTagCorrectSpellingAutomatically;
    case WebMenuItemTagSubstitutionsMenu:
        return ContextMenuItemTagSubstitutionsMenu;
    case WebMenuItemTagShowSubstitutions:
        return ContextMenuItemTagShowSubstitutions;
    case WebMenuItemTagSmartCopyPaste:
        return ContextMenuItemTagSmartCopyPaste;
    case WebMenuItemTagSmartQuotes:
        return ContextMenuItemTagSmartQuotes;
    case WebMenuItemTagSmartDashes:
        return ContextMenuItemTagSmartDashes;
    case WebMenuItemTagSmartLinks:
        return ContextMenuItemTagSmartLinks;
    case WebMenuItemTagTextReplacement:
        return ContextMenuItemTagTextReplacement;
    case WebMenuItemTagTransformationsMenu:
        return ContextMenuItemTagTransformationsMenu;
    case WebMenuItemTagMakeUpperCase:
        return ContextMenuItemTagMakeUpperCase;
    case WebMenuItemTagMakeLowerCase:
        return ContextMenuItemTagMakeLowerCase;
    case WebMenuItemTagCapitalize:
        return ContextMenuItemTagCapitalize;
    case WebMenuItemTagChangeBack:
        return ContextMenuItemTagChangeBack;
    case WebMenuItemTagOpenMediaInNewWindow:
        return ContextMenuItemTagOpenMediaInNewWindow;
    case WebMenuItemTagCopyMediaLinkToClipboard:
        return ContextMenuItemTagCopyMediaLinkToClipboard;
    case WebMenuItemTagToggleMediaControls:
        return ContextMenuItemTagToggleMediaControls;
    case WebMenuItemTagToggleMediaLoop:
        return ContextMenuItemTagToggleMediaLoop;
    case WebMenuItemTagEnterVideoFullscreen:
        return ContextMenuItemTagEnterVideoFullscreen;
    case WebMenuItemTagToggleVideoEnhancedFullscreen:
        return ContextMenuItemTagToggleVideoEnhancedFullscreen;
    case WebMenuItemTagMediaPlayPause:
        return ContextMenuItemTagMediaPlayPause;
    case WebMenuItemTagMediaMute:
        return ContextMenuItemTagMediaMute;
    case WebMenuItemTagDictationAlternative:
        return ContextMenuItemTagDictationAlternative;
    case WebMenuItemTagTranslate:
        return ContextMenuItemTagTranslate;
    }
    return std::nullopt;
}

static std::optional<NSInteger> toTag(WebCore::ContextMenuAction action)
{
    using namespace WebCore;
    switch (action) {
    case ContextMenuItemTagNoAction:
        return std::nullopt;

    case ContextMenuItemTagOpenLinkInNewWindow:
        return WebMenuItemTagOpenLinkInNewWindow;
    case ContextMenuItemTagDownloadLinkToDisk:
        return WebMenuItemTagDownloadLinkToDisk;
    case ContextMenuItemTagCopyLinkToClipboard:
        return WebMenuItemTagCopyLinkToClipboard;
    case ContextMenuItemTagOpenImageInNewWindow:
        return WebMenuItemTagOpenImageInNewWindow;
    case ContextMenuItemTagDownloadImageToDisk:
        return WebMenuItemTagDownloadImageToDisk;
    case ContextMenuItemTagCopyImageToClipboard:
        return WebMenuItemTagCopyImageToClipboard;
    case ContextMenuItemTagOpenFrameInNewWindow:
        return WebMenuItemTagOpenFrameInNewWindow;
    case ContextMenuItemTagCopy:
        return WebMenuItemTagCopy;
    case ContextMenuItemTagGoBack:
        return WebMenuItemTagGoBack;
    case ContextMenuItemTagGoForward:
        return WebMenuItemTagGoForward;
    case ContextMenuItemTagStop:
        return WebMenuItemTagStop;
    case ContextMenuItemTagReload:
        return WebMenuItemTagReload;
    case ContextMenuItemTagCut:
        return WebMenuItemTagCut;
    case ContextMenuItemTagPaste:
        return WebMenuItemTagPaste;
    case ContextMenuItemTagSpellingGuess:
        return WebMenuItemTagSpellingGuess;
    case ContextMenuItemTagNoGuessesFound:
        return WebMenuItemTagNoGuessesFound;
    case ContextMenuItemTagIgnoreSpelling:
        return WebMenuItemTagIgnoreSpelling;
    case ContextMenuItemTagLearnSpelling:
        return WebMenuItemTagLearnSpelling;
    case ContextMenuItemTagOther:
        return WebMenuItemTagOther;
    case ContextMenuItemTagSearchInSpotlight:
        return WebMenuItemTagSearchInSpotlight;
    case ContextMenuItemTagSearchWeb:
        return WebMenuItemTagSearchWeb;
    case ContextMenuItemTagLookUpInDictionary:
        return WebMenuItemTagLookUpInDictionary;
    case ContextMenuItemTagOpenWithDefaultApplication:
        return WebMenuItemTagOpenWithDefaultApplication;
    case ContextMenuItemPDFActualSize:
        return WebMenuItemPDFActualSize;
    case ContextMenuItemPDFZoomIn:
        return WebMenuItemPDFZoomIn;
    case ContextMenuItemPDFZoomOut:
        return WebMenuItemPDFZoomOut;
    case ContextMenuItemPDFAutoSize:
        return WebMenuItemPDFAutoSize;
    case ContextMenuItemPDFSinglePage:
        return WebMenuItemPDFSinglePage;
    case ContextMenuItemPDFFacingPages:
        return WebMenuItemPDFFacingPages;
    case ContextMenuItemPDFContinuous:
        return WebMenuItemPDFContinuous;
    case ContextMenuItemPDFNextPage:
        return WebMenuItemPDFNextPage;
    case ContextMenuItemPDFPreviousPage:
        return WebMenuItemPDFPreviousPage;
    case ContextMenuItemTagOpenLink:
        return WebMenuItemTagOpenLink;
    case ContextMenuItemTagIgnoreGrammar:
        return WebMenuItemTagIgnoreGrammar;
    case ContextMenuItemTagSpellingMenu:
        return WebMenuItemTagSpellingMenu;
    case ContextMenuItemTagShowSpellingPanel:
        return WebMenuItemTagShowSpellingPanel;
    case ContextMenuItemTagCheckSpelling:
        return WebMenuItemTagCheckSpelling;
    case ContextMenuItemTagCheckSpellingWhileTyping:
        return WebMenuItemTagCheckSpellingWhileTyping;
    case ContextMenuItemTagCheckGrammarWithSpelling:
        return WebMenuItemTagCheckGrammarWithSpelling;
    case ContextMenuItemTagFontMenu:
        return WebMenuItemTagFontMenu;
    case ContextMenuItemTagShowFonts:
        return WebMenuItemTagShowFonts;
    case ContextMenuItemTagBold:
        return WebMenuItemTagBold;
    case ContextMenuItemTagItalic:
        return WebMenuItemTagItalic;
    case ContextMenuItemTagUnderline:
        return WebMenuItemTagUnderline;
    case ContextMenuItemTagOutline:
        return WebMenuItemTagOutline;
    case ContextMenuItemTagStyles:
        return WebMenuItemTagStyles;
    case ContextMenuItemTagShowColors:
        return WebMenuItemTagShowColors;
    case ContextMenuItemTagSpeechMenu:
        return WebMenuItemTagSpeechMenu;
    case ContextMenuItemTagStartSpeaking:
        return WebMenuItemTagStartSpeaking;
    case ContextMenuItemTagStopSpeaking:
        return WebMenuItemTagStopSpeaking;
    case ContextMenuItemTagWritingDirectionMenu:
        return WebMenuItemTagWritingDirectionMenu;
    case ContextMenuItemTagDefaultDirection:
        return WebMenuItemTagDefaultDirection;
    case ContextMenuItemTagLeftToRight:
        return WebMenuItemTagLeftToRight;
    case ContextMenuItemTagRightToLeft:
        return WebMenuItemTagRightToLeft;
    case ContextMenuItemTagPDFSinglePageScrolling:
        return WebMenuItemPDFSinglePageScrolling;
    case ContextMenuItemTagPDFFacingPagesScrolling:
        return WebMenuItemPDFFacingPagesScrolling;
    case ContextMenuItemTagInspectElement:
        return WebMenuItemTagInspectElement;
    case ContextMenuItemTagTextDirectionMenu:
        return WebMenuItemTagTextDirectionMenu;
    case ContextMenuItemTagTextDirectionDefault:
        return WebMenuItemTagTextDirectionDefault;
    case ContextMenuItemTagTextDirectionLeftToRight:
        return WebMenuItemTagTextDirectionLeftToRight;
    case ContextMenuItemTagTextDirectionRightToLeft:
        return WebMenuItemTagTextDirectionRightToLeft;
    case ContextMenuItemTagCorrectSpellingAutomatically:
        return WebMenuItemTagCorrectSpellingAutomatically;
    case ContextMenuItemTagSubstitutionsMenu:
        return WebMenuItemTagSubstitutionsMenu;
    case ContextMenuItemTagShowSubstitutions:
        return WebMenuItemTagShowSubstitutions;
    case ContextMenuItemTagSmartCopyPaste:
        return WebMenuItemTagSmartCopyPaste;
    case ContextMenuItemTagSmartQuotes:
        return WebMenuItemTagSmartQuotes;
    case ContextMenuItemTagSmartDashes:
        return WebMenuItemTagSmartDashes;
    case ContextMenuItemTagSmartLinks:
        return WebMenuItemTagSmartLinks;
    case ContextMenuItemTagTextReplacement:
        return WebMenuItemTagTextReplacement;
    case ContextMenuItemTagTransformationsMenu:
        return WebMenuItemTagTransformationsMenu;
    case ContextMenuItemTagMakeUpperCase:
        return WebMenuItemTagMakeUpperCase;
    case ContextMenuItemTagMakeLowerCase:
        return WebMenuItemTagMakeLowerCase;
    case ContextMenuItemTagCapitalize:
        return WebMenuItemTagCapitalize;
    case ContextMenuItemTagChangeBack:
        return WebMenuItemTagChangeBack;
    case ContextMenuItemTagOpenMediaInNewWindow:
        return WebMenuItemTagOpenMediaInNewWindow;
    case ContextMenuItemTagDownloadMediaToDisk:
        return WebMenuItemTagDownloadMediaToDisk;
    case ContextMenuItemTagCopyMediaLinkToClipboard:
        return WebMenuItemTagCopyMediaLinkToClipboard;
    case ContextMenuItemTagToggleMediaControls:
        return WebMenuItemTagToggleMediaControls;
    case ContextMenuItemTagToggleMediaLoop:
        return WebMenuItemTagToggleMediaLoop;
    case ContextMenuItemTagEnterVideoFullscreen:
        return WebMenuItemTagEnterVideoFullscreen;
    case ContextMenuItemTagMediaPlayPause:
        return WebMenuItemTagMediaPlayPause;
    case ContextMenuItemTagMediaMute:
        return WebMenuItemTagMediaMute;
    case ContextMenuItemTagDictationAlternative:
        return WebMenuItemTagDictationAlternative;
    case ContextMenuItemTagToggleVideoFullscreen:
        return WebMenuItemTagToggleVideoFullscreen;
    case ContextMenuItemTagAddHighlightToCurrentQuickNote:
    case ContextMenuItemTagAddHighlightToNewQuickNote:
        return std::nullopt;
    case ContextMenuItemTagShareMenu:
        return WebMenuItemTagShareMenu;
    case ContextMenuItemTagToggleVideoEnhancedFullscreen:
        return WebMenuItemTagToggleVideoEnhancedFullscreen;
    case ContextMenuItemTagTranslate:
        return WebMenuItemTagTranslate;
    case ContextMenuItemTagCopySubject:
    case ContextMenuItemTagLookUpImage:
        return std::nullopt;

    case ContextMenuItemBaseCustomTag ... ContextMenuItemLastCustomTag:
        // We just pass these through.
        return static_cast<NSInteger>(action);

    case ContextMenuItemBaseApplicationTag:
        ASSERT_NOT_REACHED();
    }

    return std::nullopt;
}

@implementation WebMenuTarget

+ (WebMenuTarget *)sharedMenuTarget
{
    static WebMenuTarget *target = [[WebMenuTarget alloc] init];
    return target;
}

- (NakedPtr<WebCore::ContextMenuController>)menuController
{
    return _menuController;
}

- (void)setMenuController:(NakedPtr<WebCore::ContextMenuController>)menuController
{
    _menuController = menuController;
}

- (void)forwardContextMenuAction:(id)sender
{
    if (auto action = toAction([sender tag]))
        _menuController->contextMenuItemSelected(*action, [sender title]);
}

@end

@interface WebResponderChainSink : NSResponder {
    NSResponder* _lastResponderInChain;
    BOOL _receivedUnhandledCommand;
}
- (id)initWithResponderChain:(NSResponder *)chain;
- (void)detach;
- (BOOL)receivedUnhandledCommand;
@end

@interface WebLayerHostingFlippedView : NSView
@end

@implementation WebLayerHostingFlippedView

- (BOOL)isFlipped
{
    return YES;
}

@end

@interface WebRootLayer : CALayer
@end

@implementation WebRootLayer

- (void)renderInContext:(CGContextRef)graphicsContext
{
    // AppKit calls -[CALayer renderInContext:] to render layer-backed views
    // into bitmap contexts, but renderInContext: doesn't capture mask layers
    // (<rdar://problem/9539526>), so we can't rely on it. Since our layer
    // contents will have already been rendered by drawRect:, we can safely make
    // this a NOOP.
}

@end

// if YES, do the standard NSView hit test (which can't give the right result when HTML overlaps a view)
static BOOL forceNSViewHitTest;

// if YES, do the "top WebHTMLView" hit test (which we'd like to do all the time but can't because of Java requirements [see bug 4349721])
static BOOL forceWebHTMLViewHitTest;

static WebHTMLView *lastHitView;

static bool needsCursorRectsSupportAtPoint(NSWindow* window, NSPoint point)
{
    forceNSViewHitTest = YES;
    NSView* view = [window._borderView hitTest:point];
    forceNSViewHitTest = NO;

    // WebHTMLView doesn't use cursor rects.
    if ([view isKindOfClass:[WebHTMLView class]])
        return false;

    // Non-Web content, WebPDFView, and WebKit plug-ins use normal cursor handling.
    return true;
}

static IMP oldSetCursorForMouseLocationIMP;

// Overriding an internal method is a hack; <rdar://problem/7662987> tracks finding a better solution.
static void setCursor(NSWindow *self, SEL cmd, NSPoint point)
{
    if (needsCursorRectsSupportAtPoint(self, point))
        wtfCallIMP<id>(oldSetCursorForMouseLocationIMP, self, cmd, point);
}

#endif // PLATFORM(MAC)

@interface NSView ()
- (void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)isVisibleRect rectIsVisibleRectForView:(NSView *)visibleView topView:(BOOL)topView;
- (void)_recursiveDisplayAllDirtyWithLockFocus:(BOOL)needsLockFocus visRect:(NSRect)visRect;
#if PLATFORM(MAC)
- (void)_recursive:(BOOL)recursive displayRectIgnoringOpacity:(NSRect)displayRect inContext:(NSGraphicsContext *)graphicsContext stopAtLayerBackedViews:(BOOL)stopAtLayerBackedViews;
#endif
- (void)_setDrawsOwnDescendants:(BOOL)drawsOwnDescendants;
#if PLATFORM(IOS_FAMILY)
- (void)centerSelectionInVisibleArea:(id)sender;
#endif
@end

#if PLATFORM(MAC)

@interface NSView (WebSetNeedsDisplayInRect)
- (void)_web_setNeedsDisplayInRect:(NSRect)invalidRect;
@end

@implementation NSView (WebSetNeedsDisplayInRect)

- (void)_web_setNeedsDisplayInRect:(NSRect)invalidRect
{
    // Note that we call method_exchangeImplementations below, so any calls
    // to _web_setNeedsDisplayInRect: will actually call -[NSView setNeedsDisplayInRect:].

    if (![NSThread isMainThread] || ![self _drawnByAncestor]) {
        [self _web_setNeedsDisplayInRect:invalidRect];
        return;
    }

    static Class webFrameViewClass = [WebFrameView class];
    WebFrameView *enclosingWebFrameView = (WebFrameView *)self;
    while (enclosingWebFrameView && ![enclosingWebFrameView isKindOfClass:webFrameViewClass])
        enclosingWebFrameView = (WebFrameView *)[enclosingWebFrameView superview];

    if (!enclosingWebFrameView) {
        [self _web_setNeedsDisplayInRect:invalidRect];
        return;
    }

    auto* coreFrame = core([enclosingWebFrameView webFrame]);
    auto* frameView = coreFrame ? coreFrame->view() : 0;
    if (!frameView || !frameView->isEnclosedInCompositingLayer()) {
        [self _web_setNeedsDisplayInRect:invalidRect];
        return;
    }

    NSRect invalidRectInWebFrameViewCoordinates = [enclosingWebFrameView convertRect:invalidRect fromView:self];
    WebCore::IntRect invalidRectInFrameViewCoordinates(invalidRectInWebFrameViewCoordinates);
    if (![enclosingWebFrameView isFlipped])
        invalidRectInFrameViewCoordinates.setY(frameView->frameRect().size().height() - invalidRectInFrameViewCoordinates.maxY());

    frameView->invalidateRect(invalidRectInFrameViewCoordinates);
}

@end

#endif // PLATFORM(MAC)

const float _WebHTMLViewPrintingMinimumShrinkFactor = WebCore::PrintContext::minimumShrinkFactor();
const float _WebHTMLViewPrintingMaximumShrinkFactor = WebCore::PrintContext::maximumShrinkFactor();

// Any non-zero value will do, but using something recognizable might help us debug some day.
#define TRACKING_RECT_TAG 0xBADFACE

// FIXME: From AppKit's _NXSmartPaste constant. Get with an SPI header instead?
#define WebSmartPastePboardType @"NeXT smart paste pasteboard type"

#define STANDARD_WEIGHT 5
#define MIN_BOLD_WEIGHT 7
#define STANDARD_BOLD_WEIGHT 9

#if PLATFORM(MAC)

// <rdar://problem/4985524> References to WebCoreScrollView as a subview of a WebHTMLView may be present
// in some NIB files, so NSUnarchiver must be still able to look up this now-unused class.
@interface WebCoreScrollView : NSScrollView
@end

@implementation WebCoreScrollView
@end

// We need this to be able to safely reference the CachedImage for the promised drag data
static WebCore::CachedImageClient& promisedDataClient()
{
    static NeverDestroyed<WebCore::CachedImageClient> staticCachedResourceClient;
    return staticCachedResourceClient.get();
}

#endif

#if PLATFORM(IOS_FAMILY)
static NSString * const WebMarkedTextUpdatedNotification = @"WebMarkedTextUpdated";

static void hardwareKeyboardAvailabilityChangedCallback(CFNotificationCenterRef, void* observer, CFStringRef, const void*, CFDictionaryRef)
{
    ASSERT(observer);
    WeakObjCPtr<WebHTMLView> weakWebView { (__bridge WebHTMLView *)observer };
    WebThreadRun(^{
        if (auto webView = weakWebView.get()) {
            if (auto* coreFrame = core([webView _frame]))
                coreFrame->eventHandler().capsLockStateMayHaveChanged();
        }
    });
}
#endif

@interface WebHTMLView (WebHTMLViewFileInternal)
#if PLATFORM(MAC)
- (DOMDocumentFragment *)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard inContext:(DOMRange *)context allowPlainText:(BOOL)allowPlainText;
- (NSString *)_plainTextFromPasteboard:(NSPasteboard *)pasteboard;
- (void)_pasteWithPasteboard:(NSPasteboard *)pasteboard allowPlainText:(BOOL)allowPlainText;
- (void)_pasteAsPlainTextWithPasteboard:(NSPasteboard *)pasteboard;
- (void)_postFakeMouseMovedEventForFlagsChangedEvent:(NSEvent *)flagsChangedEvent;
- (void)_removeSuperviewObservers;
- (void)_removeWindowObservers;
#endif
- (BOOL)_shouldInsertFragment:(DOMDocumentFragment *)fragment replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action;
- (BOOL)_shouldInsertText:(NSString *)text replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action;
- (BOOL)_shouldReplaceSelectionWithText:(NSString *)text givenAction:(WebViewInsertAction)action;
- (DOMRange *)_selectedRange;
#if PLATFORM(MAC)
- (void)_writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard cachedAttributedString:(NSAttributedString *)attributedString;
#endif
- (DOMRange *)_documentRange;
- (void)_setMouseDownEvent:(WebEvent *)event;
- (WebHTMLView *)_topHTMLView;
- (BOOL)_isTopHTMLView;
#if PLATFORM(MAC)
- (void)_web_setPrintingModeRecursive;
- (void)_web_setPrintingModeRecursiveAndAdjustViewSize;
- (void)_web_clearPrintingModeRecursive;
#endif
@end

#if PLATFORM(MAC)

@interface WebHTMLView (WebHTMLViewTextCheckingInternal)
- (void)orderFrontSubstitutionsPanel:(id)sender;
- (BOOL)smartInsertDeleteEnabled;
- (void)setSmartInsertDeleteEnabled:(BOOL)flag;
- (void)toggleSmartInsertDelete:(id)sender;
- (BOOL)isAutomaticQuoteSubstitutionEnabled;
- (void)setAutomaticQuoteSubstitutionEnabled:(BOOL)flag;
- (void)toggleAutomaticQuoteSubstitution:(id)sender;
- (BOOL)isAutomaticLinkDetectionEnabled;
- (void)setAutomaticLinkDetectionEnabled:(BOOL)flag;
- (void)toggleAutomaticLinkDetection:(id)sender;
- (BOOL)isAutomaticDashSubstitutionEnabled;
- (void)setAutomaticDashSubstitutionEnabled:(BOOL)flag;
- (void)toggleAutomaticDashSubstitution:(id)sender;
- (BOOL)isAutomaticTextReplacementEnabled;
- (void)setAutomaticTextReplacementEnabled:(BOOL)flag;
- (void)toggleAutomaticTextReplacement:(id)sender;
- (BOOL)isAutomaticSpellingCorrectionEnabled;
- (void)setAutomaticSpellingCorrectionEnabled:(BOOL)flag;
- (void)toggleAutomaticSpellingCorrection:(id)sender;
@end

#endif

@interface WebHTMLView (WebForwardDeclaration) // FIXME: Put this in the WebFileInternal category instead of doing the forward declaration trick.
- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageWidth logicalHeight:(float)minPageHeight originalPageWidth:(float)pageLogicalWidth originalPageHeight:(float)pageLogicalHeight maximumShrinkRatio:(float)maximumShrinkRatio adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent;
@end

#if PLATFORM(MAC)
@interface WebHTMLView (WebNSTextInputSupport) <NSTextInput>
#else
@interface WebHTMLView (WebNSTextInputSupport)
#endif
#if PLATFORM(MAC)
- (void)_updateSecureInputState;
- (void)_updateSelectionForInputManager;
#endif
#if PLATFORM(IOS_FAMILY)
- (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange;
- (void)doCommandBySelector:(SEL)selector;
#endif
@end

@interface NSView (WebHTMLViewFileInternal)
- (void)_web_addDescendentWebHTMLViewsToArray:(NSMutableArray *) array;
@end

struct WebHTMLViewInterpretKeyEventsParameters {
    WebCore::KeyboardEvent* event;
    bool eventInterpretationHadSideEffects;
    bool shouldSaveCommands;
    bool consumedByIM;
    bool executingSavedKeypressCommands;
};

@interface WebHTMLViewPrivate : NSObject {
@public
    BOOL closed;
    BOOL ignoringMouseDraggedEvents;
    BOOL printing;
    BOOL paginateScreenContent;

#if PLATFORM(MAC)
    BOOL observingSuperviewNotifications;
    BOOL observingWindowNotifications;

    id savedSubviews;
    BOOL subviewsSetAside;
#endif

    NSView *layerHostingView;

#if PLATFORM(MAC)
    BOOL drawingIntoLayer;
    BOOL drawingIntoAcceleratedLayer;
#endif

    RetainPtr<WebEvent> mouseDownEvent; // Kept after handling the event.
    BOOL handlingMouseDownEvent;
    RetainPtr<WebEvent> keyDownEvent; // Kept after handling the event.

    // A WebHTMLView has a single input context, but we return nil when in non-editable content to avoid making input methods do their work.
    // This state is saved each time selection changes, because computing it causes style recalc, which is not always safe to do.
    BOOL exposeInputContext;

#if PLATFORM(MAC)
    // Track whether the view has set a secure input state.
    BOOL isInSecureInputState;

    BOOL _forceUpdateSecureInputState;
#endif

    NSPoint lastScrollPosition;
    BOOL inScrollPositionChanged;

    RetainPtr<WebPluginController> pluginController;
    
#if PLATFORM(MAC)
    RetainPtr<NSString> toolTip;
    NSToolTipTag lastToolTipTag;

    WeakObjCPtr<id> trackingRectOwner;
    void* trackingRectUserData;
    
    RetainPtr<NSTimer> autoscrollTimer;
    RetainPtr<NSEvent> autoscrollTriggerEvent;
#endif

    RetainPtr<NSArray> pageRects;

#if PLATFORM(MAC)
    RetainPtr<WebTextCompletionController> completionController;

    BOOL transparentBackground;
#endif

    WebHTMLViewInterpretKeyEventsParameters* interpretKeyEventsParameters;
    
    RetainPtr<WebDataSource> dataSource;

#if PLATFORM(MAC)
    NakedPtr<WebCore::CachedImage> promisedDragTIFFDataSource;
#endif

    SEL selectorForDoCommandBySelector;

#if PLATFORM(MAC)
    BOOL installedTrackingArea;
    id flagsChangedEventMonitor;
    NSRange softSpaceRange;
#endif

#if ENABLE(SERVICE_CONTROLS)
    RetainPtr<WebSharingServicePickerController> currentSharingServicePickerController;
#endif
}
- (void)clear;
@end

#if PLATFORM(MAC)

static NSControlStateValue kit(TriState state)
{
    switch (state) {
    case TriState::False:
        return NSControlStateValueOff;
    case TriState::True:
        return NSControlStateValueOn;
    case TriState::Indeterminate:
        return NSControlStateValueMixed;
    }
    ASSERT_NOT_REACHED();
    return NSControlStateValueOff;
}

#endif

@implementation WebHTMLViewPrivate

#if PLATFORM(MAC)

+ (void)initialize
{
    // FIXME: Shouldn't all of this move into +[WebHTMLView initialize]?
    // And some of this work is likely redundant since +[WebHTMLView initialize] is guaranteed to run first.

    JSC::initialize();
    WTF::initializeMainThread();
    WebCore::populateJITOperations();

    if (!oldSetCursorForMouseLocationIMP) {
        Method setCursorMethod = class_getInstanceMethod([NSWindow class], @selector(_setCursorForMouseLocation:));
        ASSERT(setCursorMethod);
        oldSetCursorForMouseLocationIMP = method_setImplementation(setCursorMethod, (IMP)setCursor);
        ASSERT(oldSetCursorForMouseLocationIMP);
    }

    method_exchangeImplementations(class_getInstanceMethod([NSView class], @selector(setNeedsDisplayInRect:)), class_getInstanceMethod([NSView class], @selector(_web_setNeedsDisplayInRect:)));
}

#endif

- (void)dealloc
{
    if (WebCoreObjCScheduleDeallocateOnMainThread([WebHTMLViewPrivate class], self))
        return;

#if PLATFORM(MAC)
    ASSERT(!autoscrollTimer);
    ASSERT(!autoscrollTriggerEvent);
#endif

#if PLATFORM(MAC)
    if (promisedDragTIFFDataSource)
        promisedDragTIFFDataSource->removeClient(promisedDataClient());

    if (flagsChangedEventMonitor) {
        [NSEvent removeMonitor:flagsChangedEventMonitor];
        flagsChangedEventMonitor = nil;
    }
#endif

    [super dealloc];
}

- (void)clear
{
#if PLATFORM(MAC)
    if (promisedDragTIFFDataSource)
        promisedDragTIFFDataSource->removeClient(promisedDataClient());
#endif

    mouseDownEvent = nil;
    keyDownEvent = nil;
    pluginController = nil;
#if PLATFORM(MAC)
    toolTip = nil;
    completionController = nil;
#endif
    dataSource = nil;
#if PLATFORM(MAC)
    promisedDragTIFFDataSource = nullptr;
#endif

    layerHostingView = nil;
}

@end

@implementation WebHTMLView (WebHTMLViewFileInternal)

- (DOMRange *)_documentRange
{
    return [[[self _frame] DOMDocument] _documentRange];
}

- (WebDataSource *)_dataSource
{
    return _private->dataSource.get();
}

- (WebView *)_webView
{
    return [_private->dataSource _webView];
}

- (WebFrameView *)_frameView
{
    return [[_private->dataSource webFrame] frameView];
}

#if PLATFORM(MAC)

- (DOMDocumentFragment *)_documentFragmentWithPaths:(NSArray *)paths
{
    auto textNodes = adoptNS([[NSMutableArray alloc] init]);

    for (NSString *path in paths) {
        // Non-image file types; _web_userVisibleString is appropriate here because this will
        // be pasted as visible text.
        NSString *url = [[[NSURL fileURLWithPath:path] _webkit_canonicalize] _web_userVisibleString];
        [textNodes addObject:[[[self _frame] DOMDocument] createTextNode:url]];
    }

    DOMDocumentFragment *fragment = [[self _frame] _documentFragmentWithNodesAsParagraphs:textNodes.get()];
    return [fragment firstChild] != nil ? fragment : nil;
}

+ (NSArray *)_excludedElementsForAttributedStringConversion
{
    auto elements = adoptNS([[NSMutableArray alloc] initWithObjects:
        // Omit style since we want style to be inline so the fragment can be easily inserted.
        @"style",
        // Omit xml so the result is not XHTML.
        @"xml",
        // Omit tags that will get stripped when converted to a fragment anyway.
        @"doctype", @"html", @"head", @"body",
        // Omit deprecated tags.
        @"applet", @"basefont", @"center", @"dir", @"font", @"menu", @"s", @"strike", @"u",
        // Omit object so no file attachments are part of the fragment.
#if !ENABLE(ATTACHMENT_ELEMENT)
        // Omit object so no file attachments are part of the fragment.
        @"object",
#endif
        nil]);

#if ENABLE(ATTACHMENT_ELEMENT)
    if (!WebCore::RuntimeEnabledFeatures::sharedFeatures().attachmentElementEnabled())
        [elements addObject:@"object"];
#endif

    return elements.autorelease();
}

- (DOMDocumentFragment *)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard inContext:(DOMRange *)context allowPlainText:(BOOL)allowPlainText
{
    using namespace WebCore;
    NSArray *types = [pasteboard types];
    DOMDocumentFragment *fragment = nil;

    if ([types containsObject:WebArchivePboardType] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebArchivePboardType inContext:context subresources:0]))
        return fragment;

    if ([types containsObject:WebCore::legacyFilenamesPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyFilenamesPasteboardType() inContext:context subresources:0]))
        return fragment;
    
    if ([types containsObject:WebCore::legacyHTMLPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyHTMLPasteboardType() inContext:context subresources:0]))
        return fragment;
    
    if ([types containsObject:WebCore::legacyRTFDPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyRTFDPasteboardType() inContext:context subresources:0]))
        return fragment;
    
    if ([types containsObject:WebCore::legacyRTFPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyRTFPasteboardType() inContext:context subresources:0]))
        return fragment;

    if ([types containsObject:WebCore::legacyTIFFPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyTIFFPasteboardType() inContext:context subresources:0]))
        return fragment;

    if ([types containsObject:WebCore::legacyPDFPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyPDFPasteboardType() inContext:context subresources:0]))
        return fragment;

ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    if ([types containsObject:(NSString *)kUTTypePNG] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:(NSString *)kUTTypePNG inContext:context subresources:0]))
        return fragment;
ALLOW_DEPRECATED_DECLARATIONS_END

    if ([types containsObject:WebCore::legacyURLPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyURLPasteboardType() inContext:context subresources:0]))
        return fragment;

    if (allowPlainText && [types containsObject:WebCore::legacyStringPasteboardType()] && (fragment = [self _documentFragmentFromPasteboard:pasteboard forType:WebCore::legacyStringPasteboardType() inContext:context subresources:0]))
        return fragment;
    
    return nil;
}

- (NSString *)_plainTextFromPasteboard:(NSPasteboard *)pasteboard
{
    NSArray *types = [pasteboard types];
    
    if ([types containsObject:WebCore::legacyStringPasteboardType()])
        return [[pasteboard stringForType:WebCore::legacyStringPasteboardType()] precomposedStringWithCanonicalMapping];

    RetainPtr<NSAttributedString> attributedString;
    if ([types containsObject:WebCore::legacyRTFDPasteboardType()])
        attributedString = adoptNS([[NSAttributedString alloc] initWithRTFD:[pasteboard dataForType:WebCore::legacyRTFDPasteboardType()] documentAttributes:NULL]);
    if (attributedString == nil && [types containsObject:WebCore::legacyRTFPasteboardType()])
        attributedString = adoptNS([[NSAttributedString alloc] initWithRTF:[pasteboard dataForType:WebCore::legacyRTFPasteboardType()] documentAttributes:NULL]);
    if (attributedString)
        return adoptNS([[attributedString string] copy]).autorelease();

    if ([types containsObject:WebCore::legacyFilenamesPasteboardType()]) {
        if (NSString *string = [[pasteboard propertyListForType:WebCore::legacyFilenamesPasteboardType()] componentsJoinedByString:@"\n"])
            return string;
    }

    if (NSURL *URL = [NSURL URLFromPasteboard:pasteboard]) {
        NSString *string = [URL _web_userVisibleString];
        if ([string length])
            return string;
    }

    return nil;
}

- (void)_pasteWithPasteboard:(NSPasteboard *)pasteboard allowPlainText:(BOOL)allowPlainText
{
    auto webView = retainPtr([self _webView]);
    [webView _setInsertionPasteboard:pasteboard];

    DOMRange *range = [self _selectedRange];
    auto* coreFrame = core([self _frame]);

    DOMDocumentFragment *fragment = [self _documentFragmentFromPasteboard:pasteboard inContext:range allowPlainText:allowPlainText];
    if (fragment && [self _shouldInsertFragment:fragment replacingDOMRange:range givenAction:WebViewInsertActionPasted])
        coreFrame->editor().pasteAsFragment(*core(fragment), [self _canSmartReplaceWithPasteboard:pasteboard], false);

    [webView _setInsertionPasteboard:nil];
}

- (void)_pasteAsPlainTextWithPasteboard:(NSPasteboard *)pasteboard 
{ 
    auto webView = retainPtr([self _webView]);
    [webView _setInsertionPasteboard:pasteboard];

    NSString *text = [self _plainTextFromPasteboard:pasteboard]; 
    if ([self _shouldReplaceSelectionWithText:text givenAction:WebViewInsertActionPasted]) 
        [[self _frame] _replaceSelectionWithText:text selectReplacement:NO smartReplace:[self _canSmartReplaceWithPasteboard:pasteboard]]; 

    [webView _setInsertionPasteboard:nil]; 
}

- (void)_postFakeMouseMovedEventForFlagsChangedEvent:(NSEvent *)flagsChangedEvent
{
    NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSEventTypeMouseMoved location:flagsChangedEvent.window.mouseLocationOutsideOfEventStream
        modifierFlags:flagsChangedEvent.modifierFlags timestamp:flagsChangedEvent.timestamp windowNumber:flagsChangedEvent.windowNumber
        context:nullptr eventNumber:0 clickCount:0 pressure:0];
    [self mouseMoved:fakeEvent];
}

// This method is needed to support macOS services.
- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pasteboard 
{ 
    auto* coreFrame = core([self _frame]);
    if (!coreFrame) 
        return NO; 
    if (coreFrame->selection().selection().isContentRichlyEditable())
        [self _pasteWithPasteboard:pasteboard allowPlainText:YES]; 
    else 
        [self _pasteAsPlainTextWithPasteboard:pasteboard]; 
    return YES; 
}

- (void)_removeSuperviewObservers
{
    if (!_private || !_private->observingSuperviewNotifications)
        return;

    NSView *superview = [self superview];
    if (!superview || ![self window])
        return;

    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:NSViewFrameDidChangeNotification object:superview];
    [notificationCenter removeObserver:self name:NSViewBoundsDidChangeNotification object:superview];

    _private->observingSuperviewNotifications = false;
}

- (void)_removeWindowObservers
{
    if (!_private->observingWindowNotifications)
        return;

    NSWindow *window = [self window];
    if (!window)
        return;

    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil];
    [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification object:nil];
    [notificationCenter removeObserver:self name:NSWindowWillCloseNotification object:window];

    _private->observingWindowNotifications = false;
}

#endif // PLATFORM(MAC)

- (BOOL)_shouldInsertFragment:(DOMDocumentFragment *)fragment replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action
{
    WebView *webView = [self _webView];
    DOMNode *child = [fragment firstChild];
    if ([fragment lastChild] == child && [child isKindOfClass:[DOMCharacterData class]])
        return [[webView _editingDelegateForwarder] webView:webView shouldInsertText:[(DOMCharacterData *)child data] replacingDOMRange:range givenAction:action];
    return [[webView _editingDelegateForwarder] webView:webView shouldInsertNode:fragment replacingDOMRange:range givenAction:action];
}

- (BOOL)_shouldInsertText:(NSString *)text replacingDOMRange:(DOMRange *)range givenAction:(WebViewInsertAction)action
{
    WebView *webView = [self _webView];
    return [[webView _editingDelegateForwarder] webView:webView shouldInsertText:text replacingDOMRange:range givenAction:action];
}

- (BOOL)_shouldReplaceSelectionWithText:(NSString *)text givenAction:(WebViewInsertAction)action
{
    return [self _shouldInsertText:text replacingDOMRange:[self _selectedRange] givenAction:action];
}

- (DOMRange *)_selectedRange
{
    auto* coreFrame = core([self _frame]);
    return coreFrame ? kit(coreFrame->selection().selection().toNormalizedRange()) : nil;
}

#if PLATFORM(MAC)

- (void)_writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard cachedAttributedString:(NSAttributedString *)attributedString
{
    // Put HTML on the pasteboard.
    if ([types containsObject:WebArchivePboardType]) {
        if (auto coreArchive = WebCore::LegacyWebArchive::createFromSelection(core([self _frame]))) {
            if (RetainPtr<CFDataRef> data = coreArchive ? coreArchive->rawDataRepresentation() : 0)
                [pasteboard setData:(__bridge NSData *)data.get() forType:WebArchivePboardType];
        }
    }

    // Put the attributed string on the pasteboard (RTF/RTFD format).
    if ([types containsObject:WebCore::legacyRTFDPasteboardType()]) {
        if (attributedString == nil) {
            attributedString = [self selectedAttributedString];
        }        
        NSData *RTFDData = [attributedString RTFDFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:@{ }];
        [pasteboard setData:RTFDData forType:WebCore::legacyRTFDPasteboardType()];
    }        
    if ([types containsObject:WebCore::legacyRTFPasteboardType()]) {
        if (!attributedString)
            attributedString = [self selectedAttributedString];
        if ([attributedString containsAttachments])
            attributedString = WebCore::attributedStringByStrippingAttachmentCharacters(attributedString);
        NSData *RTFData = [attributedString RTFFromRange:NSMakeRange(0, [attributedString length]) documentAttributes:@{ }];
        [pasteboard setData:RTFData forType:WebCore::legacyRTFPasteboardType()];
    }

    // Put plain string on the pasteboard.
    if ([types containsObject:WebCore::legacyStringPasteboardType()]) {
        // Map &nbsp; to a plain old space because this is better for source code, other browsers do it, and
        // because HTML forces content creators and editors to use this character any time they want two spaces in a row.
        [pasteboard setString:[[self selectedString] stringByReplacingOccurrencesOfString:@"\u00A0" withString:@" "] forType:WebCore::legacyStringPasteboardType()];
    }

    if ([self _canSmartCopyOrDelete] && [types containsObject:WebSmartPastePboardType])
        [pasteboard setData:nil forType:WebSmartPastePboardType];
}

#endif // PLATFORM(MAC)

- (void)_setMouseDownEvent:(WebEvent *)event
{
#if PLATFORM(MAC)
    ASSERT(!event || [event type] == NSEventTypeLeftMouseDown || [event type] == NSEventTypeRightMouseDown || [event type] == NSEventTypeOtherMouseDown);
#else
    ASSERT(!event || event.type == WebEventMouseDown);
#endif

    _private->mouseDownEvent = event;
}

- (WebHTMLView *)_topHTMLView
{
    // FIXME: this can fail if the dataSource is nil, which happens when the WebView is tearing down from the window closing.
    WebHTMLView *view = (WebHTMLView *)[[[[_private->dataSource _webView] mainFrame] frameView] documentView];
    ASSERT(!view || [view isKindOfClass:[WebHTMLView class]]);
    return view;
}

- (BOOL)_isTopHTMLView
{
    // FIXME: this should be a cached boolean that doesn't rely on _topHTMLView since that can fail (see _topHTMLView).
    return self == [self _topHTMLView];
}

#if PLATFORM(MAC)

- (void)_web_setPrintingModeRecursive:(BOOL)printing adjustViewSize:(BOOL)adjustViewSize
{
    auto array = adoptNS([[NSMutableArray alloc] initWithObjects:self, nil]);
    [self _web_addDescendentWebHTMLViewsToArray:array.get()];
    for (WebHTMLView *view in array.get())
        [view _setPrinting:printing minimumPageLogicalWidth:0 logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustViewSize:adjustViewSize paginateScreenContent:[self _isInScreenPaginationMode]];
}

- (void)_web_setPrintingModeRecursive
{
    [self _web_setPrintingModeRecursive:YES adjustViewSize:NO];
}

- (void)_web_clearPrintingModeRecursive
{
    [self _web_setPrintingModeRecursive:NO adjustViewSize:NO];
}

- (void)_web_setPrintingModeRecursiveAndAdjustViewSize
{
    [self _web_setPrintingModeRecursive:YES adjustViewSize:YES];
}

#endif // PLATFORM(MAC)

@end

@implementation WebHTMLView (WebPrivate)

+ (NSArray *)supportedMIMETypes
{
    return [WebHTMLRepresentation supportedMIMETypes];
}

+ (NSArray *)supportedMediaMIMETypes
{
    return [WebHTMLRepresentation supportedMediaMIMETypes];
}

+ (NSArray *)supportedImageMIMETypes
{
    return [WebHTMLRepresentation supportedImageMIMETypes];
}

+ (NSArray *)supportedNonImageMIMETypes
{
    return [WebHTMLRepresentation supportedNonImageMIMETypes];
}

+ (NSArray *)unsupportedTextMIMETypes
{
    return [WebHTMLRepresentation unsupportedTextMIMETypes];
}

#if PLATFORM(IOS_FAMILY)

- (void)mouseMoved:(WebEvent *)event
{
    if (auto* frame = core([self _frame]))
        frame->eventHandler().mouseMoved(event);
}

#endif

#if PLATFORM(MAC)

+ (void)_postFlagsChangedEvent:(NSEvent *)flagsChangedEvent
{
    // This is obsolete SPI needed only for older versions of Safari
}

- (id)_bridge
{
    // This method exists to maintain compatibility with Leopard's Dictionary.app, since it
    // calls _bridge to get access to convertNSRangeToDOMRange: and convertDOMRangeToNSRange:.
    // Return the WebFrame, which implements the compatibility methods. <rdar://problem/6002160>
    return [self _frame];
}

- (void)_updateMouseoverWithFakeEvent
{
    NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
        location:[[self window]
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        convertScreenToBase:[NSEvent mouseLocation]]
ALLOW_DEPRECATED_DECLARATIONS_END
        modifierFlags:[[NSApp currentEvent] modifierFlags]
        timestamp:[NSDate timeIntervalSinceReferenceDate]
        windowNumber:[[self window] windowNumber]
        context:nullptr
        eventNumber:0 clickCount:0 pressure:0];

    [self _updateMouseoverWithEvent:fakeEvent];
}

#endif // PLATFORM(MAC)

- (void)_frameOrBoundsChanged
{
    WebView *webView = [self _webView];
    WebDynamicScrollBarsView *scrollView = [[[webView mainFrame] frameView] _scrollView];

    NSPoint origin = [[self superview] bounds].origin;
    if (!NSEqualPoints(_private->lastScrollPosition, origin) && ![scrollView inProgrammaticScroll]) {
        if (auto* coreFrame = core([self _frame])) {
            if (auto* coreView = coreFrame->view()) {
                _private->inScrollPositionChanged = YES;
                coreView->scrollOffsetChangedViaPlatformWidget(WebCore::IntPoint(_private->lastScrollPosition), WebCore::IntPoint(origin));
                _private->inScrollPositionChanged = NO;
            }
        }
    
#if PLATFORM(MAC)
        [_private->completionController endRevertingChange:NO moveLeft:NO];
#endif
        
        [webView _didScrollDocumentInFrameView:[self _frameView]];
    }
    _private->lastScrollPosition = origin;
}

- (void)_setAsideSubviews
{
#if PLATFORM(MAC)
    ASSERT(!_private->subviewsSetAside);
    ASSERT(_private->savedSubviews == nil);
    _private->savedSubviews = self._subviewsIvar;
    // We need to keep the layer-hosting view in the subviews, otherwise the layers flash.
    if (_private->layerHostingView) {
        NSMutableArray* newSubviews = [[NSMutableArray alloc] initWithObjects:_private->layerHostingView, nil];
        self._subviewsIvar = newSubviews;
    } else
        self._subviewsIvar = nil;
    _private->subviewsSetAside = YES;
#endif
 }
 
 - (void)_restoreSubviews
 {
#if PLATFORM(MAC)
    ASSERT(_private->subviewsSetAside);
    if (_private->layerHostingView) {
        [self._subviewsIvar release];
        self._subviewsIvar = _private->savedSubviews;
    } else {
        ASSERT(self._subviewsIvar == nil);
        self._subviewsIvar = _private->savedSubviews;
    }
    _private->savedSubviews = nil;
    _private->subviewsSetAside = NO;
#endif
}

- (void)viewWillDraw
{
    // On window close we will be called when the data source is nil, then hit an assert in _topHTMLView
    // So check if the data source is nil before calling [self _isTopHTMLView], this can be removed
    // once the FIXME in _isTopHTMLView is fixed.
    if (_private->dataSource && [self _isTopHTMLView]) {
        [self _web_updateLayoutAndStyleIfNeededRecursive];
        [[self _webView] _flushCompositingChanges];
    }

    [super viewWillDraw];
}

#if PLATFORM(MAC)

// Don't let AppKit even draw subviews. We take care of that.
- (void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)isVisibleRect rectIsVisibleRectForView:(NSView *)visibleView topView:(BOOL)topView
{
    // This helps when we print as part of a larger print process.
    // If the WebHTMLView itself is what we're printing, then we will never have to do this.
    BOOL wasInPrintingMode = _private->printing;
    BOOL isPrinting = ![NSGraphicsContext currentContextDrawingToScreen];
    if (isPrinting) {
        if (!wasInPrintingMode)
            [self _web_setPrintingModeRecursive];
        else
            [self _web_updateLayoutAndStyleIfNeededRecursive];
    } else if (wasInPrintingMode)
        [self _web_clearPrintingModeRecursive];

    // There are known cases where -viewWillDraw is not called on all views being drawn.
    // See <rdar://problem/6964278> for example. Performing layout at this point prevents us from
    // trying to paint without layout (which WebCore now refuses to do, instead bailing out without
    // drawing at all), but we may still fail to update any regions dirtied by the layout which are
    // not already dirty. 
    if ([self _needsLayout]) {
        NSInteger rectCount;
        [self getRectsBeingDrawn:0 count:&rectCount];
        if (rectCount) {
            LOG_ERROR("View needs layout. Either -viewWillDraw wasn't called or layout was invalidated during the display operation. Performing layout now.");
            [self _web_updateLayoutAndStyleIfNeededRecursive];
        }
    }

    [self _setAsideSubviews];
    [super _recursiveDisplayRectIfNeededIgnoringOpacity:rect isVisibleRect:isVisibleRect rectIsVisibleRectForView:visibleView topView:topView];
    [self _restoreSubviews];

    if (wasInPrintingMode != isPrinting) {
        if (wasInPrintingMode)
            [self _web_setPrintingModeRecursive];
        else
            [self _web_clearPrintingModeRecursive];
    }
}

// Don't let AppKit even draw subviews. We take care of that.
- (void)_recursiveDisplayAllDirtyWithLockFocus:(BOOL)needsLockFocus visRect:(NSRect)visRect
{
    BOOL needToSetAsideSubviews = !_private->subviewsSetAside;

    BOOL wasInPrintingMode = _private->printing;
    BOOL isPrinting = ![NSGraphicsContext currentContextDrawingToScreen];

    if (needToSetAsideSubviews) {
        // This helps when we print as part of a larger print process.
        // If the WebHTMLView itself is what we're printing, then we will never have to do this.
        if (isPrinting) {
            if (!wasInPrintingMode)
                [self _web_setPrintingModeRecursive];
            else
                [self _web_updateLayoutAndStyleIfNeededRecursive];
        } else if (wasInPrintingMode)
            [self _web_clearPrintingModeRecursive];


        [self _setAsideSubviews];
    }

    [super _recursiveDisplayAllDirtyWithLockFocus:needsLockFocus visRect:visRect];

    if (needToSetAsideSubviews) {
        if (wasInPrintingMode != isPrinting) {
            if (wasInPrintingMode)
                [self _web_setPrintingModeRecursive];
            else
                [self _web_clearPrintingModeRecursive];
        }

        [self _restoreSubviews];
    }
}

// Don't let AppKit even draw subviews. We take care of that.
- (void)_recursive:(BOOL)recursive displayRectIgnoringOpacity:(NSRect)displayRect inContext:(NSGraphicsContext *)graphicsContext stopAtLayerBackedViews:(BOOL)stopAtLayerBackedViews
{
    [self _setAsideSubviews];
    [super _recursive:recursive displayRectIgnoringOpacity:displayRect inContext:graphicsContext stopAtLayerBackedViews:stopAtLayerBackedViews];
    [self _restoreSubviews];
}

static BOOL isQuickLookEvent(NSEvent *event)
{
    const int kCGSEventSystemSubtypeHotKeyCombinationReleased = 9;
    return [event type] == NSEventTypeSystemDefined && [event subtype] == kCGSEventSystemSubtypeHotKeyCombinationReleased && [event data1] == 'lkup';
}

#endif

- (NSView *)hitTest:(NSPoint)point
{
    // WebHTMLView objects handle all events for objects inside them.
    // To get those events, we prevent hit testing from AppKit.

    // But there are three exceptions to this:
    //   1) For right mouse clicks and control clicks we don't yet have an implementation
    //      that works for nested views, so we let the hit testing go through the
    //      standard NSView code path (needs to be fixed, see bug 4361618).
    //   2) Java depends on doing a hit test inside it's mouse moved handling,
    //      so we let the hit testing go through the standard NSView code path
    //      when the current event is a mouse move (except when we are calling
    //      from _updateMouseoverWithEvent, so we have to use a global,
    //      forceWebHTMLViewHitTest, for that)
    //   3) The acceptsFirstMouse: and shouldDelayWindowOrderingForEvent: methods
    //      both need to figure out which view to check with inside the WebHTMLView.
    //      They use a global to change the behavior of hitTest: so they can get the
    //      right view. The global is forceNSViewHitTest and the method they use to
    //      do the hit testing is _hitViewForEvent:. (But this does not work correctly
    //      when there is HTML overlapping the view, see bug 4361626)
    //   4) NSAccessibilityHitTest relies on this for checking the cursor position.
    //      Our check for that is whether the event is NSFlagsChanged.  This works
    //      for VoiceOver's Control-Option-F5 command (move focus to item under cursor)
    //      and Dictionary's Command-Control-D (open dictionary popup for item under cursor).
    //      This is of course a hack.

    if (_private->closed)
        return nil;

#if !PLATFORM(IOS_FAMILY)
    BOOL captureHitsOnSubviews;
    if (forceNSViewHitTest)
        captureHitsOnSubviews = NO;
    else if (forceWebHTMLViewHitTest)
        captureHitsOnSubviews = YES;
    else {
        // FIXME: Why doesn't this include mouse entered/exited events, or other mouse button events?
        NSEvent *event = [[self window] currentEvent];
        captureHitsOnSubviews = !([event type] == NSEventTypeMouseMoved
            || [event type] == NSEventTypeRightMouseDown
            || ([event type] == NSEventTypeLeftMouseDown && [event modifierFlags] & NSEventModifierFlagControl)
            || [event type] == NSEventTypeFlagsChanged
            || isQuickLookEvent(event));
    }

    if (!captureHitsOnSubviews) {
        NSView* hitView = [super hitTest:point];
        if (_private && hitView == _private->layerHostingView)
            hitView = self;
        return hitView;
    }
#endif // !PLATFORM(IOS_FAMILY)

    if ([[self superview] mouse:point inRect:[self frame]])
        return self;
    return nil;
}

#if PLATFORM(MAC)

- (NSTrackingRectTag)addTrackingRect:(NSRect)rect owner:(id)owner userData:(void *)data assumeInside:(BOOL)assumeInside
{
    ASSERT(!_private->trackingRectOwner);
    _private->trackingRectOwner = owner;
    _private->trackingRectUserData = data;
    return TRACKING_RECT_TAG;
}

- (NSTrackingRectTag)_addTrackingRect:(NSRect)rect owner:(id)owner userData:(void *)data assumeInside:(BOOL)assumeInside useTrackingNum:(int)tag
{
    ASSERT(tag == 0 || tag == TRACKING_RECT_TAG);
    ASSERT(!_private->trackingRectOwner);
    _private->trackingRectOwner = owner;
    _private->trackingRectUserData = data;
    return TRACKING_RECT_TAG;
}

- (void)_addTrackingRects:(NSRect *)rects owner:(id)owner userDataList:(void **)userDataList assumeInsideList:(BOOL *)assumeInsideList trackingNums:(NSTrackingRectTag *)trackingNums count:(int)count
{
    ASSERT(count == 1);
    ASSERT(trackingNums[0] == 0 || trackingNums[0] == TRACKING_RECT_TAG);
    ASSERT(!_private->trackingRectOwner);
    _private->trackingRectOwner = owner;
    _private->trackingRectUserData = userDataList[0];
    trackingNums[0] = TRACKING_RECT_TAG;
}

- (void)removeTrackingRect:(NSTrackingRectTag)tag
{
    if (tag == 0)
        return;
    
    if (_private && (tag == TRACKING_RECT_TAG)) {
        _private->trackingRectOwner = nil;
        return;
    }
    
    if (_private && (tag == _private->lastToolTipTag)) {
        [super removeTrackingRect:tag];
        _private->lastToolTipTag = 0;
        return;
    }
    
    // If any other tracking rect is being removed, we don't know how it was created
    // and it's possible there's a leak involved (see 3500217)
    ASSERT_NOT_REACHED();
}

- (void)_removeTrackingRects:(NSTrackingRectTag *)tags count:(int)count
{
    int i;
    for (i = 0; i < count; ++i) {
        int tag = tags[i];
        if (tag == 0)
            continue;
        ASSERT(tag == TRACKING_RECT_TAG);
        if (_private != nil) {
            _private->trackingRectOwner = nil;
        }
    }
}

- (id)_toolTipOwnerForSendingMouseEvents
{
    if (id owner = _private->trackingRectOwner.getAutoreleased())
        return owner;

    for (NSTrackingArea *trackingArea in self.trackingAreas) {
        static Class managerClass;
        static std::once_flag onceFlag;
        std::call_once(onceFlag, [] {
            managerClass = NSClassFromString(@"NSToolTipManager");
        });

        id owner = trackingArea.owner;
        if ([owner class] == managerClass)
            return owner;
    }
    return nil;
}

- (void)_sendToolTipMouseExited
{
    // Nothing matters except window, trackingNumber, and userData.
    NSEvent *fakeEvent = [NSEvent enterExitEventWithType:NSEventTypeMouseExited
        location:NSMakePoint(0, 0)
        modifierFlags:0
        timestamp:0
        windowNumber:[[self window] windowNumber]
        context:NULL
        eventNumber:0
        trackingNumber:TRACKING_RECT_TAG
        userData:_private->trackingRectUserData];
    [self._toolTipOwnerForSendingMouseEvents mouseExited:fakeEvent];
}

- (void)_sendToolTipMouseEntered
{
    // Nothing matters except window, trackingNumber, and userData.
    NSEvent *fakeEvent = [NSEvent enterExitEventWithType:NSEventTypeMouseEntered
        location:NSMakePoint(0, 0)
        modifierFlags:0
        timestamp:0
        windowNumber:[[self window] windowNumber]
        context:NULL
        eventNumber:0
        trackingNumber:TRACKING_RECT_TAG
        userData:_private->trackingRectUserData];
    [self._toolTipOwnerForSendingMouseEvents mouseEntered:fakeEvent];
}

#endif // PLATFORM(MAC)

- (void)_setToolTip:(NSString *)string
{
#if PLATFORM(MAC)
    NSString *toolTip = [string length] == 0 ? nil : string;
    NSString *oldToolTip = _private->toolTip.get();
    if (toolTip == oldToolTip || [toolTip isEqualToString:oldToolTip])
        return;
    if (oldToolTip)
        [self _sendToolTipMouseExited];
    _private->toolTip = adoptNS([toolTip copy]);
    if (toolTip) {
        // See radar 3500217 for why we remove all tooltips rather than just the single one we created.
        [self removeAllToolTips];
        NSRect wideOpenRect = NSMakeRect(-100000, -100000, 200000, 200000);
        _private->lastToolTipTag = [self addToolTipRect:wideOpenRect owner:self userData:NULL];
        [self _sendToolTipMouseEntered];
    }
#endif
}

#if PLATFORM(MAC)

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSString *)view:(NSView *)view stringForToolTip:(NSToolTipTag)tag point:(NSPoint)point userData:(void *)data
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    return adoptNS([_private->toolTip copy]).autorelease();
}

static bool mouseEventIsPartOfClickOrDrag(NSEvent *event)
{
    switch ([event type]) {
    case NSEventTypeLeftMouseDown:
    case NSEventTypeLeftMouseUp:
    case NSEventTypeLeftMouseDragged:
    case NSEventTypeRightMouseDown:
    case NSEventTypeRightMouseUp:
    case NSEventTypeRightMouseDragged:
    case NSEventTypeOtherMouseDown:
    case NSEventTypeOtherMouseUp:
    case NSEventTypeOtherMouseDragged:
        return true;
    default:
        return false;
    }
}

- (void)_updateMouseoverWithEvent:(NSEvent *)event
{
    if (_private->closed)
        return;

    NSView *contentView = [[event window] contentView];
    NSPoint locationForHitTest = [[contentView superview] convertPoint:[event locationInWindow] fromView:nil];
    
    forceWebHTMLViewHitTest = YES;
    NSView *hitView = [contentView hitTest:locationForHitTest];
    forceWebHTMLViewHitTest = NO;
    
    auto view = retainPtr(dynamic_objc_cast<WebHTMLView>(hitView));
    if (lastHitView != view && lastHitView && [lastHitView _frame]) {
        // If we are moving out of a view (or frame), let's pretend the mouse moved
        // all the way out of that view. But we have to account for scrolling, because
        // WebCore doesn't understand our clipping.
        NSRect visibleRect = [[[[lastHitView _frame] frameView] _scrollView] documentVisibleRect];
        float yScroll = visibleRect.origin.y;
        float xScroll = visibleRect.origin.x;

        NSEvent *event = [NSEvent mouseEventWithType:NSEventTypeMouseMoved
            location:NSMakePoint(-1 - xScroll, -1 - yScroll)
            modifierFlags:[[NSApp currentEvent] modifierFlags]
            timestamp:[NSDate timeIntervalSinceReferenceDate]
            windowNumber:[[view window] windowNumber]
            context:nullptr
            eventNumber:0 clickCount:0 pressure:0];

        if (auto* lastHitCoreFrame = core([lastHitView _frame]))
            lastHitCoreFrame->eventHandler().mouseMoved(event, [[self _webView] _pressureEvent]);
    }

    lastHitView = view.get();

    if (view) {
        if (auto* coreFrame = core([view _frame])) {
            // We need to do a full, normal hit test during this mouse event if the page is active or if a mouse
            // button is currently pressed. It is possible that neither of those things will be true on Lion and
            // newer when legacy scrollbars are enabled, because then WebKit receives mouse events all the time. 
            // If it is one of those cases where the page is not active and the mouse is not pressed, then we can
            // fire a much more restricted and efficient scrollbars-only version of the event.

            if ([[self window] isKeyWindow] || mouseEventIsPartOfClickOrDrag(event))
                coreFrame->eventHandler().mouseMoved(event, [[self _webView] _pressureEvent]);
            else {
                [self removeAllToolTips];
                coreFrame->eventHandler().passMouseMovedEventToScrollbars(event, [[self _webView] _pressureEvent]);
            }
        }
    }
}

+ (NSString *)_dummyPasteboardType
{
    return @"Apple WebKit dummy pasteboard type";
}

+ (NSArray *)_insertablePasteboardTypes
{
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    static NeverDestroyed<RetainPtr<NSArray>> types = @[
        WebArchivePboardType, WebCore::legacyHTMLPasteboardType(), WebCore::legacyFilenamesPasteboardType(), WebCore::legacyTIFFPasteboardType(),
        WebCore::legacyPDFPasteboardType(), WebCore::legacyURLPasteboardType(), WebCore::legacyRTFDPasteboardType(), WebCore::legacyRTFPasteboardType(),
        WebCore::legacyStringPasteboardType(), WebCore::legacyColorPasteboardType(), (NSString *)kUTTypePNG,
    ];
ALLOW_DEPRECATED_DECLARATIONS_END
    return types.get().get();
}

+ (NSArray *)_selectionPasteboardTypes
{
    // FIXME: We should put data for NSHTMLPboardType on the pasteboard but Microsoft Excel doesn't like our format of HTML (3640423).
    return @[WebArchivePboardType, WebCore::legacyRTFDPasteboardType(), WebCore::legacyRTFPasteboardType(), WebCore::legacyStringPasteboardType()];
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)pasteboardChangedOwner:(NSPasteboard *)pasteboard
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self setPromisedDragTIFFDataSource:nullptr];
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)pasteboard:(NSPasteboard *)pasteboard provideDataForType:(NSString *)type
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    if ([type isEqualToString:WebCore::legacyRTFDPasteboardType()] && [[pasteboard types] containsObject:WebArchivePboardType]) {
        auto archive = adoptNS([[WebArchive alloc] initWithData:[pasteboard dataForType:WebArchivePboardType]]);
        [pasteboard _web_writePromisedRTFDFromArchive:archive.get() containsImage:[[pasteboard types] containsObject:WebCore::legacyTIFFPasteboardType()]];
    } else if ([type isEqualToString:WebCore::legacyTIFFPasteboardType()] && _private->promisedDragTIFFDataSource) {
        if (auto* image = _private->promisedDragTIFFDataSource->image())
            [pasteboard setData:(__bridge NSData *)image->tiffRepresentation() forType:WebCore::legacyTIFFPasteboardType()];
        [self setPromisedDragTIFFDataSource:nullptr];
    }
}

- (void)_handleAutoscrollForMouseDragged:(NSEvent *)event 
{ 
    [self autoscroll:event]; 
    [self _startAutoscrollTimer:event]; 
}

#endif // PLATFORM(MAC)

#if PLATFORM(IOS_FAMILY)

// WAKView override.
- (void)layoutIfNeeded
{
    [self _layoutIfNeeded];
}

// WAKView override.
- (void)setScale:(float)scale
{
    [super setScale:scale];
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;

    if (auto* page = coreFrame->page())
        page->setPageScaleFactor(scale, WebCore::IntPoint());

    [[self _webView] _documentScaleChanged];
}

#endif

#if PLATFORM(MAC)

- (void)_layoutForPrinting
{
    // Set printing mode temporarily so we can adjust the size of the view. This will allow
    // AppKit's pagination code to use the correct height for the page content. Leaving printing
    // mode on indefinitely would interfere with Mail's printing mechanism (at least), so we just
    // turn it off again after adjusting the size.
    [self _web_setPrintingModeRecursiveAndAdjustViewSize];
    [self _web_clearPrintingModeRecursive];
}

- (void)_smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString
{
    if (!pasteString || !rangeToReplace || ![[self _webView] smartInsertDeleteEnabled]) {
        if (beforeString)
            *beforeString = nil;
        if (afterString)
            *afterString = nil;
        return;
    }
    
    [[self _frame] _smartInsertForString:pasteString replacingRange:rangeToReplace beforeString:beforeString afterString:afterString];
}

- (BOOL)_canSmartReplaceWithPasteboard:(NSPasteboard *)pasteboard
{
    return [[self _webView] smartInsertDeleteEnabled] && [[pasteboard types] containsObject:WebSmartPastePboardType];
}

#endif

// FIXME: _selectionRect is deprecated in favor of selectionRect, which is in protocol WebDocumentSelection.
// We can't remove this yet because it's still in use by Mail.
- (NSRect)_selectionRect
{
    return [self selectionRect];
}

#if PLATFORM(MAC)

- (void)_autoscroll
{
    // Guarantee that the autoscroll timer is invalidated, even if we don't receive
    // a mouse up event.
    BOOL isStillDown = CGEventSourceButtonState(kCGEventSourceStateCombinedSessionState, kCGMouseButtonLeft);
    if (!isStillDown){
        [self _stopAutoscrollTimer];
        return;
    }

    NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSEventTypeLeftMouseDragged
        location:[[self window]
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        convertScreenToBase:[NSEvent mouseLocation]]
ALLOW_DEPRECATED_DECLARATIONS_END
        modifierFlags:[[NSApp currentEvent] modifierFlags]
        timestamp:[NSDate timeIntervalSinceReferenceDate]
        windowNumber:[[self window] windowNumber]
        context:nullptr
        eventNumber:0 clickCount:0 pressure:0];

    [self mouseDragged:fakeEvent];
}

#endif

- (BOOL)_canEdit
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->editor().canEdit();
}

- (BOOL)_canEditRichly
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->editor().canEditRichly();
}

- (BOOL)_canAlterCurrentSelection
{
    return [self _hasSelectionOrInsertionPoint] && [self _isEditable];
}

- (BOOL)_hasSelection
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->selection().selection().isRange();
}

- (BOOL)_hasSelectionOrInsertionPoint
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->selection().selection().isCaretOrRange();
}

- (BOOL)_hasInsertionPoint
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->selection().selection().isCaret();
}

- (BOOL)_isEditable
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->selection().selection().isContentEditable();
}

#if PLATFORM(MAC)

- (BOOL)_transparentBackground
{
    return _private->transparentBackground;
}

- (void)_setTransparentBackground:(BOOL)f
{
    _private->transparentBackground = f;
}

- (NSImage *)_selectionDraggingImage
{
    if (![self _hasSelection])
        return nil;

    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return nil;

    Ref<WebCore::Frame> protectedCoreFrame(*coreFrame);

    WebCore::TextIndicatorData textIndicator;
    auto dragImage = createDragImageForSelection(*coreFrame, textIndicator);
    [dragImage _web_dissolveToFraction:WebDragImageAlpha];

    return dragImage.autorelease();
}

- (NSRect)_selectionDraggingRect
{
    // Mail currently calls this method. We can eliminate it when Mail no longer calls it.
    return [self selectionRect];
}

#endif

- (DOMNode *)_insertOrderedList
{
    auto* coreFrame = core([self _frame]);
    return coreFrame ? kit(coreFrame->editor().insertOrderedList().get()) : nil;
}

- (DOMNode *)_insertUnorderedList
{
    auto* coreFrame = core([self _frame]);
    return coreFrame ? kit(coreFrame->editor().insertUnorderedList().get()) : nil;
}

- (BOOL)_canIncreaseSelectionListLevel
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->editor().canIncreaseSelectionListLevel();
}

- (BOOL)_canDecreaseSelectionListLevel
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->editor().canDecreaseSelectionListLevel();
}

- (DOMNode *)_increaseSelectionListLevel
{
    auto* coreFrame = core([self _frame]);
    return coreFrame ? kit(coreFrame->editor().increaseSelectionListLevel().get()) : nil;
}

- (DOMNode *)_increaseSelectionListLevelOrdered
{
    auto* coreFrame = core([self _frame]);
    return coreFrame ? kit(coreFrame->editor().increaseSelectionListLevelOrdered().get()) : nil;
}

- (DOMNode *)_increaseSelectionListLevelUnordered
{
    auto* coreFrame = core([self _frame]);
    return coreFrame ? kit(coreFrame->editor().increaseSelectionListLevelUnordered().get()) : nil;
}

- (void)_decreaseSelectionListLevel
{
    auto* coreFrame = core([self _frame]);
    if (coreFrame)
        coreFrame->editor().decreaseSelectionListLevel();
}

#if PLATFORM(MAC)

- (void)_writeSelectionToPasteboard:(NSPasteboard *)pasteboard
{
    ASSERT([self _hasSelection]);
    NSArray *types = [self pasteboardTypesForSelection];

    // Don't write RTFD to the pasteboard when the copied attributed string has no attachments.
    NSAttributedString *attributedString = [self selectedAttributedString];
    RetainPtr<NSMutableArray> mutableTypes;
    if (![attributedString containsAttachments]) {
        mutableTypes = adoptNS([types mutableCopy]);
        [mutableTypes removeObject:WebCore::legacyRTFDPasteboardType()];
        types = mutableTypes.get();
    }

    [pasteboard declareTypes:types owner:[self _topHTMLView]];
    [self _writeSelectionWithPasteboardTypes:types toPasteboard:pasteboard cachedAttributedString:attributedString];
}

#endif

- (void)close
{
    // Check for a nil _private here in case we were created with initWithCoder. In that case, the WebView is just throwing
    // out the archived WebHTMLView and recreating a new one if needed. So close doesn't need to do anything in that case.
    if (!_private || _private->closed)
        return;

    _private->closed = YES;

#if PLATFORM(MAC)
    if (lastHitView == self)
        lastHitView = nil;

    [self _removeWindowObservers];
    [self _removeSuperviewObservers];
#endif

    [_private->pluginController destroyAllPlugins];
    [_private->pluginController setDataSource:nil];

#if PLATFORM(MAC)
    // remove tooltips before clearing _private so removeTrackingRect: will work correctly
    [self removeAllToolTips];

    if (_private->isInSecureInputState) {
        DisableSecureEventInput();
        _private->isInSecureInputState = NO;
    }
#endif

    [_private clear];
}

#if PLATFORM(MAC)

- (DOMDocumentFragment *)_web_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard pasteboardType:(NSString *)pasteboardType imageMIMEType:(NSString *)imageMIMEType
{
    String filename = [imageMIMEType stringByReplacingOccurrencesOfString:@"/" withString:@"."];
    auto resource = adoptNS([[WebResource alloc] initWithData:[pasteboard dataForType:pasteboardType]
        URL:URL::fakeURLWithRelativePart(filename) MIMEType:imageMIMEType textEncodingName:nil frameName:nil]);
    return [[self _dataSource] _documentFragmentWithImageResource:resource.get()];
}

- (DOMDocumentFragment *)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard
                                                 forType:(NSString *)pboardType
                                               inContext:(DOMRange *)context
                                            subresources:(NSArray **)subresources
{
    if ([pboardType isEqualToString:WebArchivePboardType]) {
        auto archive = adoptNS([[WebArchive alloc] initWithData:[pasteboard dataForType:WebArchivePboardType]]);
        if (subresources)
            *subresources = [archive subresources];
        return [[self _dataSource] _documentFragmentWithArchive:archive.get()];
    }

    if ([pboardType isEqualToString:WebCore::legacyFilenamesPasteboardType()])
        return [self _documentFragmentWithPaths:[pasteboard propertyListForType:WebCore::legacyFilenamesPasteboardType()]];

    if ([pboardType isEqualToString:WebCore::legacyHTMLPasteboardType()]) {
        NSString *HTMLString = [pasteboard stringForType:WebCore::legacyHTMLPasteboardType()];
        // This is a hack to make Microsoft's HTML pasteboard data work. See 3778785.
        if ([HTMLString hasPrefix:@"Version:"]) {
            NSRange range = [HTMLString rangeOfString:@"<html" options:NSCaseInsensitiveSearch];
            if (range.location != NSNotFound)
                HTMLString = [HTMLString substringFromIndex:range.location];
        }
        if ([HTMLString length] == 0)
            return nil;
        return [[self _frame] _documentFragmentWithMarkupString:HTMLString baseURLString:nil];
    }

    if ([pboardType isEqualToString:WebCore::legacyRTFPasteboardType()] || [pboardType isEqualToString:WebCore::legacyRTFDPasteboardType()]) {
        RetainPtr<NSAttributedString> string;
        if ([pboardType isEqualToString:WebCore::legacyRTFDPasteboardType()])
            string = adoptNS([[NSAttributedString alloc] initWithRTFD:[pasteboard dataForType:WebCore::legacyRTFDPasteboardType()] documentAttributes:NULL]);
        if (!string)
            string = adoptNS([[NSAttributedString alloc] initWithRTF:[pasteboard dataForType:WebCore::legacyRTFPasteboardType()] documentAttributes:NULL]);
        if (!string)
            return nil;

        auto documentAttributes = adoptNS([[NSDictionary alloc] initWithObjectsAndKeys:
            [[self class] _excludedElementsForAttributedStringConversion], NSExcludedElementsDocumentAttribute,
            nil]);

        BOOL wasDeferringCallbacks = [[self _webView] defersCallbacks];
        if (!wasDeferringCallbacks)
            [[self _webView] setDefersCallbacks:YES];

        NSArray *localSubresources;
        DOMDocumentFragment *fragment = [string _documentFromRange:NSMakeRange(0, [string length]) document:[[self _frame] DOMDocument]
            documentAttributes:documentAttributes.get() subresources:&localSubresources];

        if (subresources)
            *subresources = localSubresources;

        for (WebResource *resource in localSubresources)
            [[self _dataSource] addSubresource:resource];

        if (!wasDeferringCallbacks)
            [[self _webView] setDefersCallbacks:NO];

        return fragment;
    }

    if ([pboardType isEqualToString:WebCore::legacyTIFFPasteboardType()])
        return [self _web_documentFragmentFromPasteboard:pasteboard pasteboardType:WebCore::legacyTIFFPasteboardType() imageMIMEType:@"image/tiff"];
    if ([pboardType isEqualToString:WebCore::legacyPDFPasteboardType()])
        return [self _web_documentFragmentFromPasteboard:pasteboard pasteboardType:WebCore::legacyPDFPasteboardType() imageMIMEType:@"application/pdf"];
ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    if ([pboardType isEqualToString:(NSString *)kUTTypePNG])
        return [self _web_documentFragmentFromPasteboard:pasteboard pasteboardType:(NSString *)kUTTypePNG imageMIMEType:@"image/png"];
ALLOW_DEPRECATED_DECLARATIONS_END

    if ([pboardType isEqualToString:WebCore::legacyURLPasteboardType()]) {
        NSURL *URL = [NSURL URLFromPasteboard:pasteboard];
        DOMDocument* document = [[self _frame] DOMDocument];
        ASSERT(document);
        if (!document)
            return nil;
        DOMHTMLAnchorElement *anchor = (DOMHTMLAnchorElement *)[document createElement:@"a"];
        NSString *URLString = [URL _web_originalDataAsString]; // Original data is ASCII-only, so there is no need to precompose.
        if ([URLString length] == 0)
            return nil;
        NSString *URLTitleString = [[pasteboard stringForType:WebURLNamePboardType] precomposedStringWithCanonicalMapping];
        DOMText *text = [document createTextNode:URLTitleString];
        [anchor setHref:URLString];
        [anchor appendChild:text];
        DOMDocumentFragment *fragment = [document createDocumentFragment];
        [fragment appendChild:anchor];
        return fragment;
    }

    if ([pboardType isEqualToString:WebCore::legacyStringPasteboardType()]) {
        if (!context)
            return nil;
        auto string = [[pasteboard stringForType:WebCore::legacyStringPasteboardType()] precomposedStringWithCanonicalMapping];
        return kit(createFragmentFromText(makeSimpleRange(*core(context)), string).ptr());
    }

    return nil;
}

#endif // PLATFORM(MAC)

- (BOOL)_isUsingAcceleratedCompositing
{
    return _private->layerHostingView != nil;
}

- (NSView *)_compositingLayersHostingView
{
    return _private->layerHostingView;
}

- (BOOL)_isInPrintMode
{
    return _private->printing;
}

- (BOOL)_beginPrintModeWithMinimumPageWidth:(CGFloat)minimumPageWidth height:(CGFloat)minimumPageHeight maximumPageWidth:(CGFloat)maximumPageWidth
{
    auto* frame = core([self _frame]);
    if (!frame)
        return NO;

    if (frame->document() && frame->document()->isFrameSet()) {
        minimumPageWidth = 0;
        minimumPageHeight = 0;
    }

    float maximumShrinkRatio = 0;
    if (minimumPageWidth > 0.0)
        maximumShrinkRatio = maximumPageWidth / minimumPageWidth;

    [self _setPrinting:YES minimumPageLogicalWidth:minimumPageWidth logicalHeight:minimumPageHeight originalPageWidth:minimumPageWidth originalPageHeight:minimumPageHeight maximumShrinkRatio:maximumShrinkRatio adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
    return YES;
}

- (BOOL)_beginPrintModeWithPageWidth:(float)pageWidth height:(float)pageHeight shrinkToFit:(BOOL)shrinkToFit
{
    auto* frame = core([self _frame]);
    if (!frame)
        return NO;

    auto* document = frame->document();
    bool isHorizontal = !document || !document->renderView() || document->renderView()->style().isHorizontalWritingMode();

    float pageLogicalWidth = isHorizontal ? pageWidth : pageHeight;
    float pageLogicalHeight = isHorizontal ? pageHeight : pageWidth;
    WebCore::FloatSize minLayoutSize(pageLogicalWidth, pageLogicalHeight);
    float maximumShrinkRatio = 1;

    // If we are a frameset just print with the layout we have onscreen, otherwise relayout
    // according to the page width.
    if (shrinkToFit && (!frame->document() || !frame->document()->isFrameSet())) {
        minLayoutSize = frame->resizePageRectsKeepingRatio(WebCore::FloatSize(pageLogicalWidth, pageLogicalHeight), WebCore::FloatSize(pageLogicalWidth * _WebHTMLViewPrintingMinimumShrinkFactor, pageLogicalHeight * _WebHTMLViewPrintingMinimumShrinkFactor));
        maximumShrinkRatio = _WebHTMLViewPrintingMaximumShrinkFactor / _WebHTMLViewPrintingMinimumShrinkFactor;
    }

    [self _setPrinting:YES minimumPageLogicalWidth:minLayoutSize.width() logicalHeight:minLayoutSize.height() originalPageWidth:pageLogicalWidth originalPageHeight:pageLogicalHeight maximumShrinkRatio:maximumShrinkRatio adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];

    return YES;
}

- (void)_endPrintMode
{
    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
}

- (BOOL)_isInScreenPaginationMode
{
    return _private->paginateScreenContent;
}

- (BOOL)_beginScreenPaginationModeWithPageSize:(CGSize)pageSize shrinkToFit:(BOOL)shrinkToFit
{
    auto* frame = core([self _frame]);
    if (!frame)
        return NO;

    auto* document = frame->document();
    bool isHorizontal = !document || !document->renderView() || document->renderView()->style().isHorizontalWritingMode();

    float pageLogicalWidth = isHorizontal ? pageSize.width : pageSize.height;
    float pageLogicalHeight = isHorizontal ? pageSize.height : pageSize.width;
    WebCore::FloatSize minLayoutSize(pageLogicalWidth, pageLogicalHeight);
    float maximumShrinkRatio = 1;

    // If we are a frameset just print with the layout we have onscreen, otherwise relayout
    // according to the page width.
    if (shrinkToFit && (!frame->document() || !frame->document()->isFrameSet())) {
        minLayoutSize = frame->resizePageRectsKeepingRatio(WebCore::FloatSize(pageLogicalWidth, pageLogicalHeight), WebCore::FloatSize(pageLogicalWidth * _WebHTMLViewPrintingMinimumShrinkFactor, pageLogicalHeight * _WebHTMLViewPrintingMinimumShrinkFactor));
        maximumShrinkRatio = _WebHTMLViewPrintingMaximumShrinkFactor / _WebHTMLViewPrintingMinimumShrinkFactor;
    }

    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:minLayoutSize.width() logicalHeight:minLayoutSize.height() originalPageWidth:pageLogicalWidth originalPageHeight:pageLogicalHeight maximumShrinkRatio:maximumShrinkRatio adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];

    return YES;
}

- (void)_endScreenPaginationMode
{
    [self _setPrinting:[self _isInPrintMode] minimumPageLogicalWidth:0 logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustViewSize:YES paginateScreenContent:NO];
}

- (CGFloat)_adjustedBottomOfPageWithTop:(CGFloat)top bottom:(CGFloat)bottom limit:(CGFloat)bottomLimit
{
    auto* frame = core([self _frame]);
    if (!frame)
        return bottom;

    auto* view = frame->view();
    if (!view)
        return bottom;

    float newBottom;
    view->adjustPageHeightDeprecated(&newBottom, top, bottom, bottomLimit);

    // If the new bottom is equal to the old bottom (when both are treated as floats), we just return the original
    // bottom. This prevents rounding errors that can occur when converting newBottom to a double.
    if (WTF::areEssentiallyEqual(static_cast<float>(bottom), newBottom))
        return bottom;
    return newBottom;
}

#if PLATFORM(IOS_FAMILY)

- (id)accessibilityRootElement
{
    return [[self _frame] accessibilityRoot];
}

#endif

#if PLATFORM(MAC)

- (NSView *)_hitViewForEvent:(NSEvent *)event
{
    // Usually, we hack AK's hitTest method to catch all events at the topmost WebHTMLView.
    // Callers of this method, however, want to query the deepest view instead.
    forceNSViewHitTest = YES;
    NSView *hitView = [(NSView *)[[self window] contentView] hitTest:[event locationInWindow]];
    forceNSViewHitTest = NO;
    return hitView;
}

#endif

@end

@implementation NSView (WebHTMLViewFileInternal)

- (void)_web_addDescendentWebHTMLViewsToArray:(NSMutableArray *)array
{
    for (NSView *child in [self subviews]) {
        if ([child isKindOfClass:[WebHTMLView class]])
            [array addObject:child];
        [child _web_addDescendentWebHTMLViewsToArray:array];
    }
}

@end

@implementation WebHTMLView

#if PLATFORM(MAC)

+ (void)initialize
{
    [NSApp registerServicesMenuSendTypes:[[self class] _selectionPasteboardTypes] returnTypes:[[self class] _insertablePasteboardTypes]];

    JSC::initialize();
    WTF::initializeMainThread();
    WebCore::populateJITOperations();
}

#endif

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (!self)
        return nil;
    
#if PLATFORM(MAC)
    [self setFocusRingType:NSFocusRingTypeNone];
#endif
    
    // Make all drawing go through us instead of subviews.
    [self _setDrawsOwnDescendants:YES];
    
    _private = [[WebHTMLViewPrivate alloc] init];

    _private->pluginController = adoptNS([[WebPluginController alloc] initWithDocumentView:self]);

#if PLATFORM(IOS_FAMILY)
    [[NSNotificationCenter defaultCenter] 
            addObserver:self selector:@selector(markedTextUpdate:) 
                   name:WebMarkedTextUpdatedNotification object:nil];
    auto notificationName = adoptNS([[NSString alloc] initWithCString:kGSEventHardwareKeyboardAvailabilityChangedNotification encoding:NSUTF8StringEncoding]);
    auto notificationBehavior = static_cast<CFNotificationSuspensionBehavior>(CFNotificationSuspensionBehaviorCoalesce | _CFNotificationObserverIsObjC);
    CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), hardwareKeyboardAvailabilityChangedCallback, (__bridge CFStringRef)notificationName.get(), nullptr, notificationBehavior);
#endif

#if PLATFORM(MAC)
    _private->softSpaceRange = NSMakeRange(NSNotFound, 0);
#endif
    
    return self;
}

- (void)dealloc
{
    if (WebCoreObjCScheduleDeallocateOnMainThread([WebHTMLView class], self))
        return;

#if PLATFORM(IOS_FAMILY)
    [[NSNotificationCenter defaultCenter] removeObserver:self name:WebMarkedTextUpdatedNotification object:nil];
    auto notificationName = adoptNS([[NSString alloc] initWithCString:kGSEventHardwareKeyboardAvailabilityChangedNotification encoding:NSUTF8StringEncoding]);
    CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), (__bridge const void *)(self), (__bridge CFStringRef)notificationName.get(), nullptr);
#endif

    // We can't assert that close has already been called because
    // this view can be removed from it's superview, even though
    // it could be needed later, so close if needed.
    [self close];
    [_private release];
    _private = nil;

    [super dealloc];
}

// Returns YES if the delegate returns YES (so we should do no more work).
- (BOOL)callDelegateDoCommandBySelectorIfNeeded:(SEL)selector
{
    BOOL callerAlreadyCalledDelegate = _private->selectorForDoCommandBySelector == selector;
    _private->selectorForDoCommandBySelector = 0;
    if (callerAlreadyCalledDelegate)
        return NO;
    WebView *webView = [self _webView];
    return [[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector];
}

typedef HashMap<SEL, String> SelectorNameMap;

// Map selectors into Editor command names.
// This is not needed for any selectors that have the same name as the Editor command.
static const SelectorNameMap* createSelectorExceptionMap()
{
    SelectorNameMap* map = new HashMap<SEL, String>;

    map->add(@selector(insertNewlineIgnoringFieldEditor:), "InsertNewline"_s);
    map->add(@selector(insertParagraphSeparator:), "InsertNewline"_s);
    map->add(@selector(insertTabIgnoringFieldEditor:), "InsertTab"_s);
    map->add(@selector(pageDown:), "MovePageDown"_s);
    map->add(@selector(pageDownAndModifySelection:), "MovePageDownAndModifySelection"_s);
    map->add(@selector(pageUp:), "MovePageUp"_s);
    map->add(@selector(pageUpAndModifySelection:), "MovePageUpAndModifySelection"_s);

    return map;
}

static String commandNameForSelector(SEL selector)
{
    // Check the exception map first.
    static const SelectorNameMap* exceptionMap = createSelectorExceptionMap();
    SelectorNameMap::const_iterator it = exceptionMap->find(selector);
    if (it != exceptionMap->end())
        return it->value;

    // Remove the trailing colon.
    // No need to capitalize the command name since Editor command names are
    // not case sensitive.
    const char* selectorName = sel_getName(selector);
    size_t selectorNameLength = strlen(selectorName);
    if (selectorNameLength < 2 || selectorName[selectorNameLength - 1] != ':')
        return String();
    return String(selectorName, selectorNameLength - 1);
}

- (WebCore::Editor::Command)coreCommandBySelector:(SEL)selector
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return WebCore::Editor::Command();
    return coreFrame->editor().command(commandNameForSelector(selector));
}

- (WebCore::Editor::Command)coreCommandByName:(const char*)name
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return WebCore::Editor::Command();
    return coreFrame->editor().command(String::fromLatin1(name));
}

- (void)executeCoreCommandBySelector:(SEL)selector
{
    if ([self callDelegateDoCommandBySelectorIfNeeded:selector])
        return;
    [self coreCommandBySelector:selector].execute();
}

- (void)executeCoreCommandByName:(const char*)name
{
    [self coreCommandByName:name].execute();
}

// These commands are forwarded to the Editor object in WebCore.
// Ideally we'd do this for all editing commands; more of the code
// should be moved from here to there, and more commands should be
// added to this list.

// FIXME: Maybe we should set things up so that all these share a single method implementation function.
// The functions are identical.

#define WEBCORE_COMMAND(command) - (void)command:(id)sender { [self executeCoreCommandBySelector:_cmd]; }

WEBCORE_COMMAND(alignCenter)
WEBCORE_COMMAND(alignJustified)
WEBCORE_COMMAND(alignLeft)
WEBCORE_COMMAND(alignRight)
WEBCORE_COMMAND(copy)
WEBCORE_COMMAND(cut)
WEBCORE_COMMAND(paste)
WEBCORE_COMMAND(delete)
WEBCORE_COMMAND(deleteBackward)
WEBCORE_COMMAND(deleteBackwardByDecomposingPreviousCharacter)
WEBCORE_COMMAND(deleteForward)
WEBCORE_COMMAND(deleteToBeginningOfLine)
WEBCORE_COMMAND(deleteToBeginningOfParagraph)
WEBCORE_COMMAND(deleteToEndOfLine)
WEBCORE_COMMAND(deleteToEndOfParagraph)
WEBCORE_COMMAND(deleteToMark)
WEBCORE_COMMAND(deleteWordBackward)
WEBCORE_COMMAND(deleteWordForward)
WEBCORE_COMMAND(ignoreSpelling)
WEBCORE_COMMAND(indent)
WEBCORE_COMMAND(insertBacktab)
WEBCORE_COMMAND(insertLineBreak)
WEBCORE_COMMAND(insertNewline)
WEBCORE_COMMAND(insertNewlineIgnoringFieldEditor)
WEBCORE_COMMAND(insertParagraphSeparator)
WEBCORE_COMMAND(insertTab)
WEBCORE_COMMAND(insertTabIgnoringFieldEditor)
WEBCORE_COMMAND(makeTextWritingDirectionLeftToRight)
WEBCORE_COMMAND(makeTextWritingDirectionNatural)
WEBCORE_COMMAND(makeTextWritingDirectionRightToLeft)
WEBCORE_COMMAND(moveBackward)
WEBCORE_COMMAND(moveBackwardAndModifySelection)
WEBCORE_COMMAND(moveDown)
WEBCORE_COMMAND(moveDownAndModifySelection)
WEBCORE_COMMAND(moveForward)
WEBCORE_COMMAND(moveForwardAndModifySelection)
WEBCORE_COMMAND(moveLeft)
WEBCORE_COMMAND(moveLeftAndModifySelection)
WEBCORE_COMMAND(moveParagraphBackwardAndModifySelection)
WEBCORE_COMMAND(moveParagraphForwardAndModifySelection)
WEBCORE_COMMAND(moveRight)
WEBCORE_COMMAND(moveRightAndModifySelection)
WEBCORE_COMMAND(moveToBeginningOfDocument)
WEBCORE_COMMAND(moveToBeginningOfDocumentAndModifySelection)
WEBCORE_COMMAND(moveToBeginningOfLine)
WEBCORE_COMMAND(moveToBeginningOfLineAndModifySelection)
WEBCORE_COMMAND(moveToBeginningOfParagraph)
WEBCORE_COMMAND(moveToBeginningOfParagraphAndModifySelection)
WEBCORE_COMMAND(moveToBeginningOfSentence)
WEBCORE_COMMAND(moveToBeginningOfSentenceAndModifySelection)
WEBCORE_COMMAND(moveToEndOfDocument)
WEBCORE_COMMAND(moveToEndOfDocumentAndModifySelection)
WEBCORE_COMMAND(moveToEndOfLine)
WEBCORE_COMMAND(moveToEndOfLineAndModifySelection)
WEBCORE_COMMAND(moveToEndOfParagraph)
WEBCORE_COMMAND(moveToEndOfParagraphAndModifySelection)
WEBCORE_COMMAND(moveToEndOfSentence)
WEBCORE_COMMAND(moveToEndOfSentenceAndModifySelection)
WEBCORE_COMMAND(moveToLeftEndOfLine)
WEBCORE_COMMAND(moveToLeftEndOfLineAndModifySelection)
WEBCORE_COMMAND(moveToRightEndOfLine)
WEBCORE_COMMAND(moveToRightEndOfLineAndModifySelection)
WEBCORE_COMMAND(moveUp)
WEBCORE_COMMAND(moveUpAndModifySelection)
WEBCORE_COMMAND(moveWordBackward)
WEBCORE_COMMAND(moveWordBackwardAndModifySelection)
WEBCORE_COMMAND(moveWordForward)
WEBCORE_COMMAND(moveWordForwardAndModifySelection)
WEBCORE_COMMAND(moveWordLeft)
WEBCORE_COMMAND(moveWordLeftAndModifySelection)
WEBCORE_COMMAND(moveWordRight)
WEBCORE_COMMAND(moveWordRightAndModifySelection)
WEBCORE_COMMAND(outdent)
WEBCORE_COMMAND(overWrite)
WEBCORE_COMMAND(pageDown)
WEBCORE_COMMAND(pageDownAndModifySelection)
WEBCORE_COMMAND(pageUp)
WEBCORE_COMMAND(pageUpAndModifySelection)
WEBCORE_COMMAND(pasteAsPlainText)
WEBCORE_COMMAND(selectAll)
WEBCORE_COMMAND(selectLine)
WEBCORE_COMMAND(selectParagraph)
WEBCORE_COMMAND(selectSentence)
WEBCORE_COMMAND(selectToMark)
WEBCORE_COMMAND(selectWord)
WEBCORE_COMMAND(setMark)
WEBCORE_COMMAND(subscript)
WEBCORE_COMMAND(superscript)
WEBCORE_COMMAND(swapWithMark)
WEBCORE_COMMAND(transpose)
WEBCORE_COMMAND(underline)
WEBCORE_COMMAND(unscript)
WEBCORE_COMMAND(yank)
WEBCORE_COMMAND(yankAndSelect)

#if PLATFORM(IOS_FAMILY)
WEBCORE_COMMAND(clearText)
WEBCORE_COMMAND(toggleBold)
WEBCORE_COMMAND(toggleItalic)
WEBCORE_COMMAND(toggleUnderline)
#endif

#undef WEBCORE_COMMAND

#define COMMAND_PROLOGUE if ([self callDelegateDoCommandBySelectorIfNeeded:_cmd]) return;

#if PLATFORM(MAC)

- (IBAction)takeFindStringFromSelection:(id)sender
{
    COMMAND_PROLOGUE

    if (![self _hasSelection]) {
        NSBeep();
        return;
    }

    [NSPasteboard _web_setFindPasteboardString:[self selectedString] withOwner:self];
}

// This method is needed to support macOS services.
- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pasteboard types:(NSArray *)types
{
    [pasteboard declareTypes:types owner:[self _topHTMLView]];
    [self writeSelectionWithPasteboardTypes:types toPasteboard:pasteboard];
    return YES;
}

- (id)validRequestorForSendType:(NSString *)sendType returnType:(NSString *)returnType
{
    BOOL isSendTypeOK = !sendType || ([[self pasteboardTypesForSelection] containsObject:sendType] && [self _hasSelection]);
    BOOL isReturnTypeOK = NO;
    if (!returnType)
        isReturnTypeOK = YES;
    else if ([[[self class] _insertablePasteboardTypes] containsObject:returnType] && [self _isEditable]) {
        // We can insert strings in any editable context.  We can insert other types, like images, only in rich edit contexts.
        isReturnTypeOK = [returnType isEqualToString:WebCore::legacyStringPasteboardType()] || [self _canEditRichly];
    }
    if (isSendTypeOK && isReturnTypeOK)
        return self;
    return [[self nextResponder] validRequestorForSendType:sendType returnType:returnType];
}

#endif

// jumpToSelection is the old name for what AppKit now calls centerSelectionInVisibleArea. Safari
// was using the old jumpToSelection selector in its menu. Newer versions of Safari will use the
// selector centerSelectionInVisibleArea. We'll leave the old selector in place for two reasons:
// (1) Compatibility between older Safari and newer WebKit; (2) other WebKit-based applications
// might be using the selector, and we don't want to break them.
- (void)jumpToSelection:(id)sender
{
    COMMAND_PROLOGUE

    if (auto* coreFrame = core([self _frame]))
        coreFrame->selection().revealSelection(WebCore::SelectionRevealMode::Reveal, WebCore::ScrollAlignment::alignCenterAlways);
}

#if PLATFORM(MAC)

- (BOOL)validateUserInterfaceItemWithoutDelegate:(id <NSValidatedUserInterfaceItem>)item
{
    SEL action = [item action];
    RefPtr<WebCore::Frame> frame = core([self _frame]);

    if (!frame)
        return NO;

    if (WebCore::Document* doc = frame->document()) {
        if (doc->isPluginDocument())
            return NO;
        if (doc->isImageDocument()) {            
            if (action == @selector(copy:))
                return frame->loader().isComplete();
            return NO;
        }
    }
    if (action == @selector(changeSpelling:)
IGNORE_WARNINGS_BEGIN("undeclared-selector")
            || action == @selector(_changeSpellingFromMenu:)
IGNORE_WARNINGS_END
            || action == @selector(checkSpelling:)
            || action == @selector(complete:)
            || action == @selector(pasteFont:))
        return [self _canEdit];

    if (action == @selector(showGuessPanel:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
            BOOL panelShowing = [[[NSSpellChecker sharedSpellChecker] spellingPanel] isVisible];
            [menuItem setTitle:panelShowing
                ? UI_STRING_INTERNAL("Hide Spelling and Grammar", "menu item title")
                : UI_STRING_INTERNAL("Show Spelling and Grammar", "menu item title")];
        }
        return [self _canEdit];
    }
    
    if (action == @selector(changeBaseWritingDirection:)
            || action == @selector(makeBaseWritingDirectionLeftToRight:)
            || action == @selector(makeBaseWritingDirectionRightToLeft:)) {
        NSWritingDirection writingDirection;

        if (action == @selector(changeBaseWritingDirection:)) {
            writingDirection = static_cast<NSWritingDirection>([item tag]);
            if (writingDirection == NSWritingDirectionNatural)
                return NO;
        } else if (action == @selector(makeBaseWritingDirectionLeftToRight:))
            writingDirection = NSWritingDirectionLeftToRight;
        else
            writingDirection = NSWritingDirectionRightToLeft;

        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
            String direction = writingDirection == NSWritingDirectionLeftToRight ? "ltr"_s : "rtl"_s;
            [menuItem setState:(frame->editor().selectionHasStyle(WebCore::CSSPropertyDirection, direction) != TriState::False)];
        }
        return [self _canEdit];
    }

    if (action == @selector(makeBaseWritingDirectionNatural:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:NSControlStateValueOff];
        return NO;
    }

    if (action == @selector(toggleBaseWritingDirection:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
            // Take control of the title of the menu item instead of just checking/unchecking it because
            // a check would be ambiguous.
            [menuItem setTitle:(frame->editor().selectionHasStyle(WebCore::CSSPropertyDirection, "rtl"_s) != TriState::False)
                ? UI_STRING_INTERNAL("Left to Right", "Left to Right context menu item")
                : UI_STRING_INTERNAL("Right to Left", "Right to Left context menu item")];
        }
        return [self _canEdit];
    } 

    if (action == @selector(changeAttributes:)
            || action == @selector(changeColor:)        
            || action == @selector(changeFont:))
        return [self _canEditRichly];

    if (action == @selector(capitalizeWord:)
               || action == @selector(lowercaseWord:)
               || action == @selector(uppercaseWord:))
        return [self _hasSelection] && [self _isEditable];

    if (action == @selector(centerSelectionInVisibleArea:)
               || action == @selector(jumpToSelection:)
               || action == @selector(copyFont:))
        return [self _hasSelection] || ([self _isEditable] && [self _hasInsertionPoint]);

    if (action == @selector(changeDocumentBackgroundColor:))
        return [[self _webView] isEditable] && [self _canEditRichly];

IGNORE_WARNINGS_BEGIN("undeclared-selector")
    if (action == @selector(_ignoreSpellingFromMenu:)
            || action == @selector(_learnSpellingFromMenu:)
IGNORE_WARNINGS_END
            || action == @selector(takeFindStringFromSelection:))
        return [self _hasSelection];

    if (action == @selector(paste:) || action == @selector(pasteAsPlainText:))
        return frame && (frame->editor().canDHTMLPaste() || frame->editor().canPaste());

    if (action == @selector(pasteAsRichText:))
        return frame && (frame->editor().canDHTMLPaste()
            || (frame->editor().canPaste() && frame->selection().selection().isContentRichlyEditable()));

    if (action == @selector(performFindPanelAction:))
        return NO;

    if (action == @selector(_lookUpInDictionaryFromMenu:))
        return [self _hasSelection];

    if (action == @selector(stopSpeaking:))
        return [NSApp isSpeaking];

    if (action == @selector(toggleGrammarChecking:)) {
        // FIXME 4799134: WebView is the bottleneck for this grammar-checking logic, but we must validate 
        // the selector here because we implement it here, and we must implement it here because the AppKit 
        // code checks the first responder.
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:[self isGrammarCheckingEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
        return YES;
    }

    if (action == @selector(orderFrontSubstitutionsPanel:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]]) {
            BOOL panelShowing = [[[NSSpellChecker sharedSpellChecker] substitutionsPanel] isVisible];
            [menuItem setTitle:panelShowing
                ? UI_STRING_INTERNAL("Hide Substitutions", "menu item title")
                : UI_STRING_INTERNAL("Show Substitutions", "menu item title")];
        }
        return [self _canEdit];
    }

    // FIXME 4799134: WebView is the bottleneck for this logic, but we must validate 
    // the selector here because we implement it here, and we must implement it here because the AppKit 
    // code checks the first responder.
    if (action == @selector(toggleSmartInsertDelete:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:[self smartInsertDeleteEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
        return [self _canEdit];
    }

    if (action == @selector(toggleAutomaticQuoteSubstitution:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:[self isAutomaticQuoteSubstitutionEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
        return [self _canEdit];
    }

    if (action == @selector(toggleAutomaticLinkDetection:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:[self isAutomaticLinkDetectionEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
        return [self _canEdit];
    }

    if (action == @selector(toggleAutomaticDashSubstitution:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:[self isAutomaticDashSubstitutionEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
        return [self _canEdit];
    }

    if (action == @selector(toggleAutomaticTextReplacement:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:[self isAutomaticTextReplacementEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
        return [self _canEdit];
    }

    if (action == @selector(toggleAutomaticSpellingCorrection:)) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:[self isAutomaticSpellingCorrectionEnabled] ? NSControlStateValueOn : NSControlStateValueOff];
        return [self _canEdit];
    }

    auto command = [self coreCommandBySelector:action];
    if (command.isSupported()) {
        NSMenuItem *menuItem = (NSMenuItem *)item;
        if ([menuItem isKindOfClass:[NSMenuItem class]])
            [menuItem setState:kit(command.state())];
        return command.isEnabled();
    }

    return YES;
}

- (BOOL)validateUserInterfaceItem:(id <NSValidatedUserInterfaceItem>)item
{
    // This can be called during teardown when _webView is nil. Return NO when this happens, because CallUIDelegateReturningBoolean
    // assumes the WebVIew is non-nil.
    if (![self _webView])
        return NO;
    BOOL result = [self validateUserInterfaceItemWithoutDelegate:item];
    return CallUIDelegateReturningBoolean(result, [self _webView], @selector(webView:validateUserInterfaceItem:defaultValidation:), item, result);
}

#endif // PLATFORM(MAC)

- (BOOL)acceptsFirstResponder
{
    // Don't accept first responder when we first click on this view.
    // We have to pass the event down through WebCore first to be sure we don't hit a subview.
    // Do accept first responder at any other time, for example from keyboard events,
    // or from calls back from WebCore once we begin mouse-down event handling.
#if PLATFORM(MAC)
    WebEvent *event = [NSApp currentEvent];
#else
    WebEvent *event = [WAKWindow currentEvent];
#endif
    if (event && event.type == WebEventMouseDown
            && !_private->handlingMouseDownEvent
            && NSPointInRect([event locationInWindow], [self convertRect:[self visibleRect] toView:nil]))
        return NO;
    return YES;
}

- (BOOL)maintainsInactiveSelection
{
#if USE(UIKIT_EDITING)
    // We want to maintain an inactive selection, when in editable content.
    if ([[self _webView] maintainsInactiveSelection])
        return YES;

    if ([[self window] _newFirstResponderAfterResigning] == self)
        return YES;
    
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->selection().selection().isContentEditable();
#else
    // This method helps to determine whether the WebHTMLView should maintain
    // an inactive selection when it's not first responder.
    // Traditionally, these views have not maintained such selections,
    // clearing them when the view was not first responder. However,
    // to fix bugs like this one:
    // <rdar://problem/3672088>: "Editable WebViews should maintain a selection even 
    //                            when they're not firstResponder"
    // it was decided to add a switch to act more like an NSTextView.

    if ([[self _webView] maintainsInactiveSelection])
        return YES;

    // Predict the case where we are losing first responder status only to
    // gain it back again. Want to keep the selection in that case.
    id nextResponder = [[self window] _newFirstResponderAfterResigning];
    if ([nextResponder isKindOfClass:[NSScrollView class]]) {
        id contentView = [nextResponder contentView];
        if (contentView)
            nextResponder = contentView;
    }
    if ([nextResponder isKindOfClass:[NSClipView class]]) {
        id documentView = [nextResponder documentView];
        if (documentView)
            nextResponder = documentView;
    }
    if (nextResponder == self)
        return YES;

    auto* coreFrame = core([self _frame]);
    bool selectionIsEditable = coreFrame && coreFrame->selection().selection().isContentEditable();
    bool nextResponderIsInWebView = [nextResponder isKindOfClass:[NSView class]]
        && [nextResponder isDescendantOf:[[[self _webView] mainFrame] frameView]];

    return selectionIsEditable && nextResponderIsInWebView;
#endif
}

#if PLATFORM(MAC)

- (void)addSuperviewObservers
{
    if (_private->observingSuperviewNotifications)
        return;

    NSView *superview = [self superview];
    if (!superview || ![self window])
        return;
    
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter addObserver:self selector:@selector(_frameOrBoundsChanged) name:NSViewFrameDidChangeNotification object:superview];
    [notificationCenter addObserver:self selector:@selector(_frameOrBoundsChanged) name:NSViewBoundsDidChangeNotification object:superview];
    
    // In addition to registering for frame/bounds change notifications, call -_frameOrBoundsChanged.
    // It will check the current scroll against the previous layout's scroll.  We need to
    // do this here to catch the case where the WebView is laid out at one size, removed from its
    // window, resized, and inserted into another window.  Our frame/bounds changed notifications
    // will not be sent in that situation, since we only watch for changes while in the view hierarchy.
    [self _frameOrBoundsChanged];
    
    _private->observingSuperviewNotifications = true;
}

- (void)addWindowObservers
{
    if (_private->observingWindowNotifications)
        return;
    
    NSWindow *window = [self window];
    if (!window)
        return;
    
    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    [notificationCenter addObserver:self selector:@selector(windowDidBecomeKey:) name:NSWindowDidBecomeKeyNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(windowDidResignKey:) name:NSWindowDidResignKeyNotification object:nil];
    [notificationCenter addObserver:self selector:@selector(windowWillClose:) name:NSWindowWillCloseNotification object:window];
    
    _private->observingWindowNotifications = true;
}

- (void)viewWillMoveToSuperview:(NSView *)newSuperview
{
    [self _removeSuperviewObservers];
}

- (void)viewDidMoveToSuperview
{
    if ([self superview] != nil)
        [self addSuperviewObservers];

    if ([self superview] && [self _isUsingAcceleratedCompositing]) {
        WebView *webView = [self _webView];
        if ([webView _postsAcceleratedCompositingNotifications])
            [[NSNotificationCenter defaultCenter] postNotificationName:_WebViewDidStartAcceleratedCompositingNotification object:webView userInfo:nil];
    }
}

#endif // PLATFORM(MAC)

- (void)viewWillMoveToWindow:(NSWindow *)window
{
    // Don't do anything if we aren't initialized.  This happens
    // when decoding a WebView.  When WebViews are decoded their subviews
    // are created by initWithCoder: and so won't be normally
    // initialized.  The stub views are discarded by WebView.
    if (!_private)
        return;

#if PLATFORM(MAC)
    // FIXME: Some of these calls may not work because this view may be already removed from it's superview.
    [self _removeWindowObservers];
    [self _removeSuperviewObservers];
#endif

    // FIXME: This accomplishes the same thing as the call to setCanStartMedia(false) in
    // WebView. It would be nice to have a single mechanism instead of two.
    [[self _pluginController] stopAllPlugins];
}

- (void)viewDidMoveToWindow
{
    // Don't do anything if we aren't initialized.  This happens
    // when decoding a WebView.  When WebViews are decoded their subviews
    // are created by initWithCoder: and so won't be normally
    // initialized.  The stub views are discarded by WebView.
    if (!_private || _private->closed)
        return;
        
    [self _stopAutoscrollTimer];
    if ([self window]) {
        _private->lastScrollPosition = [[self superview] bounds].origin;
#if PLATFORM(MAC)
        [self addWindowObservers];
        [self addSuperviewObservers];
#endif

        // FIXME: This accomplishes the same thing as the call to setCanStartMedia(true) in
        // WebView. It would be nice to have a single mechanism instead of two.
        [[self _pluginController] startAllPlugins];

        _private->lastScrollPosition = NSZeroPoint;

#if PLATFORM(MAC)
        if (!_private->flagsChangedEventMonitor) {
            __block WebHTMLView *weakSelf = self;
            _private->flagsChangedEventMonitor = [NSEvent addLocalMonitorForEventsMatchingMask:NSEventMaskFlagsChanged handler:^(NSEvent *flagsChangedEvent) {
                [weakSelf _postFakeMouseMovedEventForFlagsChangedEvent:flagsChangedEvent];
                return flagsChangedEvent;
            }];
        }
    } else {
        [NSEvent removeMonitor:_private->flagsChangedEventMonitor];
        _private->flagsChangedEventMonitor = nil;
#endif
    }
}

- (void)viewWillMoveToHostWindow:(NSWindow *)hostWindow
{
}

- (void)viewDidMoveToHostWindow
{
}

- (void)addSubview:(NSView *)view
{
    [super addSubview:view];

    if ([WebPluginController isPlugInView:view]) {

#if PLATFORM(IOS_FAMILY)
        WebView *webView = [self _webView];
        [[webView _UIKitDelegateForwarder] webView:webView willAddPlugInView:view];
#endif

        [[self _pluginController] addPlugin:view];
    }
}

- (void)willRemoveSubview:(NSView *)subview
{
    if ([WebPluginController isPlugInView:subview])
        [[self _pluginController] destroyPlugin:subview];

    [super willRemoveSubview:subview];
}

- (void)reapplyStyles
{
#ifdef LOG_TIMES
    double start = CFAbsoluteTimeGetCurrent();
#endif

    if (auto* coreFrame = core([self _frame])) {
        coreFrame->document()->styleScope().didChangeStyleSheetEnvironment();
        coreFrame->document()->updateStyleIfNeeded();
    }

#ifdef LOG_TIMES
    double thisTime = CFAbsoluteTimeGetCurrent() - start;
    LOG(Timing, "%s apply style seconds = %f", [self URL], thisTime);
#endif
}

// Do a layout, but set up a new fixed width for the purposes of doing printing layout.
// minPageWidth==0 implies a non-printing layout
- (void)layoutToMinimumPageWidth:(float)minPageLogicalWidth height:(float)minPageLogicalHeight originalPageWidth:(float)originalPageWidth originalPageHeight:(float)originalPageHeight maximumShrinkRatio:(float)maximumShrinkRatio adjustingViewSize:(BOOL)adjustViewSize
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;
    if (coreFrame->document()) {
        if (coreFrame->document()->backForwardCacheState() != WebCore::Document::NotInBackForwardCache)
            return;
        coreFrame->document()->updateStyleIfNeeded();
    }

    if (![self _needsLayout])
        return;

#ifdef LOG_TIMES        
    double start = CFAbsoluteTimeGetCurrent();
#endif

    LOG(View, "%@ doing layout", self);

    if (auto* coreView = coreFrame->view()) {
        if (minPageLogicalWidth > 0.0) {
            WebCore::FloatSize pageSize(minPageLogicalWidth, minPageLogicalHeight);
            WebCore::FloatSize originalPageSize(originalPageWidth, originalPageHeight);
            if (coreFrame->document() && coreFrame->document()->renderView() && !coreFrame->document()->renderView()->style().isHorizontalWritingMode()) {
                pageSize = WebCore::FloatSize(minPageLogicalHeight, minPageLogicalWidth);
                originalPageSize = WebCore::FloatSize(originalPageHeight, originalPageWidth);
            }
            coreView->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, adjustViewSize ? WebCore::AdjustViewSize : WebCore::DoNotAdjustViewSize);
        } else {
            coreView->forceLayout(!adjustViewSize);
            if (adjustViewSize)
                coreView->adjustViewSize();
        }
    }
    
#ifdef LOG_TIMES        
    double thisTime = CFAbsoluteTimeGetCurrent() - start;
    LOG(Timing, "%s layout seconds = %f", [self URL], thisTime);
#endif
}

- (void)layout
{
    [self layoutToMinimumPageWidth:0 height:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustingViewSize:NO];
}

#if PLATFORM(MAC)

// Deliver mouseup events to the DOM for button 2.
- (void)rightMouseUp:(NSEvent *)event
{
    // There's a chance that if we run a nested event loop the event will be released.
    // Retaining and then autoreleasing prevents that from causing a problem later here or
    // inside AppKit code.
    retainPtr(event).autorelease();

    [super rightMouseUp:event];

    if (auto* coreFrame = core([self _frame]))
        coreFrame->eventHandler().mouseUp(event, [[self _webView] _pressureEvent]);
}

static BOOL isPreVersion3Client(void)
{
    static BOOL preVersion3Client = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_3_0_CONTEXT_MENU_TAGS);
    return preVersion3Client;
}

static BOOL isPreInspectElementTagClient(void)
{
    static BOOL preInspectElementTagClient = !WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITH_INSPECT_ELEMENT_MENU_TAG);
    return preInspectElementTagClient;
}

enum {
    // The next three values were used in WebKit 2.0 for SPI. In WebKit 3.0 these are API, with different values.
    OldWebMenuItemTagSearchInSpotlight = 1000,
    OldWebMenuItemTagSearchWeb,
    OldWebMenuItemTagLookUpInDictionary,
};

static RetainPtr<NSArray> fixMenusToSendToOldClients(NSMutableArray *defaultMenuItems)
{
    auto savedItems = adoptNS([[NSMutableArray alloc] init]);

    unsigned defaultItemsCount = [defaultMenuItems count];

    if (isPreInspectElementTagClient() && defaultItemsCount >= 2) {
        NSMenuItem *secondToLastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 2];
        NSMenuItem *lastItem = [defaultMenuItems objectAtIndex:defaultItemsCount - 1];

        if ([secondToLastItem isSeparatorItem] && [lastItem tag] == WebMenuItemTagInspectElement) {
            savedItems = adoptNS([[NSMutableArray alloc] initWithCapacity:2]);
            [savedItems addObject:secondToLastItem];
            [savedItems addObject:lastItem];

            [defaultMenuItems removeObject:secondToLastItem];
            [defaultMenuItems removeObject:lastItem];
            defaultItemsCount -= 2;
        }
    }

    BOOL preVersion3Client = isPreVersion3Client();
    if (!preVersion3Client)
        return savedItems;

    for (NSMenuItem *item in defaultMenuItems) {
        int tag = item.tag;
        int oldStyleTag = tag;

        if (tag >= WEBMENUITEMTAG_WEBKIT_3_0_SPI_START) {
            // Change all editing-related SPI tags listed in WebUIDelegatePrivate.h to WebMenuItemTagOther
            // to match our old WebKit context menu behavior.
            oldStyleTag = WebMenuItemTagOther;
        } else {
            // All items are expected to have useful tags coming into this method.
            ASSERT(tag != WebMenuItemTagOther);
            
            // Use the pre-3.0 tags for the few items that changed tags as they moved from SPI to API. We
            // do this only for old clients; new Mail already expects the new symbols in this case.
            if (preVersion3Client) {
                switch (tag) {
                case WebMenuItemTagSearchInSpotlight:
                    oldStyleTag = OldWebMenuItemTagSearchInSpotlight;
                    break;
                case WebMenuItemTagSearchWeb:
                    oldStyleTag = OldWebMenuItemTagSearchWeb;
                    break;
                case WebMenuItemTagLookUpInDictionary:
                    oldStyleTag = OldWebMenuItemTagLookUpInDictionary;
                    break;
                default:
                    break;
                }
            }
        }

        item.tag = oldStyleTag;
    }

    return savedItems;
}

static RetainPtr<NSArray> fixMenusReceivedFromOldClients(NSArray *delegateSuppliedItems, NSArray *savedItems)
{
    using namespace WebCore;
    auto newMenuItems = adoptNS([delegateSuppliedItems mutableCopy]);

    if (savedItems)
        [newMenuItems addObjectsFromArray:savedItems];

    BOOL preVersion3Client = isPreVersion3Client();
    if (!preVersion3Client)
        return newMenuItems;
    
    // Restore the modern tags to the menu items whose tags we altered in fixMenusToSendToOldClients. 
    for (NSMenuItem *item in newMenuItems.get()) {
        int tag = [item tag];
        int modernTag = tag;
        
        if (tag == WebMenuItemTagOther) {
            // Restore the specific tag for items on which we temporarily set WebMenuItemTagOther to match old behavior.
            NSString *title = [item title];
            if ([title isEqualToString:contextMenuItemTagOpenLink()])
                modernTag = WebMenuItemTagOpenLink;
            else if ([title isEqualToString:contextMenuItemTagIgnoreGrammar()])
                modernTag = WebMenuItemTagIgnoreGrammar;
            else if ([title isEqualToString:contextMenuItemTagSpellingMenu()])
                modernTag = WebMenuItemTagSpellingMenu;
            else if ([title isEqualToString:contextMenuItemTagShowSpellingPanel(true)] || [title isEqualToString:contextMenuItemTagShowSpellingPanel(false)])
                modernTag = WebMenuItemTagShowSpellingPanel;
            else if ([title isEqualToString:contextMenuItemTagCheckSpelling()])
                modernTag = WebMenuItemTagCheckSpelling;
            else if ([title isEqualToString:contextMenuItemTagCheckSpellingWhileTyping()])
                modernTag = WebMenuItemTagCheckSpellingWhileTyping;
            else if ([title isEqualToString:contextMenuItemTagCheckGrammarWithSpelling()])
                modernTag = WebMenuItemTagCheckGrammarWithSpelling;
            else if ([title isEqualToString:contextMenuItemTagFontMenu()])
                modernTag = WebMenuItemTagFontMenu;
            else if ([title isEqualToString:contextMenuItemTagShowFonts()])
                modernTag = WebMenuItemTagShowFonts;
            else if ([title isEqualToString:contextMenuItemTagBold()])
                modernTag = WebMenuItemTagBold;
            else if ([title isEqualToString:contextMenuItemTagItalic()])
                modernTag = WebMenuItemTagItalic;
            else if ([title isEqualToString:contextMenuItemTagUnderline()])
                modernTag = WebMenuItemTagUnderline;
            else if ([title isEqualToString:contextMenuItemTagOutline()])
                modernTag = WebMenuItemTagOutline;
            else if ([title isEqualToString:contextMenuItemTagStyles()])
                modernTag = WebMenuItemTagStyles;
            else if ([title isEqualToString:contextMenuItemTagShowColors()])
                modernTag = WebMenuItemTagShowColors;
            else if ([title isEqualToString:contextMenuItemTagSpeechMenu()])
                modernTag = WebMenuItemTagSpeechMenu;
            else if ([title isEqualToString:contextMenuItemTagStartSpeaking()])
                modernTag = WebMenuItemTagStartSpeaking;
            else if ([title isEqualToString:contextMenuItemTagStopSpeaking()])
                modernTag = WebMenuItemTagStopSpeaking;
            else if ([title isEqualToString:contextMenuItemTagWritingDirectionMenu()])
                modernTag = WebMenuItemTagWritingDirectionMenu;
            else if ([title isEqualToString:contextMenuItemTagDefaultDirection()])
                modernTag = WebMenuItemTagDefaultDirection;
            else if ([title isEqualToString:contextMenuItemTagLeftToRight()])
                modernTag = WebMenuItemTagLeftToRight;
            else if ([title isEqualToString:contextMenuItemTagRightToLeft()])
                modernTag = WebMenuItemTagRightToLeft;
            else if ([title isEqualToString:contextMenuItemTagInspectElement()])
                modernTag = WebMenuItemTagInspectElement;
            else if ([title isEqualToString:contextMenuItemTagCorrectSpellingAutomatically()])
                modernTag = WebMenuItemTagCorrectSpellingAutomatically;
            else if ([title isEqualToString:contextMenuItemTagSubstitutionsMenu()])
                modernTag = WebMenuItemTagSubstitutionsMenu;
            else if ([title isEqualToString:contextMenuItemTagShowSubstitutions(true)] || [title isEqualToString:contextMenuItemTagShowSubstitutions(false)])
                modernTag = WebMenuItemTagShowSubstitutions;
            else if ([title isEqualToString:contextMenuItemTagSmartCopyPaste()])
                modernTag = WebMenuItemTagSmartCopyPaste;
            else if ([title isEqualToString:contextMenuItemTagSmartQuotes()])
                modernTag = WebMenuItemTagSmartQuotes;
            else if ([title isEqualToString:contextMenuItemTagSmartDashes()])
                modernTag = WebMenuItemTagSmartDashes;
            else if ([title isEqualToString:contextMenuItemTagSmartLinks()])
                modernTag = WebMenuItemTagSmartLinks;
            else if ([title isEqualToString:contextMenuItemTagTextReplacement()])
                modernTag = WebMenuItemTagTextReplacement;
            else if ([title isEqualToString:contextMenuItemTagTransformationsMenu()])
                modernTag = WebMenuItemTagTransformationsMenu;
            else if ([title isEqualToString:contextMenuItemTagMakeUpperCase()])
                modernTag = WebMenuItemTagMakeUpperCase;
            else if ([title isEqualToString:contextMenuItemTagMakeLowerCase()])
                modernTag = WebMenuItemTagMakeLowerCase;
            else if ([title isEqualToString:contextMenuItemTagCapitalize()])
                modernTag = WebMenuItemTagCapitalize;
            else {
            // We don't expect WebMenuItemTagOther for any items other than the ones we explicitly handle.
            // There's nothing to prevent an app from applying this tag, but they are supposed to only
            // use tags in the range starting with WebMenuItemBaseApplicationTag=10000
                ASSERT_NOT_REACHED();
            }
        } else if (preVersion3Client) {
            // Restore the new API tag for items on which we temporarily set the old SPI tag. The old SPI tag was
            // needed to avoid confusing clients linked against earlier WebKits; the new API tag is needed for
            // WebCore to handle the menu items appropriately (without needing to know about the old SPI tags).
            switch (tag) {
            case OldWebMenuItemTagSearchInSpotlight:
                modernTag = WebMenuItemTagSearchInSpotlight;
                break;
            case OldWebMenuItemTagSearchWeb:
                modernTag = WebMenuItemTagSearchWeb;
                break;
            case OldWebMenuItemTagLookUpInDictionary:
                modernTag = WebMenuItemTagLookUpInDictionary;
                break;
            default:
                break;
            }
        }
        
        if (modernTag != tag)
            [item setTag:modernTag];        
    }

    return newMenuItems;
}

static RetainPtr<NSMenuItem> createShareMenuItem(const WebCore::HitTestResult& hitTestResult)
{
    auto items = adoptNS([[NSMutableArray alloc] init]);

    if (!hitTestResult.absoluteLinkURL().isEmpty()) {
        NSURL *absoluteLinkURL = hitTestResult.absoluteLinkURL();
        [items addObject:absoluteLinkURL];
    }

    if (!hitTestResult.absoluteMediaURL().isEmpty() && hitTestResult.isDownloadableMedia()) {
        NSURL *downloadableMediaURL = hitTestResult.absoluteMediaURL();
        [items addObject:downloadableMediaURL];
    }

    if (auto* image = hitTestResult.image()) {
        if (RefPtr<const WebCore::FragmentedSharedBuffer> buffer = image->data())
            [items addObject:adoptNS([[NSImage alloc] initWithData:buffer->makeContiguous()->createNSData().get()]).get()];
    }

    if (!hitTestResult.selectedText().isEmpty()) {
        NSString *selectedText = hitTestResult.selectedText();
        [items addObject:selectedText];
    }

    if (![items count])
        return nil;

    return [NSMenuItem standardShareMenuItemForItems:items.get()];
}

static RetainPtr<NSMutableArray> createMenuItems(const WebCore::HitTestResult& hitTestResult, const Vector<WebCore::ContextMenuItem>& items)
{
    return createNSArray(items, [&] (auto& item) {
        return createMenuItem(hitTestResult, item);
    });
}

static RetainPtr<NSMenuItem> createMenuItem(const WebCore::HitTestResult& hitTestResult, const WebCore::ContextMenuItem& item)
{
#if HAVE(TRANSLATION_UI_SERVICES)
    if (item.action() == WebCore::ContextMenuItemTagTranslate && !WebView._canHandleContextMenuTranslation)
        return nil;
#endif

    if (item.action() == WebCore::ContextMenuItemTagShareMenu)
        return createShareMenuItem(hitTestResult);

    switch (item.type()) {
    case WebCore::ActionType:
    case WebCore::CheckableActionType: {
        auto menuItem = adoptNS([[NSMenuItem alloc] initWithTitle:item.title() action:@selector(forwardContextMenuAction:) keyEquivalent:@""]);

        if (auto tag = toTag(item.action()))
            [menuItem setTag:*tag];
        [menuItem setEnabled:item.enabled()];
        [menuItem setState:item.checked() ? NSControlStateValueOn : NSControlStateValueOff];
        [menuItem setTarget:[WebMenuTarget sharedMenuTarget]];

        return menuItem;
    }

    case WebCore::SeparatorType:
        return [NSMenuItem separatorItem];

    case WebCore::SubmenuType: {
        auto menu = adoptNS([[NSMenu alloc] init]);
        {
            auto submenuItems = createMenuItems(hitTestResult, item.subMenuItems());
            for (NSMenuItem *menuItem in submenuItems.get())
                [menu addItem:menuItem];
        }

        auto menuItem = adoptNS([[NSMenuItem alloc] initWithTitle:item.title() action:nullptr keyEquivalent:@""]);

        if (auto tag = toTag(item.action()))
            [menuItem setTag:*tag];
        [menuItem setEnabled:item.enabled()];
        [menuItem setSubmenu:menu.get()];

        return menuItem;
    }
    }
}

static RetainPtr<NSArray> customMenuFromDefaultItems(WebView *webView, const WebCore::ContextMenu& defaultMenu)
{
    const auto& hitTestResult = webView.page->contextMenuController().hitTestResult();
    bool isPopover = webView.window._childWindowOrderingPriority == NSWindowChildOrderingPriorityPopover;
    bool isLookupDisabled = [NSUserDefaults.standardUserDefaults boolForKey:@"LULookupDisabled"];
    auto filteredItems = defaultMenu.items();
    
    if (isLookupDisabled || isPopover) {
        filteredItems.removeAllMatching([] (auto& item) {
            return item.action() == WebCore::ContextMenuItemTagLookUpInDictionary;
        });
    }
    auto defaultMenuItems = createMenuItems(hitTestResult, filteredItems);
    
    id delegate = [webView UIDelegate];
    SEL selector = @selector(webView:contextMenuItemsForElement:defaultMenuItems:);
    if (![delegate respondsToSelector:selector])
        return defaultMenuItems;

    auto element = adoptNS([[WebElementDictionary alloc] initWithHitTestResult:hitTestResult]);

    BOOL preVersion3Client = isPreVersion3Client();
    if (preVersion3Client) {
        DOMNode *node = [element objectForKey:WebElementDOMNodeKey];
        if ([node isKindOfClass:[DOMHTMLInputElement class]] && [(DOMHTMLInputElement *)node _isTextField])
            return defaultMenuItems;
        if ([node isKindOfClass:[DOMHTMLTextAreaElement class]])
            return defaultMenuItems;
    }

    for (NSMenuItem *menuItem in defaultMenuItems.get()) {
        if (!menuItem.representedObject)
            menuItem.representedObject = element.get();
    }

    auto savedItems = fixMenusToSendToOldClients(defaultMenuItems.get());

    NSArray *delegateSuppliedItems = CallUIDelegate(webView, selector, element.get(), defaultMenuItems.get());

    return fixMenusReceivedFromOldClients(delegateSuppliedItems, savedItems.get());
}

- (NSMenu *)menuForEvent:(NSEvent *)event
{
    // There's a chance that if we run a nested event loop the event will be released.
    // Retaining and then autoreleasing prevents that from causing a problem later here or
    // inside AppKit code.
    retainPtr(event).autorelease();

    [_private->completionController endRevertingChange:NO moveLeft:NO];

    RefPtr<WebCore::Frame> coreFrame = core([self _frame]);
    if (!coreFrame)
        return nil;

    auto* page = coreFrame->page();
    if (!page)
        return nil;

    // Match behavior of other browsers by sending a mousedown event for right clicks.
    _private->handlingMouseDownEvent = YES;
    page->contextMenuController().clearContextMenu();
    coreFrame->eventHandler().mouseDown(event, [[self _webView] _pressureEvent]);
    BOOL handledEvent = coreFrame->eventHandler().sendContextMenuEvent(WebCore::PlatformEventFactory::createPlatformMouseEvent(event, [[self _webView] _pressureEvent], page->chrome().platformPageClient()));
    _private->handlingMouseDownEvent = NO;

    if (!handledEvent)
        return nil;

    // Re-get page, since it might have gone away during event handling.
    page = coreFrame->page();
    if (!page)
        return nil;

    auto* contextMenu = page->contextMenuController().contextMenu();
    if (!contextMenu)
        return nil;

    auto menuItems = customMenuFromDefaultItems([self _webView], *contextMenu);
    if (![menuItems count])
        return nil;

    auto menu = adoptNS([[NSMenu alloc] init]);

    for (NSMenuItem *item in menuItems.get()) {
        [menu addItem:item];

        if (item.tag == WebCore::ContextMenuItemTagShareMenu) {
            ASSERT([item.representedObject isKindOfClass:[NSSharingServicePicker class]]);
#if ENABLE(SERVICE_CONTROLS)
            _private->currentSharingServicePickerController = adoptNS([[WebSharingServicePickerController alloc] initWithSharingServicePicker:item.representedObject client:static_cast<WebContextMenuClient&>(page->contextMenuController().client())]);
#endif
        }
    }

    [[WebMenuTarget sharedMenuTarget] setMenuController:&page->contextMenuController()];
    
    return menu.autorelease();
}

#endif // PLATFORM(MAC)

- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag
{
    return [self searchFor:string direction:forward caseSensitive:caseFlag wrap:wrapFlag startInSelection:NO];
}

- (void)clearFocus
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;
    auto* document = coreFrame->document();
    if (!document)
        return;
    
    document->setFocusedElement(0);
}

- (BOOL)isOpaque
{
    return [[self _webView] drawsBackground];
}

#if PLATFORM(MAC)

- (void)setLayer:(CALayer *)layer
{
    if (auto* frame = core([self _frame])) {
        if (auto* view = frame->view())
            view->setPaintsEntireContents(layer);
    }

    [super setLayer:layer];
}

#endif

#if !LOG_DISABLED
- (void)setNeedsDisplay:(BOOL)flag
{
    LOG(View, "%@ setNeedsDisplay:%@", self, flag ? @"YES" : @"NO");
    [super setNeedsDisplay:flag];
}
#endif

static BOOL currentScrollIsBlit(NSView *clipView)
{
#if PLATFORM(MAC)
    return [clipView isKindOfClass:[WebClipView class]] && [(WebClipView *)clipView currentScrollIsBlit];
#else
    return NO;
#endif
}

// FIXME: this entire function could be #ifdeffed out on iOS. The below workaround is AppKit-specific.
- (void)setNeedsDisplayInRect:(NSRect)invalidRect
{
    if (_private->inScrollPositionChanged && currentScrollIsBlit([self superview])) {
        // When scrolling, the dirty regions are adjusted for the scroll only
        // after NSViewBoundsDidChangeNotification is sent. Translate the invalid
        // rect to pre-scrolled coordinates in order to get the right dirty region
        // after adjustment. See <rdar://problem/7678927>.
        NSPoint origin = [[self superview] bounds].origin;
        invalidRect.origin.x -= _private->lastScrollPosition.x - origin.x;
        invalidRect.origin.y -= _private->lastScrollPosition.y - origin.y;
    }
    [super setNeedsDisplayInRect:invalidRect];
}

- (void)setNeedsLayout: (BOOL)flag
{
    LOG(View, "%@ setNeedsLayout:%@", self, flag ? @"YES" : @"NO");
    if (!flag)
        return; // There's no way to say you don't need a layout.
    if (auto* frame = core([self _frame])) {
        if (frame->document() && frame->document()->backForwardCacheState() != WebCore::Document::NotInBackForwardCache)
            return;
        if (auto* view = frame->view())
            view->setNeedsLayoutAfterViewConfigurationChange();
    }
}

- (void)setNeedsToApplyStyles: (BOOL)flag
{
    LOG(View, "%@ setNeedsToApplyStyles:%@", self, flag ? @"YES" : @"NO");
    if (!flag)
        return; // There's no way to say you don't need a style recalc.
    if (auto* frame = core([self _frame])) {
        if (frame->document() && frame->document()->backForwardCacheState() != WebCore::Document::NotInBackForwardCache)
            return;
        frame->document()->scheduleFullStyleRebuild();
    }
}

- (void)drawSingleRect:(NSRect)rect
{
#if PLATFORM(MAC)
    [NSGraphicsContext saveGraphicsState];
    NSRectClip(rect);
        
    ASSERT([[self superview] isKindOfClass:[WebClipView class]]);

    [(WebClipView *)[self superview] setAdditionalClip:rect];

    @try {
        if ([self _transparentBackground]) {
            [[NSColor clearColor] set];
            NSRectFill (rect);
        }
#endif

        [[self _frame] _drawRect:rect contentsOnly:YES];

#if PLATFORM(MAC)
        WebView *webView = [self _webView];

        // This hack is needed for <rdar://problem/5023545>. We can hit a race condition where drawRect will be
        // called after the WebView has closed. If the client did not properly close the WebView and set the 
        // UIDelegate to nil, then the UIDelegate will be stale and this code will crash. 
        static BOOL version3OrLaterClient = WebKitLinkedOnOrAfter(WEBKIT_FIRST_VERSION_WITHOUT_QUICKBOOKS_QUIRK);
        if (version3OrLaterClient)
            [[webView _UIDelegateForwarder] webView:webView didDrawRect:[webView convertRect:rect fromView:self]];
        // Clients don't need support for the didDrawRect delegate method above on iOS.
        // Also, a long time ago, when it was supported, it was part of a threading problem.

        if (WebNodeHighlight *currentHighlight = [webView currentNodeHighlight])
            [currentHighlight setNeedsUpdateInTargetViewRect:[self convertRect:rect toView:[currentHighlight targetView]]];

        [(WebClipView *)[self superview] resetAdditionalClip];
        [NSGraphicsContext restoreGraphicsState];
    } @catch (NSException *localException) {
        [(WebClipView *)[self superview] resetAdditionalClip];
        [NSGraphicsContext restoreGraphicsState];

        LOG_ERROR("Exception caught while drawing: %@", localException);
        [localException raise];
    }
#endif
}

- (void)drawRect:(NSRect)rect
{
    LOG(View, "%@ drawing", self);
    
    TraceScope scope(WebHTMLViewPaintStart, WebHTMLViewPaintEnd);

#if PLATFORM(MAC)
    const NSRect *rects;
    NSInteger count;
    [self getRectsBeingDrawn:&rects count:&count];

    BOOL subviewsWereSetAside = _private->subviewsSetAside;
    if (subviewsWereSetAside)
        [self _restoreSubviews];
#endif

#ifdef LOG_TIMES
    double start = CFAbsoluteTimeGetCurrent();
#endif

#if PLATFORM(MAC)
    // If count == 0 here, use the rect passed in for drawing. This is a workaround for: 
    // <rdar://problem/3908282> REGRESSION (Mail): No drag image dragging selected text in Blot and Mail 
    // The reason for the workaround is that this method is called explicitly from the code 
    // to generate a drag image, and at that time, getRectsBeingDrawn:count: will return a zero count. 
    const int cRectThreshold = 10; 
    const float cWastedSpaceThreshold = 0.75f; 
    BOOL useUnionedRect = (count <= 1) || (count > cRectThreshold); 
    if (!useUnionedRect) {
        // Attempt to guess whether or not we should use the unioned rect or the individual rects. 
        // We do this by computing the percentage of "wasted space" in the union.  If that wasted space 
        // is too large, then we will do individual rect painting instead. 
        float unionPixels = (rect.size.width * rect.size.height); 
        float singlePixels = 0; 
        for (int i = 0; i < count; ++i) 
            singlePixels += rects[i].size.width * rects[i].size.height; 
        float wastedSpace = 1 - (singlePixels / unionPixels); 
        if (wastedSpace <= cWastedSpaceThreshold) 
            useUnionedRect = YES; 
    }

    if (useUnionedRect) 
        [self drawSingleRect:rect];
    else {
        for (int i = 0; i < count; ++i)
            [self drawSingleRect:rects[i]];
    }
#else
    [self drawSingleRect:rect];    
#endif

#ifdef LOG_TIMES
    double thisTime = CFAbsoluteTimeGetCurrent() - start;
    LOG(Timing, "%s draw seconds = %f", widget->part()->baseURL().URL().latin1(), thisTime);
#endif

#if PLATFORM(MAC)
    if (subviewsWereSetAside)
        [self _setAsideSubviews];
#endif

    WebView *webView = [self _webView];

#if PLATFORM(MAC)
    // Only do the synchronization dance if we're drawing into the window, otherwise
    // we risk disabling screen updates when no flush is pending.
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    if ([NSGraphicsContext currentContext] == [[self window] graphicsContext] && [webView _needsOneShotDrawingSynchronization]) {
        ALLOW_DEPRECATED_DECLARATIONS_END
        // Disable screen updates to minimize the chances of the race between the CA
        // display link and AppKit drawing causing flashes.
        [[self window] disableScreenUpdatesUntilFlush];
        
        // Make sure any layer changes that happened as a result of layout
        // via -viewWillDraw are committed.
        [CATransaction flush];
        [webView _setNeedsOneShotDrawingSynchronization:NO];
    }
#endif

    if (webView)
        CallUIDelegate(webView, @selector(webView:didDrawFrame:), [self _frame]);
}

#if PLATFORM(MAC)

// Turn off the additional clip while computing our visibleRect.
- (NSRect)visibleRect
{
    if (!([[self superview] isKindOfClass:[WebClipView class]]))
        return [super visibleRect];

    WebClipView *clipView = (WebClipView *)[self superview];

    if (![clipView hasAdditionalClip])
        return [super visibleRect];

    NSRect additionalClip = [clipView additionalClip];
    [clipView resetAdditionalClip];
    NSRect visibleRect = [super visibleRect];
    [clipView setAdditionalClip:additionalClip];
    return visibleRect;
}

- (void)_invalidateGStatesForTree
{
    // AppKit is in the process of traversing the NSView tree, and is going to send -renewGState to
    // descendants, including plug-in views. This can result in calls out to plug-in code and back into
    // WebCore via JavaScript, which could normally mutate the NSView tree while it is being traversed.
    // Defer those mutations while descendants are being traveresed.
    WebCore::WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates;
    [super _invalidateGStatesForTree];
}

- (BOOL)isFlipped 
{
    return YES;
}

- (void)windowDidBecomeKey:(NSNotification *)notification
{
    if (!pthread_main_np()) {
        [self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
        return;
    }

    NSWindow *keyWindow = [notification object];

    if (keyWindow == [self window])
        [self _updateSecureInputState];
}

- (void)windowDidResignKey:(NSNotification *)notification
{
    if (!pthread_main_np()) {
        [self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
        return;
    }

    NSWindow *formerKeyWindow = [notification object];

    if (formerKeyWindow == [self window] || formerKeyWindow == [[self window] attachedSheet]) {
        [self _updateSecureInputState];
        [_private->completionController endRevertingChange:NO moveLeft:NO];
    }
}

- (void)windowWillClose:(NSNotification *)notification
{
    if (!pthread_main_np()) {
        [self performSelectorOnMainThread:_cmd withObject:notification waitUntilDone:NO];
        return;
    }

    [_private->completionController endRevertingChange:NO moveLeft:NO];
    [[self _pluginController] destroyAllPlugins];
}

#endif // PLATFORM(MAC)

- (void)scrollWheel:(WebEvent *)event
{
#if PLATFORM(MAC)
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    // FIXME: Why not do this on iOS too?
    retainPtr(event).autorelease();
#endif

    auto* frame = core([self _frame]);
    if (!frame || !frame->eventHandler().wheelEvent(event)) {
#if PLATFORM(MAC)
        [super scrollWheel:event];
#endif
    }

#if PLATFORM(MAC)
    [[[self _webView] _immediateActionController] webView:[self _webView] didHandleScrollWheel:event];
#endif
}

- (BOOL)_isSelectionEvent:(WebEvent *)event
{
#if PLATFORM(MAC)
    bool allowShadowContent = true;
#else
    bool allowShadowContent = false; // FIXME: Why does this need to be false on iOS?
#endif

    NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
    return [[[self elementAtPoint:point allowShadowContent:allowShadowContent] objectForKey:WebElementIsSelectedKey] boolValue];
}

#if PLATFORM(MAC)

- (BOOL)_isScrollBarEvent:(NSEvent *)event
{
    NSPoint point = [self convertPoint:[event locationInWindow] fromView:nil];
    return [[[self elementAtPoint:point allowShadowContent:YES] objectForKey:WebElementIsInScrollBarKey] boolValue];
}

- (BOOL)acceptsFirstMouse:(NSEvent *)event
{
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();

    NSView *hitView = [self _hitViewForEvent:event];
    WebHTMLView *hitHTMLView = [hitView isKindOfClass:[self class]] ? (WebHTMLView *)hitView : nil;

    if (hitHTMLView) {
        bool result = false;
        if (auto* coreFrame = core([hitHTMLView _frame])) {
            coreFrame->eventHandler().setActivationEventNumber([event eventNumber]);
            [hitHTMLView _setMouseDownEvent:event];
            if ([hitHTMLView _isSelectionEvent:event]) {
#if ENABLE(DRAG_SUPPORT)
                if (auto* page = coreFrame->page())
                    result = coreFrame->eventHandler().eventMayStartDrag(WebCore::PlatformEventFactory::createPlatformMouseEvent(event, [[self _webView] _pressureEvent], page->chrome().platformPageClient()));
#endif
            } else if ([hitHTMLView _isScrollBarEvent:event])
                result = true;
            [hitHTMLView _setMouseDownEvent:nil];
        }
        return result;
    }
    return [hitView acceptsFirstMouse:event];
}

- (BOOL)shouldDelayWindowOrderingForEvent:(NSEvent *)event
{
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();

    NSView *hitView = [self _hitViewForEvent:event];
    WebHTMLView *hitHTMLView = [hitView isKindOfClass:[self class]] ? (WebHTMLView *)hitView : nil;
    if (hitHTMLView) {
        bool result = false;
        if ([hitHTMLView _isSelectionEvent:event]) {
            [hitHTMLView _setMouseDownEvent:event];
#if ENABLE(DRAG_SUPPORT)
            if (auto* coreFrame = core([hitHTMLView _frame])) {
                if (auto* page = coreFrame->page())
                    result = coreFrame->eventHandler().eventMayStartDrag(WebCore::PlatformEventFactory::createPlatformMouseEvent(event, [[self _webView] _pressureEvent], page->chrome().platformPageClient()));
            }
#endif
            [hitHTMLView _setMouseDownEvent:nil];
        }
        return result;
    }
    return [hitView shouldDelayWindowOrderingForEvent:event];
}

#endif // PLATFORM(MAC)

- (void)mouseDown:(WebEvent *)event
{
    [[self _webView] prepareForMouseDown];

#if PLATFORM(MAC)
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();
#endif

    RetainPtr<WebHTMLView> protector = self;

#if PLATFORM(MAC)
    if ([[self inputContext] wantsToHandleMouseEvents] && [[self inputContext] handleMouseEvent:event])
        return;
#endif

    _private->handlingMouseDownEvent = YES;

    // Record the mouse down position so we can determine drag hysteresis.
    [self _setMouseDownEvent:event];

#if PLATFORM(IOS_FAMILY)
    // TEXTINPUT: if there is marked text and the current input
    // manager wants to handle mouse events, we need to make sure to
    // pass it to them. If not, then we need to notify the input
    // manager when the marked text is abandoned (user clicks outside
    // the marked area)
    _private->ignoringMouseDraggedEvents = NO;

    // Let WebCore get a chance to deal with the event. This will call back to us
    // to start the autoscroll timer if appropriate.
    if (auto* coreFrame = core([self _frame]))
        coreFrame->eventHandler().mouseDown(event);
#else
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    NSInputManager *currentInputManager = [NSInputManager currentInputManager];

    if (![currentInputManager wantsToHandleMouseEvents] || ![currentInputManager handleMouseEvent:event]) {
        ALLOW_DEPRECATED_DECLARATIONS_END
        [_private->completionController endRevertingChange:NO moveLeft:NO];

        // If the web page handles the context menu event and menuForEvent: returns nil, we'll get control click events here.
        // We don't want to pass them along to KHTML a second time.
        if (!([event modifierFlags] & NSEventModifierFlagControl)) {
            _private->ignoringMouseDraggedEvents = NO;

            // Let WebCore get a chance to deal with the event. This will call back to us
            // to start the autoscroll timer if appropriate.
            if (auto* coreFrame = core([self _frame]))
                coreFrame->eventHandler().mouseDown(event, [[self _webView] _pressureEvent]);
        }
    }
#endif

    _private->handlingMouseDownEvent = NO;
}

#if ENABLE(TOUCH_EVENTS)

- (void)touch:(WebEvent *)event
{
    RetainPtr<WebHTMLView> protector = self;

    // Let WebCore get a chance to deal with the event. This will call back to us
    // to start the autoscroll timer if appropriate.
    if (auto* coreFrame = core([self _frame]))
        coreFrame->eventHandler().touchEvent(event);
}

#endif

#if ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)

static NSDragOperation kit(OptionSet<WebCore::DragOperation> operationMask)
{
    NSDragOperation result = NSDragOperationNone;
    if (operationMask.contains(WebCore::DragOperation::Copy))
        result |= NSDragOperationCopy;
    if (operationMask.contains(WebCore::DragOperation::Link))
        result |= NSDragOperationLink;
    if (operationMask.contains(WebCore::DragOperation::Generic))
        result |= NSDragOperationGeneric;
    if (operationMask.contains(WebCore::DragOperation::Private))
        result |= NSDragOperationPrivate;
    if (operationMask.contains(WebCore::DragOperation::Move))
        result |= NSDragOperationMove;
    if (operationMask.contains(WebCore::DragOperation::Delete))
        result |= NSDragOperationDelete;
    return result;
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)dragImage:(NSImage *)dragImage
               at:(NSPoint)at
           offset:(NSSize)offset
            event:(NSEvent *)event
       pasteboard:(NSPasteboard *)pasteboard
           source:(id)source
        slideBack:(BOOL)slideBack
IGNORE_WARNINGS_END
{
    ASSERT(self == [self _topHTMLView]);
    [pasteboard setString:@"" forType:[WebHTMLView _dummyPasteboardType]];

    [super dragImage:dragImage at:at offset:offset event:event pasteboard:pasteboard source:source slideBack:slideBack];
}

- (void)mouseDragged:(NSEvent *)event
{
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();

    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    NSInputManager *currentInputManager = [NSInputManager currentInputManager];
    if ([currentInputManager wantsToHandleMouseEvents] && [currentInputManager handleMouseEvent:event])
        return;
    ALLOW_DEPRECATED_DECLARATIONS_END

    [self retain];

    if (!_private->ignoringMouseDraggedEvents) {
        if (auto* frame = core([self _frame])) {
            if (auto* page = frame->page())
                page->mainFrame().eventHandler().mouseDragged(event, [[self _webView] _pressureEvent]);
        }
    }

    [self release];
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    ASSERT(![self _webView] || [self _isTopHTMLView]);
    
    auto* page = core([self _webView]);
    if (!page)
        return NSDragOperationNone;

    return kit(page->dragController().sourceDragOperationMask());
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    ASSERT(![self _webView] || [self _isTopHTMLView]);
    
    NSPoint windowImageLoc = [[self window] convertScreenToBase:aPoint];
    NSPoint windowMouseLoc = windowImageLoc;
    
    if (auto* page = core([self _webView])) {
        windowMouseLoc = NSMakePoint(windowImageLoc.x + page->dragController().dragOffset().x(), windowImageLoc.y + page->dragController().dragOffset().y());
        page->dragController().dragEnded();
    }
    
    [[self _frame] _dragSourceEndedAt:windowMouseLoc operation:operation];
    
    // Prevent queued mouseDragged events from coming after the drag and fake mouseUp event.
    _private->ignoringMouseDraggedEvents = YES;
    
    // Once the dragging machinery kicks in, we no longer get mouse drags or the up event.
    // WebCore expects to get balanced down/up's, so we must fake up a mouseup.
    NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSEventTypeLeftMouseUp
                                            location:windowMouseLoc
                                       modifierFlags:[[NSApp currentEvent] modifierFlags]
                                           timestamp:[NSDate timeIntervalSinceReferenceDate]
                                        windowNumber:[[self window] windowNumber]
                                             context:nullptr
                                         eventNumber:0 clickCount:0 pressure:0];
    [self mouseUp:fakeEvent]; // This will also update the mouseover state.
}

static bool matchesExtensionOrEquivalent(NSString *filename, NSString *extension)
{
    NSString *extensionAsSuffix = [@"." stringByAppendingString:extension];
    return [filename _webkit_hasCaseInsensitiveSuffix:extensionAsSuffix]
    || ([extension _webkit_isCaseInsensitiveEqualToString:@"jpeg"]
        && [filename _webkit_hasCaseInsensitiveSuffix:@".jpg"]);
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSArray *)namesOfPromisedFilesDroppedAtDestination:(NSURL *)dropDestination
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    RetainPtr<NSFileWrapper> wrapper;
    NSURL *draggingElementURL = nil;

    if (auto tiffResource = _private->promisedDragTIFFDataSource) {
        if (auto* buffer = tiffResource->resourceBuffer()) {
            NSURLResponse *response = tiffResource->response().nsURLResponse();
            draggingElementURL = [response URL];
            wrapper = adoptNS([[NSFileWrapper alloc] initRegularFileWithContents:buffer->makeContiguous()->createNSData().get()]);
            NSString* filename = [response suggestedFilename];
            NSString* trueExtension(tiffResource->image()->filenameExtension());
            if (!matchesExtensionOrEquivalent(filename, trueExtension))
                filename = [[filename stringByAppendingString:@"."] stringByAppendingString:trueExtension];
            [wrapper setPreferredFilename:filename];
        }
    }

    if (!wrapper) {
        ASSERT(![self _webView] || [self _isTopHTMLView]);
        auto* page = core([self _webView]);

        //If a load occurs midway through a drag, the view may be detached, which gives
        //us no ability to get to the original Page, so we cannot access any drag state
        //FIXME: is there a way to recover?
        if (!page) 
            return nil; 

        const URL& imageURL = page->dragController().draggingImageURL();
        if (!imageURL.isEmpty())
            draggingElementURL = imageURL;

        wrapper = [[self _dataSource] _fileWrapperForURL:draggingElementURL];
    }
    
    if (wrapper == nil) {
        LOG_ERROR("Failed to create image file.");
        return nil;
    }

    // FIXME: Report an error if we fail to create a file.
    NSString *path = [[dropDestination path] stringByAppendingPathComponent:[wrapper preferredFilename]];
    path = [[NSFileManager defaultManager] _webkit_pathWithUniqueFilenameForPath:path];
    if (![wrapper writeToURL:[NSURL fileURLWithPath:path isDirectory:NO] options:NSFileWrapperWritingWithNameUpdating originalContentsURL:nil error:nullptr])
        LOG_ERROR("Failed to create image file via -[NSFileWrapper writeToURL:options:originalContentsURL:error:]");
    
    if (draggingElementURL)
        [[NSFileManager defaultManager] _webkit_setMetadataURL:[draggingElementURL absoluteString] referrer:nil atPath:path];
    
    return @[[path lastPathComponent]];
}

// MARK: NSDraggingSource

- (NSDragOperation)draggingSession:(NSDraggingSession *)session sourceOperationMaskForDraggingContext:(NSDraggingContext)context
{
    ASSERT(![self _webView] || [self _isTopHTMLView]);

    auto* page = core([self _webView]);
    if (!page)
        return NSDragOperationNone;

    return kit(page->dragController().sourceDragOperationMask());
}

- (void)draggingSession:(NSDraggingSession *)session endedAtPoint:(NSPoint)screenPoint operation:(NSDragOperation)operation
{
    ASSERT(![self _webView] || [self _isTopHTMLView]);

    NSPoint windowLocation = [self.window convertRectFromScreen:{ screenPoint, NSZeroSize }].origin;

    if (auto* page = core([self _webView]))
        page->dragController().dragEnded();

    [[self _frame] _dragSourceEndedAt:windowLocation operation:operation];

    // Prevent queued mouseDragged events from coming after the drag and fake mouseUp event.
    _private->ignoringMouseDraggedEvents = YES;

    // Once the dragging machinery kicks in, we no longer get mouse drags or the up event.
    // WebCore expects to get balanced down/up's, so we must fake up a mouseup.
    NSEvent *fakeEvent = [NSEvent mouseEventWithType:NSEventTypeLeftMouseUp location:windowLocation modifierFlags:[NSApp currentEvent].modifierFlags timestamp:[NSDate timeIntervalSinceReferenceDate] windowNumber:self.window. windowNumber context:nullptr eventNumber:0 clickCount:0 pressure:0];

    // This will also update the mouseover state.
    [self mouseUp:fakeEvent];
}

#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)

- (void)mouseUp:(WebEvent *)event
{
    [[self _webView] prepareForMouseUp];

#if PLATFORM(MAC)
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();
#endif

    [self _setMouseDownEvent:nil];

#if PLATFORM(MAC)
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    NSInputManager *currentInputManager = [NSInputManager currentInputManager];
    if ([currentInputManager wantsToHandleMouseEvents] && [currentInputManager handleMouseEvent:event])
        return;
    ALLOW_DEPRECATED_DECLARATIONS_END
#endif

    [self retain];

    [self _stopAutoscrollTimer];
    if (auto* frame = core([self _frame])) {
        if (auto* page = frame->page()) {
#if PLATFORM(IOS_FAMILY)
            page->mainFrame().eventHandler().mouseUp(event);
#else
            page->mainFrame().eventHandler().mouseUp(event, [[self _webView] _pressureEvent]);
#endif
        }
    }

#if PLATFORM(MAC)
    [self _updateMouseoverWithFakeEvent];
#endif

    [self release];
}

#if PLATFORM(MAC)

- (void)mouseMoved:(NSEvent *)event
{
    [self _updateMouseoverWithEvent:event];
}

#endif

- (void)pressureChangeWithEvent:(NSEvent *)event
{
#if PLATFORM(MAC)
    NSEvent *lastPressureEvent = [[self _webView] _pressureEvent];
    if (event.phase != NSEventPhaseChanged && event.phase != NSEventPhaseBegan && event.phase != NSEventPhaseEnded)
        return;

    RefPtr<WebCore::Frame> coreFrame = core([self _frame]);
    if (!coreFrame)
        return;

    coreFrame->eventHandler().pressureChange(event, lastPressureEvent);
    [[self _webView] _setPressureEvent:event];
#endif
}

#if PLATFORM(MAC)

// returning YES from this method is the way we tell AppKit that it is ok for this view
// to be in the key loop even when "tab to all controls" is not on.
- (BOOL)needsPanelToBecomeKey
{
    return YES;
}

#endif

// Utility function to make sure we don't return anything through the NSTextInput
// API when an editable region is not currently focused.
static BOOL isTextInput(WebCore::Frame* coreFrame)
{
    if (!coreFrame)
        return NO;
    const auto& selection = coreFrame->selection().selection();
    return !selection.isNone() && selection.isContentEditable();
}

#if PLATFORM(MAC)

static BOOL isInPasswordField(WebCore::Frame* coreFrame)
{
    return coreFrame && coreFrame->selection().selection().isInPasswordField();
}

#endif

static RefPtr<WebCore::KeyboardEvent> currentKeyboardEvent(WebCore::Frame* coreFrame)
{
#if PLATFORM(MAC)
    NSEvent *event = [NSApp currentEvent];
    if (!event)
        return nullptr;

    switch ([event type]) {
    case NSEventTypeKeyDown: {
        WebCore::PlatformKeyboardEvent platformEvent = WebCore::PlatformEventFactory::createPlatformKeyboardEvent(event);
        platformEvent.disambiguateKeyDownEvent(WebCore::PlatformEvent::RawKeyDown);
        return WebCore::KeyboardEvent::create(platformEvent, &coreFrame->windowProxy());
    }
    case NSEventTypeKeyUp:
        return WebCore::KeyboardEvent::create(WebCore::PlatformEventFactory::createPlatformKeyboardEvent(event), &coreFrame->windowProxy());
    default:
        return nullptr;
    }
#else
    WebEvent *event = [WAKWindow currentEvent];
    if (!event)
        return nullptr;
    WebEventType type = event.type;
    if (type == WebEventKeyDown || type == WebEventKeyUp) {
        auto* document = coreFrame->document();
        return WebCore::KeyboardEvent::create(WebCore::PlatformEventFactory::createPlatformKeyboardEvent(event), document ? document->windowProxy() : 0);
    }
    return nullptr;
#endif
}

- (BOOL)becomeFirstResponder
{
    NSSelectionDirection direction = NSDirectSelection;
    if (![[self _webView] _isPerformingProgrammaticFocus])
        direction = [[self window] keyViewSelectionDirection];

#if PLATFORM(MAC)
    [self _updateFontPanel];
#endif
    
    auto* frame = core([self _frame]);
    if (!frame)
        return YES;

#if PLATFORM(MAC)
    BOOL exposeInputContext = isTextInput(frame) && !isInPasswordField(frame);
    if (exposeInputContext != _private->exposeInputContext) {
        _private->exposeInputContext = exposeInputContext;
        [NSApp updateWindows];
    }

    _private->_forceUpdateSecureInputState = YES;
    [self _updateSecureInputState];
    _private->_forceUpdateSecureInputState = NO;
#endif

    // FIXME: Kill ring handling is mostly in WebCore, so this call should also be moved there.
    frame->editor().setStartNewKillRingSequence(true);

    auto* page = frame->page();
    if (!page)
        return YES;

    if (![[self _webView] _isPerformingProgrammaticFocus])
        page->focusController().setFocusedFrame(frame);

    page->focusController().setFocused(true);

    if (direction == NSDirectSelection)
        return YES;

    if (auto* document = frame->document())
        document->setFocusedElement(0);
    page->focusController().setInitialFocus(direction == NSSelectingNext ? WebCore::FocusDirection::Forward : WebCore::FocusDirection::Backward,
                                             currentKeyboardEvent(frame).get());
    return YES;
}

- (BOOL)resignFirstResponder
{
    BOOL resign = [super resignFirstResponder];
    if (resign) {
#if PLATFORM(MAC)
        if (_private->isInSecureInputState) {
            DisableSecureEventInput();
            _private->isInSecureInputState = NO;
        }
        [_private->completionController endRevertingChange:NO moveLeft:NO];
#endif
        auto* coreFrame = core([self _frame]);
        if (!coreFrame)
            return resign;

#if PLATFORM(IOS_FAMILY)
        if (auto* document = coreFrame->document()) {
            document->markers().removeMarkers(WebCore::DocumentMarker::DictationPhraseWithAlternatives);
            document->markers().removeMarkers(WebCore::DocumentMarker::DictationResult);
        }
#endif

        auto* page = coreFrame->page();
        if (!page)
            return resign;
        if (![self maintainsInactiveSelection]) { 
            [self deselectAll];
            if (![[self _webView] _isPerformingProgrammaticFocus])
                [self clearFocus];
        }
        
        id nextResponder = [[self window] _newFirstResponderAfterResigning];
        bool nextResponderIsInWebView = [nextResponder isKindOfClass:[NSView class]]
            && [nextResponder isDescendantOf:[[[self _webView] mainFrame] frameView]];
        if (!nextResponderIsInWebView && ![[self _webView] _isPerformingProgrammaticFocus])
            page->focusController().setFocused(false);
    }
    return resign;
}

- (void)setDataSource:(WebDataSource *)dataSource 
{
    ASSERT(dataSource);
    if (_private->dataSource == dataSource)
        return;

    ASSERT(!_private->closed);

    _private->dataSource = dataSource;
    [_private->pluginController setDataSource:dataSource];

#if PLATFORM(MAC)
    if (!_private->installedTrackingArea) {
        NSTrackingAreaOptions options = NSTrackingMouseMoved | NSTrackingMouseEnteredAndExited | NSTrackingInVisibleRect | NSTrackingCursorUpdate;
        if (_NSRecommendedScrollerStyle() == NSScrollerStyleLegacy)
            options |= NSTrackingActiveAlways;
        else
            options |= NSTrackingActiveInKeyWindow;

        [self addTrackingArea:adoptNS([[NSTrackingArea alloc] initWithRect:[self frame] options:options owner:self userInfo:nil]).get()];
        _private->installedTrackingArea = YES;
    }
#endif
}

- (void)dataSourceUpdated:(WebDataSource *)dataSource
{
}

#if PLATFORM(MAC)

// This is an override of an NSControl method that wants to repaint the entire view when the window resigns/becomes key.
// WebHTMLView is an NSControl only because it hosts NSCells that are painted by WebCore's Aqua theme
// renderer (and those cells must be hosted by an enclosing NSControl in order to paint properly).
- (void)updateCell:(NSCell *)cell
{
}

#endif

// Does setNeedsDisplay:NO as a side effect when printing is ending.
// pageWidth != 0 implies we will relayout to a new width
- (void)_setPrinting:(BOOL)printing minimumPageLogicalWidth:(float)minPageLogicalWidth logicalHeight:(float)minPageLogicalHeight originalPageWidth:(float)originalPageWidth originalPageHeight:(float)originalPageHeight maximumShrinkRatio:(float)maximumShrinkRatio adjustViewSize:(BOOL)adjustViewSize paginateScreenContent:(BOOL)paginateScreenContent
{
    if (printing == _private->printing && paginateScreenContent == _private->paginateScreenContent)
        return;

    for (WebFrame *subframe in [[self _frame] childFrames]) {
        WebFrameView *frameView = [subframe frameView];
        if ([[subframe _dataSource] _isDocumentHTML]) {
            [(WebHTMLView *)[frameView documentView] _setPrinting:printing minimumPageLogicalWidth:0 logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustViewSize:adjustViewSize paginateScreenContent:paginateScreenContent];
        }
    }

    _private->pageRects = nil;
    _private->printing = printing;
    _private->paginateScreenContent = paginateScreenContent;
    
    auto* coreFrame = core([self _frame]);
    if (coreFrame) {
        if (auto* coreView = coreFrame->view())
            coreView->setMediaType(_private->printing ? "print"_s : "screen"_s);
        if (auto* document = coreFrame->document()) {
            // In setting printing, we should not validate resources already cached for the document.
            // See https://bugs.webkit.org/show_bug.cgi?id=43704
            WebCore::ResourceCacheValidationSuppressor validationSuppressor(document->cachedResourceLoader());

            document->setPaginatedForScreen(_private->paginateScreenContent);
            document->setPrinting(_private->printing);
            document->styleScope().didChangeStyleSheetEnvironment();
        }
    }

    [self setNeedsLayout:YES];
    [self layoutToMinimumPageWidth:minPageLogicalWidth height:minPageLogicalHeight originalPageWidth:originalPageWidth originalPageHeight:originalPageHeight maximumShrinkRatio:maximumShrinkRatio adjustingViewSize:adjustViewSize];
    if (!printing) {
        // Can't do this when starting printing or nested printing won't work, see 3491427.
        [self setNeedsDisplay:NO];
    }
}

#if PLATFORM(MAC)

- (BOOL)canPrintHeadersAndFooters
{
    return YES;
}

// This is needed for the case where the webview is embedded in the view that's being printed.
// It shouldn't be called when the webview is being printed directly.
- (void)adjustPageHeightNew:(CGFloat *)newBottom top:(CGFloat)oldTop bottom:(CGFloat)oldBottom limit:(CGFloat)bottomLimit
{
    // This helps when we print as part of a larger print process.
    // If the WebHTMLView itself is what we're printing, then we will never have to do this.
    BOOL wasInPrintingMode = _private->printing;
    if (!wasInPrintingMode)
        [self _setPrinting:YES minimumPageLogicalWidth:0 logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];

    *newBottom = [self _adjustedBottomOfPageWithTop:oldTop bottom:oldBottom limit:bottomLimit];

    if (!wasInPrintingMode) {
        NSPrintOperation *currenPrintOperation = [NSPrintOperation currentOperation];
        if (currenPrintOperation)
            // delay _setPrinting:NO until back to main loop as this method may get called repeatedly
            [self performSelector:@selector(_delayedEndPrintMode:) withObject:currenPrintOperation afterDelay:0];
        else
            // not sure if this is actually ever invoked, it probably shouldn't be
            [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
    }
}

- (float)_scaleFactorForPrintOperation:(NSPrintOperation *)printOperation
{
    bool useViewWidth = true;
    auto* coreFrame = core([self _frame]);
    if (coreFrame) {
        auto* document = coreFrame->document();
        if (document && document->renderView())
            useViewWidth = document->renderView()->style().isHorizontalWritingMode();
    }

    float viewLogicalWidth = useViewWidth ? NSWidth([self bounds]) : NSHeight([self bounds]);
    if (viewLogicalWidth < 1) {
        LOG_ERROR("%@ has no logical width when printing", self);
        return 1.0f;
    }

    float userScaleFactor = [printOperation _web_pageSetupScaleFactor];
    float maxShrinkToFitScaleFactor = 1.0f / _WebHTMLViewPrintingMaximumShrinkFactor;
    float shrinkToFitScaleFactor = (useViewWidth ? [printOperation _web_availablePaperWidth] :  [printOperation _web_availablePaperHeight]) / viewLogicalWidth;
    return userScaleFactor * std::max(maxShrinkToFitScaleFactor, shrinkToFitScaleFactor);
}

// FIXME 3491344: This is a secret AppKit-internal method that we need to override in order
// to get our shrink-to-fit to work with a custom pagination scheme. We can do this better
// if AppKit makes it SPI/API.
- (CGFloat)_provideTotalScaleFactorForPrintOperation:(NSPrintOperation *)printOperation 
{
    return [self _scaleFactorForPrintOperation:printOperation];
}

// This is used for Carbon printing. At some point we might want to make this public API.
- (void)setPageWidthForPrinting:(float)pageWidth
{
    [self _setPrinting:NO minimumPageLogicalWidth:0 logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:0 adjustViewSize:NO paginateScreenContent:[self _isInScreenPaginationMode]];
    [self _setPrinting:YES minimumPageLogicalWidth:pageWidth logicalHeight:0 originalPageWidth:0 originalPageHeight:0 maximumShrinkRatio:1 adjustViewSize:YES paginateScreenContent:[self _isInScreenPaginationMode]];
}

- (void)_endPrintModeAndRestoreWindowAutodisplay
{
    [self _endPrintMode];
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    [[self window] setAutodisplay:YES];
    ALLOW_DEPRECATED_DECLARATIONS_END
}

- (void)_delayedEndPrintMode:(NSPrintOperation *)initiatingOperation
{
    ASSERT_ARG(initiatingOperation, initiatingOperation != nil);
    NSPrintOperation *currentOperation = [NSPrintOperation currentOperation];
    if (initiatingOperation == currentOperation) {
        // The print operation is still underway. We don't expect this to ever happen, hence the assert, but we're
        // being extra paranoid here since the printing code is so fragile. Delay the cleanup
        // further.
        ASSERT_NOT_REACHED();
        [self performSelector:@selector(_delayedEndPrintMode:) withObject:initiatingOperation afterDelay:0];
    } else if ([currentOperation view] == self) {
        // A new print job has started, but it is printing the same WebHTMLView again. We don't expect
        // this to ever happen, hence the assert, but we're being extra paranoid here since the printing code is so
        // fragile. Do nothing, because we don't want to break the print job currently in progress, and
        // the print job currently in progress is responsible for its own cleanup.
        ASSERT_NOT_REACHED();
    } else {
        // The print job that kicked off this delayed call has finished, and this view is not being
        // printed again. We expect that no other print job has started. Since this delayed call wasn't
        // cancelled, beginDocument and endDocument must not have been called, and we need to clean up
        // the print mode here.
        ASSERT(currentOperation == nil);
        [self _endPrintModeAndRestoreWindowAutodisplay];
    }
}

// Return the number of pages available for printing
- (BOOL)knowsPageRange:(NSRangePointer)range
{
    // Must do this explicit display here, because otherwise the view might redisplay while the print
    // sheet was up, using printer fonts (and looking different).
    [self displayIfNeeded];
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    [[self window] setAutodisplay:NO];
    ALLOW_DEPRECATED_DECLARATIONS_END

    [[self _webView] _adjustPrintingMarginsForHeaderAndFooter];
    NSPrintOperation *printOperation = [NSPrintOperation currentOperation];
    if (![self _beginPrintModeWithPageWidth:[printOperation _web_availablePaperWidth] height:[printOperation _web_availablePaperHeight] shrinkToFit:YES])
        return NO;

    // Certain types of errors, including invalid page ranges, can cause beginDocument and
    // endDocument to be skipped after we've put ourselves in print mode (see 4145905). In those cases
    // we need to get out of print mode without relying on any more callbacks from the printing mechanism.
    // If we get as far as beginDocument without trouble, then this delayed request will be cancelled.
    // If not cancelled, this delayed call will be invoked in the next pass through the main event loop,
    // which is after beginDocument and endDocument would be called.
    [self performSelector:@selector(_delayedEndPrintMode:) withObject:printOperation afterDelay:0];
    
    // There is a theoretical chance that someone could do some drawing between here and endDocument,
    // if something caused setNeedsDisplay after this point. If so, it's not a big tragedy, because
    // you'd simply see the printer fonts on screen. As of this writing, this does not happen with Safari.

    range->location = 1;
    float totalScaleFactor = [self _scaleFactorForPrintOperation:printOperation];
    float userScaleFactor = [printOperation _web_pageSetupScaleFactor];
    float fullPageWidth = floorf([printOperation _web_availablePaperWidth] / totalScaleFactor);
    float fullPageHeight = floorf([printOperation _web_availablePaperHeight] / totalScaleFactor);
    WebFrame *frame = [self _frame];
    NSArray *newPageRects = [frame _computePageRectsWithPrintScaleFactor:userScaleFactor pageSize:NSMakeSize(fullPageWidth, fullPageHeight)];

    // AppKit gets all messed up if you give it a zero-length page count (see 3576334), so if we
    // hit that case we'll pass along a degenerate 1 pixel square to print. This will print
    // a blank page (with correct-looking header and footer if that option is on), which matches
    // the behavior of IE and Camino at least.
    if ([newPageRects count] == 0)
        newPageRects = @[[NSValue valueWithRect:NSMakeRect(0, 0, 1, 1)]];

    _private->pageRects = newPageRects;

    range->length = [_private->pageRects count];

    return YES;
}

// Return the drawing rectangle for a particular page number
- (NSRect)rectForPage:(NSInteger)page
{
    return [[_private->pageRects objectAtIndex:page - 1] rectValue];
}

- (void)drawPageBorderWithSize:(NSSize)borderSize
{
    ASSERT(NSEqualSizes(borderSize, [[[NSPrintOperation currentOperation] printInfo] paperSize]));    
    [[self _webView] _drawHeaderAndFooter];
}

- (void)beginDocument
{
    @try {
        // From now on we'll get a chance to call _endPrintMode in either beginDocument or
        // endDocument, so we can cancel the "just in case" pending call.
        [NSObject cancelPreviousPerformRequestsWithTarget:self
                                                 selector:@selector(_delayedEndPrintMode:)
                                                   object:[NSPrintOperation currentOperation]];
        [super beginDocument];
    } @catch (NSException *localException) {
        // Exception during [super beginDocument] means that endDocument will not get called,
        // so we need to clean up our "print mode" here.
        [self _endPrintModeAndRestoreWindowAutodisplay];
    }
}

- (void)endDocument
{
    [super endDocument];
    // Note sadly at this point [NSGraphicsContext currentContextDrawingToScreen] is still NO 
    [self _endPrintModeAndRestoreWindowAutodisplay];
}

#endif // PLATFORM(MAC)

- (void)keyDown:(WebEvent *)event
{
#if PLATFORM(MAC)
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();
#endif

    RetainPtr<WebHTMLView> selfProtector = self;
    BOOL eventWasSentToWebCore = (_private->keyDownEvent == event);

    BOOL callSuper = NO;

    _private->keyDownEvent = event;

#if PLATFORM(MAC)
    BOOL completionPopupWasOpen = _private->completionController && [_private->completionController popupWindowIsOpen];
    auto* coreFrame = core([self _frame]);
    if (!eventWasSentToWebCore && coreFrame && coreFrame->eventHandler().keyEvent(event)) {
        // WebCore processed a key event, bail on any preexisting complete: UI
        if (completionPopupWasOpen)
            [_private->completionController endRevertingChange:YES moveLeft:NO];
    } else if (!_private->completionController || ![_private->completionController filterKeyDown:event]) {
        // Not consumed by complete: popup window
        [_private->completionController endRevertingChange:YES moveLeft:NO];
        callSuper = YES;
    }
#else
    auto* coreFrame = core([self _frame]);
    if (!eventWasSentToWebCore && coreFrame)
        coreFrame->eventHandler().keyEvent(event);
#endif

    if (callSuper)
        [super keyDown:event];
    else {
#if PLATFORM(MAC)
        [NSCursor setHiddenUntilMouseMoves:YES];
#endif
    }
}

- (void)keyUp:(WebEvent *)event
{
#if PLATFORM(MAC)
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();
#endif

    BOOL eventWasSentToWebCore = (_private->keyDownEvent == event);

    RetainPtr<WebHTMLView> selfProtector = self;
    auto* coreFrame = core([self _frame]);
    if (coreFrame && !eventWasSentToWebCore)
        coreFrame->eventHandler().keyEvent(event);
    else
        [super keyUp:event];
}

#if PLATFORM(MAC)

- (void)flagsChanged:(NSEvent *)event
{
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();

    RetainPtr<WebHTMLView> selfProtector = self;

    auto* coreFrame = core([self _frame]);
    unsigned short keyCode = [event keyCode];

    // Don't make an event from the num lock and function keys.
    if (coreFrame && keyCode != 0 && keyCode != 10 && keyCode != 63) {
        coreFrame->eventHandler().keyEvent(WebCore::PlatformEventFactory::createPlatformKeyboardEvent(event));
        return;
    }
        
    [super flagsChanged:event];
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (id)accessibilityAttributeValue:(NSString*)attributeName
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    if ([attributeName isEqualToString: NSAccessibilityChildrenAttribute]) {
        id accTree = [[self _frame] accessibilityRoot];
        if (accTree)
            return @[accTree];
        return nil;
    }
    return [super accessibilityAttributeValue:attributeName];
}

#endif

- (id)accessibilityFocusedUIElement
{
    id accTree = [[self _frame] accessibilityRoot];
    if (accTree)
        return [accTree accessibilityFocusedUIElement];
    return self;
}

- (id)accessibilityHitTest:(NSPoint)point
{
    id accTree = [[self _frame] accessibilityRoot];
    if (accTree) {
#if PLATFORM(IOS_FAMILY)
        return [accTree accessibilityHitTest:point];
#else
        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        NSPoint windowCoord = [[self window] convertScreenToBase:point];
        ALLOW_DEPRECATED_DECLARATIONS_END
        return [accTree accessibilityHitTest:[self convertPoint:windowCoord fromView:nil]];
#endif
    }
    return self;
}

- (id)_accessibilityParentForSubview:(NSView *)subview
{
    id accTree = [[self _frame] accessibilityRoot];
    if (!accTree)
        return self;
    id parent = [accTree _accessibilityParentForSubview:subview];
    if (!parent)
        return self;
    return parent;
}

- (void)centerSelectionInVisibleArea:(id)sender
{
    COMMAND_PROLOGUE

    if (auto* coreFrame = core([self _frame]))
        coreFrame->selection().revealSelection(WebCore::SelectionRevealMode::Reveal, WebCore::ScrollAlignment::alignCenterAlways);
}

#if PLATFORM(MAC)

- (NSData *)_selectionStartFontAttributesAsRTF
{
    auto* coreFrame = core([self _frame]);
    auto string = adoptNS([[NSAttributedString alloc] initWithString:@"x"
        attributes:coreFrame ? coreFrame->editor().fontAttributesAtSelectionStart().createDictionary().get() : nil]);
    return [string RTFFromRange:NSMakeRange(0, [string length]) documentAttributes:@{ }];
}

- (NSDictionary *)_fontAttributesFromFontPasteboard
{
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    NSPasteboard *fontPasteboard = [NSPasteboard pasteboardWithName:NSFontPboard];
    ALLOW_DEPRECATED_DECLARATIONS_END
    if (fontPasteboard == nil)
        return nil;
    NSData *data = [fontPasteboard dataForType:WebCore::legacyFontPasteboardType()];
    if (data == nil || [data length] == 0)
        return nil;
    // NSTextView does something more efficient by parsing the attributes only, but that's not available in API.
    auto string = adoptNS([[NSAttributedString alloc] initWithRTF:data documentAttributes:NULL]);
    if (string == nil || [string length] == 0)
        return nil;
    return [string fontAttributesInRange:NSMakeRange(0, 1)];
}

#endif

- (DOMCSSStyleDeclaration *)_emptyStyle
{
    return [[[self _frame] DOMDocument] createCSSStyleDeclaration];
}

#if PLATFORM(MAC)

- (NSString *)_colorAsString:(NSColor *)color
{
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    NSColor *rgbColor = [color colorUsingColorSpaceName:NSDeviceRGBColorSpace];
    ALLOW_DEPRECATED_DECLARATIONS_END
    // FIXME: If color is non-nil and rgbColor is nil, that means we got some kind
    // of fancy color that can't be converted to RGB. Changing that to "transparent"
    // might not be great, but it's probably OK.
    if (rgbColor == nil)
        return @"transparent";
    float r = [rgbColor redComponent];
    float g = [rgbColor greenComponent];
    float b = [rgbColor blueComponent];
    float a = [rgbColor alphaComponent];
    if (a == 0)
        return @"transparent";
    if (r == 0 && g == 0 && b == 0 && a == 1)
        return @"black";
    if (r == 1 && g == 1 && b == 1 && a == 1)
        return @"white";
    // FIXME: Lots more named colors. Maybe we could use the table in WebCore?
    if (a == 1)
        return [NSString stringWithFormat:@"rgb(%.0f,%.0f,%.0f)", r * 255, g * 255, b * 255];
    return [NSString stringWithFormat:@"rgba(%.0f,%.0f,%.0f,%f)", r * 255, g * 255, b * 255, a];
}

- (NSString *)_shadowAsString:(NSShadow *)shadow
{
    if (shadow == nil)
        return @"none";
    NSSize offset = [shadow shadowOffset];
    float blurRadius = [shadow shadowBlurRadius];
    if (offset.width == 0 && offset.height == 0 && blurRadius == 0)
        return @"none";
    NSColor *color = [shadow shadowColor];
    if (color == nil)
        return @"none";
    // FIXME: Handle non-integral values here?
    if (blurRadius == 0)
        return [NSString stringWithFormat:@"%@ %.0fpx %.0fpx", [self _colorAsString:color], offset.width, offset.height];
    return [NSString stringWithFormat:@"%@ %.0fpx %.0fpx %.0fpx", [self _colorAsString:color], offset.width, offset.height, blurRadius];
}

- (DOMCSSStyleDeclaration *)_styleFromFontAttributes:(NSDictionary *)dictionary
{
    DOMCSSStyleDeclaration *style = [self _emptyStyle];

    NSColor *color = [dictionary objectForKey:NSBackgroundColorAttributeName];
    [style setBackgroundColor:[self _colorAsString:color]];

    NSFont *font = [dictionary objectForKey:NSFontAttributeName];
    if (!font) {
        [style setFontFamily:@"Helvetica"];
        [style setFontSize:@"12px"];
        [style setFontWeight:@"normal"];
        [style setFontStyle:@"normal"];
    } else {
        NSFontManager *fm = [NSFontManager sharedFontManager];
        // FIXME: Need more sophisticated escaping code if we want to handle family names
        // with characters like single quote or backslash in their names.
        [style setFontFamily:[NSString stringWithFormat:@"'%@'", [font familyName]]];
        [style setFontSize:[NSString stringWithFormat:@"%0.fpx", [font pointSize]]];
        // FIXME: Map to the entire range of CSS weight values.
        if ([fm weightOfFont:font] >= MIN_BOLD_WEIGHT)
            [style setFontWeight:@"bold"];
        else
            [style setFontWeight:@"normal"];
        if ([fm traitsOfFont:font] & NSItalicFontMask)
            [style setFontStyle:@"italic"];
        else
            [style setFontStyle:@"normal"];
    }

    color = [dictionary objectForKey:NSForegroundColorAttributeName];
    [style setColor:color ? [self _colorAsString:color] : (NSString *)@"black"];

    NSShadow *shadow = [dictionary objectForKey:NSShadowAttributeName];
    [style setTextShadow:[self _shadowAsString:shadow]];

    int strikethroughInt = [[dictionary objectForKey:NSStrikethroughStyleAttributeName] intValue];

    int superscriptInt = [[dictionary objectForKey:NSSuperscriptAttributeName] intValue];
    if (superscriptInt > 0)
        [style setVerticalAlign:@"super"];
    else if (superscriptInt < 0)
        [style setVerticalAlign:@"sub"];
    else
        [style setVerticalAlign:@"baseline"];
    int underlineInt = [[dictionary objectForKey:NSUnderlineStyleAttributeName] intValue];
    // FIXME: Underline wins here if we have both (see bug 3790443).
    if (strikethroughInt == NSUnderlineStyleNone && underlineInt == NSUnderlineStyleNone)
        [style setProperty:@"-webkit-text-decorations-in-effect" value:@"none" priority:@""];
    else if (underlineInt == NSUnderlineStyleNone)
        [style setProperty:@"-webkit-text-decorations-in-effect" value:@"line-through" priority:@""];
    else
        [style setProperty:@"-webkit-text-decorations-in-effect" value:@"underline" priority:@""];

    return style;
}

#endif // PLATFORM(MAC)

- (void)_applyStyleToSelection:(DOMCSSStyleDeclaration *)style withUndoAction:(WebCore::EditAction)undoAction
{
    [self _applyEditingStyleToSelection:WebCore::EditingStyle::create(core(style)) withUndoAction:undoAction];
}

- (void)_applyEditingStyleToSelection:(Ref<WebCore::EditingStyle>&&)editingStyle withUndoAction:(WebCore::EditAction)undoAction
{
    if (auto* coreFrame = core([self _frame]))
        coreFrame->editor().applyStyleToSelection(WTFMove(editingStyle), undoAction, WebCore::Editor::ColorFilterMode::InvertColor);
}

#if PLATFORM(MAC)

- (BOOL)_handleStyleKeyEquivalent:(NSEvent *)event
{
    WebView *webView = [self _webView];
    if (!webView)
        return NO;

    if (![[webView preferences] respectStandardStyleKeyEquivalents])
        return NO;
    
    if (![self _canEdit])
        return NO;
    
    if (([event modifierFlags] & NSEventModifierFlagDeviceIndependentFlagsMask) != NSEventModifierFlagCommand)
        return NO;

    NSString *string = [event characters];
    if ([string caseInsensitiveCompare:@"b"] == NSOrderedSame) {
        [self executeCoreCommandByName:"ToggleBold"];
        return YES;
    }
    if ([string caseInsensitiveCompare:@"i"] == NSOrderedSame) {
        [self executeCoreCommandByName:"ToggleItalic"];
        return YES;
    }
    
    return NO;
}

- (BOOL)performKeyEquivalent:(NSEvent *)event
{
    // There's a chance that responding to this event will run a nested event loop, and
    // fetching a new event might release the old one. Retaining and then autoreleasing
    // the current event prevents that from causing a problem inside WebKit or AppKit code.
    retainPtr(event).autorelease();

    BOOL eventWasSentToWebCore = (_private->keyDownEvent == event);
    BOOL ret = NO;

    _private->keyDownEvent = event;
    
    [self retain];

    // Pass command-key combos through WebCore if there is a key binding available for
    // this event. This lets web pages have a crack at intercepting command-modified keypresses.
    // But don't do it if we have already handled the event.
    // Pressing Esc results in a fake event being sent - don't pass it to WebCore.
    if (!eventWasSentToWebCore && event == [NSApp currentEvent] && self == [[self window] firstResponder])
        if (auto* frame = core([self _frame]))
            ret = frame->eventHandler().keyEvent(event);

    if (ret) {
#if PLATFORM(MAC)
        [NSCursor setHiddenUntilMouseMoves:YES];
#endif
    } else
        ret = [self _handleStyleKeyEquivalent:event] || [super performKeyEquivalent:event];

    [self release];
    
    return ret;
}

- (void)copyFont:(id)sender
{
    COMMAND_PROLOGUE

    // Put RTF with font attributes on the pasteboard.
    // Maybe later we should add a pasteboard type that contains CSS text for "native" copy and paste font.
        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    NSPasteboard *fontPasteboard = [NSPasteboard pasteboardWithName:NSFontPboard];
    ALLOW_DEPRECATED_DECLARATIONS_END
    [fontPasteboard declareTypes:@[WebCore::legacyFontPasteboardType()] owner:nil];
    [fontPasteboard setData:[self _selectionStartFontAttributesAsRTF] forType:WebCore::legacyFontPasteboardType()];
}

- (void)pasteFont:(id)sender
{
    COMMAND_PROLOGUE

    // Read RTF with font attributes from the pasteboard.
    // Maybe later we should add a pasteboard type that contains CSS text for "native" copy and paste font.
    [self _applyStyleToSelection:[self _styleFromFontAttributes:[self _fontAttributesFromFontPasteboard]] withUndoAction:WebCore::EditAction::PasteFont];
}

- (void)pasteAsRichText:(id)sender
{
    COMMAND_PROLOGUE

    // Since rich text always beats plain text when both are on the pasteboard, it's not
    // clear how this is different from plain old paste.
    [self _pasteWithPasteboard:[NSPasteboard generalPasteboard] allowPlainText:NO];
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)changeFont:(id)sender
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    COMMAND_PROLOGUE

    [self _applyEditingStyleToSelection:WebCore::computedFontChanges(NSFontManager.sharedFontManager).createEditingStyle() withUndoAction:WebCore::EditAction::SetFont];
}

- (void)changeAttributes:(id)sender
{
    COMMAND_PROLOGUE

    [self _applyEditingStyleToSelection:WebCore::computedFontAttributeChanges(NSFontManager.sharedFontManager, sender).createEditingStyle() withUndoAction:WebCore::EditAction::ChangeAttributes];
}

- (DOMCSSStyleDeclaration *)_styleFromColorPanelWithSelector:(SEL)selector
{
    DOMCSSStyleDeclaration *style = [self _emptyStyle];

    ASSERT([style respondsToSelector:selector]);
    [style performSelector:selector withObject:[self _colorAsString:[[NSColorPanel sharedColorPanel] color]]];
    
    return style;
}

- (WebCore::EditAction)_undoActionFromColorPanelWithSelector:(SEL)selector
{
    if (selector == @selector(setBackgroundColor:))
        return WebCore::EditAction::SetBackgroundColor;
    return WebCore::EditAction::SetColor;
}

- (void)_changeCSSColorUsingSelector:(SEL)selector inRange:(DOMRange *)range
{
    DOMCSSStyleDeclaration *style = [self _styleFromColorPanelWithSelector:selector];
    WebView *webView = [self _webView];
    if ([[webView _editingDelegateForwarder] webView:webView shouldApplyStyle:style toElementsInDOMRange:range]) {
        if (auto* coreFrame = core([self _frame])) {
            // FIXME: We shouldn't have to make a copy here.
            Ref<WebCore::MutableStyleProperties> properties(core(style)->copyProperties());
            coreFrame->editor().applyStyle(properties.ptr(), [self _undoActionFromColorPanelWithSelector:selector]);
        }
    }

}

- (void)changeDocumentBackgroundColor:(id)sender
{
    COMMAND_PROLOGUE

    // Mimicking NSTextView, this method sets the background color for the
    // entire document. There is no NSTextView API for setting the background
    // color on the selected range only. Note that this method is currently
    // never called from the UI (see comment in changeColor:).
    // FIXME: this actually has no effect when called, probably due to 3654850. _documentRange seems
    // to do the right thing because it works in startSpeaking:, and I know setBackgroundColor: does the
    // right thing because I tested it with [self _selectedRange].
    // FIXME: This won't actually apply the style to the entire range here, because it ends up calling
    // [frame _applyStyle:], which operates on the current selection. To make this work right, we'll
    // need to save off the selection, temporarily set it to the entire range, make the change, then
    // restore the old selection.
    [self _changeCSSColorUsingSelector:@selector(setBackgroundColor:) inRange:[self _documentRange]];
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)changeColor:(id)sender
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    COMMAND_PROLOGUE

    // FIXME: in NSTextView, this method calls changeDocumentBackgroundColor: when a
    // private call has earlier been made by [NSFontFontEffectsBox changeColor:], see 3674493. 
    // AppKit will have to be revised to allow this to work with anything that isn't an 
    // NSTextView. However, this might not be required for Tiger, since the background-color 
    // changing box in the font panel doesn't work in Mail (3674481), though it does in TextEdit.
    [self _applyStyleToSelection:[self _styleFromColorPanelWithSelector:@selector(setColor:)] withUndoAction:WebCore::EditAction::SetColor];
}

#endif // PLATFORM(MAC)

- (void)_changeWordCaseWithSelector:(SEL)selector
{
    if (![self _canEdit])
        return;

    WebFrame *frame = [self _frame];
    [self selectWord:nil];
    NSString *word = [[frame _selectedString] performSelector:selector];
    // FIXME: Does this need a different action context other than "typed"?
    if ([self _shouldReplaceSelectionWithText:word givenAction:WebViewInsertActionTyped])
        [frame _replaceSelectionWithText:word selectReplacement:NO smartReplace:NO];
}

- (void)uppercaseWord:(id)sender
{
    COMMAND_PROLOGUE

    [self _changeWordCaseWithSelector:@selector(uppercaseString)];
}

- (void)lowercaseWord:(id)sender
{
    COMMAND_PROLOGUE

    [self _changeWordCaseWithSelector:@selector(lowercaseString)];
}

- (void)capitalizeWord:(id)sender
{
    COMMAND_PROLOGUE

    [self _changeWordCaseWithSelector:@selector(capitalizedString)];
}

#if PLATFORM(MAC)

- (void)complete:(id)sender
{
    COMMAND_PROLOGUE

    if (![self _canEdit])
        return;
    if (!_private->completionController)
        _private->completionController = adoptNS([[WebTextCompletionController alloc] initWithWebView:[self _webView] HTMLView:self]);
    [_private->completionController doCompletion];
}

- (void)checkSpelling:(id)sender
{
    COMMAND_PROLOGUE

    if (auto* coreFrame = core([self _frame]))
        coreFrame->editor().advanceToNextMisspelling();
}

- (void)showGuessPanel:(id)sender
{
    COMMAND_PROLOGUE

    NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker];
    if (!checker) {
        LOG_ERROR("No NSSpellChecker");
        return;
    }
    
    NSPanel *spellingPanel = [checker spellingPanel];
    if ([spellingPanel isVisible]) {
        [spellingPanel orderOut:sender];
        return;
    }
    
    if (auto* coreFrame = core([self _frame]))
        coreFrame->editor().advanceToNextMisspelling(true);
    [spellingPanel orderFront:sender];
}

- (void)changeSpelling:(id)sender
{
    COMMAND_PROLOGUE

    [self _changeSpellingToWord:[[sender selectedCell] stringValue]];
}

- (void)performFindPanelAction:(id)sender
{
    COMMAND_PROLOGUE

    // Implementing this will probably require copying all of NSFindPanel.h and .m.
    // We need *almost* the same thing as AppKit, but not quite.
    LOG_ERROR("unimplemented");
}

- (void)startSpeaking:(id)sender
{
    COMMAND_PROLOGUE

    WebFrame *frame = [self _frame];
    DOMRange *range = [self _selectedRange];
    if (!range || [range collapsed])
        range = [self _documentRange];
    [NSApp speakString:[frame _stringForRange:range]];
}

- (void)stopSpeaking:(id)sender
{
    COMMAND_PROLOGUE

    [NSApp stopSpeaking:sender];
}

- (void)toggleBaseWritingDirection:(id)sender
{
    COMMAND_PROLOGUE

    if (![self _canEdit])
        return;
    
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;

    auto direction = WebCore::WritingDirection::RightToLeft;
    switch (coreFrame->editor().baseWritingDirectionForSelectionStart()) {
    case WebCore::WritingDirection::LeftToRight:
        break;
    case WebCore::WritingDirection::RightToLeft:
        direction = WebCore::WritingDirection::LeftToRight;
        break;
    // The writingDirectionForSelectionStart method will never return "natural". It
    // will always return a concrete direction. So, keep the compiler happy, and assert not reached.
    case WebCore::WritingDirection::Natural:
        ASSERT_NOT_REACHED();
        break;
    }

    if (auto* coreFrame = core([self _frame]))
        coreFrame->editor().setBaseWritingDirection(direction);
}

- (void)changeBaseWritingDirection:(id)sender
{
    COMMAND_PROLOGUE

    if (![self _canEdit])
        return;
    
    NSWritingDirection writingDirection = static_cast<NSWritingDirection>([sender tag]);
    
    // We disable the menu item that performs this action because we can't implement
    // NSWritingDirectionNatural's behavior using CSS.
    ASSERT(writingDirection != NSWritingDirectionNatural);

    if (auto* coreFrame = core([self _frame]))
        coreFrame->editor().setBaseWritingDirection(writingDirection == NSWritingDirectionLeftToRight ? WebCore::WritingDirection::LeftToRight : WebCore::WritingDirection::RightToLeft);
}

static BOOL writingDirectionKeyBindingsEnabled()
{
    return YES;
}

- (void)_changeBaseWritingDirectionTo:(NSWritingDirection)direction
{
    if (![self _canEdit])
        return;

    static BOOL bindingsEnabled = writingDirectionKeyBindingsEnabled();

    if (!bindingsEnabled) {
        NSBeep();
        return;
    }

    if (auto* coreFrame = core([self _frame]))
        coreFrame->editor().setBaseWritingDirection(direction == NSWritingDirectionLeftToRight ? WebCore::WritingDirection::LeftToRight : WebCore::WritingDirection::RightToLeft);
}

- (void)makeBaseWritingDirectionLeftToRight:(id)sender
{
    COMMAND_PROLOGUE

    [self _changeBaseWritingDirectionTo:NSWritingDirectionLeftToRight];
}

- (void)makeBaseWritingDirectionRightToLeft:(id)sender
{
    COMMAND_PROLOGUE

    [self _changeBaseWritingDirectionTo:NSWritingDirectionRightToLeft];
}

#endif // PLATFORM(MAC)

- (void)makeBaseWritingDirectionNatural:(id)sender
{
    LOG_ERROR("Sent from %@.", sender);
}

#if 0

// CSS does not have a way to specify an outline font, which may make this difficult to implement.
// Maybe a special case of text-shadow?
- (void)outline:(id)sender;

// This is part of table support, which may be in NSTextView for Tiger.
// It's probably simple to do the equivalent thing for WebKit.
- (void)insertTable:(id)sender;

// This could be important.
- (void)toggleTraditionalCharacterShape:(id)sender;

// I'm not sure what the equivalents of these in the web world are.
- (void)insertLineSeparator:(id)sender;
- (void)insertPageBreak:(id)sender;

// These methods are not implemented in NSTextView yet at the time of this writing.
- (void)changeCaseOfLetter:(id)sender;
- (void)transposeWords:(id)sender;

#endif

// Override this so that AppKit will send us arrow keys as key down events so we can
// support them via the key bindings mechanism.
- (BOOL)_wantsKeyDownForEvent:(NSEvent *)event
{
    bool haveWebCoreFrame = core([self _frame]);

    // If we have a frame, our keyDown method will handle key bindings after sending
    // the event through the DOM, so ask AppKit not to do its early special key binding
    // mapping. If we don't have a frame, just let things work the normal way without
    // a keyDown.
    return haveWebCoreFrame;
}

#if PLATFORM(MAC)

- (BOOL)_automaticFocusRingDisabled
{
    // The default state for _automaticFocusRingDisabled is NO, which prevents focus rings
    // from being painted for search fields. Calling NSSetFocusRingStyle has the side effect
    // of changing this to YES, so just return YES all the time. <rdar://problem/13780122>,
    return YES;
}

- (void)_updateControlTints
{
    auto* frame = core([self _frame]);
    if (!frame)
        return;
    auto* view = frame->view();
    if (!view)
        return;
    view->updateControlTints();
}

// Despite its name, this is called at different times than windowDidBecomeKey is.
// It takes into account all the other factors that determine when NSCell draws
// with different tints, so it's the right call to use for control tints. We'd prefer
// to do this with API. <rdar://problem/5136760>
- (void)_windowChangedKeyState
{
    if (pthread_main_np())
        [self _updateControlTints];
    else
        [self performSelectorOnMainThread:@selector(_updateControlTints) withObject:nil waitUntilDone:NO];

    [super _windowChangedKeyState];
}

- (void)otherMouseDown:(NSEvent *)event
{
    if (event.buttonNumber != 2 || [NSMenu menuTypeForEvent:event] == NSMenuTypeContextMenu) {
        [super otherMouseDown:event];
        return;
    }

    [self mouseDown:event];
}

- (void)otherMouseDragged:(NSEvent *)event
{
    if ([event buttonNumber] == 2)
        [self mouseDragged:event];
    else
        [super otherMouseDragged:event];
}

- (void)otherMouseUp:(NSEvent *)event
{
    if ([event buttonNumber] == 2)
        [self mouseUp:event];
    else
        [super otherMouseUp:event];
}

#endif

#if PLATFORM(IOS_FAMILY)
- (void)markedTextUpdate:(NSNotification *)notification
{
    NSString *text = [notification object];
    NSRange range = NSMakeRange(0, [text length]);
    [self setMarkedText:text selectedRange:range];
}
#endif

@end

@implementation WebHTMLView (WebInternal)

- (void)_selectionChanged
{
#if PLATFORM(MAC)
    [self _updateSelectionForInputManager];
    [self _updateFontPanel];
    if (auto* coreFrame = core([self _frame])) {
        if (!coreFrame->editor().isHandlingAcceptedCandidate())
            _private->softSpaceRange = NSMakeRange(NSNotFound, 0);
    }
#endif
}

#if PLATFORM(MAC)

- (void)_updateFontPanel
{
    // FIXME: NSTextView bails out if becoming or resigning first responder, for which it has ivar flags. Not
    // sure if we need to do something similar.

    if (![self _canEdit])
        return;

    NSWindow *window = [self window];
    // FIXME: is this first-responder check correct? What happens if a subframe is editable and is first responder?
    if (![window isKeyWindow] || [window firstResponder] != self)
        return;

    bool multipleFonts = false;
    NSFont *font = nil;
    RetainPtr<NSDictionary> attributes;
    if (auto* coreFrame = core([self _frame])) {
        if (auto coreFont = coreFrame->editor().fontForSelection(multipleFonts))
            font = (NSFont *)coreFont->platformData().registeredFont();
        attributes = coreFrame->editor().fontAttributesAtSelectionStart().createDictionary();
    }

    // FIXME: for now, return a bogus font that distinguishes the empty selection from the non-empty
    // selection. We should be able to remove this once the rest of this code works properly.
    if (font == nil)
        font = [self _hasSelection] ? [NSFont menuFontOfSize:23] : [NSFont toolTipsFontOfSize:17];
    ASSERT(font != nil);

    NSFontManager *fontManager = [NSFontManager sharedFontManager];
    [fontManager setSelectedFont:font isMultiple:multipleFonts];
    [fontManager setSelectedAttributes:(attributes ? attributes.get() : @{ }) isMultiple:multipleFonts];
}

- (void)_setSoftSpaceRange:(NSRange)range
{
    _private->softSpaceRange = range;
}

#endif // PLATFORM(MAC)

- (BOOL)_canSmartCopyOrDelete
{
    if (![[self _webView] smartInsertDeleteEnabled])
        return NO;
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->selection().granularity() == WebCore::TextGranularity::WordGranularity;
}

#if PLATFORM(MAC)

- (NSEvent *)_mouseDownEvent
{
    return _private->mouseDownEvent.get();
}

#endif

- (WebFrame *)_frame
{
    return [_private->dataSource webFrame];
}

- (void)closeIfNotCurrentView
{
    if ([[[self _frame] frameView] documentView] != self)
        [self close];
}

#if PLATFORM(MAC)

- (DOMDocumentFragment*)_documentFragmentFromPasteboard:(NSPasteboard *)pasteboard
{
    return [self _documentFragmentFromPasteboard:pasteboard inContext:nil allowPlainText:NO];
}


- (BOOL)isGrammarCheckingEnabled
{
    // FIXME 4799134: WebView is the bottleneck for this grammar-checking logic, but we must implement the method here because
    // the AppKit code checks the first responder.
    return [[self _webView] isGrammarCheckingEnabled];
}

- (void)setGrammarCheckingEnabled:(BOOL)flag
{
    // FIXME 4799134: WebView is the bottleneck for this grammar-checking logic, but we must implement the method here because
    // the AppKit code checks the first responder.
    [[self _webView] setGrammarCheckingEnabled:flag];
}

- (void)toggleGrammarChecking:(id)sender
{
    // FIXME 4799134: WebView is the bottleneck for this grammar-checking logic, but we must implement the method here because
    // the AppKit code checks the first responder.
    [[self _webView] toggleGrammarChecking:sender];
}

- (void)orderFrontSubstitutionsPanel:(id)sender
{
    COMMAND_PROLOGUE

    NSSpellChecker *checker = [NSSpellChecker sharedSpellChecker];
    if (!checker) {
        LOG_ERROR("No NSSpellChecker");
        return;
    }
    
    NSPanel *substitutionsPanel = [checker substitutionsPanel];
    if ([substitutionsPanel isVisible]) {
        [substitutionsPanel orderOut:sender];
        return;
    }
    [substitutionsPanel orderFront:sender];
}

// FIXME 4799134: WebView is the bottleneck for this logic, but we must implement these methods here because
// the AppKit code checks the first responder.

- (BOOL)smartInsertDeleteEnabled
{
    return [[self _webView] smartInsertDeleteEnabled];
}

- (void)setSmartInsertDeleteEnabled:(BOOL)flag
{
    [[self _webView] setSmartInsertDeleteEnabled:flag];
}

- (void)toggleSmartInsertDelete:(id)sender
{
    [[self _webView] toggleSmartInsertDelete:sender];
}

- (BOOL)isAutomaticQuoteSubstitutionEnabled
{
    return [[self _webView] isAutomaticQuoteSubstitutionEnabled];
}

- (void)setAutomaticQuoteSubstitutionEnabled:(BOOL)flag
{
    [[self _webView] setAutomaticQuoteSubstitutionEnabled:flag];
}

- (void)toggleAutomaticQuoteSubstitution:(id)sender
{
    [[self _webView] toggleAutomaticQuoteSubstitution:sender];
}

- (BOOL)isAutomaticLinkDetectionEnabled
{
    return [[self _webView] isAutomaticLinkDetectionEnabled];
}

- (void)setAutomaticLinkDetectionEnabled:(BOOL)flag
{
    [[self _webView] setAutomaticLinkDetectionEnabled:flag];
}

- (void)toggleAutomaticLinkDetection:(id)sender
{
    [[self _webView] toggleAutomaticLinkDetection:sender];
}

- (BOOL)isAutomaticDashSubstitutionEnabled
{
    return [[self _webView] isAutomaticDashSubstitutionEnabled];
}

- (void)setAutomaticDashSubstitutionEnabled:(BOOL)flag
{
    [[self _webView] setAutomaticDashSubstitutionEnabled:flag];
}

- (void)toggleAutomaticDashSubstitution:(id)sender
{
    [[self _webView] toggleAutomaticDashSubstitution:sender];
}

- (BOOL)isAutomaticTextReplacementEnabled
{
    return [[self _webView] isAutomaticTextReplacementEnabled];
}

- (void)setAutomaticTextReplacementEnabled:(BOOL)flag
{
    [[self _webView] setAutomaticTextReplacementEnabled:flag];
}

- (void)toggleAutomaticTextReplacement:(id)sender
{
    [[self _webView] toggleAutomaticTextReplacement:sender];
}

- (BOOL)isAutomaticSpellingCorrectionEnabled
{
    return [[self _webView] isAutomaticSpellingCorrectionEnabled];
}

- (void)setAutomaticSpellingCorrectionEnabled:(BOOL)flag
{
    [[self _webView] setAutomaticSpellingCorrectionEnabled:flag];
}

- (void)toggleAutomaticSpellingCorrection:(id)sender
{
    [[self _webView] toggleAutomaticSpellingCorrection:sender];
}

- (void)_lookUpInDictionaryFromMenu:(id)sender
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;

    auto selectionRange = coreFrame->selection().selection().firstRange();
    if (!selectionRange)
        return;

    [[self _webView] _showDictionaryLookupPopup:[WebImmediateActionController _dictionaryPopupInfoForRange:*selectionRange inFrame:coreFrame withLookupOptions:nil indicatorOptions:{ WebCore::TextIndicatorOption::IncludeSnapshotWithSelectionHighlight } transition:WebCore::TextIndicatorPresentationTransition::BounceAndCrossfade]];
}

- (void)quickLookWithEvent:(NSEvent *)event
{
    [[self _webView] _clearTextIndicatorWithAnimation:WebCore::TextIndicatorDismissalAnimation::FadeOut];
    [super quickLookWithEvent:event];
}

#endif // PLATFORM(MAC)

#undef COMMAND_PROLOGUE

- (void)_executeSavedKeypressCommands
{
    auto* parameters = _private->interpretKeyEventsParameters;
    if (!parameters || parameters->event->keypressCommands().isEmpty())
        return;

    // We could be called again if the execution of one command triggers a call to selectedRange.
    // In this case, the state is up to date, and we don't need to execute any more saved commands to return a result
    if (parameters->executingSavedKeypressCommands)
        return;
    
    // Avoid an infinite loop that would occur if executing a command appended it to event->keypressCommands() again.
    bool wasSavingCommands = parameters->shouldSaveCommands;
    parameters->shouldSaveCommands = false;
    parameters->executingSavedKeypressCommands = true;
    
    const Vector<WebCore::KeypressCommand>& commands = parameters->event->keypressCommands();

    for (size_t i = 0; i < commands.size(); ++i) {
        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        if (commands[i].commandName == "insertText:"_s)
            [self insertText:commands[i].text];
        else if (commands[i].commandName == "noop:"_s)
            ; // Do nothing. This case can be removed once <rdar://problem/9025012> is fixed.
        else
            [self doCommandBySelector:NSSelectorFromString(commands[i].commandName)];
        ALLOW_DEPRECATED_DECLARATIONS_END
    }
    parameters->event->keypressCommands().clear();
    parameters->shouldSaveCommands = wasSavingCommands;
    parameters->executingSavedKeypressCommands = false;
}

#if PLATFORM(MAC)

- (BOOL)_interpretKeyEvent:(NakedPtr<WebCore::KeyboardEvent>)event savingCommands:(BOOL)savingCommands
{
    ASSERT(core([self _frame]) == downcast<WebCore::Node>(event->target())->document().frame());
    ASSERT(!savingCommands || event->keypressCommands().isEmpty()); // Save commands once for each event.

    WebHTMLViewInterpretKeyEventsParameters parameters;
    parameters.eventInterpretationHadSideEffects = false;
    parameters.shouldSaveCommands = savingCommands;
    parameters.executingSavedKeypressCommands = false;
    // If we're intercepting the initial IM call we assume that the IM has consumed the event, 
    // and only change this assumption if one of the NSTextInput/Responder callbacks is used.
    // We assume the IM will *not* consume hotkey sequences
    parameters.consumedByIM = savingCommands && !event->metaKey();

    auto* platformEvent = event->underlyingPlatformEvent();
    if (!platformEvent)
        return NO;

    NSEvent *macEvent = platformEvent->macEvent();
    if ([macEvent type] == NSEventTypeKeyDown && [_private->completionController filterKeyDown:macEvent])
        return YES;
    
    if ([macEvent type] == NSEventTypeFlagsChanged)
        return NO;
    
    parameters.event = event;
    _private->interpretKeyEventsParameters = &parameters;
    const Vector<WebCore::KeypressCommand>& commands = event->keypressCommands();

    if (savingCommands) {
        // AppKit will respond with a series of NSTextInput protocol method calls. There are three groups that we heuristically differentiate:
        // 1. Key Bindings. Only doCommandBySelector: and insertText: calls will be made, which we save in the event for execution
        // after DOM dispatch. This is safe, because neither returns a result, so there is no branching on AppKit side.
        // 2. Plain text input. Here as well, we need to dispatch DOM events prior to inserting text, so we save the insertText: command.
        // 3. Input method processing. An IM can make any NSTextInput calls, and can base its decisions on results it gets, so we must
        // execute the calls immediately. DOM events like keydown are tweaked to have keyCode of 229, and canceling them has no effect.
        // Unfortunately, there is no real difference between plain text input and IM processing - for example, AppKit queries hasMarkedText
        // when typing with U.S. keyboard, and inserts marked text for dead keys.
        [self interpretKeyEvents:@[macEvent]];
    } else {
        // Are there commands that could just cause text insertion if executed via Editor?
        // WebKit doesn't have enough information about mode to decide how they should be treated, so we leave it upon WebCore
        // to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
        // (e.g. Tab that inserts a Tab character, or Enter).
        bool haveTextInsertionCommands = false;
        for (size_t i = 0; i < commands.size(); ++i) {
            if ([self coreCommandBySelector:NSSelectorFromString(commands[i].commandName)].isTextInsertion())
                haveTextInsertionCommands = true;
        }
        // If there are no text insertion commands, default keydown handler is the right time to execute the commands.
        // Keypress (Char event) handler is the latest opportunity to execute.
        if (!haveTextInsertionCommands || platformEvent->type() == WebCore::PlatformEvent::Char)
            [self _executeSavedKeypressCommands];
    }
    _private->interpretKeyEventsParameters = nullptr;

    // An input method may make several actions per keypress. For example, pressing Return with Korean IM both confirms it and sends a newline.
    // IM-like actions are handled immediately (so parameters.eventInterpretationHadSideEffects is true), but there are saved commands that
    // should be handled like normal text input after DOM event dispatch.
    if (!event->keypressCommands().isEmpty())
        return NO;

    // An input method may consume an event and not tell us (e.g. when displaying a candidate window),
    // in which case we should not bubble the event up the DOM.
    if (parameters.consumedByIM)
        return YES;

    // If we have already executed all commands, don't do it again.
    return parameters.eventInterpretationHadSideEffects;
}

#endif // PLATFORM(MAC)

#if PLATFORM(IOS_FAMILY)
    
- (BOOL)_handleEditingKeyEvent:(WebCore::KeyboardEvent *)wcEvent
{
    // Use the isEditable state to determine whether or not to process tab key events.
    // The idea here is that isEditable will be NO when this WebView is being used
    // in a browser, and we desire the behavior where tab moves to the next element
    // in tab order. If isEditable is YES, it is likely that the WebView is being
    // embedded as the whole view, as in Mail, and tabs should input tabs as expected
    // in a text editor.
    
    if (auto* platformEvent = wcEvent->underlyingPlatformEvent()) {
        WebEvent *event = platformEvent->event();
        if (event.keyboardFlags & WebEventKeyboardInputModifierFlagsChanged)
            return NO;

        WebView *webView = [self _webView];
        if (!webView.isEditable && event.isTabKey)
            return NO;

        bool isCharEvent = platformEvent->type() == WebCore::PlatformKeyboardEvent::Char;

        if (!isCharEvent && [webView._UIKitDelegateForwarder handleKeyTextCommandForCurrentEvent])
            return YES;
        if (isCharEvent && [webView._UIKitDelegateForwarder handleKeyAppCommandForCurrentEvent])
            return YES;

        NSString *s = [event characters];
        if (!s.length)
            return NO;
        switch ([s characterAtIndex:0]) {
        case NSBackspaceCharacter:
        case NSDeleteCharacter:
            [[webView _UIKitDelegateForwarder] deleteFromInputWithFlags:event.keyboardFlags];
            return YES;
        case NSEnterCharacter:
        case NSCarriageReturnCharacter:
            if (isCharEvent) {
                // Map \r from HW keyboard to \n to match the behavior of the soft keyboard.
                [[webView _UIKitDelegateForwarder] addInputString:@"\n" withFlags:0];
                return YES;
            }
            break;
        default:
            if (isCharEvent) {
                [[webView _UIKitDelegateForwarder] addInputString:event.characters withFlags:event.keyboardFlags];
                return YES;
            }
        }
    }
    return NO;
}
#endif // PLATFORM(IOS_FAMILY)

#if PLATFORM(MAC)

- (void)setPromisedDragTIFFDataSource:(NakedPtr<WebCore::CachedImage>)source
{
    if (source)
        source->addClient(promisedDataClient());
    
    if (_private->promisedDragTIFFDataSource)
        _private->promisedDragTIFFDataSource->removeClient(promisedDataClient());
    _private->promisedDragTIFFDataSource = source;
}

#endif

- (void)_layoutIfNeeded
{
#if PLATFORM(MAC)
    ASSERT(!_private->subviewsSetAside);
#endif

    if ([self _needsLayout])
        [self layout];
}

- (void)_web_updateLayoutAndStyleIfNeededRecursive
{
    WebFrame *webFrame = [self _frame];
    auto* coreFrame = core(webFrame);
    if (coreFrame && coreFrame->view())
        coreFrame->view()->updateLayoutAndStyleIfNeededRecursive();
}

- (void) _destroyAllWebPlugins
{
    [[self _pluginController] destroyAllPlugins];
}

- (BOOL)_needsLayout
{
    return [[self _frame] _needsLayout];
}

#if PLATFORM(MAC)

- (void)attachRootLayer:(CALayer *)layer
{
    if (!_private->layerHostingView) {
        auto hostingView = adoptNS([[WebLayerHostingFlippedView alloc] initWithFrame:[self bounds]]);
        [hostingView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
        [self addSubview:hostingView.get()];
        // hostingView is owned by being a subview of self
        _private->layerHostingView = hostingView.get();
    }

    // Make a container layer, which will get sized/positioned by AppKit and CA.
    CALayer* viewLayer = [WebRootLayer layer];

    if ([self layer]) {
        // If we are in a layer-backed view, we need to manually initialize the geometry for our layer.
        [viewLayer setBounds:NSRectToCGRect([_private->layerHostingView bounds])];
        [viewLayer setAnchorPoint:CGPointMake(0, [self isFlipped] ? 1 : 0)];
        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        CGPoint layerPosition = NSPointToCGPoint([self convertPointToBase:[_private->layerHostingView frame].origin]);
        ALLOW_DEPRECATED_DECLARATIONS_END
        [viewLayer setPosition:layerPosition];
    }
    
    [_private->layerHostingView setLayer:viewLayer];
    [_private->layerHostingView setWantsLayer:YES];
    
    // Parent our root layer in the container layer
    [viewLayer addSublayer:layer];
    
    if ([[self _webView] _postsAcceleratedCompositingNotifications])
        [[NSNotificationCenter defaultCenter] postNotificationName:_WebViewDidStartAcceleratedCompositingNotification object:[self _webView] userInfo:nil];

    if (!_CFExecutableLinkedOnOrAfter(CFSystemVersionMountainLion))
        [viewLayer setGeometryFlipped:YES];
}

- (void)detachRootLayer
{
    if (_private->layerHostingView) {
        [_private->layerHostingView setLayer:nil];
        [_private->layerHostingView setWantsLayer:NO];
        [_private->layerHostingView removeFromSuperview];
        _private->layerHostingView = nil;
    }
}

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    if (_private) {
        ASSERT(!_private->drawingIntoLayer);
        _private->drawingIntoLayer = YES;
        _private->drawingIntoAcceleratedLayer = [layer drawsAsynchronously];
    }

    [super drawLayer:layer inContext:ctx];

    if (_private) {
        _private->drawingIntoLayer = NO;
        _private->drawingIntoAcceleratedLayer = NO;
    }
}

- (BOOL)_web_isDrawingIntoLayer
{
    return _private->drawingIntoLayer;
}

- (BOOL)_web_isDrawingIntoAcceleratedLayer
{
    return _private->drawingIntoAcceleratedLayer;
}

- (void)_changeSpellingToWord:(NSString *)newWord
{
    if (![self _canEdit])
        return;

    if (![NSSpellChecker sharedSpellChecker]) {
        LOG_ERROR("No NSSpellChecker");
        return;
    }

    // Don't correct to empty string.  (AppKit checked this, we might as well too.)    
    if ([newWord isEqualToString:@""])
        return;

    if ([self _shouldReplaceSelectionWithText:newWord givenAction:WebViewInsertActionPasted])
        [[self _frame] _replaceSelectionWithText:newWord selectReplacement:YES smartReplace:NO];
}

- (void)_startAutoscrollTimer:(NSEvent *)triggerEvent
{
    if (_private->autoscrollTimer)
        return;
    _private->autoscrollTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(_autoscroll) userInfo:nil repeats:YES];
    _private->autoscrollTriggerEvent = triggerEvent;
}

#endif

- (void)_stopAutoscrollTimer
{
#if PLATFORM(MAC)
    [_private->autoscrollTimer invalidate];
    _private->autoscrollTimer = nil;
    _private->autoscrollTriggerEvent = nil;
#endif
}

- (WebPluginController *)_pluginController
{
    return _private->pluginController.get();
}

@end

@implementation WebHTMLView (WebNSTextInputSupport)

#if PLATFORM(MAC)

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSArray *)validAttributesForMarkedText
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    static NSArray *validAttributes = [[NSArray alloc] initWithObjects:
        NSUnderlineStyleAttributeName,
        NSUnderlineColorAttributeName,
        NSMarkedClauseSegmentAttributeName,
        NSTextInputReplacementRangeAttributeName,
        NSTextAlternativesAttributeName,
        NSTextInsertionUndoableAttributeName,
        nil];
    LOG(TextInput, "validAttributesForMarkedText -> (...)");
    return validAttributes;
}

- (NSTextInputContext *)inputContext
{
    return _private->exposeInputContext ? [super inputContext] : nil;
}

- (NSAttributedString *)textStorage
{
    if (!_private->exposeInputContext) {
        LOG(TextInput, "textStorage -> nil");
        return nil;
    }
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    NSAttributedString *result = [self attributedSubstringFromRange:NSMakeRange(0, UINT_MAX)];
    ALLOW_DEPRECATED_DECLARATIONS_END

    LOG(TextInput, "textStorage -> \"%@\"", result ? [result string] : @"");
    
    // We have to return an empty string rather than null to prevent TSM from calling -string
    return result ? result : adoptNS([[NSAttributedString alloc] init]).autorelease();
}

#endif // PLATFORM(MAC)

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self _executeSavedKeypressCommands];

    NSWindow *window = [self window];
    WebFrame *frame = [self _frame];

    if (window) {
        NSRect screenRect = { thePoint, NSZeroSize };
        thePoint = [window convertRectFromScreen:screenRect].origin;
    }
    thePoint = [self convertPoint:thePoint fromView:nil];

    DOMRange *range = [frame _characterRangeAtPoint:thePoint];
    if (!range) {
        LOG(TextInput, "characterIndexForPoint:(%f, %f) -> NSNotFound", thePoint.x, thePoint.y);
        return NSNotFound;
    }
    
    unsigned result = [frame _convertDOMRangeToNSRange:range].location;
    LOG(TextInput, "characterIndexForPoint:(%f, %f) -> %u", thePoint.x, thePoint.y, result);
    return result;
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSRect)firstRectForCharacterRange:(NSRange)theRange
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self _executeSavedKeypressCommands];

    WebFrame *frame = [self _frame];
    
    // Just to match NSTextView's behavior. Regression tests cannot detect this;
    // to reproduce, use a test application from http://bugs.webkit.org/show_bug.cgi?id=4682
    // (type something; try ranges (1, -1) and (2, -1).
    if ((theRange.location + theRange.length < theRange.location) && (theRange.location + theRange.length != 0))
        theRange.length = 0;
    
    DOMRange *range = [frame _convertNSRangeToDOMRange:theRange];
    if (!range) {
        LOG(TextInput, "firstRectForCharacterRange:(%u, %u) -> (0, 0, 0, 0)", theRange.location, theRange.length);
        return NSZeroRect;
    }
    
    ASSERT([range startContainer]);
    ASSERT([range endContainer]);
    
    NSRect resultRect = [frame _firstRectForDOMRange:range];
    resultRect = [self convertRect:resultRect toView:nil];

    NSWindow *window = [self window];
    if (window)
        resultRect.origin = [window convertRectToScreen:resultRect].origin;
    
    LOG(TextInput, "firstRectForCharacterRange:(%u, %u) -> (%f, %f, %f, %f)", theRange.location, theRange.length, resultRect.origin.x, resultRect.origin.y, resultRect.size.width, resultRect.size.height);
    return resultRect;
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSRange)selectedRange
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self _executeSavedKeypressCommands];

    if (!isTextInput(core([self _frame]))) {
        LOG(TextInput, "selectedRange -> (NSNotFound, 0)");
        return NSMakeRange(NSNotFound, 0);
    }
    NSRange result = [[self _frame] _selectedNSRange];

    LOG(TextInput, "selectedRange -> (%u, %u)", result.location, result.length);
    return result;
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSRange)markedRange
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self _executeSavedKeypressCommands];

    WebFrame *webFrame = [self _frame];
    auto* coreFrame = core(webFrame);
    if (!coreFrame)
        return NSMakeRange(0, 0); // FIXME: Why not NSNotFound, 0?

    auto range = coreFrame->editor().compositionRange();
    if (!range)
        return NSMakeRange(NSNotFound, 0);

    NSRange result = [webFrame _convertToNSRange:*range];
    LOG(TextInput, "markedRange -> (%u, %u)", result.location, result.length);
    return result;
}

#if PLATFORM(MAC)

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSAttributedString *)attributedSubstringFromRange:(NSRange)nsRange
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self _executeSavedKeypressCommands];

    WebFrame *frame = [self _frame];
    auto* coreFrame = core(frame);
    if (!isTextInput(coreFrame) || isInPasswordField(coreFrame)) {
        LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> nil", nsRange.location, nsRange.length);
        return nil;
    }
    auto range = [frame _convertToDOMRange:nsRange];
    if (!range) {
        LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> nil", nsRange.location, nsRange.length);
        return nil;
    }

    auto result = editingAttributedString(*range).string;
    
    // WebCore::editingAttributedStringFromRange() insists on inserting a trailing
    // whitespace at the end of the string which breaks the ATOK input method.  <rdar://problem/5400551>
    // To work around this we truncate the resultant string to the correct length.
    if ([result length] > nsRange.length) {
        ASSERT([result length] == nsRange.length + 1);
        ASSERT([[result string] characterAtIndex:nsRange.length] == '\n' || [[result string] characterAtIndex:nsRange.length] == ' ');
        result = [result attributedSubstringFromRange:NSMakeRange(0, nsRange.length)];
    }
    LOG(TextInput, "attributedSubstringFromRange:(%u, %u) -> \"%@\"", nsRange.location, nsRange.length, [result string]);
    return result.autorelease();
}

#endif

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (NSInteger)conversationIdentifier
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    return (NSInteger)self;
}

- (BOOL)hasMarkedText
{
    auto* coreFrame = core([self _frame]);
    BOOL result = coreFrame && coreFrame->editor().hasComposition();

    if (result) {
        // A saved command can confirm a composition, but it cannot start a new one.
        [self _executeSavedKeypressCommands];
        result = coreFrame->editor().hasComposition();
    }

    LOG(TextInput, "hasMarkedText -> %u", result);
    return result;
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)unmarkText
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self _executeSavedKeypressCommands];

    LOG(TextInput, "unmarkText");

    // Use pointer to get parameters passed to us by the caller of interpretKeyEvents.
    auto* parameters = _private->interpretKeyEventsParameters;

    if (parameters) {
        parameters->eventInterpretationHadSideEffects = true;
        parameters->consumedByIM = false;
    }
    
    if (auto* coreFrame = core([self _frame]))
        coreFrame->editor().confirmComposition();
}

#if PLATFORM(MAC)

static void extractUnderlines(NSAttributedString *string, Vector<WebCore::CompositionUnderline>& result)
{
    int length = [[string string] length];

    int i = 0;
    while (i < length) {
        NSRange range;
        NSDictionary *attrs = [string attributesAtIndex:i longestEffectiveRange:&range inRange:NSMakeRange(i, length - i)];

        if (NSNumber *style = [attrs objectForKey:NSUnderlineStyleAttributeName]) {
            WebCore::Color color = WebCore::Color::black;
            auto compositionUnderlineColor = WebCore::CompositionUnderlineColor::TextColor;
            if (NSColor *colorAttr = [attrs objectForKey:NSUnderlineColorAttributeName]) {
                color = WebCore::colorFromCocoaColor(colorAttr);
                compositionUnderlineColor = WebCore::CompositionUnderlineColor::GivenColor;
            }
            result.append(WebCore::CompositionUnderline(range.location, NSMaxRange(range), compositionUnderlineColor, color, [style intValue] > 1));
        }

        i = range.location + range.length;
    }
}

#endif

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)setMarkedText:(id)string selectedRange:(NSRange)newSelRange
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    [self _executeSavedKeypressCommands];

#if PLATFORM(MAC)
    BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]];
    ASSERT(isAttributedString || [string isKindOfClass:[NSString class]]);

    LOG(TextInput, "setMarkedText:\"%@\" selectedRange:(%u, %u)", isAttributedString ? [string string] : string, newSelRange.location, newSelRange.length);
#endif

    // Use pointer to get parameters passed to us by the caller of interpretKeyEvents.
    auto* parameters = _private->interpretKeyEventsParameters;

    if (parameters) {
        parameters->eventInterpretationHadSideEffects = true;
        parameters->consumedByIM = false;
    }
    
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;

    if (![self _isEditable])
        return;

    Vector<WebCore::CompositionUnderline> underlines;
    NSString *text;
    NSRange replacementRange = { NSNotFound, 0 };

#if PLATFORM(MAC)
    if (isAttributedString) {
        // FIXME: We ignore most attributes from the string, so an input method cannot specify e.g. a font or a glyph variation.
        text = [string string];
        NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:0 inRange:NSMakeRange(0, [text length])];
        LOG(TextInput, "    ReplacementRange: %@", rangeString);
        // The AppKit adds a 'secret' property to the string that contains the replacement range.
        // The replacement range is the range of the text that should be replaced with the new string.
        if (rangeString)
            replacementRange = NSRangeFromString(rangeString);

        extractUnderlines(string, underlines);
    } else {
        text = string;
        underlines.append(WebCore::CompositionUnderline(0, [text length], WebCore::CompositionUnderlineColor::TextColor, WebCore::Color::black, false));
    }
#else
    text = string;
#endif

    if (replacementRange.location != NSNotFound)
        [[self _frame] _selectNSRange:replacementRange];

    coreFrame->editor().setComposition(text, underlines, { }, newSelRange.location, NSMaxRange(newSelRange));
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)doCommandBySelector:(SEL)selector
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
    LOG(TextInput, "doCommandBySelector:\"%s\"", sel_getName(selector));

    // Use pointer to get parameters passed to us by the caller of interpretKeyEvents.
    // The same call to interpretKeyEvents can do more than one command.
    auto* parameters = _private->interpretKeyEventsParameters;
    if (parameters)
        parameters->consumedByIM = false;

    auto* event = parameters ? parameters->event : 0;
    bool shouldSaveCommand = parameters && parameters->shouldSaveCommands;

    // As in insertText:, we assume that the call comes from an input method if there is marked text.
    RefPtr<WebCore::Frame> coreFrame = core([self _frame]);
    bool isFromInputMethod = coreFrame && coreFrame->editor().hasComposition();

    if (event && shouldSaveCommand && !isFromInputMethod)
        event->keypressCommands().append(WebCore::KeypressCommand(NSStringFromSelector(selector)));
    else {
        // Make sure that only direct calls to doCommandBySelector: see the parameters by setting to 0.
        _private->interpretKeyEventsParameters = 0;

        bool eventWasHandled;

        WebView *webView = [self _webView];
        if ([[webView _editingDelegateForwarder] webView:webView doCommandBySelector:selector])
            eventWasHandled = true;
        else {
            WebCore::Editor::Command command = [self coreCommandBySelector:selector];
            if (command.isSupported())
                eventWasHandled = command.execute(event);
            else {
#if PLATFORM(MAC)
                // If WebKit does not support this command, we need to pass the selector to super.
                _private->selectorForDoCommandBySelector = selector;

                // The sink does two things: 1) Tells us if the responder went unhandled, and
                // 2) prevents any NSBeep; we don't ever want to beep here.
                auto sink = adoptNS([[WebResponderChainSink alloc] initWithResponderChain:self]);
                [super doCommandBySelector:selector];
                eventWasHandled = ![sink receivedUnhandledCommand];
                [sink detach];

                _private->selectorForDoCommandBySelector = 0;
#else
                eventWasHandled = false;
#endif
            }
        }

        if (parameters)
            parameters->eventInterpretationHadSideEffects |= eventWasHandled;

        _private->interpretKeyEventsParameters = parameters;
    }
}

ALLOW_DEPRECATED_IMPLEMENTATIONS_BEGIN
- (void)insertText:(id)string
ALLOW_DEPRECATED_IMPLEMENTATIONS_END
{
#if PLATFORM(MAC)
    BOOL isAttributedString = [string isKindOfClass:[NSAttributedString class]];
    ASSERT(isAttributedString || [string isKindOfClass:[NSString class]]);

    LOG(TextInput, "insertText:\"%@\"", isAttributedString ? [string string] : string);
#endif

    auto* parameters = _private->interpretKeyEventsParameters;
    if (parameters)
        parameters->consumedByIM = false;

    RefPtr<WebCore::Frame> coreFrame = core([self _frame]);
    NSString *text;
    NSRange replacementRange = { NSNotFound, 0 };
    bool isFromInputMethod = coreFrame && coreFrame->editor().hasComposition();
#if USE(INSERTION_UNDO_GROUPING)
    bool registerUndoGroup = false;
#endif

    Vector<WebCore::DictationAlternative> dictationAlternativeLocations;
#if PLATFORM(MAC)
    if (isAttributedString) {
        Vector<WebCore::TextAlternativeWithRange> textAlternatives;
        collectDictationTextAlternatives(string, textAlternatives);
        if (!textAlternatives.isEmpty())
            [[self _webView] _getWebCoreDictationAlternatives:dictationAlternativeLocations fromTextAlternatives:textAlternatives];
        registerUndoGroup = WebCore::shouldRegisterInsertionUndoGroup(string);
        // FIXME: We ignore most attributes from the string, so for example inserting from Character Palette loses font and glyph variation data.
        // It does not look like any input methods ever use insertText: with attributes other than NSTextInputReplacementRangeAttributeName.
        text = [string string];
        NSString *rangeString = [string attribute:NSTextInputReplacementRangeAttributeName atIndex:0 longestEffectiveRange:0 inRange:NSMakeRange(0, [text length])];
        LOG(TextInput, "    ReplacementRange: %@", rangeString);
        if (rangeString) {
            replacementRange = NSRangeFromString(rangeString);
            isFromInputMethod = true;
        }
    } else
#endif
        text = string;

    auto* event = parameters ? parameters->event : 0;

    // insertText can be called for several reasons:
    // - If it's from normal key event processing (including key bindings), we may need to save the action to perform it later.
    // - If it's from an input method, then we should insert the text now. We assume it's from the input method if we have marked text.
    // FIXME: In theory, this could be wrong for some input methods, so we should try to find another way to determine if the call is from the input method.
    // - If it's sent outside of keyboard event processing (e.g. from Character Viewer, or when confirming an inline input area with a mouse),
    // then we also execute it immediately, as there will be no other chance.
    bool shouldSaveCommand = parameters && parameters->shouldSaveCommands;
    if (event && shouldSaveCommand && !isFromInputMethod) {
        auto isFunctionKeyCommandWithMatchingMenuItem = ([&] {
#if PLATFORM(MAC)
            auto menu = NSApp.mainMenu;
            auto* platformKeyEvent = event->underlyingPlatformEvent();
            if (!platformKeyEvent)
                return NO;

            NSEvent *nsEvent = platformKeyEvent->macEvent();
            if (!(nsEvent.modifierFlags & NSEventModifierFlagFunction))
                return NO;

            if (![menu respondsToSelector:@selector(_containsItemMatchingEvent:includingDisabledItems:)])
                return NO;

            return [menu _containsItemMatchingEvent:nsEvent includingDisabledItems:YES];
#else
            return NO;
#endif
        })();

        if (!isFunctionKeyCommandWithMatchingMenuItem)
            event->keypressCommands().append(WebCore::KeypressCommand("insertText:"_s, text));
        return;
    }

    if (!coreFrame || !coreFrame->editor().canEdit())
        return;

    BOOL needToRemoveSoftSpace = NO;
#if PLATFORM(MAC)
    if (_private->softSpaceRange.location != NSNotFound && (replacementRange.location == NSMaxRange(_private->softSpaceRange) || replacementRange.location == NSNotFound) && !replacementRange.length && [[NSSpellChecker sharedSpellChecker] deletesAutospaceBeforeString:text language:nil]) {
        replacementRange = _private->softSpaceRange;
        needToRemoveSoftSpace = YES;
    }
    _private->softSpaceRange = NSMakeRange(NSNotFound, 0);
#endif

    bool replacesText = false;
    if (replacementRange.location != NSNotFound) {
        WebRangeIsRelativeTo rangeIsRelativeTo = needToRemoveSoftSpace ? WebRangeIsRelativeTo::Paragraph : WebRangeIsRelativeTo::EditableRoot;
        if (auto domRange = [[self _frame] _convertToDOMRange:replacementRange rangeIsRelativeTo:rangeIsRelativeTo]) {
            WebCore::IgnoreSelectionChangeForScope selectionChange { *coreFrame };
            coreFrame->selection().setSelection(WebCore::VisibleSelection(*domRange));
            replacesText = replacementRange.length;
        }
    }

    bool eventHandled = false;
    String eventText = makeStringByReplacingAll(text, NSBackTabCharacter, NSTabCharacter); // same thing is done in KeyEventMac.mm in WebCore
    if (!coreFrame->editor().hasComposition()) {
        // An insertText: might be handled by other responders in the chain if we don't handle it.
        // One example is space bar that results in scrolling down the page.

        if (!dictationAlternativeLocations.isEmpty())
            eventHandled = coreFrame->editor().insertDictatedText(eventText, dictationAlternativeLocations, event);
        else
            eventHandled = coreFrame->editor().insertText(eventText, event, replacesText ? WebCore::TextEventInputAutocompletion : WebCore::TextEventInputKeyboard);
        
#if USE(INSERTION_UNDO_GROUPING)
        if (registerUndoGroup)
            WebCore::registerInsertionUndoGroupingWithUndoManager([[self _webView] undoManager]);
#endif
    } else {
        eventHandled = true;
        coreFrame->editor().confirmComposition(eventText);
    }
    
    if (parameters)
        parameters->eventInterpretationHadSideEffects |= eventHandled;
}

#if PLATFORM(MAC)

- (void)_updateSecureInputState
{
    if (![[self window] isKeyWindow] || ([[self window] firstResponder] != self && !_private->_forceUpdateSecureInputState)) {
        if (_private->isInSecureInputState) {
            DisableSecureEventInput();
            _private->isInSecureInputState = NO;
        }
        return;
    }

    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;

    if (isInPasswordField(coreFrame)) {
        if (!_private->isInSecureInputState)
            EnableSecureEventInput();
        _private->isInSecureInputState = YES;
        // WebKit substitutes nil for input context when in password field, which corresponds to null TSMDocument. So, there is
        // no need to call TSMGetActiveDocument(), which may return an incorrect result when selection hasn't been yet updated
        // after focusing a node.
        static CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
        TSMSetDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag, sizeof(CFArrayRef), &inputSources);
    } else {
        if (_private->isInSecureInputState)
            DisableSecureEventInput();
        _private->isInSecureInputState = NO;
        TSMRemoveDocumentProperty(0, kTSMDocumentEnabledInputSourcesPropertyTag);
    }
}

- (void)_updateSelectionForInputManager
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;

    BOOL exposeInputContext = isTextInput(coreFrame) && !isInPasswordField(coreFrame);
    if (exposeInputContext != _private->exposeInputContext) {
        _private->exposeInputContext = exposeInputContext;
        // Let AppKit cache a potentially changed input context.
        // WebCore routinely sets the selection to None when editing, and IMs become unhappy when an input context suddenly turns nil, see bug 26009.
        if (!coreFrame->selection().isNone())
            [NSApp updateWindows];
    }

    [self _updateSecureInputState];

    if (!coreFrame->editor().hasComposition() || coreFrame->editor().ignoreSelectionChanges())
        return;

    unsigned start;
    unsigned end;
    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    if (coreFrame->editor().getCompositionSelection(start, end))
        [[NSInputManager currentInputManager] markedTextSelectionChanged:NSMakeRange(start, end - start) client:self];
    else {
        coreFrame->editor().cancelComposition();
        [[NSInputManager currentInputManager] markedTextAbandoned:self];
    }
    ALLOW_DEPRECATED_DECLARATIONS_END
}

#endif

#if HAVE(TOUCH_BAR)

- (NSCandidateListTouchBarItem *)candidateListTouchBarItem
{
    return [[self _webView] candidateList];
}

#endif

@end

@implementation WebHTMLView (WebDocumentPrivateProtocols)

- (NSRect)selectionRect
{
    if (![self _hasSelection])
        return NSZeroRect;
    return core([self _frame])->selection().selectionBounds();
}

- (NSArray *)selectionTextRects
{
    if (![self _hasSelection])
        return nil;

    Vector<WebCore::FloatRect> rects;
    if (auto* coreFrame = core([self _frame]))
        coreFrame->selection().getClippedVisibleTextRectangles(rects);
    return createNSArray(rects).autorelease();
}

- (NSView *)selectionView
{
    return self;
}

#if PLATFORM(IOS_FAMILY)

static CGImageRef imageFromRect(WebCore::Frame* frame, CGRect rect)
{
    auto* page = frame->page();
    if (!page)
        return nil;
    WAKView* documentView = frame->view()->documentView();
    if (!documentView)
        return nil;
    if (![documentView isKindOfClass:[WebHTMLView class]])
        return nil;
    
    WebHTMLView *view = (WebHTMLView *)documentView;
    
    OptionSet<WebCore::PaintBehavior> oldPaintBehavior = frame->view()->paintBehavior();
    frame->view()->setPaintBehavior(oldPaintBehavior | WebCore::PaintBehavior::FlattenCompositingLayers | WebCore::PaintBehavior::Snapshotting);

    BEGIN_BLOCK_OBJC_EXCEPTIONS
    
    CGRect bounds = [view bounds];
    
    float scale = page->pageScaleFactor() * page->deviceScaleFactor();
    
    // 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];
    if (rect.size.width == 0 || rect.size.height == 0)
        return nil;
    
    size_t width = static_cast<size_t>(rect.size.width * scale);
    size_t height = static_cast<size_t>(rect.size.height * scale);
    size_t bitsPerComponent = 8;
    size_t bitsPerPixel = 4 * bitsPerComponent;
    size_t bytesPerRow = ((bitsPerPixel + 7) / 8) * width;
    RetainPtr<CGContextRef> context = adoptCF(CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, WebCore::sRGBColorSpaceRef(), kCGImageAlphaPremultipliedLast));
    if (!context)
        return nil;
    
    CGContextRef oldContext = WKGetCurrentGraphicsContext();
    CGContextRef contextRef = context.get();
    WKSetCurrentGraphicsContext(contextRef);
    
    CGContextClearRect(contextRef, CGRectMake(0, 0, width, height));
    CGContextSaveGState(contextRef);
    CGContextScaleCTM(contextRef, scale, scale);
    CGContextSetBaseCTM(contextRef, CGAffineTransformMakeScale(scale, scale));
    CGContextTranslateCTM(contextRef, bounds.origin.x - rect.origin.x,  bounds.origin.y - rect.origin.y);
    
    [view drawSingleRect:rect];
    
    CGContextRestoreGState(contextRef);
    
    RetainPtr<CGImageRef> resultImage = adoptCF(CGBitmapContextCreateImage(contextRef));
    
    WKSetCurrentGraphicsContext(oldContext);
    frame->view()->setPaintBehavior(oldPaintBehavior);
    
    return resultImage.autorelease();
    
    END_BLOCK_OBJC_EXCEPTIONS

    frame->view()->setPaintBehavior(oldPaintBehavior);
    return nil;
}

static CGImageRef selectionImage(WebCore::Frame* frame, bool forceBlackText)
{
    ASSERT(!WebThreadIsEnabled() || WebThreadIsLocked());
    frame->view()->setPaintBehavior(WebCore::PaintBehavior::SelectionOnly | (forceBlackText ? OptionSet<WebCore::PaintBehavior>(WebCore::PaintBehavior::ForceBlackText) : OptionSet<WebCore::PaintBehavior>()));
    frame->document()->updateLayout();
    CGImageRef result = imageFromRect(frame, frame->selection().selectionBounds());
    frame->view()->setPaintBehavior(WebCore::PaintBehavior::Normal);
    return result;
}

#endif // PLATFORM(IOS_FAMILY)

#if PLATFORM(MAC)
- (NSImage *)selectionImageForcingBlackText:(BOOL)forceBlackText
#else
- (CGImageRef)selectionImageForcingBlackText:(BOOL)forceBlackText
#endif
{
    if (![self _hasSelection])
        return nil;

    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return nil;

    Ref<WebCore::Frame> protectedCoreFrame(*coreFrame);

#if PLATFORM(IOS_FAMILY)
    return selectionImage(coreFrame, forceBlackText);
#else
    WebCore::TextIndicatorData textIndicator;
    return createDragImageForSelection(*coreFrame, textIndicator, forceBlackText).autorelease();
#endif
}

- (NSRect)selectionImageRect
{
    if (![self _hasSelection])
        return NSZeroRect;
    return core([self _frame])->selection().selectionBounds();
}

#if PLATFORM(MAC)

- (NSArray *)pasteboardTypesForSelection
{
    if ([self _canSmartCopyOrDelete]) {
        auto types = adoptNS([[[self class] _selectionPasteboardTypes] mutableCopy]);
        [types addObject:WebSmartPastePboardType];
        return types.autorelease();
    }
    return [[self class] _selectionPasteboardTypes];
}

- (void)writeSelectionWithPasteboardTypes:(NSArray *)types toPasteboard:(NSPasteboard *)pasteboard
{
    [self _writeSelectionWithPasteboardTypes:types toPasteboard:pasteboard cachedAttributedString:nil];
}

#endif

- (void)selectAll
{
    auto* coreFrame = core([self _frame]);
    if (coreFrame)
        coreFrame->selection().selectAll();
}

- (void)deselectAll
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;
    coreFrame->selection().clear();
}

- (NSString *)string
{
    return [[self _frame] _stringForRange:[self _documentRange]];
}

#if PLATFORM(MAC)

- (NSAttributedString *)_legacyAttributedStringFrom:(DOMNode *)startContainer offset:(int)startOffset to:(DOMNode *)endContainer offset:(int)endOffset
{
    if (!startContainer || !endContainer)
        return adoptNS([[NSAttributedString alloc] init]).autorelease();
    return attributedString(WebCore::SimpleRange { { *core(startContainer), static_cast<unsigned>(startOffset) },
        { *core(endContainer), static_cast<unsigned>(endOffset) } }).string.autorelease();
}

- (NSAttributedString *)attributedString
{
    auto document = core([[self _frame] DOMDocument]);
    if (!document)
        return adoptNS([[NSAttributedString alloc] init]).autorelease();
    auto range = makeRangeSelectingNodeContents(*document);
    if (auto result = attributedString(range).string)
        return result.autorelease();
    return editingAttributedString(range).string.autorelease();
}

- (NSAttributedString *)selectedAttributedString
{
    auto frame = core([self _frame]);
    if (!frame)
        return adoptNS([[NSAttributedString alloc] init]).autorelease();
    auto range = frame->selection().selection().firstRange();
    if (!range)
        return adoptNS([[NSAttributedString alloc] init]).autorelease();
    if (auto result = attributedString(*range).string)
        return result.autorelease();
    return editingAttributedString(*range).string.autorelease();
}

#endif

- (NSString *)selectedString
{
    return [[self _frame] _selectedString];
}

- (BOOL)supportsTextEncoding
{
    return YES;
}

- (BOOL)searchFor:(NSString *)string direction:(BOOL)forward caseSensitive:(BOOL)caseFlag wrap:(BOOL)wrapFlag startInSelection:(BOOL)startInSelection
{
    return [self _findString:string options:(forward ? 0 : WebFindOptionsBackwards) | (caseFlag ? 0 : WebFindOptionsCaseInsensitive) | (wrapFlag ? WebFindOptionsWrapAround : 0) | (startInSelection ? WebFindOptionsStartInSelection : 0)];
}

@end

@implementation WebHTMLView (WebDocumentInternalProtocols)

- (NSDictionary *)elementAtPoint:(NSPoint)point
{
    return [self elementAtPoint:point allowShadowContent:NO];
}

- (NSDictionary *)elementAtPoint:(NSPoint)point allowShadowContent:(BOOL)allowShadowContent
{
    using namespace WebCore;

    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return nil;
    OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::AllowChildFrameContent };
    if (!allowShadowContent)
        hitType.add(HitTestRequest::Type::DisallowUserAgentShadowContent);
    return adoptNS([[WebElementDictionary alloc] initWithHitTestResult:coreFrame->eventHandler().hitTestResultAtPoint(IntPoint { point }, hitType)]).autorelease();
}

- (NSUInteger)countMatchesForText:(NSString *)string inDOMRange:(DOMRange *)range options:(WebFindOptions)options limit:(NSUInteger)limit markMatches:(BOOL)markMatches
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return 0;

    return coreFrame->editor().countMatchesForText(string, makeSimpleRange(core(range)), coreOptions(options), limit, markMatches, 0);
}

- (void)setMarkedTextMatchesAreHighlighted:(BOOL)newValue
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;
    coreFrame->editor().setMarkedTextMatchesAreHighlighted(newValue);
}

- (BOOL)markedTextMatchesAreHighlighted
{
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->editor().markedTextMatchesAreHighlighted();
}

- (void)unmarkAllTextMatches
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return;
    auto* document = coreFrame->document();
    if (!document)
        return;
    document->markers().removeMarkers(WebCore::DocumentMarker::TextMatch);
}

- (NSArray *)rectsForTextMatches
{
    auto* coreFrame = core([self _frame]);
    if (!coreFrame)
        return @[];
    auto* document = coreFrame->document();
    if (!document)
        return @[];

    return createNSArray(document->markers().renderedRectsForMarkers(WebCore::DocumentMarker::TextMatch)).autorelease();
}

- (BOOL)_findString:(NSString *)string options:(WebFindOptions)options
{
    if (![string length])
        return NO;
    auto* coreFrame = core([self _frame]);
    return coreFrame && coreFrame->editor().findString(string, coreOptions(options));
}

@end

#if PLATFORM(MAC)

@implementation WebHTMLView (TestingSupportMac)

- (BOOL)_secureEventInputEnabledForTesting
{
    return _private->isInSecureInputState;
}

@end

#endif // PLATFORM(MAC)

// This is used by AppKit/TextKit. It should be possible to remove this once
// -[NSAttributedString _documentFromRange:document:documentAttributes:subresources:] is removed.
@implementation NSURL (WebDataURL)

+ (NSURL *)_web_uniqueWebDataURL
{
    return URL::fakeURLWithRelativePart(emptyString());
}

@end

#if PLATFORM(MAC)

@implementation WebResponderChainSink

- (id)initWithResponderChain:(NSResponder *)chain
{
    self = [super init];
    _lastResponderInChain = chain;
    while (NSResponder *next = [_lastResponderInChain nextResponder])
        _lastResponderInChain = next;
    [_lastResponderInChain setNextResponder:self];
    return self;
}

- (void)detach
{
    [_lastResponderInChain setNextResponder:nil];
    _lastResponderInChain = nil;
}

- (BOOL)receivedUnhandledCommand
{
    return _receivedUnhandledCommand;
}

- (void)noResponderFor:(SEL)selector
{
    _receivedUnhandledCommand = YES;
}

- (void)doCommandBySelector:(SEL)selector
{
    _receivedUnhandledCommand = YES;
}

- (BOOL)tryToPerform:(SEL)action with:(id)object
{
    _receivedUnhandledCommand = YES;
    return YES;
}

@end

#endif
