Changeset 290112 in webkit


Ignore:
Timestamp:
Feb 17, 2022 9:21:37 PM (5 months ago)
Author:
Patrick Angle
Message:

Web Inspector: [Flexbox] Add indicators for layout context in element tooltips
https://bugs.webkit.org/show_bug.cgi?id=236738

Reviewed by Devin Rousso.

  • en.lproj/Localizable.strings:
  • inspector/InspectorOverlay.cpp:

(WebCore::rendererIsFlexboxItem):
(WebCore::rendererIsGridItem):
(WebCore::InspectorOverlay::drawElementTitle):

  • Add new Flex Item, Flex, Grid Item, and Grid bubblea to element tooltips to allow provide more

context about layout while selecting nodes on a page.

  • Move the role into its own bubble with special color (based on the previous coloring of the Role text).
  • inspector/InspectorOverlayLabel.cpp:

(WebCore::InspectorOverlayLabel::draw):

  • inspector/InspectorOverlayLabel.h:

(WebCore::InspectorOverlayLabel::Content::encode const):
(WebCore::InspectorOverlayLabel::Content::decode):
(WebCore::InspectorOverlayLabel::Content::Decoration::encode const):
(WebCore::InspectorOverlayLabel::Content::Decoration::decode):

  • Add the concept of text decoration (currently just bordered text).
  • Create an intermediate ComputedContentRun to hold the intermediate representation of content with the

