Changeset 240540 in webkit


Ignore:
Timestamp:
Jan 25, 2019 7:57:17 PM (5 years ago)
Author:
Devin Rousso
Message:

Web Inspector: provide a way to edit page settings on a remote target
https://bugs.webkit.org/show_bug.cgi?id=193813
<rdar://problem/47359510>

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

  • inspector/protocol/Page.json:

Add overrideSetting command with supporting Setting enum type.

Source/WebCore:

Test: inspector/page/overrideSetting.html

  • page/Settings.yaml:
  • Scripts/GenerateSettings.rb:
  • Scripts/SettingsTemplates/Settings.cpp.erb:
  • Scripts/SettingsTemplates/Settings.h.erb:

Add support for an inspectorOverride boolean value for each setting that will take
precedence over the actual Setting's value when set.

  • inspector/agents/InspectorPageAgent.h:
  • inspector/agents/InspectorPageAgent.cpp:

(WebCore::InspectorPageAgent::disable):
(WebCore::InspectorPageAgent::overrideSetting): Added.

  • inspector/InspectorFrontendHost.idl:
  • inspector/InspectorFrontendHost.h:
  • inspector/InspectorFrontendHost.cpp:

(WebCore::InspectorFrontendHost::isRemote const): Added.

  • inspector/InspectorFrontendClient.h:

(WebCore::InspectorFrontendClient::isRemote const): Added.

  • inspector/InspectorFrontendClientLocal.h:

(WebCore::InspectorFrontendClientLocal::isRemote const): Added.

Source/WebInspectorUI:

Add toolbar button that shows a popover with the target's (page's) settings when clicked.

  • UserInterface/Base/Main.js:

(WI.loaded):
(WI.contentLoaded):
(WI.initializeTarget): Added.
(WI._handleDeviceSettingsToolbarButtonClicked): Added.
(WI.didDismissPopover): Added.

  • UserInterface/Views/Main.css:

(.device-settings-content): Added.
(.device-settings-content .columns): Added.
(.device-settings-content .columns > .column): Added.
(.device-settings-content .columns > .column + .column): Added.
(body[dir=ltr] .device-settings-content label > input): Added.
(body[dir=rtl] .device-settings-content label > input): Added.

  • UserInterface/Views/Popover.js:

(WI.Popover.prototype._update.area):
(WI.Popover.prototype._update):
(WI.Popover.prototype._drawBackground):
(WI.Popover.prototype._bestMetricsForEdge):
(WI.Popover.prototype._drawFrame):
If the best area is negative, treat it as the worst area.
Allow areas to be clamped so long as the clamped edge is not the preferred edge.

  • UserInterface/Base/Test.js:

(WI.initializeTarget): Added.

  • UserInterface/Images/Device.svg: Added.
  • Localizations/en.lproj/localizedStrings.js:

Source/WebKit:

  • WebProcess/WebPage/WebInspectorUI.h:

(WebKit::WebInspectorUI::isRemote() const): Added.

  • WebProcess/WebPage/RemoteWebInspectorUI.h:

(WebKit::RemoteWebInspectorUI::isRemote() const): Added.

LayoutTests:

  • inspector/page/overrideSetting.html: Added.
  • inspector/page/overrideSetting-expected.txt: Added.
