Changeset 290112 in webkit
- Timestamp:
- Feb 17, 2022 9:21:37 PM (5 months ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 5 edited
-
ChangeLog (modified) (1 diff)
-
en.lproj/Localizable.strings (modified) (2 diffs)
-
inspector/InspectorOverlay.cpp (modified) (5 diffs)
-
inspector/InspectorOverlayLabel.cpp (modified) (10 diffs)
-
inspector/InspectorOverlayLabel.h (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r290109 r290112 1 2022-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 1 30 2022-02-17 Simon Fraser <simon.fraser@apple.com> 2 31 -
trunk/Source/WebCore/en.lproj/Localizable.strings
r289696 r290112 479 479 "Finder" = "Finder"; 480 480 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 481 487 /* Font context sub-menu item */ 482 488 "Font" = "Font"; … … 503 509 "Google Safe Browsing" = "Google Safe Browsing"; 504 510 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 505 517 /* accessibility role description for web area */ 506 518 "HTML content" = "HTML content"; -
trunk/Source/WebCore/inspector/InspectorOverlay.cpp
r289769 r290112 57 57 #include "IntRect.h" 58 58 #include "IntSize.h" 59 #include "LocalizedStrings.h" 59 60 #include "Node.h" 60 61 #include "NodeList.h" … … 1020 1021 } 1021 1022 1023 static 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 1031 static bool rendererIsGridItem(RenderObject& renderer) 1032 { 1033 if (is<RenderGrid>(renderer.parent())) 1034 return !renderer.isOutOfFlowPositioned() && !renderer.isExcludedFromNormalLayout(); 1035 1036 return false; 1037 } 1038 1022 1039 Path InspectorOverlay::drawElementTitle(GraphicsContext& context, Node& node, const InspectorOverlay::Highlight::Bounds& bounds) 1023 1040 { … … 1073 1090 } 1074 1091 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 1075 1104 // Need to enable AX to get the computed role. 1076 1105 if (!WebCore::AXObjectCache::accessibilityEnabled()) … … 1086 1115 constexpr auto elementTitleAttributeValueColor = SRGBA<uint8_t> { 26, 26, 166 }; // Keep this in sync with XMLViewer.css (.attribute-value) 1087 1116 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); 1089 1119 1090 1120 Vector<InspectorOverlayLabel::Content> labelContents = { … … 1099 1129 }; 1100 1130 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 } 1104 1144 } 1105 1145 -
trunk/Source/WebCore/inspector/InspectorOverlayLabel.cpp
r289769 r290112 30 30 #include "InspectorOverlayLabel.h" 31 31 32 #include "FloatRoundedRect.h" 32 33 #include "FloatSize.h" 33 34 #include "FontCascade.h" … … 40 41 static constexpr float labelPadding = 4; 41 42 static constexpr float labelArrowSize = 6; 43 static constexpr float labelAdditionalLineSpacing = 1; 44 static constexpr float labelContentDecorationBorderedLeadingAndTrailingPadding = 1; 42 45 43 46 InspectorOverlayLabel::InspectorOverlayLabel(Vector<Content>&& contents, FloatPoint location, Color backgroundColor, Arrow arrow) … … 194 197 } 195 198 199 struct ComputedContentRun { 200 TextRun textRun; 201 Color textColor; 202 InspectorOverlayLabel::Content::Decoration decoration; 203 bool startsNewLine; 204 float computedWidth; 205 }; 206 196 207 Path InspectorOverlayLabel::draw(GraphicsContext& context, float maximumLineWidth) 197 208 { … … 202 213 float lineDescent = font.metricsOfPrimaryFont().floatDescent(); 203 214 204 Vector<TextRun> textRuns; 205 Vector<Color> textColors; 206 Vector<float> textWidths; 207 Vector<size_t> lineStartIndexes; 215 Vector<ComputedContentRun> computedContentRuns; 216 208 217 float longestLineWidth = 0; 209 218 int currentLine = 0; … … 212 221 for (auto content : m_contents) { 213 222 auto lines = content.text.splitAllowingEmptyEntries('\n'); 223 224 ASSERT(content.decoration.type == Content::Decoration::Type::None || lines.size() <= 1); 225 214 226 for (size_t i = 0; i < lines.size(); ++i) { 215 if (i) {216 lineStartIndexes.append(textRuns.size());227 auto startsNewLine = !!i; 228 if (startsNewLine) { 217 229 currentLineWidth = 0; 218 230 ++currentLine; … … 220 232 221 233 auto text = lines[i]; 222 if (text.isEmpty())223 continue;224 225 234 auto textRun = TextRun(text); 226 235 float textWidth = font.width(textRun); … … 236 245 } 237 246 238 textRuns.append(WTFMove(textRun)); 239 textColors.append(content.textColor); 240 textWidths.append(textWidth); 247 computedContentRuns.append({ textRun, content.textColor, content.decoration, startsNewLine, textWidth }); 241 248 242 249 currentLineWidth += textWidth; … … 246 253 } 247 254 248 float totalTextHeight = lineHeight * (currentLine + 1);255 float totalTextHeight = (lineHeight * (currentLine + 1)) + (currentLine * labelAdditionalLineSpacing); 249 256 250 257 FloatPoint textPosition; … … 326 333 int line = 0; 327 334 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) { 330 338 xOffset = 0; 331 339 ++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; 338 371 } 339 372 … … 368 401 } 369 402 370 float totalTextHeight = lineHeight * (currentLine + 1);403 float totalTextHeight = (lineHeight * (currentLine + 1)) + (currentLine * labelAdditionalLineSpacing); 371 404 372 405 switch (direction) { -
trunk/Source/WebCore/inspector/InspectorOverlayLabel.h
r289769 r290112 80 80 WTF_MAKE_STRUCT_FAST_ALLOCATED; 81 81 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 82 97 String text; 83 98 Color textColor; 99 Decoration decoration { Decoration::Type::None, Color::transparentBlack }; 84 100 85 101 #if PLATFORM(IOS_FAMILY) … … 174 190 encoder << text; 175 191 encoder << textColor; 192 encoder << decoration; 176 193 } 177 194 … … 188 205 return std::nullopt; 189 206 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 215 template<class Encoder> void InspectorOverlayLabel::Content::Decoration::encode(Encoder& encoder) const 216 { 217 encoder << type; 218 encoder << color; 219 } 220 221 template<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 } }; 191 234 } 192 235 … … 218 261 }; 219 262 220 } 263 template<> 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.