computed attributes of each piece of text. This allows us to better scale with the addition of the new text
decorations and other configuration properties instead of having to create even more Vectors of things that need
to be kept in sync with each other.

Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r290109 r290112  
     12022-02-17  Patrick Angle  <pangle@apple.com>
     2
     3        Web Inspector: [Flexbox] Add indicators for layout context in element tooltips
     4        https://bugs.webkit.org/show_bug.cgi?id=236738
     5
     6        Reviewed by Devin Rousso.
     7
     8        * en.lproj/Localizable.strings:
     9        * inspector/InspectorOverlay.cpp:
     10        (WebCore::rendererIsFlexboxItem):
     11        (WebCore::rendererIsGridItem):
     12        (WebCore::InspectorOverlay::drawElementTitle):
     13        - Add new `Flex Item`, `Flex`, `Grid Item`, and `Grid` bubblea to element tooltips to allow provide more
     14        context about layout while selecting nodes on a page.
     15        - Move the role into its own bubble with special color (based on the previous coloring of the `Role` text).
     16
     17        * inspector/InspectorOverlayLabel.cpp:
     18        (WebCore::InspectorOverlayLabel::draw):
     19        * inspector/InspectorOverlayLabel.h:
     20        (WebCore::InspectorOverlayLabel::Content::encode const):
     21        (WebCore::InspectorOverlayLabel::Content::decode):
     22        (WebCore::InspectorOverlayLabel::Content::Decoration::encode const):
     23        (WebCore::InspectorOverlayLabel::Content::Decoration::decode):
     24        - Add the concept of text decoration (currently just bordered text).
     25        - Create an intermediate `ComputedContentRun` to hold the intermediate representation of content with the
     26        computed attributes of each piece of text. This allows us to better scale with the addition of the new text
     27        decorations and other configuration properties instead of having to create even more Vectors of things that need
     28        to be kept in sync with each other.
     29
    1302022-02-17  Simon Fraser  <simon.fraser@apple.com>
    231
  • trunk/Source/WebCore/en.lproj/Localizable.strings

    r289696 r290112  
    479479"Finder" = "Finder";
    480480
     481/* Inspector element selection tooltip text for Flexbox containers. */
     482"Flex (Inspector Element Selection)" = "Flex";
     483
     484/* Inspector element selection tooltip text for items inside a Flexbox Container. */
     485"Flex Item (Inspector Element Selection)" = "Flex Item";
     486
    481487/* Font context sub-menu item */
    482488"Font" = "Font";
     
    503509"Google Safe Browsing" = "Google Safe Browsing";
    504510
     511/* Inspector element selection tooltip text for Grid containers. */
     512"Grid (Inspector Element Selection)" = "Grid";
     513
     514/* Inspector element selection tooltip text for items inside a Grid Container. */
     515"Grid Item (Inspector Element Selection)" = "Grid Item";
     516
    505517/* accessibility role description for web area */
    506518"HTML content" = "HTML content";
  • trunk/Source/WebCore/inspector/InspectorOverlay.cpp

    r289769 r290112  
    5757#include "IntRect.h"
    5858#include "IntSize.h"
     59#include "LocalizedStrings.h"
    5960#include "Node.h"
    6061#include "NodeList.h"
     
    10201021}
    10211022
     1023static bool rendererIsFlexboxItem(RenderObject& renderer)
     1024{
     1025    if (auto* parentFlexRenderer = dynamicDowncast<RenderFlexibleBox>(renderer.parent()))
     1026        return !parentFlexRenderer->orderIterator().shouldSkipChild(renderer);
     1027
     1028    return false;
     1029}
     1030
     1031static bool rendererIsGridItem(RenderObject& renderer)
     1032{
     1033    if (is<RenderGrid>(renderer.parent()))
     1034        return !renderer.isOutOfFlowPositioned() && !renderer.isExcludedFromNormalLayout();
     1035
     1036    return false;
     1037}
     1038
    10221039Path InspectorOverlay::drawElementTitle(GraphicsContext& context, Node& node, const InspectorOverlay::Highlight::Bounds& bounds)
    10231040{
     
    10731090    }
    10741091
     1092    Vector<String> layoutContextBubbleStrings;
     1093   
     1094    if (rendererIsFlexboxItem(*renderer))
     1095        layoutContextBubbleStrings.append(WEB_UI_STRING_KEY("Flex Item", "Flex Item (Inspector Element Selection)", "Inspector element selection tooltip text for items inside a Flexbox Container."));
     1096    else if (rendererIsGridItem(*renderer))
     1097        layoutContextBubbleStrings.append(WEB_UI_STRING_KEY("Grid Item", "Grid Item (Inspector Element Selection)", "Inspector element selection tooltip text for items inside a Grid Container."));
     1098
     1099    if (is<RenderFlexibleBox>(renderer))
     1100        layoutContextBubbleStrings.append(WEB_UI_STRING_KEY("Flex", "Flex (Inspector Element Selection)", "Inspector element selection tooltip text for Flexbox containers."));
     1101    else if (is<RenderGrid>(renderer))
     1102        layoutContextBubbleStrings.append(WEB_UI_STRING_KEY("Grid", "Grid (Inspector Element Selection)", "Inspector element selection tooltip text for Grid containers."));
     1103
    10751104    // Need to enable AX to get the computed role.
    10761105    if (!WebCore::AXObjectCache::accessibilityEnabled())
     
    10861115    constexpr auto elementTitleAttributeValueColor = SRGBA<uint8_t> { 26, 26, 166 }; // Keep this in sync with XMLViewer.css (.attribute-value)
    10871116    constexpr auto elementTitleAttributeNameColor = SRGBA<uint8_t> { 153, 69, 0 }; // Keep this in sync with XMLViewer.css (.attribute-name)
    1088     constexpr auto elementTitleRoleColor = SRGBA<uint8_t> { 170, 13, 145 };
     1117    constexpr auto elementTitleRoleBubbleColor = SRGBA<uint8_t> { 170, 13, 145, 48 };
     1118    constexpr auto elementTitleLayoutBubbleColor = Color::gray.colorWithAlphaByte(64);
    10891119
    10901120    Vector<InspectorOverlayLabel::Content> labelContents = {
     
    10991129    };
    11001130
    1101     if (!elementRole.isEmpty()) {
    1102         labelContents.append({ "\nRole "_s, elementTitleRoleColor });
    1103         labelContents.append({ elementRole, Color::black });
     1131    if (!elementRole.isEmpty() || !layoutContextBubbleStrings.isEmpty()) {
     1132        labelContents.append({ "\n"_s, Color::black });
     1133
     1134        if (!elementRole.isEmpty())
     1135            labelContents.append({ makeString("Role: "_s, elementRole), Color::black, { InspectorOverlayLabel::Content::Decoration::Type::Bordered, elementTitleRoleBubbleColor } });
     1136
     1137        auto isFirstBubble = elementRole.isEmpty();
     1138        for (auto& layoutContextBubbleString : layoutContextBubbleStrings) {
     1139            if (!isFirstBubble)
     1140                labelContents.append({ "  "_s, Color::black });
     1141            labelContents.append({ layoutContextBubbleString, Color::black, { InspectorOverlayLabel::Content::Decoration::Type::Bordered, elementTitleLayoutBubbleColor } });
     1142            isFirstBubble = false;
     1143        }
    11041144    }
    11051145
  • trunk/Source/WebCore/inspector/InspectorOverlayLabel.cpp

    r289769 r290112  
    3030#include "InspectorOverlayLabel.h"
    3131
     32#include "FloatRoundedRect.h"
    3233#include "FloatSize.h"
    3334#include "FontCascade.h"
     
    4041static constexpr float labelPadding = 4;
    4142static constexpr float labelArrowSize = 6;
     43static constexpr float labelAdditionalLineSpacing = 1;
     44static constexpr float labelContentDecorationBorderedLeadingAndTrailingPadding = 1;
    4245
    4346InspectorOverlayLabel::InspectorOverlayLabel(Vector<Content>&& contents, FloatPoint location, Color backgroundColor, Arrow arrow)
     
    194197}
    195198
     199struct ComputedContentRun {
     200    TextRun textRun;
     201    Color textColor;
     202    InspectorOverlayLabel::Content::Decoration decoration;
     203    bool startsNewLine;
     204    float computedWidth;
     205};
     206
    196207Path InspectorOverlayLabel::draw(GraphicsContext& context, float maximumLineWidth)
    197208{
     
    202213    float lineDescent = font.metricsOfPrimaryFont().floatDescent();
    203214
    204     Vector<TextRun> textRuns;
    205     Vector<Color> textColors;
    206     Vector<float> textWidths;
    207     Vector<size_t> lineStartIndexes;
     215    Vector<ComputedContentRun> computedContentRuns;
     216
    208217    float longestLineWidth = 0;
    209218    int currentLine = 0;
     
    212221    for (auto content : m_contents) {
    213222        auto lines = content.text.splitAllowingEmptyEntries('\n');
     223
     224        ASSERT(content.decoration.type == Content::Decoration::Type::None || lines.size() <= 1);
     225
    214226        for (size_t i = 0; i < lines.size(); ++i) {
    215             if (i) {
    216                 lineStartIndexes.append(textRuns.size());
     227            auto startsNewLine = !!i;
     228            if (startsNewLine) {
    217229                currentLineWidth = 0;
    218230                ++currentLine;
     
    220232
    221233            auto text = lines[i];
    222             if (text.isEmpty())
    223                 continue;
    224 
    225234            auto textRun = TextRun(text);
    226235            float textWidth = font.width(textRun);
     
    236245            }
    237246
    238             textRuns.append(WTFMove(textRun));
    239             textColors.append(content.textColor);
    240             textWidths.append(textWidth);
     247            computedContentRuns.append({ textRun, content.textColor, content.decoration, startsNewLine, textWidth });
    241248
    242249            currentLineWidth += textWidth;
     
    246253    }
    247254
    248     float totalTextHeight = lineHeight * (currentLine + 1);
     255    float totalTextHeight = (lineHeight * (currentLine + 1)) + (currentLine * labelAdditionalLineSpacing);
    249256
    250257    FloatPoint textPosition;
     
    326333    int line = 0;
    327334    float xOffset = 0;
    328     for (size_t i = 0; i < textRuns.size(); ++i) {
    329         if (lineStartIndexes.contains(i)) {
     335    float yOffset = 0;
     336    for (auto& computedContentRun : computedContentRuns) {
     337        if (computedContentRun.startsNewLine) {
    330338            xOffset = 0;
    331339            ++line;
    332         }
    333 
    334         context.setFillColor(textColors[i]);
    335         context.drawText(font, textRuns[i], textPosition + FloatPoint(xOffset, line * lineHeight));
    336 
    337         xOffset += textWidths[i];
     340            yOffset += lineHeight + labelAdditionalLineSpacing;
     341        }
     342
     343        switch (computedContentRun.decoration.type) {
     344        case Content::Decoration::Type::Bordered: {
     345            auto backgroundRect = FloatRoundedRect({
     346                textPosition.x() + xOffset - labelContentDecorationBorderedLeadingAndTrailingPadding,
     347                textPosition.y() + yOffset - lineHeight + lineDescent,
     348                computedContentRun.computedWidth + (labelContentDecorationBorderedLeadingAndTrailingPadding * 2),
     349                lineHeight,
     350            }, FloatRoundedRect::Radii(2));
     351
     352            Path backgroundPath;
     353            backgroundPath.addRoundedRect(backgroundRect);
     354
     355            context.setFillColor(computedContentRun.decoration.color);
     356            context.setStrokeColor(computedContentRun.decoration.color.darkened());
     357
     358            context.fillPath(backgroundPath);
     359            context.strokePath(backgroundPath);
     360            break;
     361        }
     362
     363        case Content::Decoration::Type::None:
     364            break;
     365        }
     366
     367        context.setFillColor(computedContentRun.textColor);
     368        context.drawText(font, computedContentRun.textRun, textPosition + FloatPoint(xOffset, yOffset));
     369
     370        xOffset += computedContentRun.computedWidth;
    338371    }
    339372
     
    368401    }
    369402
    370     float totalTextHeight = lineHeight * (currentLine + 1);
     403    float totalTextHeight = (lineHeight * (currentLine + 1)) + (currentLine * labelAdditionalLineSpacing);
    371404
    372405    switch (direction) {
  • trunk/Source/WebCore/inspector/InspectorOverlayLabel.h

    r289769 r290112  
    8080        WTF_MAKE_STRUCT_FAST_ALLOCATED;
    8181
     82        struct Decoration {
     83            enum class Type : uint8_t {
     84                None,
     85                Bordered,
     86            };
     87
     88            Type type;
     89            Color color;
     90
     91#if PLATFORM(IOS_FAMILY)
     92            template<class Encoder> void encode(Encoder&) const;
     93            template<class Decoder> static std::optional<InspectorOverlayLabel::Content::Decoration> decode(Decoder&);
     94#endif
     95        };
     96
    8297        String text;
    8398        Color textColor;
     99        Decoration decoration { Decoration::Type::None, Color::transparentBlack };
    84100
    85101#if PLATFORM(IOS_FAMILY)
     
    174190    encoder << text;
    175191    encoder << textColor;
     192    encoder << decoration;
    176193}
    177194
     
    188205        return std::nullopt;
    189206
    190     return { { *text, *textColor } };
     207    std::optional<Decoration> decoration;
     208    decoder >> decoration;
     209    if (!decoration)
     210        return std::nullopt;
     211
     212    return { { *text, *textColor, *decoration } };
     213}
     214
     215template<class Encoder> void InspectorOverlayLabel::Content::Decoration::encode(Encoder& encoder) const
     216{
     217    encoder << type;
     218    encoder << color;
     219}
     220
     221template<class Decoder> std::optional<InspectorOverlayLabel::Content::Decoration> InspectorOverlayLabel::Content::Decoration::decode(Decoder& decoder)
     222{
     223    std::optional<Type> type;
     224    decoder >> type;
     225    if (!type)
     226        return std::nullopt;
     227
     228    std::optional<Color> color;
     229    decoder >> color;
     230    if (!color)
     231        return std::nullopt;
     232
     233    return { { *type, *color } };
    191234}
    192235
     
    218261};
    219262
    220 }
     263template<> struct EnumTraits<WebCore::InspectorOverlayLabel::Content::Decoration::Type> {
     264    using values = EnumValues<
     265        WebCore::InspectorOverlayLabel::Content::Decoration::Type,
     266        WebCore::InspectorOverlayLabel::Content::Decoration::Type::None,
     267        WebCore::InspectorOverlayLabel::Content::Decoration::Type::Bordered
     268    >;
     269};
     270
     271}
Note: See TracChangeset for help on using the changeset viewer.