Location:
trunk
Files:
3 added
25 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r240537 r240540  
     12019-01-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: provide a way to edit page settings on a remote target
     4        https://bugs.webkit.org/show_bug.cgi?id=193813
     5        <rdar://problem/47359510>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/page/overrideSetting.html: Added.
     10        * inspector/page/overrideSetting-expected.txt: Added.
     11
    1122019-01-25  Jer Noble  <jer.noble@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r240525 r240540  
     12019-01-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: provide a way to edit page settings on a remote target
     4        https://bugs.webkit.org/show_bug.cgi?id=193813
     5        <rdar://problem/47359510>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * inspector/protocol/Page.json:
     10        Add `overrideSetting` command with supporting `Setting` enum type.
     11
    1122019-01-25  Keith Rollin  <krollin@apple.com>
    213
  • trunk/Source/JavaScriptCore/inspector/protocol/Page.json

    r238570 r240540  
    44    "availability": ["web"],
    55    "types": [
     6        {
     7            "id": "Setting",
     8            "type": "string",
     9            "description": "List of settings able to be overridden by WebInspector. Keep this in sync with FOR_EACH_INSPECTOR_OVERRIDE_SETTING.",
     10            "enum": [
     11                "AuthorAndUserStylesEnabled",
     12                "ImagesEnabled",
     13                "NeedsSiteSpecificQuirks",
     14                "ScriptEnabled",
     15                "WebSecurityEnabled"
     16            ]
     17        },
    618        {
    719            "id": "ResourceType",
     
    119131        },
    120132        {
     133            "name": "overrideSetting",
     134            "description": "Allows the frontend to override the inspected page's settings.",
     135            "parameters": [
     136                { "name": "setting", "$ref": "Setting" },
     137                { "name": "value", "type": "boolean", "optional": true, "description": "Value to override the setting with. If this value is not provided, the override is removed. Overrides are removed when Web Inspector closes/disconnects." }
     138            ]
     139        },
     140        {
    121141            "name": "getCookies",
    122142            "description": "Returns all browser cookies. Depending on the backend support, will return detailed cookie information in the <code>cookies</code> field.",
  • trunk/Source/WebCore/ChangeLog

    r240539 r240540  
     12019-01-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: provide a way to edit page settings on a remote target
     4        https://bugs.webkit.org/show_bug.cgi?id=193813
     5        <rdar://problem/47359510>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        Test: inspector/page/overrideSetting.html
     10
     11        * page/Settings.yaml:
     12        * Scripts/GenerateSettings.rb:
     13        * Scripts/SettingsTemplates/Settings.cpp.erb:
     14        * Scripts/SettingsTemplates/Settings.h.erb:
     15        Add support for an `inspectorOverride` boolean value for each setting that will take
     16        precedence over the actual `Setting`'s value when set.
     17
     18        * inspector/agents/InspectorPageAgent.h:
     19        * inspector/agents/InspectorPageAgent.cpp:
     20        (WebCore::InspectorPageAgent::disable):
     21        (WebCore::InspectorPageAgent::overrideSetting): Added.
     22
     23        * inspector/InspectorFrontendHost.idl:
     24        * inspector/InspectorFrontendHost.h:
     25        * inspector/InspectorFrontendHost.cpp:
     26        (WebCore::InspectorFrontendHost::isRemote const): Added.
     27        * inspector/InspectorFrontendClient.h:
     28        (WebCore::InspectorFrontendClient::isRemote const): Added.
     29        * inspector/InspectorFrontendClientLocal.h:
     30        (WebCore::InspectorFrontendClientLocal::isRemote const): Added.
     31
    1322019-01-25  Wenson Hsieh  <wenson_hsieh@apple.com>
    233
  • trunk/Source/WebCore/Scripts/GenerateSettings.rb

    r223828 r240540  
    6969  attr_accessor :onChange
    7070  attr_accessor :getter
     71  attr_accessor :inspectorOverride
    7172 
    7273  def initialize(name, opts)
     
    7778    @onChange = opts["onChange"]
    7879    @getter = opts["getter"]
     80    @inspectorOverride = opts["inspectorOverride"]
    7981  end
    8082
     
    114116  end
    115117
     118  def hasComplexGetter?
     119    hasInspectorOverride?
     120  end
     121
    116122  def setterFunctionName
    117123    if @name.start_with?("css", "xss", "ftp", "dom", "dns")
     
    125131    @getter || @name
    126132  end
     133
     134  def hasInspectorOverride?
     135    @inspectorOverride == true
     136  end
    127137end
    128138
     
    132142  attr_accessor :boolSettings
    133143  attr_accessor :nonBoolSettings
     144  attr_accessor :settingsWithComplexGetters
    134145  attr_accessor :settingsWithComplexSetters
    135146
     
    140151    @boolSettings = @settings.select { |setting| setting.type == "bool" }
    141152    @nonBoolSettings = @settings.reject { |setting| setting.type == "bool" }
     153    @settingsWithComplexGetters = @settings.select { |setting| setting.hasComplexGetter? }
    142154    @settingsWithComplexSetters = @settings.select { |setting| setting.hasComplexSetter? }
    143155  end
     
    149161  attr_accessor :unconditionalBoolSetting
    150162  attr_accessor :unconditionalNonBoolSetting
     163  attr_accessor :unconditionalSettingWithComplexGetters
    151164  attr_accessor :unconditionalSettingWithComplexSetters
    152165  attr_accessor :conditionals
     
    162175    @unconditionalBoolSetting = @unconditionalSetting.select { |setting| setting.type == "bool" }
    163176    @unconditionalNonBoolSetting = @unconditionalSetting.reject { |setting| setting.type == "bool" }
     177    @unconditionalSettingWithComplexGetters = @unconditionalSetting.select { |setting| setting.hasComplexGetter? }
    164178    @unconditionalSettingWithComplexSetters = @unconditionalSetting.select { |setting| setting.hasComplexSetter? }
     179    @inspectorOverrideSettings = @settings.select { |setting| setting.hasInspectorOverride? }
    165180
    166181    @conditionals = []
  • trunk/Source/WebCore/Scripts/SettingsTemplates/Settings.cpp.erb

    r223828 r240540  
    7272}
    7373
     74<%- for @setting in @unconditionalSettingWithComplexGetters do -%>
     75<%= @setting.parameterType %> Settings::<%= @setting.getterFunctionName %>() const
     76{
     77<%- if @setting.hasInspectorOverride? -%>
     78    if (m_<%= @setting.name %>InspectorOverride)
     79        return m_<%= @setting.name %>InspectorOverride.value();
     80<%- end -%>
     81    return m_<%= @setting.name %>;
     82}
     83
     84<%- end -%>
    7485<%- for @setting in @unconditionalSettingWithComplexSetters do -%>
    7586void Settings::<%= @setting.setterFunctionName %>(<%= @setting.parameterType %> <%= @setting.name %>)
     
    8394<%- end -%>
    8495<%- for @conditional in @conditionals do -%>
    85 <%- if @conditional.settingsWithComplexSetters.length != 0 -%>
     96<%- if @conditional.settingsWithComplexGetters.length != 0 or @conditional.settingsWithComplexSetters.length != 0-%>
    8697#if ENABLE(<%= @conditional.condition %>)
     98<%- for @setting in @conditional.settingsWithComplexGetters do -%>
     99<%= @setting.parameterType %> Settings::<%= @setting.getterFunctionName %>() const
     100{
     101<%- if @setting.hasInspectorOverride? -%>
     102    if (m_<%= @setting.name %>InspectorOverride)
     103        return m_<%= @setting.name %>InspectorOverride.value();
     104<%- end -%>
     105    return m_<%= @setting.name %>;
     106}
     107<%- end -%>
    87108<%- for @setting in @conditional.settingsWithComplexSetters -%>
    88109void Settings::<%= @setting.setterFunctionName %>(<%= @setting.parameterType %> <%= @setting.name %>)
     
    98119<%- end -%>
    99120<%- end -%>
     121<%- for @setting in @inspectorOverrideSettings do -%>
     122<%- if @setting.hasComplexSetter? -%>
     123void Settings::<%= @setting.setterFunctionName %>InspectorOverride(Optional<<%= @setting.parameterType %>> <%= @setting.name %>InspectorOverride)
     124{
     125    if (m_<%= @setting.name %>InspectorOverride == <%= @setting.name %>InspectorOverride)
     126        return;
     127    m_<%= @setting.name %>InspectorOverride = <%= @setting.name %>InspectorOverride;
     128    <%= @setting.onChange %>();
    100129}
     130
     131<%- end -%>
     132<%- end -%>
     133}
  • trunk/Source/WebCore/Scripts/SettingsTemplates/Settings.h.erb

    r223828 r240540  
    4242
    4343<%- for @setting in @unconditionalSetting do -%>
     44    <%- if @setting.hasComplexGetter? -%>
     45    WEBCORE_EXPORT <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const;
     46    <%- else -%>
    4447    <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const { return m_<%= @setting.name %>; }
     48    <%- end -%>
    4549    <%- if @setting.hasComplexSetter? -%>
    4650    WEBCORE_EXPORT void <%= @setting.setterFunctionName %>(<%= @setting.parameterType %>);
     
    5357#if ENABLE(<%= @conditional.condition %>)
    5458<%- for @setting in @conditional.settings do -%>
     59    <%- if @setting.hasComplexGetter? -%>
     60    WEBCORE_EXPORT <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const;
     61    <%- else -%>
    5562    <%= @setting.parameterType %> <%= @setting.getterFunctionName %>() const { return m_<%= @setting.name %>; }
     63    <%- end -%>
    5664    <%- if @setting.hasComplexSetter? -%>
    5765    WEBCORE_EXPORT void <%= @setting.setterFunctionName %>(<%= @setting.parameterType %>);
     
    6371
    6472<%- end -%>
     73<%- for @setting in @inspectorOverrideSettings do -%>
     74    <%- if @setting.hasComplexSetter? -%>
     75    WEBCORE_EXPORT void <%= @setting.setterFunctionName %>InspectorOverride(Optional<<%= @setting.parameterType %>>);
     76    <%- else -%>
     77    void <%= @setting.setterFunctionName %>InspectorOverride(Optional<<%= @setting.parameterType %>> <%= @setting.name %>InspectorOverride) { m_<%= @setting.name %>InspectorOverride = <%= @setting.name %>InspectorOverride; }
     78    <%- end -%>
     79<%- end -%>
    6580
    6681private:
    6782    explicit Settings(Page*);
     83
     84<%- for @setting in @inspectorOverrideSettings do -%>
     85    Optional<<%= @setting.type %>> m_<%= @setting.name %>InspectorOverride;
     86<%- end -%>
    6887
    6988<%- for @setting in @unconditionalNonBoolSetting do -%>
  • trunk/Source/WebCore/inspector/InspectorFrontendClient.h

    r238378 r240540  
    5555    virtual void moveWindowBy(float x, float y) = 0;
    5656
     57    virtual bool isRemote() const = 0;
    5758    virtual String localizedStringsURL() = 0;
    5859    virtual unsigned inspectionLevel() const = 0;
  • trunk/Source/WebCore/inspector/InspectorFrontendClientLocal.h

    r225263 r240540  
    8282
    8383    WEBCORE_EXPORT bool isUnderTest() final;
     84    bool isRemote() const final { return false; }
    8485    WEBCORE_EXPORT unsigned inspectionLevel() const final;
    8586
  • trunk/Source/WebCore/inspector/InspectorFrontendHost.cpp

    r239779 r240540  
    255255}
    256256
     257bool InspectorFrontendHost::isRemote() const
     258{
     259    return m_client ? m_client->isRemote() : false;
     260}
     261
    257262String InspectorFrontendHost::localizedStringsURL()
    258263{
  • trunk/Source/WebCore/inspector/InspectorFrontendHost.h

    r239779 r240540  
    7676    void moveWindowBy(float x, float y) const;
    7777
     78    bool isRemote() const;
    7879    String localizedStringsURL();
    7980    String backendCommandsURL();
  • trunk/Source/WebCore/inspector/InspectorFrontendHost.idl

    r239779 r240540  
    5757    void moveWindowBy(unrestricted float x, unrestricted float y);
    5858
     59    readonly attribute boolean isRemote;
    5960    DOMString localizedStringsURL();
    6061    DOMString backendCommandsURL();
  • trunk/Source/WebCore/inspector/agents/InspectorPageAgent.cpp

    r240014 r240540  
    8484using namespace Inspector;
    8585
     86#define FOR_EACH_INSPECTOR_OVERRIDE_SETTING(macro) \
     87    macro(AuthorAndUserStylesEnabled) \
     88    macro(ImagesEnabled) \
     89    macro(NeedsSiteSpecificQuirks) \
     90    macro(ScriptEnabled) \
     91    macro(WebSecurityEnabled)
     92
    8693static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
    8794{
     
    316323    setEmulatedMedia(unused, emptyString());
    317324    setForcedAppearance(unused, emptyString());
     325
     326#define DISABLE_INSPECTOR_OVERRIDE_SETTING(name) \
     327    m_page.settings().set##name##InspectorOverride(WTF::nullopt);
     328
     329    FOR_EACH_INSPECTOR_OVERRIDE_SETTING(DISABLE_INSPECTOR_OVERRIDE_SETTING)
     330
     331#undef DISABLE_INSPECTOR_OVERRIDE_SETTING
    318332}
    319333
     
    340354    FrameLoadRequest frameLoadRequest { *frame.document(), frame.document()->securityOrigin(), resourceRequest, "_self"_s, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::No, NewFrameOpenerPolicy::Allow, ShouldOpenExternalURLsPolicy::ShouldNotAllow, InitiatedByMainFrame::Unknown };
    341355    frame.loader().changeLocation(WTFMove(frameLoadRequest));
     356}
     357
     358void InspectorPageAgent::overrideSetting(ErrorString& errorString, const String& settingString, const bool* value)
     359{
     360    if (settingString.isEmpty()) {
     361        errorString = "Preference is empty"_s;
     362        return;
     363    }
     364
     365    auto setting = Inspector::Protocol::InspectorHelpers::parseEnumValueFromString<Inspector::Protocol::Page::Setting>(settingString);
     366    if (!setting) {
     367        errorString = makeString("Unknown setting: "_s, settingString);
     368        return;
     369    }
     370
     371    switch (setting.value()) {
     372#define CASE_INSPECTOR_OVERRIDE_SETTING(name) \
     373    case Inspector::Protocol::Page::Setting::name: { \
     374        if (value) \
     375            m_page.settings().set##name##InspectorOverride(*value); \
     376        else \
     377            m_page.settings().set##name##InspectorOverride(WTF::nullopt); \
     378        return; \
     379    } \
     380
     381    FOR_EACH_INSPECTOR_OVERRIDE_SETTING(CASE_INSPECTOR_OVERRIDE_SETTING)
     382
     383#undef CASE_INSPECTOR_OVERRIDE_SETTING
     384    }
     385
     386    ASSERT_NOT_REACHED();
    342387}
    343388
  • trunk/Source/WebCore/inspector/agents/InspectorPageAgent.h

    r238771 r240540  
    9191    void reload(ErrorString&, const bool* optionalReloadFromOrigin, const bool* optionalRevalidateAllResources) final;
    9292    void navigate(ErrorString&, const String& url) final;
     93    void overrideSetting(ErrorString&, const String& setting, const bool* value) final;
    9394    void getCookies(ErrorString&, RefPtr<JSON::ArrayOf<Inspector::Protocol::Page::Cookie>>& cookies) final;
    9495    void deleteCookie(ErrorString&, const String& cookieName, const String& url) final;
  • trunk/Source/WebCore/page/Settings.yaml

    r240444 r240540  
    129129  initial: true
    130130  onChange: setNeedsRecalcStyleInAllFrames
     131  inspectorOverride: true
    131132userStyleSheetLocation:
    132133  type: URL
     
    180181needsSiteSpecificQuirks:
    181182  initial: false
     183  inspectorOverride: true
    182184domTimersThrottlingEnabled:
    183185  initial: true
     
    386388webSecurityEnabled:
    387389  initial: true
     390  inspectorOverride: true
    388391spatialNavigationEnabled:
    389392  initial: false
     
    670673  getter: areImagesEnabled
    671674  onChange: imagesEnabledChanged
     675  inspectorOverride: true
    672676scriptEnabled:
    673677  initial: false
    674678  getter: isScriptEnabled
     679  inspectorOverride: true
    675680pluginsEnabled:
    676681  initial: false
  • trunk/Source/WebInspectorUI/ChangeLog

    r240538 r240540  
     12019-01-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: provide a way to edit page settings on a remote target
     4        https://bugs.webkit.org/show_bug.cgi?id=193813
     5        <rdar://problem/47359510>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        Add toolbar button that shows a popover with the target's (page's) settings when clicked.
     10
     11        * UserInterface/Base/Main.js:
     12        (WI.loaded):
     13        (WI.contentLoaded):
     14        (WI.initializeTarget): Added.
     15        (WI._handleDeviceSettingsToolbarButtonClicked): Added.
     16        (WI.didDismissPopover): Added.
     17        * UserInterface/Views/Main.css:
     18        (.device-settings-content): Added.
     19        (.device-settings-content .columns): Added.
     20        (.device-settings-content .columns > .column): Added.
     21        (.device-settings-content .columns > .column + .column): Added.
     22        (body[dir=ltr] .device-settings-content label > input): Added.
     23        (body[dir=rtl] .device-settings-content label > input): Added.
     24
     25        * UserInterface/Views/Popover.js:
     26        (WI.Popover.prototype._update.area):
     27        (WI.Popover.prototype._update):
     28        (WI.Popover.prototype._drawBackground):
     29        (WI.Popover.prototype._bestMetricsForEdge):
     30        (WI.Popover.prototype._drawFrame):
     31        If the best area is negative, treat it as the worst area.
     32        Allow areas to be clamped so long as the clamped edge is not the preferred edge.
     33
     34        * UserInterface/Base/Test.js:
     35        (WI.initializeTarget): Added.
     36
     37        * UserInterface/Images/Device.svg: Added.
     38        * Localizations/en.lproj/localizedStrings.js:
     39
    1402019-01-25  Devin Rousso  <drousso@apple.com>
    241
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r240502 r240540  
    265265localizedStrings["Create Breakpoint"] = "Create Breakpoint";
    266266localizedStrings["Create a new tab"] = "Create a new tab";
     267localizedStrings["Cross-Origin Restrictions"] = "Cross-Origin Restrictions";
    267268localizedStrings["Current"] = "Current";
    268269localizedStrings["Current State"] = "Current State";
     
    296297localizedStrings["Detached"] = "Detached";
    297298localizedStrings["Details"] = "Details";
     299localizedStrings["Device Settings"] = "Device Settings";
    298300localizedStrings["Dimensions"] = "Dimensions";
    299301localizedStrings["Disable Breakpoint"] = "Disable Breakpoint";
     
    303305localizedStrings["Disable all breakpoints (%s)"] = "Disable all breakpoints (%s)";
    304306localizedStrings["Disable paint flashing"] = "Disable paint flashing";
     307localizedStrings["Disable:"] = "Disable:";
    305308localizedStrings["Disabled"] = "Disabled";
    306309localizedStrings["Disk Cache"] = "Disk Cache";
     
    874877localizedStrings["Show:"] = "Show:";
    875878localizedStrings["Showing:"] = "Showing:";
     879localizedStrings["Site-specific Hacks"] = "Site-specific Hacks";
    876880localizedStrings["Size"] = "Size";
    877881localizedStrings["Size of current object plus all objects it keeps alive"] = "Size of current object plus all objects it keeps alive";
  • trunk/Source/WebInspectorUI/UserInterface/Base/Main.js

    r240502 r240540  
    162162    this._windowKeydownListeners = [];
    163163    this._targetsAvailablePromise = new WI.WrappedPromise;
     164    this._overridenDeviceSettings = new Set;
    164165
    165166    // Targets.
     
    446447    this._inspectModeToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._toggleInspectMode, this);
    447448
     449    // COMPATIBILITY (iOS 12.2): Page.overrideSetting did not exist.
     450    if (InspectorFrontendHost.isRemote && WI.sharedApp.debuggableType === WI.DebuggableType.Web && InspectorBackend.domains.Page && InspectorBackend.domains.Page.overrideSetting) {
     451        const deviceSettingsTooltip = WI.UIString("Device Settings");
     452        this._deviceSettingsToolbarButton = new WI.ActivateButtonToolbarItem("device-settings", deviceSettingsTooltip, deviceSettingsTooltip, "Images/Device.svg");
     453        this._deviceSettingsToolbarButton.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._handleDeviceSettingsToolbarButtonClicked, this);
     454
     455        this._deviceSettingsPopover = null;
     456    }
     457
    448458    this._updateReloadToolbarButton();
    449459    this._updateDownloadToolbarButton();
     
    470480
    471481    this.toolbar.addToolbarItem(this._inspectModeToolbarButton, WI.Toolbar.Section.CenterRight);
     482
     483    if (this._deviceSettingsToolbarButton)
     484        this.toolbar.addToolbarItem(this._deviceSettingsToolbarButton, WI.Toolbar.Section.CenterRight);
    472485
    473486    this._searchTabContentView = new WI.SearchTabContentView;
     
    590603};
    591604
     605WI.initializeTarget = function(target)
     606{
     607    if (target.PageAgent) {
     608        // COMPATIBILITY (iOS 12.2): Page.overrideSetting did not exist.
     609        if (target.PageAgent.overrideSetting) {
     610            for (let setting of this._overridenDeviceSettings)
     611                target.PageAgent.overrideSetting(setting, true);
     612        }
     613
     614        // COMPATIBILITY (iOS 8): Page.setShowPaintRects did not exist.
     615        if (target.PageAgent.setShowPaintRects && WI.settings.showPaintRects.value)
     616            target.PageAgent.setShowPaintRects(true);
     617    }
     618};
     619
    592620WI.whenTargetsAvailable = function()
    593621{
     
    19171945};
    19181946
     1947WI._handleDeviceSettingsToolbarButtonClicked = function(event)
     1948{
     1949    if (WI._deviceSettingsPopover) {
     1950        WI._deviceSettingsPopover.dismiss();
     1951        WI._deviceSettingsPopover = null;
     1952        return;
     1953    }
     1954
     1955    let updateActivatedState = () => {
     1956        this._deviceSettingsToolbarButton.activated = this._overridenDeviceSettings.size > 0;
     1957    };
     1958
     1959    let createContainer = (parent, title) => {
     1960        let container = parent.appendChild(document.createElement("div"));
     1961        container.classList.add("container");
     1962
     1963        if (title) {
     1964            let titleElement = container.appendChild(document.createElement("div"));
     1965            titleElement.textContent = title;
     1966        }
     1967
     1968        return container;
     1969    };
     1970
     1971    let createColumns = (parent, count) => {
     1972        let columnContainer = parent.appendChild(document.createElement("div"));
     1973        columnContainer.classList.add("columns");
     1974
     1975        let columns = [];
     1976        for (let i = 0; i < count; ++i) {
     1977            let column = columnContainer.appendChild(document.createElement("div"));
     1978            column.classList.add("column");
     1979            columns.push(column);
     1980        }
     1981        return columns;
     1982    };
     1983
     1984    let createCheckbox = (container, label, setting) => {
     1985        let enabled = this._overridenDeviceSettings.has(setting);
     1986
     1987        let labelElement = container.appendChild(document.createElement("label"));
     1988
     1989        let checkboxElement = labelElement.appendChild(document.createElement("input"));
     1990        checkboxElement.type = "checkbox";
     1991        checkboxElement.checked = enabled;
     1992        checkboxElement.addEventListener("change", (event) => {
     1993            if (enabled) {
     1994                // We've just "disabled" the checkbox, so clear the override instead of applying it.
     1995                PageAgent.overrideSetting(setting, (error) => {
     1996                    if (error) {
     1997                        console.error(error);
     1998                        return;
     1999                    }
     2000
     2001                    this._overridenDeviceSettings.delete(setting);
     2002                    enabled = checkboxElement.checked = false;
     2003                    updateActivatedState();
     2004                });
     2005               
     2006            } else {
     2007                // Override to false since the labels are the inverse of the setting.
     2008                const value = false;
     2009                PageAgent.overrideSetting(setting, value, (error) => {
     2010                    if (error) {
     2011                        console.error(error);
     2012                        return;
     2013                    }
     2014
     2015                    this._overridenDeviceSettings.add(setting);
     2016                    enabled = checkboxElement.checked = true;
     2017                    updateActivatedState();
     2018                });
     2019            }
     2020        });
     2021
     2022        labelElement.append(label);
     2023    };
     2024
     2025    let calculateTargetFrame = () => {
     2026        return WI.Rect.rectFromClientRect(this._deviceSettingsToolbarButton.element.getBoundingClientRect());
     2027    };
     2028
     2029    const preferredEdges = [WI.RectEdge.MAX_Y, WI.RectEdge.MIN_X, WI.RectEdge.MAX_X];
     2030
     2031    WI._deviceSettingsPopover = new WI.Popover(this);
     2032    WI._deviceSettingsPopover.windowResizeHandler = function(event) {
     2033        WI._deviceSettingsPopover.present(calculateTargetFrame(), preferredEdges);
     2034    };
     2035
     2036    let contentElement = document.createElement("div");
     2037    contentElement.classList.add("device-settings-content");
     2038
     2039    let disableColumns = createColumns(createContainer(contentElement, WI.UIString("Disable:")), 2);
     2040    createCheckbox(disableColumns[0], WI.UIString("Images"), PageAgent.Setting.ImagesEnabled);
     2041    createCheckbox(disableColumns[0], WI.UIString("Styles"), PageAgent.Setting.AuthorAndUserStylesEnabled);
     2042    createCheckbox(disableColumns[0], WI.UIString("JavaScript"), PageAgent.Setting.ScriptEnabled);
     2043    createCheckbox(disableColumns[1], WI.UIString("Site-specific Hacks"), PageAgent.Setting.NeedsSiteSpecificQuirks);
     2044    createCheckbox(disableColumns[1], WI.UIString("Cross-Origin Restrictions"), PageAgent.Setting.WebSecurityEnabled);
     2045
     2046    WI._deviceSettingsPopover.presentNewContentWithFrame(contentElement, calculateTargetFrame(), preferredEdges);
     2047};
     2048
    19192049WI._downloadWebArchive = function(event)
    19202050{
     
    28282958};
    28292959
     2960// Popover delegate
     2961
     2962WI.didDismissPopover = function(popover)
     2963{
     2964    if (popover === WI._deviceSettingsPopover)
     2965        WI._deviceSettingsPopover = null;
     2966};
     2967
    28302968WI.DockConfiguration = {
    28312969    Right: "right",
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/Target.js

    r240457 r240540  
    7474
    7575        // Non-manager specific initialization.
    76         // COMPATIBILITY (iOS 8): Page.setShowPaintRects did not exist.
    77         if (this.PageAgent) {
    78             if (this.PageAgent.setShowPaintRects && WI.settings.showPaintRects.value)
    79                 this.PageAgent.setShowPaintRects(true);
    80         }
     76        WI.initializeTarget(this);
    8177
    8278        // Intentionally defer ConsoleAgent initialization to the end. We do this so that any
  • trunk/Source/WebInspectorUI/UserInterface/Test/Test.js

    r240457 r240540  
    152152};
    153153
     154WI.initializeTarget = function(target)
     155{
     156};
     157
    154158Object.defineProperty(WI, "mainTarget",
    155159{
  • trunk/Source/WebInspectorUI/UserInterface/Views/Main.css

    r239760 r240540  
    388388}
    389389
     390.device-settings-content {
     391    padding: 8px;
     392
     393    --label-input-margin-after: 4px;
     394}
     395
     396.device-settings-content .columns {
     397    display: flex;
     398}
     399
     400.device-settings-content .columns > .column {
     401    display: flex;
     402    flex-direction: column;
     403}
     404
     405.device-settings-content .columns > .column + .column {
     406    -webkit-margin-start: 20px;
     407}
     408
     409body[dir=ltr] .device-settings-content label > input {
     410    margin-right: var(--label-input-margin-after);
     411}
     412
     413body[dir=rtl] .device-settings-content label > input {
     414    margin-left: var(--label-input-margin-after);
     415}
     416
    390417@media (prefers-color-scheme: dark) {
    391418    .go-to-arrow {
  • trunk/Source/WebInspectorUI/UserInterface/Views/Popover.js

    r237883 r240540  
    256256        function area(size)
    257257        {
    258             return size.width * size.height;
     258            return Math.max(0, size.width) * Math.max(0, size.height);
    259259        }
    260260
     
    269269            }
    270270        }
     271
     272        console.assert(area(bestMetrics.contentSize) > 0);
    271273
    272274        var anchorPoint;
     
    401403        // of the content contained within the frame.
    402404        let bounds;
    403         let arrowHeight = WI.Popover.AnchorSize.height;
    404405        switch (this._edge) {
    405406        case WI.RectEdge.MIN_X: // Displayed on the left of the target, arrow points right.
    406             bounds = new WI.Rect(0, 0, width - arrowHeight, height);
     407            bounds = new WI.Rect(0, 0, width - WI.Popover.AnchorSize, height);
    407408            break;
    408409        case WI.RectEdge.MAX_X: // Displayed on the right of the target, arrow points left.
    409             bounds = new WI.Rect(arrowHeight, 0, width - arrowHeight, height);
     410            bounds = new WI.Rect(WI.Popover.AnchorSize, 0, width - WI.Popover.AnchorSize, height);
    410411            break;
    411412        case WI.RectEdge.MIN_Y: // Displayed above the target, arrow points down.
    412             bounds = new WI.Rect(0, 0, width, height - arrowHeight);
     413            bounds = new WI.Rect(0, 0, width, height - WI.Popover.AnchorSize);
    413414            break;
    414415        case WI.RectEdge.MAX_Y: // Displayed below the target, arrow points up.
    415             bounds = new WI.Rect(0, arrowHeight, width, height - arrowHeight);
     416            bounds = new WI.Rect(0, WI.Popover.AnchorSize, width, height - WI.Popover.AnchorSize);
    416417            break;
    417418        }
     
    452453        var width = preferredSize.width + (WI.Popover.ShadowPadding * 2) + (WI.Popover.ContentPadding * 2);
    453454        var height = preferredSize.height + (WI.Popover.ShadowPadding * 2) + (WI.Popover.ContentPadding * 2);
    454         var arrowLength = WI.Popover.AnchorSize.height;
    455455
    456456        switch (edge) {
    457457        case WI.RectEdge.MIN_X: // Displayed on the left of the target, arrow points right.
    458             width += arrowLength;
     458            width += WI.Popover.AnchorSize;
    459459            x = targetFrame.origin.x - width + WI.Popover.ShadowPadding;
    460460            y = targetFrame.origin.y - (height - targetFrame.size.height) / 2;
    461461            break;
    462462        case WI.RectEdge.MAX_X: // Displayed on the right of the target, arrow points left.
    463             width += arrowLength;
     463            width += WI.Popover.AnchorSize;
    464464            x = targetFrame.origin.x + targetFrame.size.width - WI.Popover.ShadowPadding;
    465465            y = targetFrame.origin.y - (height - targetFrame.size.height) / 2;
    466466            break;
    467467        case WI.RectEdge.MIN_Y: // Displayed above the target, arrow points down.
    468             height += arrowLength;
     468            height += WI.Popover.AnchorSize;
    469469            x = targetFrame.origin.x - (width - targetFrame.size.width) / 2;
    470470            y = targetFrame.origin.y - height + WI.Popover.ShadowPadding;
    471471            break;
    472472        case WI.RectEdge.MAX_Y: // Displayed below the target, arrow points up.
    473             height += arrowLength;
     473            height += WI.Popover.AnchorSize;
    474474            x = targetFrame.origin.x - (width - targetFrame.size.width) / 2;
    475475            y = targetFrame.origin.y + targetFrame.size.height - WI.Popover.ShadowPadding;
     
    477477        }
    478478
    479         if (edge === WI.RectEdge.MIN_X || edge === WI.RectEdge.MAX_X) {
    480             if (y < containerFrame.minY())
    481                 y = containerFrame.minY();
    482             if (y + height > containerFrame.maxY())
    483                 y = containerFrame.maxY() - height;
    484         } else {
    485             if (x < containerFrame.minX())
    486                 x = containerFrame.minX();
    487             if (x + width > containerFrame.maxX())
    488                 x = containerFrame.maxX() - width;
    489         }
     479        if (edge !== WI.RectEdge.MIN_X && x < containerFrame.minX())
     480            x = containerFrame.minX();
     481        if (edge !== WI.RectEdge.MAX_X && x + width > containerFrame.maxX())
     482            x = containerFrame.maxX() - width;
     483        if (edge !== WI.RectEdge.MIN_Y && y < containerFrame.minY())
     484            y = containerFrame.minY();
     485        if (edge !== WI.RectEdge.MAX_Y && y + height > containerFrame.maxY())
     486            y = containerFrame.maxY() - height;
    490487
    491488        var preferredFrame = new WI.Rect(x, y, width, height);
     
    498495        case WI.RectEdge.MIN_X: // Displayed on the left of the target, arrow points right.
    499496        case WI.RectEdge.MAX_X: // Displayed on the right of the target, arrow points left.
    500             width -= arrowLength;
     497            width -= WI.Popover.AnchorSize;
    501498            break;
    502499        case WI.RectEdge.MIN_Y: // Displayed above the target, arrow points down.
    503500        case WI.RectEdge.MAX_Y: // Displayed below the target, arrow points up.
    504             height -= arrowLength;
     501            height -= WI.Popover.AnchorSize;
    505502            break;
    506503        }
     
    515512    {
    516513        let cornerRadius = WI.Popover.CornerRadius;
    517         let arrowHalfLength = WI.Popover.AnchorSize.width * 0.5;
    518514        let anchorPoint = this._anchorPoint;
    519515
    520516        // Prevent the arrow from being positioned against one of the popover's rounded corners.
    521         let arrowPadding = cornerRadius + arrowHalfLength;
     517        let arrowPadding = cornerRadius + WI.Popover.AnchorSize;
    522518        if (anchorEdge === WI.RectEdge.MIN_Y || anchorEdge === WI.RectEdge.MAX_Y)
    523519            anchorPoint.x = Number.constrain(anchorPoint.x, bounds.minX() + arrowPadding, bounds.maxX() - arrowPadding);
     
    529525        case WI.RectEdge.MIN_X: // Displayed on the left of the target, arrow points right.
    530526            ctx.moveTo(bounds.maxX(), bounds.minY() + cornerRadius);
    531             ctx.lineTo(bounds.maxX(), anchorPoint.y - arrowHalfLength);
     527            ctx.lineTo(bounds.maxX(), anchorPoint.y - WI.Popover.AnchorSize);
    532528            ctx.lineTo(anchorPoint.x, anchorPoint.y);
    533             ctx.lineTo(bounds.maxX(), anchorPoint.y + arrowHalfLength);
     529            ctx.lineTo(bounds.maxX(), anchorPoint.y + WI.Popover.AnchorSize);
    534530            ctx.arcTo(bounds.maxX(), bounds.maxY(), bounds.minX(), bounds.maxY(), cornerRadius);
    535531            ctx.arcTo(bounds.minX(), bounds.maxY(), bounds.minX(), bounds.minY(), cornerRadius);
     
    539535        case WI.RectEdge.MAX_X: // Displayed on the right of the target, arrow points left.
    540536            ctx.moveTo(bounds.minX(), bounds.maxY() - cornerRadius);
    541             ctx.lineTo(bounds.minX(), anchorPoint.y + arrowHalfLength);
     537            ctx.lineTo(bounds.minX(), anchorPoint.y + WI.Popover.AnchorSize);
    542538            ctx.lineTo(anchorPoint.x, anchorPoint.y);
    543             ctx.lineTo(bounds.minX(), anchorPoint.y - arrowHalfLength);
     539            ctx.lineTo(bounds.minX(), anchorPoint.y - WI.Popover.AnchorSize);
    544540            ctx.arcTo(bounds.minX(), bounds.minY(), bounds.maxX(), bounds.minY(), cornerRadius);
    545541            ctx.arcTo(bounds.maxX(), bounds.minY(), bounds.maxX(), bounds.maxY(), cornerRadius);
     
    549545        case WI.RectEdge.MIN_Y: // Displayed above the target, arrow points down.
    550546            ctx.moveTo(bounds.maxX() - cornerRadius, bounds.maxY());
    551             ctx.lineTo(anchorPoint.x + arrowHalfLength, bounds.maxY());
     547            ctx.lineTo(anchorPoint.x + WI.Popover.AnchorSize, bounds.maxY());
    552548            ctx.lineTo(anchorPoint.x, anchorPoint.y);
    553             ctx.lineTo(anchorPoint.x - arrowHalfLength, bounds.maxY());
     549            ctx.lineTo(anchorPoint.x - WI.Popover.AnchorSize, bounds.maxY());
    554550            ctx.arcTo(bounds.minX(), bounds.maxY(), bounds.minX(), bounds.minY(), cornerRadius);
    555551            ctx.arcTo(bounds.minX(), bounds.minY(), bounds.maxX(), bounds.minY(), cornerRadius);
     
    559555        case WI.RectEdge.MAX_Y: // Displayed below the target, arrow points up.
    560556            ctx.moveTo(bounds.minX() + cornerRadius, bounds.minY());
    561             ctx.lineTo(anchorPoint.x - arrowHalfLength, bounds.minY());
     557            ctx.lineTo(anchorPoint.x - WI.Popover.AnchorSize, bounds.minY());
    562558            ctx.lineTo(anchorPoint.x, anchorPoint.y);
    563             ctx.lineTo(anchorPoint.x + arrowHalfLength, bounds.minY());
     559            ctx.lineTo(anchorPoint.x + WI.Popover.AnchorSize, bounds.minY());
    564560            ctx.arcTo(bounds.maxX(), bounds.minY(), bounds.maxX(), bounds.maxY(), cornerRadius);
    565561            ctx.arcTo(bounds.maxX(), bounds.maxY(), bounds.minX(), bounds.maxY(), cornerRadius);
     
    592588WI.Popover.ShadowPadding = 5;
    593589WI.Popover.ContentPadding = 5;
    594 WI.Popover.AnchorSize = new WI.Size(22, 11);
     590WI.Popover.AnchorSize = 11;
    595591WI.Popover.ShadowEdgeInsets = new WI.EdgeInsets(WI.Popover.ShadowPadding);
    596592WI.Popover.IgnoreAutoDismissClassName = "popover-ignore-auto-dismiss";
  • trunk/Source/WebKit/ChangeLog

    r240533 r240540  
     12019-01-25  Devin Rousso  <drousso@apple.com>
     2
     3        Web Inspector: provide a way to edit page settings on a remote target
     4        https://bugs.webkit.org/show_bug.cgi?id=193813
     5        <rdar://problem/47359510>
     6
     7        Reviewed by Joseph Pecoraro.
     8
     9        * WebProcess/WebPage/WebInspectorUI.h:
     10        (WebKit::WebInspectorUI::isRemote() const): Added.
     11        * WebProcess/WebPage/RemoteWebInspectorUI.h:
     12        (WebKit::RemoteWebInspectorUI::isRemote() const): Added.
     13
    1142019-01-25  Dean Jackson  <dino@apple.com>
    215
  • trunk/Source/WebKit/WebProcess/WebPage/RemoteWebInspectorUI.h

    r238378 r240540  
    5959    void moveWindowBy(float x, float y) override;
    6060
     61    bool isRemote() const final { return true; }
    6162    String localizedStringsURL() override;
    6263    String backendCommandsURL() override { return m_backendCommandsURL; }
  • trunk/Source/WebKit/WebProcess/WebPage/WebInspectorUI.h

    r238378 r240540  
    8989    void moveWindowBy(float x, float y) override;
    9090
     91    bool isRemote() const final { return false; }
    9192    String localizedStringsURL() override;
    9293
Note: See TracChangeset for help on using the changeset viewer.