/*
 * Copyright (C) 2013-2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.ContentViewCookieType = {
    ApplicationCache: "application-cache",
    CookieStorage: "cookie-storage",
    Database: "database",
    DatabaseTable: "database-table",
    DOMStorage: "dom-storage",
    Resource: "resource", // includes Frame too.
    Timelines: "timelines"
};

WI.SelectedSidebarPanelCookieKey = "selected-sidebar-panel";
WI.TypeIdentifierCookieKey = "represented-object-type";

WI.StateRestorationType = {
    Load: "state-restoration-load",
    Navigation: "state-restoration-navigation",
    Delayed: "state-restoration-delayed",
};

WI.LayoutDirection = {
    System: "system",
    LTR: "ltr",
    RTL: "rtl",
};

WI.loaded = function()
{
    // Register observers for events from the InspectorBackend.
    if (InspectorBackend.registerAnimationDispatcher)
        InspectorBackend.registerAnimationDispatcher(WI.AnimationObserver);
    if (InspectorBackend.registerApplicationCacheDispatcher)
        InspectorBackend.registerApplicationCacheDispatcher(WI.ApplicationCacheObserver);
    if (InspectorBackend.registerCPUProfilerDispatcher)
        InspectorBackend.registerCPUProfilerDispatcher(WI.CPUProfilerObserver);
    if (InspectorBackend.registerCSSDispatcher)
        InspectorBackend.registerCSSDispatcher(WI.CSSObserver);
    if (InspectorBackend.registerCanvasDispatcher)
        InspectorBackend.registerCanvasDispatcher(WI.CanvasObserver);
    if (InspectorBackend.registerConsoleDispatcher)
        InspectorBackend.registerConsoleDispatcher(WI.ConsoleObserver);
    if (InspectorBackend.registerDOMDispatcher)
        InspectorBackend.registerDOMDispatcher(WI.DOMObserver);
    if (InspectorBackend.registerDOMStorageDispatcher)
        InspectorBackend.registerDOMStorageDispatcher(WI.DOMStorageObserver);
    if (InspectorBackend.registerDatabaseDispatcher)
        InspectorBackend.registerDatabaseDispatcher(WI.DatabaseObserver);
    if (InspectorBackend.registerDebuggerDispatcher)
        InspectorBackend.registerDebuggerDispatcher(WI.DebuggerObserver);
    if (InspectorBackend.registerHeapDispatcher)
        InspectorBackend.registerHeapDispatcher(WI.HeapObserver);
    if (InspectorBackend.registerInspectorDispatcher)
        InspectorBackend.registerInspectorDispatcher(WI.InspectorObserver);
    if (InspectorBackend.registerLayerTreeDispatcher)
        InspectorBackend.registerLayerTreeDispatcher(WI.LayerTreeObserver);
    if (InspectorBackend.registerMemoryDispatcher)
        InspectorBackend.registerMemoryDispatcher(WI.MemoryObserver);
    if (InspectorBackend.registerNetworkDispatcher)
        InspectorBackend.registerNetworkDispatcher(WI.NetworkObserver);
    if (InspectorBackend.registerPageDispatcher)
        InspectorBackend.registerPageDispatcher(WI.PageObserver);
    if (InspectorBackend.registerRuntimeDispatcher)
        InspectorBackend.registerRuntimeDispatcher(WI.RuntimeObserver);
    if (InspectorBackend.registerScriptProfilerDispatcher)
        InspectorBackend.registerScriptProfilerDispatcher(WI.ScriptProfilerObserver);
    if (InspectorBackend.registerTargetDispatcher)
        InspectorBackend.registerTargetDispatcher(WI.TargetObserver);
    if (InspectorBackend.registerTimelineDispatcher)
        InspectorBackend.registerTimelineDispatcher(WI.TimelineObserver);
    if (InspectorBackend.registerWorkerDispatcher)
        InspectorBackend.registerWorkerDispatcher(WI.WorkerObserver);

    // Listen for the ProvisionalLoadStarted event before registering for events so our code gets called before any managers or sidebars.
    // This lets us save a state cookie before any managers or sidebars do any resets that would affect state (namely TimelineManager).
    WI.Frame.addEventListener(WI.Frame.Event.ProvisionalLoadStarted, WI._provisionalLoadStarted,);

    // Populate any UIStrings that must be done early after localized strings have loaded.
    WI.KeyboardShortcut.Key.Space._displayName = WI.UIString("Space");

    // Create the singleton managers next, before the user interface elements, so the user interface can register
    // as event listeners on these managers.
    WI.managers = [
        WI.targetManager = new WI.TargetManager,
        WI.networkManager = new WI.NetworkManager,
        WI.domStorageManager = new WI.DOMStorageManager,
        WI.databaseManager = new WI.DatabaseManager,
        WI.indexedDBManager = new WI.IndexedDBManager,
        WI.domManager = new WI.DOMManager,
        WI.cssManager = new WI.CSSManager,
        WI.consoleManager = new WI.ConsoleManager,
        WI.runtimeManager = new WI.RuntimeManager,
        WI.heapManager = new WI.HeapManager,
        WI.memoryManager = new WI.MemoryManager,
        WI.applicationCacheManager = new WI.ApplicationCacheManager,
        WI.timelineManager = new WI.TimelineManager,
        WI.auditManager = new WI.AuditManager,
        WI.debuggerManager = new WI.DebuggerManager,
        WI.layerTreeManager = new WI.LayerTreeManager,
        WI.workerManager = new WI.WorkerManager,
        WI.domDebuggerManager = new WI.DOMDebuggerManager,
        WI.canvasManager = new WI.CanvasManager,
    ];

    // Register for events.
    WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Paused, WI._debuggerDidPause);
    WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.Resumed, WI._debuggerDidResume);
    WI.domManager.addEventListener(WI.DOMManager.Event.InspectModeStateChanged, WI._inspectModeStateChanged);
    WI.domManager.addEventListener(WI.DOMManager.Event.DOMNodeWasInspected, WI._domNodeWasInspected);
    WI.domStorageManager.addEventListener(WI.DOMStorageManager.Event.DOMStorageObjectWasInspected, WI._domStorageWasInspected);
    WI.databaseManager.addEventListener(WI.DatabaseManager.Event.DatabaseWasInspected, WI._databaseWasInspected);
    WI.networkManager.addEventListener(WI.NetworkManager.Event.MainFrameDidChange, WI._mainFrameDidChange);
    WI.networkManager.addEventListener(WI.NetworkManager.Event.FrameWasAdded, WI._frameWasAdded);

    WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, WI._mainResourceDidChange);

    document.addEventListener("DOMContentLoaded", WI.contentLoaded);

    // Create settings.
    WI._showingSplitConsoleSetting = new WI.Setting("showing-split-console", false);
    WI._openTabsSetting = new WI.Setting("open-tab-types", [
        WI.ElementsTabContentView.Type,
        WI.NetworkTabContentView.Type,
        WI.SourcesTabContentView.Type,
        WI.TimelineTabContentView.Type,
        WI.StorageTabContentView.Type,
        WI.CanvasTabContentView.Type,
        WI.AuditTabContentView.Type,
        WI.ConsoleTabContentView.Type,
    ]);
    WI._selectedTabIndexSetting = new WI.Setting("selected-tab-index", 0);

    // Replace the Debugger/Resources Tab with the Sources Tab.
    let debuggerIndex = WI._openTabsSetting.value.indexOf("debugger");
    let resourcesIndex = WI._openTabsSetting.value.indexOf("resources");
    if (debuggerIndex >= 0 || resourcesIndex >= 0) {
        WI._openTabsSetting.value.remove("debugger");
        WI._openTabsSetting.value.remove("resources");

        if (debuggerIndex === -1)
            debuggerIndex = Infinity;
        if (resourcesIndex === -1)
            resourcesIndex = Infinity;

        let sourcesIndex = Math.min(debuggerIndex, resourcesIndex);
        WI._openTabsSetting.value.splice(sourcesIndex, 1, WI.SourcesTabContentView.Type);
        WI._openTabsSetting.save();

        if (WI._selectedTabIndexSetting.value === debuggerIndex || WI._selectedTabIndexSetting.value === resourcesIndex)
            WI._selectedTabIndexSetting.value = sourcesIndex;
    }

    // State.
    WI.printStylesEnabled = false;
    WI.setZoomFactor(WI.settings.zoomFactor.value);
    WI.mouseCoords = {x: 0, y: 0};
    WI.modifierKeys = {altKey: false, metaKey: false, shiftKey: false};
    WI.visible = false;
    WI._windowKeydownListeners = [];
    WI._overridenDeviceUserAgent = null;
    WI._overridenDeviceSettings = new Map;

    // Targets.
    WI.backendTarget = null;
    WI.pageTarget = null;
    WI._targetsAvailablePromise = new WI.WrappedPromise;

    // COMPATIBILITY (iOS 13.0): Target.exists was "replaced" by differentiating "web" debuggables
    // into "page" (direct) and "web-page" debuggables (multiplexing).
    if (InspectorBackend.hasDomain("Target")) {
        if (InspectorBackend.hasCommand("Target.exists")) {
            console.assert(WI.sharedApp.debuggableType === WI.DebuggableType.WebPage);
            InspectorBackend.invokeCommand("Target.exists", WI.TargetType.WebPage, InspectorBackend.backendConnection, {}, (error) => {
                if (error) {
                    WI.sharedApp._debuggableType = WI.DebuggableType.Page;
                    WI.targetManager.createDirectBackendTarget();
                }
            });
        } else
            WI.targetManager.createMultiplexingBackendTarget();
    } else
        WI.targetManager.createDirectBackendTarget();
};

WI.contentLoaded = function()
{
    // If there was an uncaught exception earlier during loading, then
    // abort loading more content. We could be in an inconsistent state.
    if (window.__uncaughtExceptions)
        return;

    // Register for global events.
    document.addEventListener("beforecopy", WI._beforecopy);
    document.addEventListener("copy", WI._copy);
    document.addEventListener("paste", WI._paste);

    document.addEventListener("click", WI._mouseWasClicked);
    document.addEventListener("dragover", WI._handleDragOver);
    document.addEventListener("drop", WI._handleDrop);
    document.addEventListener("focus", WI._focusChanged, true);

    window.addEventListener("focus", WI._windowFocused);
    window.addEventListener("blur", WI._windowBlurred);
    window.addEventListener("resize", WI._windowResized);
    window.addEventListener("keydown", WI._windowKeyDown);
    window.addEventListener("keyup", WI._windowKeyUp);
    window.addEventListener("mousedown", WI._mouseDown, true);
    window.addEventListener("mousemove", WI._mouseMoved, true);
    window.addEventListener("pagehide", WI._pageHidden);
    window.addEventListener("contextmenu", WI._contextMenuRequested);

    // Add platform style classes so the UI can be tweaked per-platform.
    document.body.classList.add(WI.Platform.name + "-platform");
    if (WI.Platform.isNightlyBuild)
        document.body.classList.add("nightly-build");

    if (WI.Platform.name === "mac")
        document.body.classList.add(WI.Platform.version.name);

    document.body.classList.add(WI.sharedApp.debuggableType);
    document.body.setAttribute("dir", WI.resolvedLayoutDirection());

    WI.layoutMeasurementContainer = document.body.appendChild(document.createElement("div"));
    WI.layoutMeasurementContainer.id = "layout-measurement-container";

    WI.settings.showJavaScriptTypeInformation.addEventListener(WI.Setting.Event.Changed, WI._showJavaScriptTypeInformationSettingChanged);
    WI.settings.enableControlFlowProfiler.addEventListener(WI.Setting.Event.Changed, WI._enableControlFlowProfilerSettingChanged);
    WI.settings.resourceCachingDisabled.addEventListener(WI.Setting.Event.Changed, WI._resourceCachingDisabledSettingChanged);

    function setTabSize() {
        document.body.style.tabSize = WI.settings.tabSize.value;
    }
    WI.settings.tabSize.addEventListener(WI.Setting.Event.Changed, setTabSize);
    setTabSize();

    function setInvisibleCharacterClassName() {
        document.body.classList.toggle("show-invisible-characters", WI.settings.showInvisibleCharacters.value);
    }
    WI.settings.showInvisibleCharacters.addEventListener(WI.Setting.Event.Changed, setInvisibleCharacterClassName);
    setInvisibleCharacterClassName();

    function setWhitespaceCharacterClassName() {
        document.body.classList.toggle("show-whitespace-characters", WI.settings.showWhitespaceCharacters.value);
    }
    WI.settings.showWhitespaceCharacters.addEventListener(WI.Setting.Event.Changed, setWhitespaceCharacterClassName);
    setWhitespaceCharacterClassName();

    WI.settingsTabContentView = new WI.SettingsTabContentView;

    WI._settingsKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Comma, WI._handleSettingsKeyboardShortcut);

    // Create the user interface elements.
    WI.toolbar = new WI.Toolbar(document.getElementById("toolbar"));

    if (WI.settings.experimentalEnableNewTabBar.value)
        WI.tabBar = new WI.TabBar(document.getElementById("tab-bar"));
    else {
        WI.tabBar = new WI.LegacyTabBar(document.getElementById("tab-bar"));
        WI.tabBar.addEventListener(WI.TabBar.Event.OpenDefaultTab, WI._openDefaultTab);
    }

    WI._contentElement = document.getElementById("content");
    WI._contentElement.setAttribute("role", "main");
    WI._contentElement.setAttribute("aria-label", WI.UIString("Content"));

    WI.clearKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "K", WI._clear);

    // FIXME: <https://webkit.org/b/151310> Web Inspector: Command-E should propagate to other search fields (including the system)
    WI.populateFindKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "E", WI._populateFind);
    WI.populateFindKeyboardShortcut.implicitlyPreventsDefault = false;
    WI.findNextKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "G", WI._findNext);
    WI.findPreviousKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Shift | WI.KeyboardShortcut.Modifier.CommandOrControl, "G", WI._findPrevious);

    WI.consoleDrawer = new WI.ConsoleDrawer(document.getElementById("console-drawer"));
    WI.consoleDrawer.addEventListener(WI.ConsoleDrawer.Event.CollapsedStateChanged, WI._consoleDrawerCollapsedStateDidChange);
    WI.consoleDrawer.addEventListener(WI.ConsoleDrawer.Event.Resized, WI._consoleDrawerDidResize);

    WI.quickConsole = new WI.QuickConsole(document.getElementById("quick-console"));

    WI._consoleRepresentedObject = new WI.LogObject;
    WI.consoleContentView = WI.consoleDrawer.contentViewForRepresentedObject(WI._consoleRepresentedObject);
    WI.consoleLogViewController = WI.consoleContentView.logViewController;
    WI.breakpointPopoverController = new WI.BreakpointPopoverController;

    // FIXME: The sidebars should be flipped in RTL languages.
    WI.navigationSidebar = new WI.Sidebar(document.getElementById("navigation-sidebar"), WI.Sidebar.Sides.Left);
    WI.navigationSidebar.addEventListener(WI.Sidebar.Event.WidthDidChange, WI._sidebarWidthDidChange);

    WI.detailsSidebar = new WI.Sidebar(document.getElementById("details-sidebar"), WI.Sidebar.Sides.Right, null, null, WI.UIString("Details"), true);
    WI.detailsSidebar.addEventListener(WI.Sidebar.Event.WidthDidChange, WI._sidebarWidthDidChange);

    WI.searchKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "F", WI._focusSearchField);
    WI._findKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "F", WI._find);
    WI.saveKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "S", WI._save);
    WI._saveAsKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Shift | WI.KeyboardShortcut.Modifier.CommandOrControl, "S", WI._saveAs);

    WI.openResourceKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "O", WI._showOpenResourceDialog);
    new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "P", WI._showOpenResourceDialog);

    WI.navigationSidebarKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "0", WI.toggleNavigationSidebar);
    WI.detailsSidebarKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Option, "0", WI.toggleDetailsSidebar);

    let boundIncreaseZoom = WI._increaseZoom;
    let boundDecreaseZoom = WI._decreaseZoom;
    WI._increaseZoomKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Plus, boundIncreaseZoom);
    WI._decreaseZoomKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Minus, boundDecreaseZoom);
    WI._increaseZoomKeyboardShortcut2 = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, WI.KeyboardShortcut.Key.Plus, boundIncreaseZoom);
    WI._decreaseZoomKeyboardShortcut2 = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, WI.KeyboardShortcut.Key.Minus, boundDecreaseZoom);
    WI._resetZoomKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "0", WI._resetZoom);

    WI._showTabAtIndexKeyboardShortcuts = [1, 2, 3, 4, 5, 6, 7, 8, 9].map((i) => new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Option, `${i}`, (event) => { WI._showTabAtIndex(i); }));
    WI._openNewTabKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Option, "T", WI.showNewTabTab);

    WI.tabBrowser = new WI.TabBrowser(document.getElementById("tab-browser"), WI.tabBar, WI.navigationSidebar, WI.detailsSidebar);
    WI.tabBrowser.addEventListener(WI.TabBrowser.Event.SelectedTabContentViewDidChange, WI._tabBrowserSelectedTabContentViewDidChange);

    WI._reloadPageKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "R", WI._reloadPage);
    WI._reloadPageFromOriginKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Option, "R", WI._reloadPageFromOrigin);
    WI._reloadPageKeyboardShortcut.implicitlyPreventsDefault = WI._reloadPageFromOriginKeyboardShortcut.implicitlyPreventsDefault = false;

    WI._consoleTabKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Option | WI.KeyboardShortcut.Modifier.CommandOrControl, "C", WI._showConsoleTab);
    WI._quickConsoleKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Control, WI.KeyboardShortcut.Key.Apostrophe, WI._focusConsolePrompt);

    WI._inspectModeKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "C", WI._toggleInspectMode);

    WI._undoKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "Z", WI._undoKeyboardShortcut);
    WI._redoKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "Z", WI._redoKeyboardShortcut);
    WI._undoKeyboardShortcut.implicitlyPreventsDefault = WI._redoKeyboardShortcut.implicitlyPreventsDefault = false;

    WI.toggleBreakpointsKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, "Y", WI.debuggerToggleBreakpoints);
    WI.pauseOrResumeKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Control | WI.KeyboardShortcut.Modifier.CommandOrControl, "Y", WI.debuggerPauseResumeToggle);
    WI.stepOverKeyboardShortcut = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.F6, WI.debuggerStepOver);
    WI.stepIntoKeyboardShortcut = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.F7, WI.debuggerStepInto);
    WI.stepOutKeyboardShortcut = new WI.KeyboardShortcut(null, WI.KeyboardShortcut.Key.F8, WI.debuggerStepOut);

    WI.pauseOrResumeAlternateKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Backslash, WI.debuggerPauseResumeToggle);
    WI.stepOverAlternateKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.SingleQuote, WI.debuggerStepOver);
    WI.stepIntoAlternateKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Semicolon, WI.debuggerStepInto);
    WI.stepOutAlternateKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.Shift | WI.KeyboardShortcut.Modifier.CommandOrControl, WI.KeyboardShortcut.Key.Semicolon, WI.debuggerStepOut);

    WI._closeToolbarButton = new WI.ControlToolbarItem("dock-close", WI.UIString("Close"), "Images/Close.svg", 16, 14);
    WI._closeToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI.close);

    WI._undockToolbarButton = new WI.ButtonToolbarItem("undock", WI.UIString("Detach into separate window"), "Images/Undock.svg");
    WI._undockToolbarButton.element.classList.add(WI.Popover.IgnoreAutoDismissClassName);
    WI._undockToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI._undock);

    let dockImage = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "Images/DockLeft.svg" : "Images/DockRight.svg";
    WI._dockToSideToolbarButton = new WI.ButtonToolbarItem("dock-right", WI.UIString("Dock to side of window"), dockImage);
    WI._dockToSideToolbarButton.element.classList.add(WI.Popover.IgnoreAutoDismissClassName);

    let dockToSideCallback = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? WI._dockLeft : WI._dockRight;
    WI._dockToSideToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, dockToSideCallback);

    WI._dockBottomToolbarButton = new WI.ButtonToolbarItem("dock-bottom", WI.UIString("Dock to bottom of window"), "Images/DockBottom.svg");
    WI._dockBottomToolbarButton.element.classList.add(WI.Popover.IgnoreAutoDismissClassName);
    WI._dockBottomToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI._dockBottom);

    WI._togglePreviousDockConfigurationKeyboardShortcut = new WI.KeyboardShortcut(WI.KeyboardShortcut.Modifier.CommandOrControl | WI.KeyboardShortcut.Modifier.Shift, "D", WI._togglePreviousDockConfiguration);

    let reloadToolTip;
    if (WI.sharedApp.debuggableType === WI.DebuggableType.JavaScript)
        reloadToolTip = WI.UIString("Restart (%s)").format(WI._reloadPageKeyboardShortcut.displayName);
    else
        reloadToolTip = WI.UIString("Reload page (%s)\nReload page ignoring cache (%s)").format(WI._reloadPageKeyboardShortcut.displayName, WI._reloadPageFromOriginKeyboardShortcut.displayName);
    WI._reloadToolbarButton = new WI.ButtonToolbarItem("reload", reloadToolTip, "Images/ReloadToolbar.svg");
    WI._reloadToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI._reloadToolbarButtonClicked);

    WI._downloadToolbarButton = new WI.ButtonToolbarItem("download", WI.UIString("Download Web Archive"), "Images/DownloadArrow.svg");
    WI._downloadToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI._downloadWebArchive);

    let elementSelectionToolTip = WI.UIString("Start element selection (%s)").format(WI._inspectModeKeyboardShortcut.displayName);
    let activatedElementSelectionToolTip = WI.UIString("Stop element selection (%s)").format(WI._inspectModeKeyboardShortcut.displayName);
    WI._inspectModeToolbarButton = new WI.ActivateButtonToolbarItem("inspect", elementSelectionToolTip, activatedElementSelectionToolTip, "Images/Crosshair.svg");
    WI._inspectModeToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI._toggleInspectMode);

    // COMPATIBILITY (iOS 12.2): Page.overrideSetting did not exist.
    if (InspectorFrontendHost.isRemote && InspectorBackend.hasCommand("Page.overrideUserAgent") && InspectorBackend.hasCommand("Page.overrideSetting")) {
        const deviceSettingsTooltip = WI.UIString("Device Settings");
        WI._deviceSettingsToolbarButton = new WI.ActivateButtonToolbarItem("device-settings", deviceSettingsTooltip, deviceSettingsTooltip, "Images/Device.svg");
        WI._deviceSettingsToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, WI._handleDeviceSettingsToolbarButtonClicked);

        WI._deviceSettingsPopover = null;
    }

    WI._updateReloadToolbarButton();
    WI._updateDownloadToolbarButton();
    WI._updateInspectModeToolbarButton();

    WI._dashboards = {
        default: new WI.DefaultDashboard,
        debugger: new WI.DebuggerDashboard,
    };

    WI._dashboardContainer = new WI.DashboardContainerView;
    WI._dashboardContainer.showDashboardViewForRepresentedObject(WI._dashboards.default);

    WI.toolbar.addToolbarItem(WI._closeToolbarButton, WI.Toolbar.Section.Control);

    WI.toolbar.addToolbarItem(WI._undockToolbarButton, WI.Toolbar.Section.Left);
    WI.toolbar.addToolbarItem(WI._dockToSideToolbarButton, WI.Toolbar.Section.Left);
    WI.toolbar.addToolbarItem(WI._dockBottomToolbarButton, WI.Toolbar.Section.Left);

    WI.toolbar.addToolbarItem(WI._reloadToolbarButton, WI.Toolbar.Section.CenterLeft);
    WI.toolbar.addToolbarItem(WI._downloadToolbarButton, WI.Toolbar.Section.CenterLeft);

    WI.toolbar.addToolbarItem(WI._dashboardContainer.toolbarItem, WI.Toolbar.Section.Center);

    WI.toolbar.addToolbarItem(WI._inspectModeToolbarButton, WI.Toolbar.Section.CenterRight);

    if (WI._deviceSettingsToolbarButton)
        WI.toolbar.addToolbarItem(WI._deviceSettingsToolbarButton, WI.Toolbar.Section.CenterRight);

    WI._searchTabContentView = new WI.SearchTabContentView;

    if (WI.settings.experimentalEnableNewTabBar.value) {
        WI.tabBrowser.addTabForContentView(WI._searchTabContentView, {suppressAnimations: true});
        WI.tabBar.addTabBarItem(WI.settingsTabContentView.tabBarItem, {suppressAnimations: true});
    } else {
        const incremental = false;
        WI._searchToolbarItem = new WI.SearchBar("inspector-search", WI.UIString("Search"), incremental);
        WI._searchToolbarItem.addEventListener(WI.SearchBar.Event.TextChanged, WI._searchTextDidChange);
        WI.toolbar.addToolbarItem(WI._searchToolbarItem, WI.Toolbar.Section.Right);
    }

    let dockedResizerElement = document.getElementById("docked-resizer");
    dockedResizerElement.classList.add(WI.Popover.IgnoreAutoDismissClassName);
    dockedResizerElement.addEventListener("mousedown", WI._dockedResizerMouseDown);

    WI._dockingAvailable = false;

    WI._updateDockNavigationItems();
    WI._setupViewHierarchy();

    // These tabs are always available for selecting, modulo isTabAllowed().
    // Other tabs may be engineering-only or toggled at runtime if incomplete.
    let productionTabClasses = [
        WI.ElementsTabContentView,
        WI.NetworkTabContentView,
        WI.SourcesTabContentView,
        WI.TimelineTabContentView,
        WI.StorageTabContentView,
        WI.CanvasTabContentView,
        WI.LayersTabContentView,
        WI.AuditTabContentView,
        WI.ConsoleTabContentView,
        WI.SearchTabContentView,
        WI.NewTabContentView,
        WI.SettingsTabContentView,
    ];

    WI._knownTabClassesByType = new Map;
    // Set tab classes directly. The public API triggers other updates and
    // notifications that won't work or have no listeners at WI point.
    for (let tabClass of productionTabClasses)
        WI._knownTabClassesByType.set(tabClass.Type, tabClass);

    WI._pendingOpenTabs = [];

    // Previously we may have stored duplicates in WI setting. Avoid creating duplicate tabs.
    let openTabTypes = WI._openTabsSetting.value;
    let seenTabTypes = new Set;

    for (let i = 0; i < openTabTypes.length; ++i) {
        let tabType = openTabTypes[i];

        if (seenTabTypes.has(tabType))
            continue;
        seenTabTypes.add(tabType);

        if (!WI.isTabTypeAllowed(tabType)) {
            WI._pendingOpenTabs.push({tabType, index: i});
            continue;
        }

        if (!WI.isNewTabWithTypeAllowed(tabType))
            continue;

        let tabContentView = WI._createTabContentViewForType(tabType);
        if (!tabContentView)
            continue;
        WI.tabBrowser.addTabForContentView(tabContentView, {suppressAnimations: true});
    }

    WI._restoreCookieForOpenTabs(WI.StateRestorationType.Load);

    WI.tabBar.selectedTabBarItem = WI._selectedTabIndexSetting.value;

    if (!WI.tabBar.selectedTabBarItem)
        WI.tabBar.selectedTabBarItem = 0;

    if (!WI.tabBar.normalTabCount)
        WI.showNewTabTab({suppressAnimations: true});

    // Listen to the events after restoring the saved tabs to avoid recursion.
    WI.tabBar.addEventListener(WI.TabBar.Event.TabBarItemAdded, WI._rememberOpenTabs);
    WI.tabBar.addEventListener(WI.TabBar.Event.TabBarItemRemoved, WI._rememberOpenTabs);
    WI.tabBar.addEventListener(WI.TabBar.Event.TabBarItemsReordered, WI._rememberOpenTabs);

    function updateConsoleSavedResultPrefixCSSVariable() {
        document.body.style.setProperty("--console-saved-result-prefix", "\"" + WI.RuntimeManager.preferredSavedResultPrefix() + "\"");
    }
    WI.settings.consoleSavedResultAlias.addEventListener(WI.Setting.Event.Changed, updateConsoleSavedResultPrefixCSSVariable);
    updateConsoleSavedResultPrefixCSSVariable();

    // Signal that the frontend is now ready to receive messages.
    WI.whenTargetsAvailable().then(() => {
        InspectorFrontendAPI.loadCompleted();
    });

    WI._updateSheetRect();

    // Tell the InspectorFrontendHost we loaded, which causes the window to display
    // and pending InspectorFrontendAPI commands to be sent.
    InspectorFrontendHost.loaded();

    if (WI._showingSplitConsoleSetting.value)
        WI.showSplitConsole();

    // Store WI on the window in case the WebInspector global gets corrupted.
    window.__frontendCompletedLoad = true;

    if (WI.runBootstrapOperations)
        WI.runBootstrapOperations();

    if (WI.DiagnosticController.supportsDiagnosticLogging())
        WI._diagnosticController = new WI.DiagnosticController;
};

WI.performOneTimeFrontendInitializationsUsingTarget = function(target)
{
    if (!WI.__didPerformConsoleInitialization && target.hasDomain("Console")) {
        WI.__didPerformConsoleInitialization = true;
        WI.consoleManager.initializeLogChannels(target);
    }

    if (!WI.__didPerformCSSInitialization && target.hasDomain("CSS")) {
        WI.__didPerformCSSInitialization = true;
        WI.CSSCompletions.initializeCSSCompletions(target);
    }
};

WI.initializeTarget = function(target)
{
    if (target.hasDomain("Page")) {
        // COMPATIBILITY (iOS 12.2): Page.overrideUserAgent did not exist.
        if (target.hasCommand("Page.overrideUserAgent") && WI._overridenDeviceUserAgent)
            target.PageAgent.overrideUserAgent(WI._overridenDeviceUserAgent);

        // COMPATIBILITY (iOS 12.2): Page.overrideSetting did not exist.
        if (target.hasCommand("Page.overrideSetting")) {
            for (let [setting, value] of WI._overridenDeviceSettings)
                target.PageAgent.overrideSetting(setting, value);
        }

        // COMPATIBILITY (iOS 11.3)
        if (target.hasCommand("Page.setShowRulers") && WI.settings.showRulers.value)
            target.PageAgent.setShowRulers(true);

        // COMPATIBILITY (iOS 8): Page.setShowPaintRects did not exist.
        if (target.hasCommand("Page.setShowPaintRects") && WI.settings.showPaintRects.value)
            target.PageAgent.setShowPaintRects(true);
    }
};

WI.targetsAvailable = function()
{
    return WI._targetsAvailablePromise.settled;
};

WI.whenTargetsAvailable = function()
{
    return WI._targetsAvailablePromise.promise;
};

WI.isTabTypeAllowed = function(tabType)
{
    let tabClass = WI._knownTabClassesByType.get(tabType);
    if (!tabClass)
        return false;

    return tabClass.isTabAllowed();
};

WI.knownTabClasses = function()
{
    return new Set(WI._knownTabClassesByType.values());
};

WI._showOpenResourceDialog = function()
{
    if (!WI._openResourceDialog)
        WI._openResourceDialog = new WI.OpenResourceDialog(WI);

    if (WI._openResourceDialog.visible)
        return;

    WI._openResourceDialog.present(WI._contentElement);
};

WI._createTabContentViewForType = function(tabType)
{
    let tabClass = WI._knownTabClassesByType.get(tabType);
    if (!tabClass) {
        console.error("Unknown tab type", tabType);
        return null;
    }

    console.assert(WI.TabContentView.isPrototypeOf(tabClass));
    return new tabClass;
};

WI._rememberOpenTabs = function()
{
    let seenTabTypes = new Set;
    let openTabs = [];

    for (let tabBarItem of WI.tabBar.tabBarItems) {
        let tabContentView = tabBarItem.representedObject;
        if (!(tabContentView instanceof WI.TabContentView))
            continue;
        if (!tabContentView.constructor.shouldSaveTab())
            continue;
        console.assert(tabContentView.type, "Tab type can't be null, undefined, or empty string", tabContentView.type, tabContentView);
        openTabs.push(tabContentView.type);
        seenTabTypes.add(tabContentView.type);
    }

    // Keep currently unsupported tabs in the setting at their previous index.
    for (let {tabType, index} of WI._pendingOpenTabs) {
        if (seenTabTypes.has(tabType))
            continue;
        openTabs.insertAtIndex(tabType, index);
        seenTabTypes.add(tabType);
    }

    WI._openTabsSetting.value = openTabs;
};

WI._openDefaultTab = function(event)
{
    WI.showNewTabTab({suppressAnimations: true});
};

WI._handleSettingsKeyboardShortcut = function(event)
{
    if (event.keyIdentifier === "U+002C") // ","
        WI.tabBrowser.showTabForContentView(WI.settingsTabContentView);
};

WI._tryToRestorePendingTabs = function()
{
    let stillPendingOpenTabs = [];
    for (let {tabType, index} of WI._pendingOpenTabs) {
        if (!WI.isTabTypeAllowed(tabType)) {
            stillPendingOpenTabs.push({tabType, index});
            continue;
        }

        let tabContentView = WI._createTabContentViewForType(tabType);
        if (!tabContentView)
            continue;

        WI.tabBrowser.addTabForContentView(tabContentView, {
            suppressAnimations: true,
            insertionIndex: index,
        });

        tabContentView.restoreStateFromCookie(WI.StateRestorationType.Load);
    }

    WI._pendingOpenTabs = stillPendingOpenTabs;

    if (!WI.settings.experimentalEnableNewTabBar.value)
        WI.tabBar.updateNewTabTabBarItemState();
};

WI.showNewTabTab = function(options)
{
    if (!WI.isNewTabWithTypeAllowed(WI.NewTabContentView.Type))
        return;

    let tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.NewTabContentView);
    if (!tabContentView)
        tabContentView = new WI.NewTabContentView;
    WI.tabBrowser.showTabForContentView(tabContentView, options);
};

WI.isNewTabWithTypeAllowed = function(tabType)
{
    let tabClass = WI._knownTabClassesByType.get(tabType);
    if (!tabClass || !tabClass.isTabAllowed())
        return false;

    // Only allow one tab per class for now.
    for (let tabBarItem of WI.tabBar.tabBarItems) {
        let tabContentView = tabBarItem.representedObject;
        if (!(tabContentView instanceof WI.TabContentView))
            continue;
        if (tabContentView.constructor === tabClass)
            return false;
    }

    if (tabClass === WI.NewTabContentView) {
        let allTabs = Array.from(WI.knownTabClasses());
        let addableTabs = allTabs.filter((tabClass) => !tabClass.tabInfo().isEphemeral);
        let canMakeNewTab = addableTabs.some((tabClass) => WI.isNewTabWithTypeAllowed(tabClass.Type));
        return canMakeNewTab;
    }

    return true;
};

WI.createNewTabWithType = function(tabType, options = {})
{
    console.assert(WI.isNewTabWithTypeAllowed(tabType));

    let {referencedView, shouldReplaceTab, shouldShowNewTab} = options;
    console.assert(!referencedView || referencedView instanceof WI.TabContentView, referencedView);
    console.assert(!shouldReplaceTab || referencedView, "Must provide a reference view to replace a tab.");

    let tabContentView = WI._createTabContentViewForType(tabType);
    const suppressAnimations = true;
    WI.tabBrowser.addTabForContentView(tabContentView, {
        suppressAnimations,
        insertionIndex: referencedView ? WI.tabBar.tabBarItems.indexOf(referencedView.tabBarItem) : undefined,
    });

    if (shouldReplaceTab)
        WI.tabBrowser.closeTabForContentView(referencedView, {suppressAnimations});

    if (shouldShowNewTab)
        WI.tabBrowser.showTabForContentView(tabContentView);
};

WI.activateExtraDomains = function(domains)
{
    WI.notifications.dispatchEventToListeners(WI.Notification.ExtraDomainsActivated, {domains});

    if (WI.mainTarget) {
        if (!WI.pageTarget && WI.mainTarget.hasDomain("DOM"))
            WI.pageTarget = WI.mainTarget;

        if (WI.mainTarget.hasDomain("CSS"))
            WI.CSSCompletions.initializeCSSCompletions(WI.assumingMainTarget());

        if (WI.mainTarget.hasDomain("DOM"))
            WI.domManager.ensureDocument();

        if (WI.mainTarget.hasDomain("Page"))
            WI.networkManager.initializeTarget(WI.mainTarget);
    }

    WI._updateReloadToolbarButton();
    WI._updateDownloadToolbarButton();
    WI._updateInspectModeToolbarButton();

    WI._tryToRestorePendingTabs();
};

WI.updateWindowTitle = function()
{
    var mainFrame = WI.networkManager.mainFrame;
    if (!mainFrame)
        return;

    var urlComponents = mainFrame.mainResource.urlComponents;

    var lastPathComponent;
    try {
        lastPathComponent = decodeURIComponent(urlComponents.lastPathComponent || "");
    } catch {
        lastPathComponent = urlComponents.lastPathComponent;
    }

    // Build a title based on the URL components.
    if (urlComponents.host && lastPathComponent)
        var title = WI.displayNameForHost(urlComponents.host) + " \u2014 " + lastPathComponent;
    else if (urlComponents.host)
        var title = WI.displayNameForHost(urlComponents.host);
    else if (lastPathComponent)
        var title = lastPathComponent;
    else
        var title = mainFrame.url;

    // The name "inspectedURLChanged" sounds like the whole URL is required, however WI is only
    // used for updating the window title and it can be any string.
    InspectorFrontendHost.inspectedURLChanged(title);
};

WI.updateDockingAvailability = function(available)
{
    WI._dockingAvailable = available;

    WI._updateDockNavigationItems();
};

WI.updateDockedState = function(side)
{
    if (WI._dockConfiguration === side)
        return;

    WI._previousDockConfiguration = WI._dockConfiguration;

    if (!WI._previousDockConfiguration) {
        if (side === WI.DockConfiguration.Right || side === WI.DockConfiguration.Left)
            WI._previousDockConfiguration = WI.DockConfiguration.Bottom;
        else
            WI._previousDockConfiguration = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? WI.DockConfiguration.Left : WI.DockConfiguration.Right;
    }

    WI._dockConfiguration = side;

    WI.docked = side !== WI.DockConfiguration.Undocked;

    WI._ignoreToolbarModeDidChangeEvents = true;

    if (side === WI.DockConfiguration.Bottom) {
        document.body.classList.add("docked", WI.DockConfiguration.Bottom);
        document.body.classList.remove("window-inactive", WI.DockConfiguration.Right, WI.DockConfiguration.Left);
    } else if (side === WI.DockConfiguration.Right) {
        document.body.classList.add("docked", WI.DockConfiguration.Right);
        document.body.classList.remove("window-inactive", WI.DockConfiguration.Bottom, WI.DockConfiguration.Left);
    } else if (side === WI.DockConfiguration.Left) {
        document.body.classList.add("docked", WI.DockConfiguration.Left);
        document.body.classList.remove("window-inactive", WI.DockConfiguration.Bottom, WI.DockConfiguration.Right);
    } else
        document.body.classList.remove("docked", WI.DockConfiguration.Right, WI.DockConfiguration.Left, WI.DockConfiguration.Bottom);

    WI._ignoreToolbarModeDidChangeEvents = false;

    WI._updateDockNavigationItems();

    if (!WI.dockedConfigurationSupportsSplitContentBrowser() && !WI.doesCurrentTabSupportSplitContentBrowser())
        WI.hideSplitConsole();
};

WI.updateVisibilityState = function(visible)
{
    WI.visible = visible;
    WI.notifications.dispatchEventToListeners(WI.Notification.VisibilityStateDidChange);
};

WI.handlePossibleLinkClick = function(event, frame, options = {})
{
    let anchorElement = event.target.closest("a");
    if (!anchorElement || !anchorElement.href)
        return false;

    if (WI.isBeingEdited(anchorElement)) {
        // Don't follow the link when it is being edited.
        return false;
    }

    // Prevent the link from navigating, since we don't do any navigation by following links normally.
    event.preventDefault();
    event.stopPropagation();

    WI.openURL(anchorElement.href, frame, {
        ...options,
        lineNumber: anchorElement.lineNumber,
        ignoreSearchTab: !WI.isShowingSearchTab(),
    });

    return true;
};

WI.openURL = function(url, frame, options = {})
{
    console.assert(url);
    if (!url)
        return;

    console.assert(typeof options.lineNumber === "undefined" || typeof options.lineNumber === "number", "lineNumber should be a number.");

    // If alwaysOpenExternally is not defined, base it off the command/meta key for the current event.
    if (options.alwaysOpenExternally === undefined || options.alwaysOpenExternally === null)
        options.alwaysOpenExternally = window.event ? window.event.metaKey : false;

    if (options.alwaysOpenExternally) {
        InspectorFrontendHost.openInNewTab(url);
        return;
    }

    let searchChildFrames = false;
    if (!frame) {
        frame = WI.networkManager.mainFrame;
        searchChildFrames = true;
    }

    let resource;
    let simplifiedURL = removeURLFragment(url);
    if (frame) {
        // WI.Frame.resourceForURL does not check the main resource, only sub-resources. So check both.
        resource = frame.url === simplifiedURL ? frame.mainResource : frame.resourceForURL(simplifiedURL, searchChildFrames);
    } else if (WI.sharedApp.debuggableType === WI.DebuggableType.ServiceWorker)
        resource = WI.mainTarget.resourceCollection.resourceForURL(removeURLFragment(url));

    if (resource) {
        let positionToReveal = new WI.SourceCodePosition(options.lineNumber, 0);
        WI.showSourceCode(resource, {...options, positionToReveal});
        return;
    }

    InspectorFrontendHost.openInNewTab(url);
};

WI.close = function()
{
    if (WI._isClosing)
        return;

    WI._isClosing = true;

    InspectorFrontendHost.closeWindow();
};

WI.isContentAreaFocused = function()
{
    return WI._contentElement.contains(document.activeElement);
}

WI.isConsoleFocused = function()
{
    return !WI._didAutofocusConsolePrompt && WI.quickConsole.prompt.focused;
};

WI.isShowingSplitConsole = function()
{
    return !WI.consoleDrawer.collapsed;
};

WI.dockedConfigurationSupportsSplitContentBrowser = function()
{
    return WI._dockConfiguration !== WI.DockConfiguration.Bottom;
};

WI.doesCurrentTabSupportSplitContentBrowser = function()
{
    var currentContentView = WI.tabBrowser.selectedTabContentView;
    return !currentContentView || currentContentView.supportsSplitContentBrowser;
};

WI.toggleSplitConsole = function()
{
    if (!WI.doesCurrentTabSupportSplitContentBrowser()) {
        WI.showConsoleTab();
        return;
    }

    if (WI.isShowingSplitConsole())
        WI.hideSplitConsole();
    else
        WI.showSplitConsole();
};

WI.showSplitConsole = function()
{
    if (!WI.doesCurrentTabSupportSplitContentBrowser()) {
        WI.showConsoleTab();
        return;
    }

    WI.consoleDrawer.collapsed = false;

    if (WI.consoleDrawer.currentContentView === WI.consoleContentView)
        return;

    WI.consoleDrawer.showContentView(WI.consoleContentView);
};

WI.hideSplitConsole = function()
{
    if (!WI.isShowingSplitConsole())
        return;

    WI.consoleDrawer.collapsed = true;
};

WI.showConsoleTab = function(requestedScope)
{
    requestedScope = requestedScope || WI.LogContentView.Scopes.All;

    WI.hideSplitConsole();

    WI.consoleContentView.scopeBar.item(requestedScope).selected = true;

    WI.showRepresentedObject(WI._consoleRepresentedObject);

    console.assert(WI.isShowingConsoleTab());
};

WI.isShowingConsoleTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.ConsoleTabContentView;
};

WI.showElementsTab = function()
{
    var tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.ElementsTabContentView);
    if (!tabContentView)
        tabContentView = new WI.ElementsTabContentView;
    WI.tabBrowser.showTabForContentView(tabContentView);
};

WI.isShowingElementsTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.ElementsTabContentView;
};

WI.showSourcesTab = function(options = {})
{
    let tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.SourcesTabContentView);
    if (!tabContentView)
        tabContentView = new WI.SourcesTabContentView;

    if (options.breakpointToSelect instanceof WI.Breakpoint)
        tabContentView.revealAndSelectBreakpoint(options.breakpointToSelect);

    if (options.showScopeChainSidebar)
        tabContentView.showScopeChainDetailsSidebarPanel();

    WI.tabBrowser.showTabForContentView(tabContentView);
};

WI.isShowingSourcesTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.SourcesTabContentView;
};

WI.showStorageTab = function()
{
    var tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.StorageTabContentView);
    if (!tabContentView)
        tabContentView = new WI.StorageTabContentView;
    WI.tabBrowser.showTabForContentView(tabContentView);
};

WI.showNetworkTab = function()
{
    let tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.NetworkTabContentView);
    if (!tabContentView)
        tabContentView = new WI.NetworkTabContentView;

    WI.tabBrowser.showTabForContentView(tabContentView);
};

WI.isShowingNetworkTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.NetworkTabContentView;
};

WI.isShowingSearchTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.SearchTabContentView;
};

WI.showTimelineTab = function()
{
    var tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.TimelineTabContentView);
    if (!tabContentView)
        tabContentView = new WI.TimelineTabContentView;
    WI.tabBrowser.showTabForContentView(tabContentView);
};

WI.isShowingTimelineTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.TimelineTabContentView;
};

WI.isShowingAuditTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.AuditTabContentView;
}

WI.showLayersTab = function(options = {})
{
    let tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.LayersTabContentView);
    if (!tabContentView)
        tabContentView = new WI.LayersTabContentView;
    if (options.nodeToSelect)
        tabContentView.selectLayerForNode(options.nodeToSelect);
    WI.tabBrowser.showTabForContentView(tabContentView);
};

WI.isShowingLayersTab = function()
{
    return WI.tabBrowser.selectedTabContentView instanceof WI.LayersTabContentView;
};

WI.showSettingsTab = function(options = {})
{
    WI.tabBrowser.showTabForContentView(WI.settingsTabContentView);

    if (options.blackboxPatternToSelect)
        WI.settingsTabContentView.selectBlackboxPattern(options.blackboxPatternToSelect);
};

WI.indentString = function()
{
    if (WI.settings.indentWithTabs.value)
        return "\t";
    return " ".repeat(WI.settings.indentUnit.value);
};

WI.restoreFocusFromElement = function(element)
{
    if (element && element.contains(WI.currentFocusElement))
        WI.previousFocusElement.focus();
};

WI.toggleNavigationSidebar = function(event)
{
    if (!WI.navigationSidebar.collapsed || !WI.navigationSidebar.sidebarPanels.length) {
        WI.navigationSidebar.collapsed = true;
        return;
    }

    if (!WI.navigationSidebar.selectedSidebarPanel)
        WI.navigationSidebar.selectedSidebarPanel = WI.navigationSidebar.sidebarPanels[0];
    WI.navigationSidebar.collapsed = false;
};

WI.toggleDetailsSidebar = function(event)
{
    if (!WI.detailsSidebar.collapsed || !WI.detailsSidebar.sidebarPanels.length) {
        WI.detailsSidebar.collapsed = true;
        return;
    }

    if (!WI.detailsSidebar.selectedSidebarPanel)
        WI.detailsSidebar.selectedSidebarPanel = WI.detailsSidebar.sidebarPanels[0];
    WI.detailsSidebar.collapsed = false;
};

WI.getMaximumSidebarWidth = function(sidebar)
{
    console.assert(sidebar instanceof WI.Sidebar);

    const minimumContentBrowserWidth = 100;

    let minimumWidth = window.innerWidth - minimumContentBrowserWidth;
    let tabContentView = WI.tabBrowser.selectedTabContentView;
    console.assert(tabContentView);
    if (!tabContentView)
        return minimumWidth;

    let otherSidebar = null;
    if (sidebar === WI.navigationSidebar)
        otherSidebar = tabContentView.detailsSidebarPanels.length ? WI.detailsSidebar : null;
    else
        otherSidebar = tabContentView.navigationSidebarPanel ? WI.navigationSidebar : null;

    if (otherSidebar)
        minimumWidth -= otherSidebar.width;

    return minimumWidth;
};

WI.tabContentViewClassForRepresentedObject = function(representedObject)
{
    if (representedObject instanceof WI.DOMTree)
        return WI.ElementsTabContentView;

    if (representedObject instanceof WI.TimelineRecording)
        return WI.TimelineTabContentView;

    // We only support one console tab right now. So WI isn't an instanceof check.
    if (representedObject === WI._consoleRepresentedObject)
        return WI.ConsoleTabContentView;

    if (representedObject instanceof WI.Frame
        || representedObject instanceof WI.FrameCollection
        || representedObject instanceof WI.Resource
        || representedObject instanceof WI.ResourceCollection
        || representedObject instanceof WI.Script
        || representedObject instanceof WI.ScriptCollection
        || representedObject instanceof WI.CSSStyleSheet
        || representedObject instanceof WI.CSSStyleSheetCollection)
        return WI.SourcesTabContentView;

    if (representedObject instanceof WI.DOMStorageObject || representedObject instanceof WI.CookieStorageObject ||
        representedObject instanceof WI.DatabaseTableObject || representedObject instanceof WI.DatabaseObject ||
        representedObject instanceof WI.ApplicationCacheFrame || representedObject instanceof WI.IndexedDatabaseObjectStore ||
        representedObject instanceof WI.IndexedDatabase || representedObject instanceof WI.IndexedDatabaseObjectStoreIndex)
        return WI.StorageTabContentView;

    if (representedObject instanceof WI.AuditTestCase || representedObject instanceof WI.AuditTestGroup
        || representedObject instanceof WI.AuditTestCaseResult || representedObject instanceof WI.AuditTestGroupResult)
        return WI.AuditTabContentView;

    if (representedObject instanceof WI.CanvasCollection)
        return WI.CanvasTabContentView;

    if (representedObject instanceof WI.Recording)
        return WI.CanvasTabContentView;

    return null;
};

WI.tabContentViewForRepresentedObject = function(representedObject, options = {})
{
    let tabContentView = WI.tabBrowser.bestTabContentViewForRepresentedObject(representedObject, options);
    if (tabContentView)
        return tabContentView;

    var tabContentViewClass = WI.tabContentViewClassForRepresentedObject(representedObject);
    if (!tabContentViewClass) {
        console.error("Unknown representedObject, couldn't create TabContentView.", representedObject);
        return null;
    }

    tabContentView = new tabContentViewClass;

    WI.tabBrowser.addTabForContentView(tabContentView);

    return tabContentView;
};

WI.showRepresentedObject = function(representedObject, cookie, options = {})
{
    let tabContentView = WI.tabContentViewForRepresentedObject(representedObject, options);
    console.assert(tabContentView);
    if (!tabContentView)
        return;

    WI.tabBrowser.showTabForContentView(tabContentView, options);
    tabContentView.showRepresentedObject(representedObject, cookie);
};

WI.showLocalResourceOverride = function(localResourceOverride)
{
    console.assert(localResourceOverride instanceof WI.LocalResourceOverride);
    const cookie = null;
    const options = {ignoreNetworkTab: true, ignoreSearchTab: true};
    WI.showRepresentedObject(localResourceOverride, cookie, options);
};

WI.showMainFrameDOMTree = function(nodeToSelect, options = {})
{
    console.assert(WI.networkManager.mainFrame);
    if (!WI.networkManager.mainFrame)
        return;
    WI.showRepresentedObject(WI.networkManager.mainFrame.domTree, {nodeToSelect}, options);
};

WI.showSourceCodeForFrame = function(frameIdentifier, options = {})
{
    var frame = WI.networkManager.frameForIdentifier(frameIdentifier);
    if (!frame) {
        WI._frameIdentifierToShowSourceCodeWhenAvailable = frameIdentifier;
        return;
    }

    WI._frameIdentifierToShowSourceCodeWhenAvailable = undefined;

    WI.showRepresentedObject(frame, null, options);
};

WI.showSourceCode = function(sourceCode, options = {})
{
    const positionToReveal = options.positionToReveal;

    console.assert(!positionToReveal || positionToReveal instanceof WI.SourceCodePosition, positionToReveal);
    var representedObject = sourceCode;

    if (representedObject instanceof WI.Script) {
        // A script represented by a resource should always show the resource.
        representedObject = representedObject.resource || representedObject;
    }

    var cookie = positionToReveal ? {lineNumber: positionToReveal.lineNumber, columnNumber: positionToReveal.columnNumber} : {};
    WI.showRepresentedObject(representedObject, cookie, options);
};

WI.showSourceCodeLocation = function(sourceCodeLocation, options = {})
{
    WI.showSourceCode(sourceCodeLocation.displaySourceCode, {
        ...options,
        positionToReveal: sourceCodeLocation.displayPosition(),
    });
};

WI.showOriginalUnformattedSourceCodeLocation = function(sourceCodeLocation, options = {})
{
    WI.showSourceCode(sourceCodeLocation.sourceCode, {
        ...options,
        positionToReveal: sourceCodeLocation.position(),
        forceUnformatted: true,
    });
};

WI.showOriginalOrFormattedSourceCodeLocation = function(sourceCodeLocation, options = {})
{
    WI.showSourceCode(sourceCodeLocation.sourceCode, {
        ...options,
        positionToReveal: sourceCodeLocation.formattedPosition(),
    });
};

WI.showOriginalOrFormattedSourceCodeTextRange = function(sourceCodeTextRange, options = {})
{
    var textRangeToSelect = sourceCodeTextRange.formattedTextRange;
    WI.showSourceCode(sourceCodeTextRange.sourceCode, {
        ...options,
        positionToReveal: textRangeToSelect.startPosition(),
        textRangeToSelect,
    });
};

WI.showResourceRequest = function(resource, options = {})
{
    WI.showRepresentedObject(resource, {[WI.ResourceClusterContentView.ContentViewIdentifierCookieKey]: WI.ResourceClusterContentView.Identifier.Request}, options);
};

WI.debuggerToggleBreakpoints = function(event)
{
    WI.debuggerManager.breakpointsEnabled = !WI.debuggerManager.breakpointsEnabled;
};

WI.debuggerPauseResumeToggle = function(event)
{
    if (WI.debuggerManager.paused)
        WI.debuggerManager.resume();
    else
        WI.debuggerManager.pause();
};

WI.debuggerStepOver = function(event)
{
    WI.debuggerManager.stepOver();
};

WI.debuggerStepInto = function(event)
{
    WI.debuggerManager.stepInto();
};

WI.debuggerStepOut = function(event)
{
    WI.debuggerManager.stepOut();
};

WI._searchTextDidChange = function(event)
{
    var tabContentView = WI.tabBrowser.bestTabContentViewForClass(WI.SearchTabContentView);
    if (!tabContentView)
        tabContentView = new WI.SearchTabContentView;

    var searchQuery = WI._searchToolbarItem.text;
    WI._searchToolbarItem.text = "";

    WI.tabBrowser.showTabForContentView(tabContentView);

    tabContentView.performSearch(searchQuery);
};

WI._focusSearchField = function(event)
{
    if (WI.settings.experimentalEnableNewTabBar.value)
        WI.tabBrowser.showTabForContentView(WI._searchTabContentView);

    if (WI.tabBrowser.selectedTabContentView instanceof WI.SearchTabContentView) {
        WI.tabBrowser.selectedTabContentView.focusSearchField();
        return;
    }

    if (WI._searchToolbarItem)
        WI._searchToolbarItem.focus();
};

WI._focusChanged = function(event)
{
    WI._didAutofocusConsolePrompt = false;

    // Make a caret selection inside the focused element if there isn't a range selection and there isn't already
    // a caret selection inside. This is needed (at least) to remove caret from console when focus is moved.
    // The selection change should not apply to text fields and text areas either.

    if (WI.isEventTargetAnEditableField(event)) {
        // Still update the currentFocusElement if inside of a CodeMirror editor or an input element.
        let newFocusElement = null;
        if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement)
            newFocusElement = event.target;
        else {
            let codeMirror = WI.enclosingCodeMirror(event.target);
            if (codeMirror) {
                let codeMirrorElement = codeMirror.getWrapperElement();
                if (codeMirrorElement && codeMirrorElement !== WI.currentFocusElement)
                    newFocusElement = codeMirrorElement;
            }
        }

        if (newFocusElement) {
            WI.previousFocusElement = WI.currentFocusElement;
            WI.currentFocusElement = newFocusElement;
        }

        // Due to the change in WI.isEventTargetAnEditableField (r196271), WI return
        // will also get run when WI.startEditing is called on an element. We do not want
        // to return early in WI case, as WI.EditingConfig handles its own editing
        // completion, so only return early if the focus change target is not from WI.startEditing.
        if (!WI.isBeingEdited(event.target))
            return;
    }

    var selection = window.getSelection();
    if (!selection.isCollapsed)
        return;

    var element = event.target;

    if (element !== WI.currentFocusElement) {
        WI.previousFocusElement = WI.currentFocusElement;
        WI.currentFocusElement = element;
    }

    if (element.isInsertionCaretInside())
        return;

    var selectionRange = element.ownerDocument.createRange();
    selectionRange.setStart(element, 0);
    selectionRange.setEnd(element, 0);

    selection.removeAllRanges();
    selection.addRange(selectionRange);
};

WI._mouseWasClicked = function(event)
{
    WI.handlePossibleLinkClick(event);
};

WI._handleDragOver = function(event)
{
    // Do nothing if another event listener handled the event already.
    if (event.defaultPrevented)
        return;

    // Allow dropping into editable areas.
    if (WI.isEventTargetAnEditableField(event))
        return;

    let tabContentView = WI.tabBrowser.selectedTabContentView;
    if (!tabContentView || !tabContentView.handleFileDrop || !event.dataTransfer.types.includes("Files")) {
        // Prevent the drop from being accepted.
        event.dataTransfer.dropEffect = "none";
    }

    event.preventDefault();
};

WI._handleDrop = function(event)
{
    // Do nothing if another event listener handled the event already.
    if (event.defaultPrevented)
        return;

    // Allow dropping into editable areas.
    if (WI.isEventTargetAnEditableField(event))
        return;

    let tabContentView = WI.tabBrowser.selectedTabContentView;
    if (tabContentView && tabContentView.handleFileDrop && event.dataTransfer.files) {
        event.preventDefault();

        tabContentView.handleFileDrop(event.dataTransfer.files)
        .then(() => {
            event.dataTransfer.clearData();
        });
    }
};

WI._debuggerDidPause = function(event)
{
    WI.showSourcesTab({showScopeChainSidebar: WI.settings.showScopeChainOnPause.value});

    WI._dashboardContainer.showDashboardViewForRepresentedObject(WI._dashboards.debugger);

    InspectorFrontendHost.bringToFront();
};

WI._debuggerDidResume = function(event)
{
    WI._dashboardContainer.closeDashboardViewForRepresentedObject(WI._dashboards.debugger);
};

WI._frameWasAdded = function(event)
{
    if (!WI._frameIdentifierToShowSourceCodeWhenAvailable)
        return;

    var frame = event.data.frame;
    if (frame.id !== WI._frameIdentifierToShowSourceCodeWhenAvailable)
        return;

    function delayedWork()
    {
        const options = {
            ignoreNetworkTab: true,
            ignoreSearchTab: true,
        };
        WI.showSourceCodeForFrame(frame.id, options);
    }

    // Delay showing the frame since FrameWasAdded is called before MainFrameChanged.
    // Calling showSourceCodeForFrame before MainFrameChanged will show the frame then close it.
    setTimeout(delayedWork);
};

WI._mainFrameDidChange = function(event)
{
    WI._updateDownloadToolbarButton();

    WI.updateWindowTitle();
};

WI._mainResourceDidChange = function(event)
{
    if (!event.target.isMainFrame())
        return;

    // Run cookie restoration after we are sure all of the Tabs and NavigationSidebarPanels
    // have updated with respect to the main resource change.
    setTimeout(() => {
        WI._restoreCookieForOpenTabs(WI.StateRestorationType.Navigation);
    });

    WI._updateDownloadToolbarButton();

    WI.updateWindowTitle();
};

WI._provisionalLoadStarted = function(event)
{
    if (!event.target.isMainFrame())
        return;

    WI._saveCookieForOpenTabs();
};

WI._restoreCookieForOpenTabs = function(restorationType)
{
    for (var tabBarItem of WI.tabBar.tabBarItems) {
        var tabContentView = tabBarItem.representedObject;
        if (!(tabContentView instanceof WI.TabContentView))
            continue;
        tabContentView.restoreStateFromCookie(restorationType);
    }

    // Only attempt to autofocus when Web Inspector is first opened.
    if (WI._didAutofocusConsolePrompt === undefined) {
        window.requestAnimationFrame(() => {
            if (WI.isContentAreaFocused() || WI.isShowingTimelineTab() || WI.isShowingAuditTab())
                return;

            WI.quickConsole.prompt.focus();
            WI._didAutofocusConsolePrompt = true;
        });
    }
};

WI._saveCookieForOpenTabs = function()
{
    for (var tabBarItem of WI.tabBar.tabBarItems) {
        var tabContentView = tabBarItem.representedObject;
        if (!(tabContentView instanceof WI.TabContentView))
            continue;
        tabContentView.saveStateToCookie();
    }
};

WI._windowFocused = function(event)
{
    if (event.target.document.nodeType !== Node.DOCUMENT_NODE)
        return;

    // FIXME: We should use the :window-inactive pseudo class once https://webkit.org/b/38927 is fixed.
    document.body.classList.remove(WI.docked ? "window-docked-inactive" : "window-inactive");
};

WI._windowBlurred = function(event)
{
    if (event.target.document.nodeType !== Node.DOCUMENT_NODE)
        return;

    // FIXME: We should use the :window-inactive pseudo class once https://webkit.org/b/38927 is fixed.
    document.body.classList.add(WI.docked ? "window-docked-inactive" : "window-inactive");
};

WI._windowResized = function(event)
{
    WI.toolbar.updateLayout(WI.View.LayoutReason.Resize);
    WI.tabBar.updateLayout(WI.View.LayoutReason.Resize);
    WI._tabBrowserSizeDidChange();
    WI._updateSheetRect();
};

WI._updateSheetRect = function()
{
    let mainElementRect = document.getElementById("main").getBoundingClientRect();
    InspectorFrontendHost.setSheetRect(mainElementRect.x, mainElementRect.y, mainElementRect.width, mainElementRect.height);
};

WI._updateModifierKeys = function(event)
{
    let keys = {
        altKey: event.altKey,
        metaKey: event.metaKey,
        ctrlKey: event.ctrlKey,
        shiftKey: event.shiftKey,
    };

    let changed = !Object.shallowEqual(WI.modifierKeys, keys);

    WI.modifierKeys = keys;

    document.body.classList.toggle("alt-key-pressed", WI.modifierKeys.altKey);
    document.body.classList.toggle("ctrl-key-pressed", WI.modifierKeys.ctrlKey);
    document.body.classList.toggle("meta-key-pressed", WI.modifierKeys.metaKey);
    document.body.classList.toggle("shift-key-pressed", WI.modifierKeys.shiftKey);

    if (changed)
        WI.notifications.dispatchEventToListeners(WI.Notification.GlobalModifierKeysDidChange, event);
};

WI._windowKeyDown = function(event)
{
    WI._updateModifierKeys(event);
};

WI._windowKeyUp = function(event)
{
    WI._updateModifierKeys(event);
};

WI._mouseDown = function(event)
{
    if (WI.toolbar.element.contains(event.target))
        WI._toolbarMouseDown(event);
};

WI._mouseMoved = function(event)
{
    WI._updateModifierKeys(event);
    WI.mouseCoords = {
        x: event.pageX,
        y: event.pageY
    };
};

WI._pageHidden = function(event)
{
    WI._saveCookieForOpenTabs();
};

WI._contextMenuRequested = function(event)
{
    let proposedContextMenu;

    // This is setting is only defined in engineering builds.
    if (WI.isDebugUIEnabled()) {
        proposedContextMenu = WI.ContextMenu.createFromEvent(event);
        proposedContextMenu.appendSeparator();
        proposedContextMenu.appendItem(WI.unlocalizedString("Reload Web Inspector"), () => {
            InspectorFrontendHost.reopen();
        });

        let protocolSubMenu = proposedContextMenu.appendSubMenuItem(WI.unlocalizedString("Protocol Debugging"), null, false);
        let isCapturingTraffic = InspectorBackend.activeTracer instanceof WI.CapturingProtocolTracer;

        protocolSubMenu.appendCheckboxItem(WI.unlocalizedString("Capture Trace"), () => {
            if (isCapturingTraffic)
                InspectorBackend.activeTracer = null;
            else
                InspectorBackend.activeTracer = new WI.CapturingProtocolTracer;
        }, isCapturingTraffic);

        protocolSubMenu.appendSeparator();

        protocolSubMenu.appendItem(WI.unlocalizedString("Export Trace\u2026"), () => {
            const forceSaveAs = true;
            WI.FileUtilities.save(InspectorBackend.activeTracer.trace.saveData, forceSaveAs);
        }, !isCapturingTraffic);
    } else {
        const onlyExisting = true;
        proposedContextMenu = WI.ContextMenu.createFromEvent(event, onlyExisting);
    }

    if (proposedContextMenu)
        proposedContextMenu.show();
};

WI.isDebugUIEnabled = function()
{
    return WI.showDebugUISetting && WI.showDebugUISetting.value;
};

WI._undock = function(event)
{
    InspectorFrontendHost.requestSetDockSide(WI.DockConfiguration.Undocked);
};

WI._dockBottom = function(event)
{
    InspectorFrontendHost.requestSetDockSide(WI.DockConfiguration.Bottom);
};

WI._dockRight = function(event)
{
    InspectorFrontendHost.requestSetDockSide(WI.DockConfiguration.Right);
};

WI._dockLeft = function(event)
{
    InspectorFrontendHost.requestSetDockSide(WI.DockConfiguration.Left);
};

WI._togglePreviousDockConfiguration = function(event)
{
    InspectorFrontendHost.requestSetDockSide(WI._previousDockConfiguration);
};

WI._updateDockNavigationItems = function()
{
    if (WI._dockingAvailable || WI.docked) {
        WI._closeToolbarButton.hidden = !WI.docked;
        WI._undockToolbarButton.hidden = WI._dockConfiguration === WI.DockConfiguration.Undocked;
        WI._dockBottomToolbarButton.hidden = WI._dockConfiguration === WI.DockConfiguration.Bottom;
        WI._dockToSideToolbarButton.hidden = WI._dockConfiguration === WI.DockConfiguration.Right || WI._dockConfiguration === WI.DockConfiguration.Left;
    } else {
        WI._closeToolbarButton.hidden = true;
        WI._undockToolbarButton.hidden = true;
        WI._dockBottomToolbarButton.hidden = true;
        WI._dockToSideToolbarButton.hidden = true;
    }
};

WI._tabBrowserSizeDidChange = function()
{
    WI.tabBrowser.updateLayout(WI.View.LayoutReason.Resize);
    WI.consoleDrawer.updateLayout(WI.View.LayoutReason.Resize);
    WI.quickConsole.updateLayout(WI.View.LayoutReason.Resize);
};

WI._consoleDrawerCollapsedStateDidChange = function(event)
{
    WI._showingSplitConsoleSetting.value = WI.isShowingSplitConsole();

    WI._consoleDrawerDidResize();
};

WI._consoleDrawerDidResize = function(event)
{
    WI.tabBrowser.updateLayout(WI.View.LayoutReason.Resize);
};

WI._sidebarWidthDidChange = function(event)
{
    WI._tabBrowserSizeDidChange();
};

WI._setupViewHierarchy = function()
{
    let rootView = WI.View.rootView();
    rootView.addSubview(WI.toolbar);
    rootView.addSubview(WI.tabBar);
    rootView.addSubview(WI.navigationSidebar);
    rootView.addSubview(WI.tabBrowser);
    rootView.addSubview(WI.consoleDrawer);
    rootView.addSubview(WI.quickConsole);
    rootView.addSubview(WI.detailsSidebar);
};

WI._tabBrowserSelectedTabContentViewDidChange = function(event)
{
    if (WI.tabBar.selectedTabBarItem && WI.tabBar.selectedTabBarItem.representedObject.constructor.shouldSaveTab())
        WI._selectedTabIndexSetting.value = WI.tabBar.tabBarItems.indexOf(WI.tabBar.selectedTabBarItem);

    if (WI.doesCurrentTabSupportSplitContentBrowser()) {
        if (WI._shouldRevealSpitConsoleIfSupported) {
            WI._shouldRevealSpitConsoleIfSupported = false;
            WI.showSplitConsole();
        }
        return;
    }

    WI._shouldRevealSpitConsoleIfSupported = WI.isShowingSplitConsole();
    WI.hideSplitConsole();
};

WI._toolbarMouseDown = function(event)
{
    if (event.ctrlKey)
        return;

    if (WI._dockConfiguration === WI.DockConfiguration.Right || WI._dockConfiguration === WI.DockConfiguration.Left)
        return;

    if (WI.docked)
        WI._dockedResizerMouseDown(event);
    else
        WI._moveWindowMouseDown(event);
};

WI._dockedResizerMouseDown = function(event)
{
    if (event.button !== 0 || event.ctrlKey)
        return;

    if (!WI.docked)
        return;

    // Only start dragging if the target is one of the elements that we expect.
    if (event.target.id !== "docked-resizer" && !event.target.classList.contains("toolbar") &&
        !event.target.classList.contains("flexible-space") && !event.target.classList.contains("item-section"))
        return;

    event[WI.Popover.EventPreventDismissSymbol] = true;

    let windowProperty = WI._dockConfiguration === WI.DockConfiguration.Bottom ? "innerHeight" : "innerWidth";
    let eventScreenProperty = WI._dockConfiguration === WI.DockConfiguration.Bottom ? "screenY" : "screenX";
    let eventClientProperty = WI._dockConfiguration === WI.DockConfiguration.Bottom ? "clientY" : "clientX";

    var resizerElement = event.target;
    var firstClientPosition = event[eventClientProperty];
    var lastScreenPosition = event[eventScreenProperty];

    function dockedResizerDrag(event)
    {
        if (event.button !== 0)
            return;

        var position = event[eventScreenProperty];
        var delta = position - lastScreenPosition;
        var clientPosition = event[eventClientProperty];

        lastScreenPosition = position;

        if (WI._dockConfiguration === WI.DockConfiguration.Left) {
            // If the mouse is travelling rightward but is positioned left of the resizer, ignore the event.
            if (delta > 0 && clientPosition < firstClientPosition)
                return;

            // If the mouse is travelling leftward but is positioned to the right of the resizer, ignore the event.
            if (delta < 0 && clientPosition > window[windowProperty])
                return;

            // We later subtract the delta from the current position, but since the inspected view and inspector view
            // are flipped when docked to left, we want dragging to have the opposite effect from docked to right.
            delta *= -1;
        } else {
            // If the mouse is travelling downward/rightward but is positioned above/left of the resizer, ignore the event.
            if (delta > 0 && clientPosition < firstClientPosition)
                return;

            // If the mouse is travelling upward/leftward but is positioned below/right of the resizer, ignore the event.
            if (delta < 0 && clientPosition > firstClientPosition)
                return;
        }

        let dimension = Math.max(0, window[windowProperty] - delta);
        // If zoomed in/out, there be greater/fewer document pixels shown, but the inspector's
        // width or height should be the same in device pixels regardless of the document zoom.
        dimension *= WI.getZoomFactor();

        if (WI._dockConfiguration === WI.DockConfiguration.Bottom)
            InspectorFrontendHost.setAttachedWindowHeight(dimension);
        else
            InspectorFrontendHost.setAttachedWindowWidth(dimension);
    }

    function dockedResizerDragEnd(event)
    {
        if (event.button !== 0)
            return;

        WI.elementDragEnd(event);
    }

    WI.elementDragStart(resizerElement, dockedResizerDrag, dockedResizerDragEnd, event, WI._dockConfiguration === WI.DockConfiguration.Bottom ? "row-resize" : "col-resize");
};

WI._moveWindowMouseDown = function(event)
{
    console.assert(!WI.docked);

    if (event.button !== 0 || event.ctrlKey)
        return;

    // Only start dragging if the target is one of the elements that we expect.
    if (!event.target.classList.contains("toolbar") && !event.target.classList.contains("flexible-space") &&
        !event.target.classList.contains("item-section"))
        return;

    event[WI.Popover.EventPreventDismissSymbol] = true;

    if (WI.Platform.name === "mac") {
        InspectorFrontendHost.startWindowDrag();
        event.preventDefault();
        return;
    }

    var lastScreenX = event.screenX;
    var lastScreenY = event.screenY;

    function toolbarDrag(event)
    {
        if (event.button !== 0)
            return;

        var x = event.screenX - lastScreenX;
        var y = event.screenY - lastScreenY;

        InspectorFrontendHost.moveWindowBy(x, y);

        lastScreenX = event.screenX;
        lastScreenY = event.screenY;
    }

    function toolbarDragEnd(event)
    {
        if (event.button !== 0)
            return;

        WI.elementDragEnd(event);
    }

    WI.elementDragStart(event.target, toolbarDrag, toolbarDragEnd, event, "default");
};

WI._domStorageWasInspected = function(event)
{
    WI.showStorageTab();
    WI.showRepresentedObject(event.data.domStorage, null, {ignoreSearchTab: true});
};

WI._databaseWasInspected = function(event)
{
    WI.showStorageTab();
    WI.showRepresentedObject(event.data.database, null, {ignoreSearchTab: true});
};

WI._domNodeWasInspected = function(event)
{
    WI.domManager.highlightDOMNodeForTwoSeconds(event.data.node.id);

    InspectorFrontendHost.bringToFront();

    WI.showElementsTab();
    WI.showMainFrameDOMTree(event.data.node, {ignoreSearchTab: true});
};

WI._inspectModeStateChanged = function(event)
{
    WI._inspectModeToolbarButton.activated = WI.domManager.inspectModeEnabled;
};

WI._toggleInspectMode = function(event)
{
    WI.domManager.inspectModeEnabled = !WI.domManager.inspectModeEnabled;
};

WI._handleDeviceSettingsToolbarButtonClicked = function(event)
{
    if (WI._deviceSettingsPopover) {
        WI._deviceSettingsPopover.dismiss();
        WI._deviceSettingsPopover = null;
        return;
    }

    let target = WI.assumingMainTarget();

    function updateActivatedState() {
        WI._deviceSettingsToolbarButton.activated = WI._overridenDeviceUserAgent || WI._overridenDeviceSettings.size > 0;
    }

    function applyOverriddenUserAgent(value, force) {
        if (value === WI._overridenDeviceUserAgent)
            return;

        if (!force && (!value || value === "default")) {
            target.PageAgent.overrideUserAgent((error) => {
                if (error) {
                    console.error(error);
                    return;
                }

                WI._overridenDeviceUserAgent = null;
                updateActivatedState();
                target.PageAgent.reload();
            });
        } else {
            target.PageAgent.overrideUserAgent(value, (error) => {
                if (error) {
                    console.error(error);
                    return;
                }

                WI._overridenDeviceUserAgent = value;
                updateActivatedState();
                target.PageAgent.reload();
            });
        }
    }

    function applyOverriddenSetting(setting, value, callback) {
        if (WI._overridenDeviceSettings.has(setting)) {
            // We've just "disabled" the checkbox, so clear the override instead of applying it.
            target.PageAgent.overrideSetting(setting, (error) => {
                if (error) {
                    console.error(error);
                    return;
                }

                WI._overridenDeviceSettings.delete(setting);
                callback(false);
                updateActivatedState();
            });
        } else {
            target.PageAgent.overrideSetting(setting, value, (error) => {
                if (error) {
                    console.error(error);
                    return;
                }

                WI._overridenDeviceSettings.set(setting, value);
                callback(true);
                updateActivatedState();
            });
        }
    }

    function createCheckbox(container, label, setting, value) {
        if (!setting)
            return;

        let labelElement = container.appendChild(document.createElement("label"));

        let checkboxElement = labelElement.appendChild(document.createElement("input"));
        checkboxElement.type = "checkbox";
        checkboxElement.checked = WI._overridenDeviceSettings.has(setting);
        checkboxElement.addEventListener("change", (event) => {
            applyOverriddenSetting(setting, value, (enabled) => {
                checkboxElement.checked = enabled;
            });
        });

        labelElement.append(label);
    }

    function calculateTargetFrame() {
        return WI.Rect.rectFromClientRect(WI._deviceSettingsToolbarButton.element.getBoundingClientRect());
    }

    const preferredEdges = [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_X, WI.RectEdge.MAX_X];

    WI._deviceSettingsPopover = new WI.Popover(WI);
    WI._deviceSettingsPopover.windowResizeHandler = function(event) {
        WI._deviceSettingsPopover.present(calculateTargetFrame(), preferredEdges);
    };

    let contentElement = document.createElement("table");
    contentElement.classList.add("device-settings-content");

    let userAgentRow = contentElement.appendChild(document.createElement("tr"));

    let userAgentTitle = userAgentRow.appendChild(document.createElement("td"));
    userAgentTitle.textContent = WI.UIString("User Agent:");

    let userAgentValue = userAgentRow.appendChild(document.createElement("td"));
    userAgentValue.classList.add("user-agent");

    let userAgentValueSelect = userAgentValue.appendChild(document.createElement("select"));

    let userAgentValueInput = null;

    const userAgents = [
        [
            { name: WI.UIString("Default"), value: "default" },
        ],
        [
            { name: "Safari 13.0", value: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0 Safari/605.1.15" },
        ],
        [
            { name: `Safari ${emDash} iOS 12.1.3 ${emDash} iPhone`, value: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1" },
            { name: `Safari ${emDash} iOS 12.1.3 ${emDash} iPod touch`, value: "Mozilla/5.0 (iPod; CPU iPhone OS 12_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1" },
            { name: `Safari ${emDash} iOS 12.1.3 ${emDash} iPad`, value: "Mozilla/5.0 (iPad; CPU iPhone OS 12_1_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1" },
        ],
        [
            { name: `Microsoft Edge`, value: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 Edge/16.16299" },
        ],
        [
            { name: `Google Chrome ${emDash} macOS`, value: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" },
            { name: `Google Chrome ${emDash} Windows`, value: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36" },
        ],
        [
            { name: `Firefox ${emDash} macOS`, value: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:63.0) Gecko/20100101 Firefox/63.0" },
            { name: `Firefox ${emDash} Windows`, value: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0" },
        ],
        [
            { name: WI.UIString("Other\u2026"), value: "other" },
        ],
    ];

    let selectedOptionElement = null;

    for (let group of userAgents) {
        for (let {name, value} of group) {
            let optionElement = userAgentValueSelect.appendChild(document.createElement("option"));
            optionElement.value = value;
            optionElement.textContent = name;

            if (value === WI._overridenDeviceUserAgent)
                selectedOptionElement = optionElement;
        }

        if (group !== userAgents.lastValue)
            userAgentValueSelect.appendChild(document.createElement("hr"));
    }

    function showUserAgentInput() {
        if (userAgentValueInput)
            return;

        userAgentValueInput = userAgentValue.appendChild(document.createElement("input"));
        userAgentValueInput.value = userAgentValueInput.placeholder = WI._overridenDeviceUserAgent || navigator.userAgent;
        userAgentValueInput.addEventListener("click", (clickEvent) => {
            clickEvent.preventDefault();
        });
        userAgentValueInput.addEventListener("change", (inputEvent) => {
            applyOverriddenUserAgent(userAgentValueInput.value, true);
        });

        WI._deviceSettingsPopover.update();
    }

    if (selectedOptionElement)
        userAgentValueSelect.value = selectedOptionElement.value;
    else if (WI._overridenDeviceUserAgent) {
        userAgentValueSelect.value = "other";
        showUserAgentInput();
    }

    userAgentValueSelect.addEventListener("change", () => {
        let value = userAgentValueSelect.value;
        if (value === "other") {
            showUserAgentInput();
            userAgentValueInput.select();
        } else {
            if (userAgentValueInput) {
                userAgentValueInput.remove();
                userAgentValueInput = null;

                WI._deviceSettingsPopover.update();
            }

            applyOverriddenUserAgent(value);
        }
    });

    const settings = [
        {
            name: WI.UIString("Disable:"),
            columns: [
                [
                    {name: WI.UIString("Images"), setting: InspectorBackend.Enum.Page.Setting.ImagesEnabled, value: false},
                    {name: WI.UIString("Styles"), setting: InspectorBackend.Enum.Page.Setting.AuthorAndUserStylesEnabled, value: false},
                    {name: WI.UIString("JavaScript"), setting: InspectorBackend.Enum.Page.Setting.ScriptEnabled, value: false},
                ],
                [
                    {name: WI.UIString("Site-specific Hacks"), setting: InspectorBackend.Enum.Page.Setting.NeedsSiteSpecificQuirks, value: false},
                    {name: WI.UIString("Cross-Origin Restrictions"), setting: InspectorBackend.Enum.Page.Setting.WebSecurityEnabled, value: false},
                ]
            ],
        },
        {
            name: WI.UIString("%s:").format(WI.unlocalizedString("WebRTC")),
            columns: [
                [
                    {name: WI.UIString("Allow Media Capture on Insecure Sites"), setting: InspectorBackend.Enum.Page.Setting.MediaCaptureRequiresSecureConnection, value: false},
                    {name: WI.UIString("Disable ICE Candidate Restrictions"), setting: InspectorBackend.Enum.Page.Setting.ICECandidateFilteringEnabled, value: false},
                    {name: WI.UIString("Use Mock Capture Devices"), setting: InspectorBackend.Enum.Page.Setting.MockCaptureDevicesEnabled, value: true},
                    {name: WI.UIString("Disable Encryption"), setting: InspectorBackend.Enum.Page.Setting.WebRTCEncryptionEnabled, value: false},
                ],
            ],
        },
    ];

    for (let group of settings) {
        if (!group.columns.some((column) => column.some((item) => item.setting)))
            continue;

        let settingsGroupRow = contentElement.appendChild(document.createElement("tr"));

        let settingsGroupTitle = settingsGroupRow.appendChild(document.createElement("td"));
        settingsGroupTitle.textContent = group.name;

        let settingsGroupValue = settingsGroupRow.appendChild(document.createElement("td"));

        let settingsGroupItemContainer = settingsGroupValue.appendChild(document.createElement("div"));
        settingsGroupItemContainer.classList.add("container");

        for (let column of group.columns) {
            let columnElement = settingsGroupItemContainer.appendChild(document.createElement("div"));
            columnElement.classList.add("column");

            for (let item of column)
                createCheckbox(columnElement, item.name, item.setting, item.value);
        }
    }

    WI._deviceSettingsPopover.presentNewContentWithFrame(contentElement, calculateTargetFrame(), preferredEdges);
};

WI._downloadWebArchive = function(event)
{
    WI.archiveMainFrame();
};

WI._reloadInspectedInspector = function()
{
    const options = {};
    WI.runtimeManager.evaluateInInspectedWindow(`InspectorFrontendHost.reopen()`, options, function(){});
};

WI._reloadPage = function(event)
{
    let target = WI.assumingMainTarget();
    if (!target.hasDomain("Page"))
        return;

    event.preventDefault();

    if (InspectorFrontendHost.inspectionLevel() > 1) {
        WI._reloadInspectedInspector();
        return;
    }

    target.PageAgent.reload();
};

WI._reloadPageFromOrigin = function(event)
{
    let target = WI.assumingMainTarget();
    if (!target.hasDomain("Page"))
        return;

    event.preventDefault();

    if (InspectorFrontendHost.inspectionLevel() > 1) {
        WI._reloadInspectedInspector();
        return;
    }

    target.PageAgent.reload.invoke({ignoreCache: true});
};

WI._reloadToolbarButtonClicked = function(event)
{
    if (InspectorFrontendHost.inspectionLevel() > 1) {
        WI._reloadInspectedInspector();
        return;
    }

    // Reload page from origin if the button is clicked while the shift key is pressed down.
    let target = WI.assumingMainTarget();
    target.PageAgent.reload.invoke({ignoreCache: WI.modifierKeys.shiftKey});
};

WI._updateReloadToolbarButton = function()
{
    WI._reloadToolbarButton.hidden = !InspectorBackend.hasDomain("Page");
};

WI._updateDownloadToolbarButton = function()
{
    if (!InspectorBackend.hasDomain("Page")) {
        WI._downloadToolbarButton.hidden = true;
        return;
    }

    if (WI._downloadingPage) {
        WI._downloadToolbarButton.enabled = false;
        return;
    }

    WI._downloadToolbarButton.enabled = WI.canArchiveMainFrame();
};

WI._updateInspectModeToolbarButton = function()
{
    WI._inspectModeToolbarButton.hidden = !InspectorBackend.hasDomain("DOM");
};

WI._toggleInspectMode = function(event)
{
    WI.domManager.inspectModeEnabled = !WI.domManager.inspectModeEnabled;
};

WI._showConsoleTab = function(event)
{
    WI.showConsoleTab();
};

WI._focusConsolePrompt = function(event)
{
    WI.quickConsole.prompt.focus();
};

WI._focusedContentBrowser = function()
{
    if (WI.currentFocusElement) {
        let contentBrowserElement = WI.currentFocusElement.closest(".content-browser");
        if (contentBrowserElement && contentBrowserElement.__view && contentBrowserElement.__view instanceof WI.ContentBrowser)
            return contentBrowserElement.__view;
    }

    if (WI.tabBrowser.element.contains(WI.currentFocusElement) || document.activeElement === document.body) {
        let tabContentView = WI.tabBrowser.selectedTabContentView;
        if (tabContentView.contentBrowser)
            return tabContentView.contentBrowser;
        return null;
    }

    if (WI.consoleDrawer.element.contains(WI.currentFocusElement)
        || (WI.isShowingSplitConsole() && WI.quickConsole.element.contains(WI.currentFocusElement)))
        return WI.consoleDrawer;

    return null;
};

WI._focusedContentView = function()
{
    if (WI.tabBrowser.element.contains(WI.currentFocusElement) || document.activeElement === document.body) {
        var tabContentView = WI.tabBrowser.selectedTabContentView;
        if (tabContentView.contentBrowser)
            return tabContentView.contentBrowser.currentContentView;
        return tabContentView;
    }

    if (WI.consoleDrawer.element.contains(WI.currentFocusElement)
        || (WI.isShowingSplitConsole() && WI.quickConsole.element.contains(WI.currentFocusElement)))
        return WI.consoleDrawer.currentContentView;

    return null;
};

WI._focusedOrVisibleContentBrowser = function()
{
    let focusedContentBrowser = WI._focusedContentBrowser();
    if (focusedContentBrowser)
        return focusedContentBrowser;

    var tabContentView = WI.tabBrowser.selectedTabContentView;
    if (tabContentView.contentBrowser)
        return tabContentView.contentBrowser;

    return null;
};

WI.focusedOrVisibleContentView = function()
{
    let focusedContentView = WI._focusedContentView();
    if (focusedContentView)
        return focusedContentView;

    var tabContentView = WI.tabBrowser.selectedTabContentView;
    if (tabContentView.contentBrowser)
        return tabContentView.contentBrowser.currentContentView;
    return tabContentView;
};

WI._beforecopy = function(event)
{
    var selection = window.getSelection();

    // If there is no selection, see if the focused element or focused ContentView can handle the copy event.
    if (selection.isCollapsed && !WI.isEventTargetAnEditableField(event)) {
        var focusedCopyHandler = WI.currentFocusElement && WI.currentFocusElement.copyHandler;
        if (focusedCopyHandler && typeof focusedCopyHandler.handleBeforeCopyEvent === "function") {
            focusedCopyHandler.handleBeforeCopyEvent(event);
            if (event.defaultPrevented)
                return;
        }

        var focusedContentView = WI._focusedContentView();
        if (focusedContentView && typeof focusedContentView.handleCopyEvent === "function") {
            event.preventDefault();
            return;
        }

        return;
    }

    if (selection.isCollapsed)
        return;

    // Say we can handle it (by preventing default) to remove word break characters.
    event.preventDefault();
};

WI._find = function(event)
{
    let tabContentView = WI.tabBrowser.selectedTabContentView;
    if (tabContentView && tabContentView.canHandleFindEvent) {
        tabContentView.handleFindEvent(event);
        return;
    }

    let contentBrowser = WI._focusedOrVisibleContentBrowser();
    if (!contentBrowser)
        return;

    contentBrowser.showFindBanner();
};

WI._save = function(event)
{
    var contentView = WI.focusedOrVisibleContentView();
    if (!contentView || !contentView.supportsSave)
        return;

    WI.FileUtilities.save(contentView.saveData);
};

WI._saveAs = function(event)
{
    var contentView = WI.focusedOrVisibleContentView();
    if (!contentView || !contentView.supportsSave)
        return;

    WI.FileUtilities.save(contentView.saveData, true);
};

WI._clear = function(event)
{
    let contentView = WI.focusedOrVisibleContentView();
    if (!contentView || typeof contentView.handleClearShortcut !== "function") {
        // If the current content view is unable to handle WI event, clear the console to reset
        // the dashboard counters.
        WI.consoleManager.requestClearMessages();
        return;
    }

    contentView.handleClearShortcut(event);
};

WI._populateFind = function(event)
{
    let focusedContentView = WI._focusedContentView();
    if (!focusedContentView)
        return;

    if (focusedContentView.supportsCustomFindBanner) {
        focusedContentView.handlePopulateFindShortcut();
        return;
    }

    let contentBrowser = WI._focusedOrVisibleContentBrowser();
    if (!contentBrowser)
        return;

    contentBrowser.handlePopulateFindShortcut();
};

WI._findNext = function(event)
{
    let focusedContentView = WI._focusedContentView();
    if (!focusedContentView)
        return;

    if (focusedContentView.supportsCustomFindBanner) {
        focusedContentView.handleFindNextShortcut();
        return;
    }

    let contentBrowser = WI._focusedOrVisibleContentBrowser();
    if (!contentBrowser)
        return;

    contentBrowser.handleFindNextShortcut();
};

WI._findPrevious = function(event)
{
    let focusedContentView = WI._focusedContentView();
    if (!focusedContentView)
        return;

    if (focusedContentView.supportsCustomFindBanner) {
        focusedContentView.handleFindPreviousShortcut();
        return;
    }

    let contentBrowser = WI._focusedOrVisibleContentBrowser();
    if (!contentBrowser)
        return;

    contentBrowser.handleFindPreviousShortcut();
};

WI._copy = function(event)
{
    var selection = window.getSelection();

    // If there is no selection, pass the copy event on to the focused element or focused ContentView.
    if (selection.isCollapsed && !WI.isEventTargetAnEditableField(event)) {
        var focusedCopyHandler = WI.currentFocusElement && WI.currentFocusElement.copyHandler;
        if (focusedCopyHandler && typeof focusedCopyHandler.handleCopyEvent === "function") {
            focusedCopyHandler.handleCopyEvent(event);
            if (event.defaultPrevented)
                return;
        }

        var focusedContentView = WI._focusedContentView();
        if (focusedContentView && typeof focusedContentView.handleCopyEvent === "function") {
            focusedContentView.handleCopyEvent(event);
            return;
        }

        let tabContentView = WI.tabBrowser.selectedTabContentView;
        if (tabContentView && typeof tabContentView.handleCopyEvent === "function") {
            tabContentView.handleCopyEvent(event);
            return;
        }

        return;
    }

    if (selection.isCollapsed)
        return;

    // Remove word break characters from the selection before putting it on the pasteboard.
    var selectionString = selection.toString().removeWordBreakCharacters();
    event.clipboardData.setData("text/plain", selectionString);
    event.preventDefault();
};

WI._paste = function(event)
{
    if (event.defaultPrevented)
        return;

    let selection = window.getSelection();

    // If there is no selection, pass the paste event on to the focused element or focused ContentView.
    if (!selection.isCollapsed || WI.isEventTargetAnEditableField(event))
        return;

    let focusedPasteHandler = WI.currentFocusElement && WI.currentFocusElement.pasteHandler;
    if (focusedPasteHandler && focusedPasteHandler.handlePasteEvent) {
        focusedPasteHandler.handlePasteEvent(event);
        if (event.defaultPrevented)
            return;
    }

    let focusedContentView = WI._focusedContentView();
    if (focusedContentView && focusedContentView.handlePasteEvent) {
        focusedContentView.handlePasteEvent(event);
        return;
    }

    let tabContentView = WI.tabBrowser.selectedTabContentView;
    if (tabContentView && tabContentView.handlePasteEvent) {
        tabContentView.handlePasteEvent(event);
        return;
    }
};

WI._increaseZoom = function(event)
{
    const epsilon = 0.0001;
    const maximumZoom = 2.4;
    let currentZoom = WI.getZoomFactor();
    if (currentZoom + epsilon >= maximumZoom) {
        InspectorFrontendHost.beep();
        return;
    }

    WI.setZoomFactor(Math.min(maximumZoom, currentZoom + 0.2));
};

WI._decreaseZoom = function(event)
{
    const epsilon = 0.0001;
    const minimumZoom = 0.6;
    let currentZoom = WI.getZoomFactor();
    if (currentZoom - epsilon <= minimumZoom) {
        InspectorFrontendHost.beep();
        return;
    }

    WI.setZoomFactor(Math.max(minimumZoom, currentZoom - 0.2));
};

WI._resetZoom = function(event)
{
    WI.setZoomFactor(1);
};

WI.getZoomFactor = function()
{
    return WI.settings.zoomFactor.value;
};

WI.setZoomFactor = function(factor)
{
    InspectorFrontendHost.setZoomFactor(factor);
    // Round-trip through the frontend host API in case the requested factor is not used.
    WI.settings.zoomFactor.value = InspectorFrontendHost.zoomFactor();
};

WI.resolvedLayoutDirection = function()
{
    let layoutDirection = WI.settings.debugLayoutDirection.value;
    if (!WI.isDebugUIEnabled() || layoutDirection === WI.LayoutDirection.System)
        layoutDirection = InspectorFrontendHost.userInterfaceLayoutDirection();
    return layoutDirection;
};

WI.resolveLayoutDirectionForElement = function(element)
{
    let layoutDirection = WI.resolvedLayoutDirection();

    // Global LTR never includes RTL containers. Return early.
    if (layoutDirection === WI.LayoutDirection.LTR)
        return layoutDirection;

    let style = getComputedStyle(element);
    return style.direction;
};

WI.setLayoutDirection = function(value)
{
    console.assert(WI.isDebugUIEnabled());

    if (!Object.values(WI.LayoutDirection).includes(value))
        WI.reportInternalError("Unknown layout direction requested: " + value);

    if (value === WI.settings.debugLayoutDirection.value)
        return;

    WI.settings.debugLayoutDirection.value = value;

    if (WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL && WI._dockConfiguration === WI.DockConfiguration.Right)
        WI._dockLeft();

    if (WI.resolvedLayoutDirection() === WI.LayoutDirection.LTR && WI._dockConfiguration === WI.DockConfiguration.Left)
        WI._dockRight();

    InspectorFrontendHost.reopen();
};

WI._showTabAtIndex = function(i)
{
    if (i <= WI.tabBar.tabBarItems.length)
        WI.tabBar.selectedTabBarItem = i - 1;
};

WI._showJavaScriptTypeInformationSettingChanged = function(event)
{
    if (WI.settings.showJavaScriptTypeInformation.value) {
        for (let target of WI.targets)
            target.RuntimeAgent.enableTypeProfiler();
    } else {
        for (let target of WI.targets)
            target.RuntimeAgent.disableTypeProfiler();
    }
};

WI._enableControlFlowProfilerSettingChanged = function(event)
{
    if (WI.settings.enableControlFlowProfiler.value) {
        for (let target of WI.targets)
            target.RuntimeAgent.enableControlFlowProfiler();
    } else {
        for (let target of WI.targets)
            target.RuntimeAgent.disableControlFlowProfiler();
    }
};

WI._resourceCachingDisabledSettingChanged = function(event)
{
    for (let target of WI.targets)
        target.NetworkAgent.setResourceCachingDisabled(WI.settings.resourceCachingDisabled.value);
};

WI.measureElement = function(element)
{
    WI.layoutMeasurementContainer.appendChild(element.cloneNode(true));
    let rect = WI.layoutMeasurementContainer.getBoundingClientRect();
    WI.layoutMeasurementContainer.removeChildren();
    return rect;
};

WI.elementDragStart = function(element, dividerDrag, elementDragEnd, event, cursor, eventTarget)
{
    if (WI._elementDraggingEventListener || WI._elementEndDraggingEventListener)
        WI.elementDragEnd(event);

    if (element) {
        // Install glass pane
        if (WI._elementDraggingGlassPane)
            WI._elementDraggingGlassPane.remove();

        var glassPane = document.createElement("div");
        glassPane.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;opacity:0;z-index:1";
        glassPane.id = "glass-pane-for-drag";
        element.ownerDocument.body.appendChild(glassPane);
        WI._elementDraggingGlassPane = glassPane;
    }

    WI._elementDraggingEventListener = dividerDrag;
    WI._elementEndDraggingEventListener = elementDragEnd;

    var targetDocument = event.target.ownerDocument;

    WI._elementDraggingEventTarget = eventTarget || targetDocument;
    WI._elementDraggingEventTarget.addEventListener("mousemove", dividerDrag, true);
    WI._elementDraggingEventTarget.addEventListener("mouseup", elementDragEnd, true);

    targetDocument.body.style.cursor = cursor;

    event.preventDefault();
};

WI.elementDragEnd = function(event)
{
    WI._elementDraggingEventTarget.removeEventListener("mousemove", WI._elementDraggingEventListener, true);
    WI._elementDraggingEventTarget.removeEventListener("mouseup", WI._elementEndDraggingEventListener, true);

    event.target.ownerDocument.body.style.removeProperty("cursor");

    if (WI._elementDraggingGlassPane)
        WI._elementDraggingGlassPane.remove();

    delete WI._elementDraggingGlassPane;
    delete WI._elementDraggingEventTarget;
    delete WI._elementDraggingEventListener;
    delete WI._elementEndDraggingEventListener;

    event.preventDefault();
};

WI.createMessageTextView = function(message, isError)
{
    let messageElement = document.createElement("div");
    messageElement.className = "message-text-view";
    if (isError)
        messageElement.classList.add("error");

    let textElement = messageElement.appendChild(document.createElement("div"));
    textElement.className = "message";
    textElement.textContent = message;

    return messageElement;
};

WI.createNavigationItemHelp = function(formatString, navigationItem)
{
    console.assert(typeof formatString === "string");
    console.assert(navigationItem instanceof WI.NavigationItem);

    function append(a, b) {
        a.append(b);
        return a;
    }

    let containerElement = document.createElement("div");
    containerElement.className = "navigation-item-help";
    containerElement.__navigationItem = navigationItem;

    let wrapperElement = document.createElement("div");
    wrapperElement.className = "navigation-bar";
    wrapperElement.appendChild(navigationItem.element);

    String.format(formatString, [wrapperElement], String.standardFormatters, containerElement, append);
    return containerElement;
};

WI.createGoToArrowButton = function()
{
    var button = document.createElement("button");
    button.addEventListener("mousedown", (event) => { event.stopPropagation(); }, true);
    button.className = "go-to-arrow";
    button.tabIndex = -1;
    return button;
};

WI.createSourceCodeLocationLink = function(sourceCodeLocation, options = {})
{
    console.assert(sourceCodeLocation);
    if (!sourceCodeLocation)
        return null;

    var linkElement = document.createElement("a");
    linkElement.className = "go-to-link";
    WI.linkifyElement(linkElement, sourceCodeLocation, options);
    sourceCodeLocation.populateLiveDisplayLocationTooltip(linkElement);

    if (options.useGoToArrowButton)
        linkElement.appendChild(WI.createGoToArrowButton());
    else
        sourceCodeLocation.populateLiveDisplayLocationString(linkElement, "textContent", options.columnStyle, options.nameStyle, options.prefix);

    if (options.dontFloat)
        linkElement.classList.add("dont-float");

    return linkElement;
};

WI.linkifyLocation = function(url, sourceCodePosition, options = {})
{
    var sourceCode = WI.sourceCodeForURL(url);
    if (sourceCode)
        return WI.linkifySourceCode(sourceCode, sourceCodePosition, options);

    var anchor = document.createElement("a");
    anchor.href = url;
    anchor.lineNumber = sourceCodePosition.lineNumber;
    if (options.className)
        anchor.className = options.className;
    anchor.append(WI.displayNameForURL(url) + ":" + sourceCodePosition.lineNumber);
    return anchor;
};

WI.linkifySourceCode = function(sourceCode, sourceCodePosition, options = {})
{
    let sourceCodeLocation = sourceCode.createSourceCodeLocation(sourceCodePosition.lineNumber, sourceCodePosition.columnNumber);
    let linkElement = WI.createSourceCodeLocationLink(sourceCodeLocation, {
        ...options,
        dontFloat: true,
    });

    if (options.className)
        linkElement.classList.add(options.className);

    return linkElement;
};

WI.linkifyElement = function(linkElement, sourceCodeLocation, options = {}) {
    console.assert(sourceCodeLocation);

    function showSourceCodeLocation(event)
    {
        event.stopPropagation();
        event.preventDefault();

        if (event.metaKey)
            WI.showOriginalUnformattedSourceCodeLocation(sourceCodeLocation, options);
        else
            WI.showSourceCodeLocation(sourceCodeLocation, options);
    }

    linkElement.addEventListener("click", showSourceCodeLocation);
    linkElement.addEventListener("contextmenu", (event) => {
        let contextMenu = WI.ContextMenu.createFromEvent(event);
        WI.appendContextMenuItemsForSourceCode(contextMenu, sourceCodeLocation);
    });
};

WI.sourceCodeForURL = function(url)
{
    var sourceCode = WI.networkManager.resourceForURL(url);
    if (!sourceCode) {
        sourceCode = WI.debuggerManager.scriptsForURL(url, WI.assumingMainTarget())[0];
        if (sourceCode)
            sourceCode = sourceCode.resource || sourceCode;
    }
    return sourceCode || null;
};

WI.linkifyURLAsNode = function(url, linkText, className)
{
    let a = document.createElement("a");
    a.href = url;
    a.className = className || "";
    a.textContent = linkText || url;
    a.style.maxWidth = "100%";
    return a;
};

WI.linkifyStringAsFragmentWithCustomLinkifier = function(string, linkifier)
{
    var container = document.createDocumentFragment();
    var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@&#~]/;
    var lineColumnRegEx = /:(\d+)(:(\d+))?$/;

    while (string) {
        var linkString = linkStringRegEx.exec(string);
        if (!linkString)
            break;

        linkString = linkString[0];
        var linkIndex = string.indexOf(linkString);
        var nonLink = string.substring(0, linkIndex);
        container.append(nonLink);

        if (linkString.startsWith("data:") || linkString.startsWith("javascript:") || linkString.startsWith("mailto:")) {
            container.append(linkString);
            string = string.substring(linkIndex + linkString.length, string.length);
            continue;
        }

        var title = linkString;
        var realURL = linkString.startsWith("www.") ? "http://" + linkString : linkString;
        var lineColumnMatch = lineColumnRegEx.exec(realURL);
        if (lineColumnMatch)
            realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length);

        var lineNumber;
        if (lineColumnMatch)
            lineNumber = parseInt(lineColumnMatch[1]) - 1;

        var linkNode = linkifier(title, realURL, lineNumber);
        container.appendChild(linkNode);
        string = string.substring(linkIndex + linkString.length, string.length);
    }

    if (string)
        container.append(string);

    return container;
};

WI.linkifyStringAsFragment = function(string)
{
    function linkifier(title, url, lineNumber)
    {
        var urlNode = WI.linkifyURLAsNode(url, title, undefined);
        if (lineNumber !== undefined)
            urlNode.lineNumber = lineNumber;

        return urlNode;
    }

    return WI.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier);
};

WI.createResourceLink = function(resource, className)
{
    function handleClick(event)
    {
        event.stopPropagation();
        event.preventDefault();

        WI.showRepresentedObject(resource);
    }

    let linkNode = document.createElement("a");
    linkNode.classList.add("resource-link", className);
    linkNode.title = resource.url;
    linkNode.textContent = (resource.urlComponents.lastPathComponent || resource.url).insertWordBreakCharacters();
    linkNode.addEventListener("click", handleClick);
    return linkNode;
};

WI._undoKeyboardShortcut = function(event)
{
    if (!WI.isEditingAnyField() && !WI.isEventTargetAnEditableField(event)) {
        WI.undo();
        event.preventDefault();
    }
};

WI._redoKeyboardShortcut = function(event)
{
    if (!WI.isEditingAnyField() && !WI.isEventTargetAnEditableField(event)) {
        WI.redo();
        event.preventDefault();
    }
};

WI.undo = function()
{
    let target = WI.assumingMainTarget();
    target.DOMAgent.undo();
};

WI.redo = function()
{
    let target = WI.assumingMainTarget();
    target.DOMAgent.redo();
};

WI.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes)
{
    changes = changes || [];
    var highlightNodes = [];
    var lineText = element.textContent;
    var ownerDocument = element.ownerDocument;
    var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

    var snapshotLength = textNodeSnapshot.snapshotLength;
    if (snapshotLength === 0)
        return highlightNodes;

    var nodeRanges = [];
    var rangeEndOffset = 0;
    for (var i = 0; i < snapshotLength; ++i) {
        var range = {};
        range.offset = rangeEndOffset;
        range.length = textNodeSnapshot.snapshotItem(i).textContent.length;
        rangeEndOffset = range.offset + range.length;
        nodeRanges.push(range);
    }

    var startIndex = 0;
    for (var i = 0; i < resultRanges.length; ++i) {
        var startOffset = resultRanges[i].offset;
        var endOffset = startOffset + resultRanges[i].length;

        while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
            startIndex++;
        var endIndex = startIndex;
        while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
            endIndex++;
        if (endIndex === snapshotLength)
            break;

        var highlightNode = ownerDocument.createElement("span");
        highlightNode.className = styleClass;
        highlightNode.textContent = lineText.substring(startOffset, endOffset);

        var lastTextNode = textNodeSnapshot.snapshotItem(endIndex);
        var lastText = lastTextNode.textContent;
        lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
        changes.push({node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent});

        if (startIndex === endIndex) {
            lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
            changes.push({node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement});
            highlightNodes.push(highlightNode);

            var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
            lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
            changes.push({node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement});
        } else {
            var firstTextNode = textNodeSnapshot.snapshotItem(startIndex);
            var firstText = firstTextNode.textContent;
            var anchorElement = firstTextNode.nextSibling;

            firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
            changes.push({node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement});
            highlightNodes.push(highlightNode);

            firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
            changes.push({node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent});

            for (var j = startIndex + 1; j < endIndex; j++) {
                var textNode = textNodeSnapshot.snapshotItem(j);
                var text = textNode.textContent;
                textNode.textContent = "";
                changes.push({node: textNode, type: "changed", oldText: text, newText: textNode.textContent});
            }
        }
        startIndex = endIndex;
        nodeRanges[startIndex].offset = endOffset;
        nodeRanges[startIndex].length = lastTextNode.textContent.length;

    }
    return highlightNodes;
};

WI.revertDOMChanges = function(domChanges)
{
    for (var i = domChanges.length - 1; i >= 0; --i) {
        var entry = domChanges[i];
        switch (entry.type) {
        case "added":
            entry.node.remove();
            break;
        case "changed":
            entry.node.textContent = entry.oldText;
            break;
        }
    }
};

WI.archiveMainFrame = function()
{
    WI._downloadingPage = true;
    WI._updateDownloadToolbarButton();

    let target = WI.assumingMainTarget();
    target.PageAgent.archive((error, data) => {
        WI._downloadingPage = false;
        WI._updateDownloadToolbarButton();

        if (error)
            return;

        let mainFrame = WI.networkManager.mainFrame;
        let archiveName = mainFrame.mainResource.urlComponents.host || mainFrame.mainResource.displayName || "Archive";
        let url = WI.FileUtilities.inspectorURLForFilename(archiveName + ".webarchive");

        InspectorFrontendHost.save(url, data, true, true);
    });
};

WI.canArchiveMainFrame = function()
{
    if (!WI.sharedApp.isWebDebuggable())
        return false;

    if (!WI.networkManager.mainFrame || !WI.networkManager.mainFrame.mainResource)
        return false;

    return WI.Resource.typeFromMIMEType(WI.networkManager.mainFrame.mainResource.mimeType) === WI.Resource.Type.Document;
};

WI.addWindowKeydownListener = function(listener)
{
    if (typeof listener.handleKeydownEvent !== "function")
        return;

    WI._windowKeydownListeners.push(listener);

    WI._updateWindowKeydownListener();
};

WI.removeWindowKeydownListener = function(listener)
{
    WI._windowKeydownListeners.remove(listener);

    WI._updateWindowKeydownListener();
};

WI._updateWindowKeydownListener = function()
{
    if (WI._windowKeydownListeners.length === 1)
        window.addEventListener("keydown", WI._sharedWindowKeydownListener, true);
    else if (!WI._windowKeydownListeners.length)
        window.removeEventListener("keydown", WI._sharedWindowKeydownListener, true);
};

WI._sharedWindowKeydownListener = function(event)
{
    for (var i = WI._windowKeydownListeners.length - 1; i >= 0; --i) {
        if (WI._windowKeydownListeners[i].handleKeydownEvent(event)) {
            event.stopImmediatePropagation();
            event.preventDefault();
            break;
        }
    }
};

WI.reportInternalError = function(errorOrString, details = {})
{
    // The 'details' object includes additional information from the caller as free-form string keys and values.
    // Each key and value will be shown in the uncaught exception reporter, console error message, or in
    // a pre-filled bug report generated for this internal error.

    let error = errorOrString instanceof Error ? errorOrString : new Error(errorOrString);
    error.details = details;

    // The error will be displayed in the Uncaught Exception Reporter sheet if DebugUI is enabled.
    if (WI.isDebugUIEnabled()) {
        // This assert allows us to stop the debugger at an internal exception. It doesn't re-throw
        // exceptions because the original exception would be lost through window.onerror.
        // This workaround can be removed once <https://webkit.org/b/158192> is fixed.
        console.assert(false, "An internal exception was thrown.", error);
        handleInternalException(error);
    } else
        console.error(error);
};

// Many places assume the "main" target has resources.
// In the case where the main backend target is a MultiplexingBackendTarget
// that target has essentially nothing. In that case defer to the page
// target, since that is the real "main" target the frontend is assuming.
Object.defineProperty(WI, "mainTarget",
{
    get() { return WI.pageTarget || WI.backendTarget; }
});

// This list of targets are non-Multiplexing targets.
// So if there is a multiplexing target, and multiple sub-targets
// this is just the list of sub-targets. Almost no code expects
// to actually interact with the Multiplexing target.
Object.defineProperty(WI, "targets",
{
    get() { return WI.targetManager.targets; }
});

// Many places assume the main target because they cannot yet be
// used by reached by Worker debugging. Eventually, once all
// Worker domains have been implemented, all of these must be
// handled properly.
WI.assumingMainTarget = function()
{
    return WI.mainTarget;
};

WI.reset = async function()
{
    await WI.ObjectStore.reset();
    WI.Setting.reset();
    InspectorFrontendHost.reset();
};

WI.isEngineeringBuild = false;
WI.isExperimentalBuild = InspectorFrontendHost.isExperimentalBuild();

// OpenResourceDialog delegate

WI.dialogWasDismissedWithRepresentedObject = function(dialog, representedObject)
{
    if (!representedObject)
        return;

    WI.showRepresentedObject(representedObject, dialog.cookie, {
        ignoreSearchTab: true,
        ignoreNetworkTab: true,
    });
};

// Popover delegate

WI.didDismissPopover = function(popover)
{
    if (popover === WI._deviceSettingsPopover)
        WI._deviceSettingsPopover = null;
};

WI.DockConfiguration = {
    Right: "right",
    Left: "left",
    Bottom: "bottom",
    Undocked: "undocked",
};
