chrome-devtools-frontend 1.0.1568190 → 1.0.1568864

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,6 @@
1
+ <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M11 9V3L17 3V9H11Z" fill="black"/>
3
+ <path d="M3 9L3 3L9 3V9H3Z" fill="black"/>
4
+ <path d="M3 17L3 11H9V17H3Z" fill="black"/>
5
+ <path d="M15.1893 13.2803H10V14.7803H15.1894L13.4697 16.5L14.5303 17.5607L18.0607 14.0304L14.5303 10.5L13.4697 11.5607L15.1893 13.2803Z" fill="black"/>
6
+ </svg>
@@ -66,7 +66,7 @@ inspectorBackend.registerType("Animation.KeyframesRule", [{"name": "name", "type
66
66
  inspectorBackend.registerType("Animation.KeyframeStyle", [{"name": "offset", "type": "string", "optional": false, "description": "Keyframe's time offset.", "typeRef": null}, {"name": "easing", "type": "string", "optional": false, "description": "`AnimationEffect`'s timing function.", "typeRef": null}]);
67
67
 
68
68
  // Audits.
69
- inspectorBackend.registerEnum("Audits.CookieExclusionReason", {ExcludeSameSiteUnspecifiedTreatedAsLax: "ExcludeSameSiteUnspecifiedTreatedAsLax", ExcludeSameSiteNoneInsecure: "ExcludeSameSiteNoneInsecure", ExcludeSameSiteLax: "ExcludeSameSiteLax", ExcludeSameSiteStrict: "ExcludeSameSiteStrict", ExcludeInvalidSameParty: "ExcludeInvalidSameParty", ExcludeSamePartyCrossPartyContext: "ExcludeSamePartyCrossPartyContext", ExcludeDomainNonASCII: "ExcludeDomainNonASCII", ExcludeThirdPartyCookieBlockedInFirstPartySet: "ExcludeThirdPartyCookieBlockedInFirstPartySet", ExcludeThirdPartyPhaseout: "ExcludeThirdPartyPhaseout", ExcludePortMismatch: "ExcludePortMismatch", ExcludeSchemeMismatch: "ExcludeSchemeMismatch"});
69
+ inspectorBackend.registerEnum("Audits.CookieExclusionReason", {ExcludeSameSiteUnspecifiedTreatedAsLax: "ExcludeSameSiteUnspecifiedTreatedAsLax", ExcludeSameSiteNoneInsecure: "ExcludeSameSiteNoneInsecure", ExcludeSameSiteLax: "ExcludeSameSiteLax", ExcludeSameSiteStrict: "ExcludeSameSiteStrict", ExcludeDomainNonASCII: "ExcludeDomainNonASCII", ExcludeThirdPartyCookieBlockedInFirstPartySet: "ExcludeThirdPartyCookieBlockedInFirstPartySet", ExcludeThirdPartyPhaseout: "ExcludeThirdPartyPhaseout", ExcludePortMismatch: "ExcludePortMismatch", ExcludeSchemeMismatch: "ExcludeSchemeMismatch"});
70
70
  inspectorBackend.registerEnum("Audits.CookieWarningReason", {WarnSameSiteUnspecifiedCrossSiteContext: "WarnSameSiteUnspecifiedCrossSiteContext", WarnSameSiteNoneInsecure: "WarnSameSiteNoneInsecure", WarnSameSiteUnspecifiedLaxAllowUnsafe: "WarnSameSiteUnspecifiedLaxAllowUnsafe", WarnSameSiteStrictLaxDowngradeStrict: "WarnSameSiteStrictLaxDowngradeStrict", WarnSameSiteStrictCrossDowngradeStrict: "WarnSameSiteStrictCrossDowngradeStrict", WarnSameSiteStrictCrossDowngradeLax: "WarnSameSiteStrictCrossDowngradeLax", WarnSameSiteLaxCrossDowngradeStrict: "WarnSameSiteLaxCrossDowngradeStrict", WarnSameSiteLaxCrossDowngradeLax: "WarnSameSiteLaxCrossDowngradeLax", WarnAttributeValueExceedsMaxSize: "WarnAttributeValueExceedsMaxSize", WarnDomainNonASCII: "WarnDomainNonASCII", WarnThirdPartyPhaseout: "WarnThirdPartyPhaseout", WarnCrossSiteRedirectDowngradeChangesInclusion: "WarnCrossSiteRedirectDowngradeChangesInclusion", WarnDeprecationTrialMetadata: "WarnDeprecationTrialMetadata", WarnThirdPartyCookieHeuristic: "WarnThirdPartyCookieHeuristic"});
71
71
  inspectorBackend.registerEnum("Audits.CookieOperation", {SetCookie: "SetCookie", ReadCookie: "ReadCookie"});
72
72
  inspectorBackend.registerEnum("Audits.InsightType", {GitHubResource: "GitHubResource", GracePeriod: "GracePeriod", Heuristics: "Heuristics"});
@@ -773,8 +773,8 @@ inspectorBackend.registerEnum("Network.TrustTokenOperationType", {Issuance: "Iss
773
773
  inspectorBackend.registerEnum("Network.AlternateProtocolUsage", {AlternativeJobWonWithoutRace: "alternativeJobWonWithoutRace", AlternativeJobWonRace: "alternativeJobWonRace", MainJobWonRace: "mainJobWonRace", MappingMissing: "mappingMissing", Broken: "broken", DnsAlpnH3JobWonWithoutRace: "dnsAlpnH3JobWonWithoutRace", DnsAlpnH3JobWonRace: "dnsAlpnH3JobWonRace", UnspecifiedReason: "unspecifiedReason"});
774
774
  inspectorBackend.registerEnum("Network.ServiceWorkerRouterSource", {Network: "network", Cache: "cache", FetchEvent: "fetch-event", RaceNetworkAndFetchHandler: "race-network-and-fetch-handler", RaceNetworkAndCache: "race-network-and-cache"});
775
775
  inspectorBackend.registerEnum("Network.InitiatorType", {Parser: "parser", Script: "script", Preload: "preload", SignedExchange: "SignedExchange", Preflight: "preflight", FedCM: "FedCM", Other: "other"});
776
- inspectorBackend.registerEnum("Network.SetCookieBlockedReason", {SecureOnly: "SecureOnly", SameSiteStrict: "SameSiteStrict", SameSiteLax: "SameSiteLax", SameSiteUnspecifiedTreatedAsLax: "SameSiteUnspecifiedTreatedAsLax", SameSiteNoneInsecure: "SameSiteNoneInsecure", UserPreferences: "UserPreferences", ThirdPartyPhaseout: "ThirdPartyPhaseout", ThirdPartyBlockedInFirstPartySet: "ThirdPartyBlockedInFirstPartySet", SyntaxError: "SyntaxError", SchemeNotSupported: "SchemeNotSupported", OverwriteSecure: "OverwriteSecure", InvalidDomain: "InvalidDomain", InvalidPrefix: "InvalidPrefix", UnknownError: "UnknownError", SchemefulSameSiteStrict: "SchemefulSameSiteStrict", SchemefulSameSiteLax: "SchemefulSameSiteLax", SchemefulSameSiteUnspecifiedTreatedAsLax: "SchemefulSameSiteUnspecifiedTreatedAsLax", SamePartyFromCrossPartyContext: "SamePartyFromCrossPartyContext", SamePartyConflictsWithOtherAttributes: "SamePartyConflictsWithOtherAttributes", NameValuePairExceedsMaxSize: "NameValuePairExceedsMaxSize", DisallowedCharacter: "DisallowedCharacter", NoCookieContent: "NoCookieContent"});
777
- inspectorBackend.registerEnum("Network.CookieBlockedReason", {SecureOnly: "SecureOnly", NotOnPath: "NotOnPath", DomainMismatch: "DomainMismatch", SameSiteStrict: "SameSiteStrict", SameSiteLax: "SameSiteLax", SameSiteUnspecifiedTreatedAsLax: "SameSiteUnspecifiedTreatedAsLax", SameSiteNoneInsecure: "SameSiteNoneInsecure", UserPreferences: "UserPreferences", ThirdPartyPhaseout: "ThirdPartyPhaseout", ThirdPartyBlockedInFirstPartySet: "ThirdPartyBlockedInFirstPartySet", UnknownError: "UnknownError", SchemefulSameSiteStrict: "SchemefulSameSiteStrict", SchemefulSameSiteLax: "SchemefulSameSiteLax", SchemefulSameSiteUnspecifiedTreatedAsLax: "SchemefulSameSiteUnspecifiedTreatedAsLax", SamePartyFromCrossPartyContext: "SamePartyFromCrossPartyContext", NameValuePairExceedsMaxSize: "NameValuePairExceedsMaxSize", PortMismatch: "PortMismatch", SchemeMismatch: "SchemeMismatch", AnonymousContext: "AnonymousContext"});
776
+ inspectorBackend.registerEnum("Network.SetCookieBlockedReason", {SecureOnly: "SecureOnly", SameSiteStrict: "SameSiteStrict", SameSiteLax: "SameSiteLax", SameSiteUnspecifiedTreatedAsLax: "SameSiteUnspecifiedTreatedAsLax", SameSiteNoneInsecure: "SameSiteNoneInsecure", UserPreferences: "UserPreferences", ThirdPartyPhaseout: "ThirdPartyPhaseout", ThirdPartyBlockedInFirstPartySet: "ThirdPartyBlockedInFirstPartySet", SyntaxError: "SyntaxError", SchemeNotSupported: "SchemeNotSupported", OverwriteSecure: "OverwriteSecure", InvalidDomain: "InvalidDomain", InvalidPrefix: "InvalidPrefix", UnknownError: "UnknownError", SchemefulSameSiteStrict: "SchemefulSameSiteStrict", SchemefulSameSiteLax: "SchemefulSameSiteLax", SchemefulSameSiteUnspecifiedTreatedAsLax: "SchemefulSameSiteUnspecifiedTreatedAsLax", NameValuePairExceedsMaxSize: "NameValuePairExceedsMaxSize", DisallowedCharacter: "DisallowedCharacter", NoCookieContent: "NoCookieContent"});
777
+ inspectorBackend.registerEnum("Network.CookieBlockedReason", {SecureOnly: "SecureOnly", NotOnPath: "NotOnPath", DomainMismatch: "DomainMismatch", SameSiteStrict: "SameSiteStrict", SameSiteLax: "SameSiteLax", SameSiteUnspecifiedTreatedAsLax: "SameSiteUnspecifiedTreatedAsLax", SameSiteNoneInsecure: "SameSiteNoneInsecure", UserPreferences: "UserPreferences", ThirdPartyPhaseout: "ThirdPartyPhaseout", ThirdPartyBlockedInFirstPartySet: "ThirdPartyBlockedInFirstPartySet", UnknownError: "UnknownError", SchemefulSameSiteStrict: "SchemefulSameSiteStrict", SchemefulSameSiteLax: "SchemefulSameSiteLax", SchemefulSameSiteUnspecifiedTreatedAsLax: "SchemefulSameSiteUnspecifiedTreatedAsLax", NameValuePairExceedsMaxSize: "NameValuePairExceedsMaxSize", PortMismatch: "PortMismatch", SchemeMismatch: "SchemeMismatch", AnonymousContext: "AnonymousContext"});
778
778
  inspectorBackend.registerEnum("Network.CookieExemptionReason", {None: "None", UserSetting: "UserSetting", TPCDMetadata: "TPCDMetadata", TPCDDeprecationTrial: "TPCDDeprecationTrial", TopLevelTPCDDeprecationTrial: "TopLevelTPCDDeprecationTrial", TPCDHeuristics: "TPCDHeuristics", EnterprisePolicy: "EnterprisePolicy", StorageAccess: "StorageAccess", TopLevelStorageAccess: "TopLevelStorageAccess", Scheme: "Scheme", SameSiteNoneCookiesInSandbox: "SameSiteNoneCookiesInSandbox"});
779
779
  inspectorBackend.registerEnum("Network.AuthChallengeSource", {Server: "Server", Proxy: "Proxy"});
780
780
  inspectorBackend.registerEnum("Network.AuthChallengeResponseResponse", {Default: "Default", CancelAuth: "CancelAuth", ProvideCredentials: "ProvideCredentials"});
@@ -865,7 +865,7 @@ inspectorBackend.registerCommand("Network.searchInResponseBody", [{"name": "requ
865
865
  inspectorBackend.registerCommand("Network.setBlockedURLs", [{"name": "urlPatterns", "type": "array", "optional": true, "description": "Patterns to match in the order in which they are given. These patterns also take precedence over any wildcard patterns defined in `urls`.", "typeRef": "Network.BlockPattern"}, {"name": "urls", "type": "array", "optional": true, "description": "URL patterns to block. Wildcards ('*') are allowed.", "typeRef": "string"}], [], "Blocks URLs from loading.");
866
866
  inspectorBackend.registerCommand("Network.setBypassServiceWorker", [{"name": "bypass", "type": "boolean", "optional": false, "description": "Bypass service worker and load from network.", "typeRef": null}], [], "Toggles ignoring of service worker for each request.");
867
867
  inspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false, "description": "Cache disabled state.", "typeRef": null}], [], "Toggles ignoring cache for each request. If `true`, cache will not be used.");
868
- inspectorBackend.registerCommand("Network.setCookie", [{"name": "name", "type": "string", "optional": false, "description": "Cookie name.", "typeRef": null}, {"name": "value", "type": "string", "optional": false, "description": "Cookie value.", "typeRef": null}, {"name": "url", "type": "string", "optional": true, "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain, path, source port, and source scheme values of the created cookie.", "typeRef": null}, {"name": "domain", "type": "string", "optional": true, "description": "Cookie domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": true, "description": "Cookie path.", "typeRef": null}, {"name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure.", "typeRef": null}, {"name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only.", "typeRef": null}, {"name": "sameSite", "type": "string", "optional": true, "description": "Cookie SameSite type.", "typeRef": "Network.CookieSameSite"}, {"name": "expires", "type": "number", "optional": true, "description": "Cookie expiration date, session cookie if not set", "typeRef": "Network.TimeSinceEpoch"}, {"name": "priority", "type": "string", "optional": true, "description": "Cookie Priority type.", "typeRef": "Network.CookiePriority"}, {"name": "sameParty", "type": "boolean", "optional": true, "description": "True if cookie is SameParty.", "typeRef": null}, {"name": "sourceScheme", "type": "string", "optional": true, "description": "Cookie source scheme type.", "typeRef": "Network.CookieSourceScheme"}, {"name": "sourcePort", "type": "number", "optional": true, "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port. An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. This is a temporary ability and it will be removed in the future.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "Cookie partition key. If not set, the cookie will be set as not partitioned.", "typeRef": "Network.CookiePartitionKey"}], ["success"], "Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist.");
868
+ inspectorBackend.registerCommand("Network.setCookie", [{"name": "name", "type": "string", "optional": false, "description": "Cookie name.", "typeRef": null}, {"name": "value", "type": "string", "optional": false, "description": "Cookie value.", "typeRef": null}, {"name": "url", "type": "string", "optional": true, "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain, path, source port, and source scheme values of the created cookie.", "typeRef": null}, {"name": "domain", "type": "string", "optional": true, "description": "Cookie domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": true, "description": "Cookie path.", "typeRef": null}, {"name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure.", "typeRef": null}, {"name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only.", "typeRef": null}, {"name": "sameSite", "type": "string", "optional": true, "description": "Cookie SameSite type.", "typeRef": "Network.CookieSameSite"}, {"name": "expires", "type": "number", "optional": true, "description": "Cookie expiration date, session cookie if not set", "typeRef": "Network.TimeSinceEpoch"}, {"name": "priority", "type": "string", "optional": true, "description": "Cookie Priority type.", "typeRef": "Network.CookiePriority"}, {"name": "sourceScheme", "type": "string", "optional": true, "description": "Cookie source scheme type.", "typeRef": "Network.CookieSourceScheme"}, {"name": "sourcePort", "type": "number", "optional": true, "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port. An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. This is a temporary ability and it will be removed in the future.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "Cookie partition key. If not set, the cookie will be set as not partitioned.", "typeRef": "Network.CookiePartitionKey"}], ["success"], "Sets a cookie with the given cookie data; may overwrite equivalent cookies if they exist.");
869
869
  inspectorBackend.registerCommand("Network.setCookies", [{"name": "cookies", "type": "array", "optional": false, "description": "Cookies to be set.", "typeRef": "Network.CookieParam"}], [], "Sets given cookies.");
870
870
  inspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false, "description": "Map with extra HTTP headers.", "typeRef": "Network.Headers"}], [], "Specifies whether to always send extra HTTP headers with the requests from this page.");
871
871
  inspectorBackend.registerCommand("Network.setAttachDebugStack", [{"name": "enabled", "type": "boolean", "optional": false, "description": "Whether to attach a page script stack for debugging purpose.", "typeRef": null}], [], "Specifies whether to attach a page script stack id in requests");
@@ -893,11 +893,11 @@ inspectorBackend.registerType("Network.WebSocketFrame", [{"name": "opcode", "typ
893
893
  inspectorBackend.registerType("Network.CachedResource", [{"name": "url", "type": "string", "optional": false, "description": "Resource URL. This is the url of the original network request.", "typeRef": null}, {"name": "type", "type": "string", "optional": false, "description": "Type of this resource.", "typeRef": "Network.ResourceType"}, {"name": "response", "type": "object", "optional": true, "description": "Cached response data.", "typeRef": "Network.Response"}, {"name": "bodySize", "type": "number", "optional": false, "description": "Cached response body size.", "typeRef": null}]);
894
894
  inspectorBackend.registerType("Network.Initiator", [{"name": "type", "type": "string", "optional": false, "description": "Type of this initiator.", "typeRef": null}, {"name": "stack", "type": "object", "optional": true, "description": "Initiator JavaScript stack trace, set for Script only. Requires the Debugger domain to be enabled.", "typeRef": "Runtime.StackTrace"}, {"name": "url", "type": "string", "optional": true, "description": "Initiator URL, set for Parser type or for Script type (when script is importing module) or for SignedExchange type.", "typeRef": null}, {"name": "lineNumber", "type": "number", "optional": true, "description": "Initiator line number, set for Parser type or for Script type (when script is importing module) (0-based).", "typeRef": null}, {"name": "columnNumber", "type": "number", "optional": true, "description": "Initiator column number, set for Parser type or for Script type (when script is importing module) (0-based).", "typeRef": null}, {"name": "requestId", "type": "string", "optional": true, "description": "Set if another request triggered this request (e.g. preflight).", "typeRef": "Network.RequestId"}]);
895
895
  inspectorBackend.registerType("Network.CookiePartitionKey", [{"name": "topLevelSite", "type": "string", "optional": false, "description": "The site of the top-level URL the browser was visiting at the start of the request to the endpoint that set the cookie.", "typeRef": null}, {"name": "hasCrossSiteAncestor", "type": "boolean", "optional": false, "description": "Indicates if the cookie has any ancestors that are cross-site to the topLevelSite.", "typeRef": null}]);
896
- inspectorBackend.registerType("Network.Cookie", [{"name": "name", "type": "string", "optional": false, "description": "Cookie name.", "typeRef": null}, {"name": "value", "type": "string", "optional": false, "description": "Cookie value.", "typeRef": null}, {"name": "domain", "type": "string", "optional": false, "description": "Cookie domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": false, "description": "Cookie path.", "typeRef": null}, {"name": "expires", "type": "number", "optional": false, "description": "Cookie expiration date as the number of seconds since the UNIX epoch. The value is set to -1 if the expiry date is not set. The value can be null for values that cannot be represented in JSON (\u00b1Inf).", "typeRef": null}, {"name": "size", "type": "number", "optional": false, "description": "Cookie size.", "typeRef": null}, {"name": "httpOnly", "type": "boolean", "optional": false, "description": "True if cookie is http-only.", "typeRef": null}, {"name": "secure", "type": "boolean", "optional": false, "description": "True if cookie is secure.", "typeRef": null}, {"name": "session", "type": "boolean", "optional": false, "description": "True in case of session cookie.", "typeRef": null}, {"name": "sameSite", "type": "string", "optional": true, "description": "Cookie SameSite type.", "typeRef": "Network.CookieSameSite"}, {"name": "priority", "type": "string", "optional": false, "description": "Cookie Priority", "typeRef": "Network.CookiePriority"}, {"name": "sameParty", "type": "boolean", "optional": false, "description": "True if cookie is SameParty.", "typeRef": null}, {"name": "sourceScheme", "type": "string", "optional": false, "description": "Cookie source scheme type.", "typeRef": "Network.CookieSourceScheme"}, {"name": "sourcePort", "type": "number", "optional": false, "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port. An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. This is a temporary ability and it will be removed in the future.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "Cookie partition key.", "typeRef": "Network.CookiePartitionKey"}, {"name": "partitionKeyOpaque", "type": "boolean", "optional": true, "description": "True if cookie partition key is opaque.", "typeRef": null}]);
896
+ inspectorBackend.registerType("Network.Cookie", [{"name": "name", "type": "string", "optional": false, "description": "Cookie name.", "typeRef": null}, {"name": "value", "type": "string", "optional": false, "description": "Cookie value.", "typeRef": null}, {"name": "domain", "type": "string", "optional": false, "description": "Cookie domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": false, "description": "Cookie path.", "typeRef": null}, {"name": "expires", "type": "number", "optional": false, "description": "Cookie expiration date as the number of seconds since the UNIX epoch. The value is set to -1 if the expiry date is not set. The value can be null for values that cannot be represented in JSON (\u00b1Inf).", "typeRef": null}, {"name": "size", "type": "number", "optional": false, "description": "Cookie size.", "typeRef": null}, {"name": "httpOnly", "type": "boolean", "optional": false, "description": "True if cookie is http-only.", "typeRef": null}, {"name": "secure", "type": "boolean", "optional": false, "description": "True if cookie is secure.", "typeRef": null}, {"name": "session", "type": "boolean", "optional": false, "description": "True in case of session cookie.", "typeRef": null}, {"name": "sameSite", "type": "string", "optional": true, "description": "Cookie SameSite type.", "typeRef": "Network.CookieSameSite"}, {"name": "priority", "type": "string", "optional": false, "description": "Cookie Priority", "typeRef": "Network.CookiePriority"}, {"name": "sourceScheme", "type": "string", "optional": false, "description": "Cookie source scheme type.", "typeRef": "Network.CookieSourceScheme"}, {"name": "sourcePort", "type": "number", "optional": false, "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port. An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. This is a temporary ability and it will be removed in the future.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "Cookie partition key.", "typeRef": "Network.CookiePartitionKey"}, {"name": "partitionKeyOpaque", "type": "boolean", "optional": true, "description": "True if cookie partition key is opaque.", "typeRef": null}]);
897
897
  inspectorBackend.registerType("Network.BlockedSetCookieWithReason", [{"name": "blockedReasons", "type": "array", "optional": false, "description": "The reason(s) this cookie was blocked.", "typeRef": "Network.SetCookieBlockedReason"}, {"name": "cookieLine", "type": "string", "optional": false, "description": "The string representing this individual cookie as it would appear in the header. This is not the entire \\\"cookie\\\" or \\\"set-cookie\\\" header which could have multiple cookies.", "typeRef": null}, {"name": "cookie", "type": "object", "optional": true, "description": "The cookie object which represents the cookie which was not stored. It is optional because sometimes complete cookie information is not available, such as in the case of parsing errors.", "typeRef": "Network.Cookie"}]);
898
898
  inspectorBackend.registerType("Network.ExemptedSetCookieWithReason", [{"name": "exemptionReason", "type": "string", "optional": false, "description": "The reason the cookie was exempted.", "typeRef": "Network.CookieExemptionReason"}, {"name": "cookieLine", "type": "string", "optional": false, "description": "The string representing this individual cookie as it would appear in the header.", "typeRef": null}, {"name": "cookie", "type": "object", "optional": false, "description": "The cookie object representing the cookie.", "typeRef": "Network.Cookie"}]);
899
899
  inspectorBackend.registerType("Network.AssociatedCookie", [{"name": "cookie", "type": "object", "optional": false, "description": "The cookie object representing the cookie which was not sent.", "typeRef": "Network.Cookie"}, {"name": "blockedReasons", "type": "array", "optional": false, "description": "The reason(s) the cookie was blocked. If empty means the cookie is included.", "typeRef": "Network.CookieBlockedReason"}, {"name": "exemptionReason", "type": "string", "optional": true, "description": "The reason the cookie should have been blocked by 3PCD but is exempted. A cookie could only have at most one exemption reason.", "typeRef": "Network.CookieExemptionReason"}]);
900
- inspectorBackend.registerType("Network.CookieParam", [{"name": "name", "type": "string", "optional": false, "description": "Cookie name.", "typeRef": null}, {"name": "value", "type": "string", "optional": false, "description": "Cookie value.", "typeRef": null}, {"name": "url", "type": "string", "optional": true, "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain, path, source port, and source scheme values of the created cookie.", "typeRef": null}, {"name": "domain", "type": "string", "optional": true, "description": "Cookie domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": true, "description": "Cookie path.", "typeRef": null}, {"name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure.", "typeRef": null}, {"name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only.", "typeRef": null}, {"name": "sameSite", "type": "string", "optional": true, "description": "Cookie SameSite type.", "typeRef": "Network.CookieSameSite"}, {"name": "expires", "type": "number", "optional": true, "description": "Cookie expiration date, session cookie if not set", "typeRef": "Network.TimeSinceEpoch"}, {"name": "priority", "type": "string", "optional": true, "description": "Cookie Priority.", "typeRef": "Network.CookiePriority"}, {"name": "sameParty", "type": "boolean", "optional": true, "description": "True if cookie is SameParty.", "typeRef": null}, {"name": "sourceScheme", "type": "string", "optional": true, "description": "Cookie source scheme type.", "typeRef": "Network.CookieSourceScheme"}, {"name": "sourcePort", "type": "number", "optional": true, "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port. An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. This is a temporary ability and it will be removed in the future.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "Cookie partition key. If not set, the cookie will be set as not partitioned.", "typeRef": "Network.CookiePartitionKey"}]);
900
+ inspectorBackend.registerType("Network.CookieParam", [{"name": "name", "type": "string", "optional": false, "description": "Cookie name.", "typeRef": null}, {"name": "value", "type": "string", "optional": false, "description": "Cookie value.", "typeRef": null}, {"name": "url", "type": "string", "optional": true, "description": "The request-URI to associate with the setting of the cookie. This value can affect the default domain, path, source port, and source scheme values of the created cookie.", "typeRef": null}, {"name": "domain", "type": "string", "optional": true, "description": "Cookie domain.", "typeRef": null}, {"name": "path", "type": "string", "optional": true, "description": "Cookie path.", "typeRef": null}, {"name": "secure", "type": "boolean", "optional": true, "description": "True if cookie is secure.", "typeRef": null}, {"name": "httpOnly", "type": "boolean", "optional": true, "description": "True if cookie is http-only.", "typeRef": null}, {"name": "sameSite", "type": "string", "optional": true, "description": "Cookie SameSite type.", "typeRef": "Network.CookieSameSite"}, {"name": "expires", "type": "number", "optional": true, "description": "Cookie expiration date, session cookie if not set", "typeRef": "Network.TimeSinceEpoch"}, {"name": "priority", "type": "string", "optional": true, "description": "Cookie Priority.", "typeRef": "Network.CookiePriority"}, {"name": "sourceScheme", "type": "string", "optional": true, "description": "Cookie source scheme type.", "typeRef": "Network.CookieSourceScheme"}, {"name": "sourcePort", "type": "number", "optional": true, "description": "Cookie source port. Valid values are {-1, [1, 65535]}, -1 indicates an unspecified port. An unspecified port value allows protocol clients to emulate legacy cookie scope for the port. This is a temporary ability and it will be removed in the future.", "typeRef": null}, {"name": "partitionKey", "type": "object", "optional": true, "description": "Cookie partition key. If not set, the cookie will be set as not partitioned.", "typeRef": "Network.CookiePartitionKey"}]);
901
901
  inspectorBackend.registerType("Network.AuthChallenge", [{"name": "source", "type": "string", "optional": true, "description": "Source of the authentication challenge.", "typeRef": null}, {"name": "origin", "type": "string", "optional": false, "description": "Origin of the challenger.", "typeRef": null}, {"name": "scheme", "type": "string", "optional": false, "description": "The authentication scheme used, such as basic or digest", "typeRef": null}, {"name": "realm", "type": "string", "optional": false, "description": "The realm of the challenge. May be empty.", "typeRef": null}]);
902
902
  inspectorBackend.registerType("Network.AuthChallengeResponse", [{"name": "response", "type": "string", "optional": false, "description": "The decision on what to do in response to the authorization challenge. Default means deferring to the default behavior of the net stack, which will likely either the Cancel authentication or display a popup dialog box.", "typeRef": null}, {"name": "username", "type": "string", "optional": true, "description": "The username to provide, possibly empty. Should only be set if response is ProvideCredentials.", "typeRef": null}, {"name": "password", "type": "string", "optional": true, "description": "The password to provide, possibly empty. Should only be set if response is ProvideCredentials.", "typeRef": null}]);
903
903
  inspectorBackend.registerType("Network.RequestPattern", [{"name": "urlPattern", "type": "string", "optional": true, "description": "Wildcards (`'*'` -> zero or more, `'?'` -> exactly one) are allowed. Escape character is backslash. Omitting is equivalent to `\\\"*\\\"`.", "typeRef": null}, {"name": "resourceType", "type": "string", "optional": true, "description": "If set, only requests for matching resource types will be intercepted.", "typeRef": "Network.ResourceType"}, {"name": "interceptionStage", "type": "string", "optional": true, "description": "Stage at which to begin intercepting requests. Default is Request.", "typeRef": "Network.InterceptionStage"}]);
@@ -771,8 +771,6 @@ export namespace Audits {
771
771
  ExcludeSameSiteNoneInsecure = 'ExcludeSameSiteNoneInsecure',
772
772
  ExcludeSameSiteLax = 'ExcludeSameSiteLax',
773
773
  ExcludeSameSiteStrict = 'ExcludeSameSiteStrict',
774
- ExcludeInvalidSameParty = 'ExcludeInvalidSameParty',
775
- ExcludeSamePartyCrossPartyContext = 'ExcludeSamePartyCrossPartyContext',
776
774
  ExcludeDomainNonASCII = 'ExcludeDomainNonASCII',
777
775
  ExcludeThirdPartyCookieBlockedInFirstPartySet = 'ExcludeThirdPartyCookieBlockedInFirstPartySet',
778
776
  ExcludeThirdPartyPhaseout = 'ExcludeThirdPartyPhaseout',
@@ -10673,11 +10671,6 @@ export namespace Network {
10673
10671
  * Cookie Priority
10674
10672
  */
10675
10673
  priority: CookiePriority;
10676
- /**
10677
- * True if cookie is SameParty.
10678
- * @deprecated
10679
- */
10680
- sameParty: boolean;
10681
10674
  /**
10682
10675
  * Cookie source scheme type.
10683
10676
  */
@@ -10719,8 +10712,6 @@ export namespace Network {
10719
10712
  SchemefulSameSiteStrict = 'SchemefulSameSiteStrict',
10720
10713
  SchemefulSameSiteLax = 'SchemefulSameSiteLax',
10721
10714
  SchemefulSameSiteUnspecifiedTreatedAsLax = 'SchemefulSameSiteUnspecifiedTreatedAsLax',
10722
- SamePartyFromCrossPartyContext = 'SamePartyFromCrossPartyContext',
10723
- SamePartyConflictsWithOtherAttributes = 'SamePartyConflictsWithOtherAttributes',
10724
10715
  NameValuePairExceedsMaxSize = 'NameValuePairExceedsMaxSize',
10725
10716
  DisallowedCharacter = 'DisallowedCharacter',
10726
10717
  NoCookieContent = 'NoCookieContent',
@@ -10744,7 +10735,6 @@ export namespace Network {
10744
10735
  SchemefulSameSiteStrict = 'SchemefulSameSiteStrict',
10745
10736
  SchemefulSameSiteLax = 'SchemefulSameSiteLax',
10746
10737
  SchemefulSameSiteUnspecifiedTreatedAsLax = 'SchemefulSameSiteUnspecifiedTreatedAsLax',
10747
- SamePartyFromCrossPartyContext = 'SamePartyFromCrossPartyContext',
10748
10738
  NameValuePairExceedsMaxSize = 'NameValuePairExceedsMaxSize',
10749
10739
  PortMismatch = 'PortMismatch',
10750
10740
  SchemeMismatch = 'SchemeMismatch',
@@ -10873,10 +10863,6 @@ export namespace Network {
10873
10863
  * Cookie Priority.
10874
10864
  */
10875
10865
  priority?: CookiePriority;
10876
- /**
10877
- * True if cookie is SameParty.
10878
- */
10879
- sameParty?: boolean;
10880
10866
  /**
10881
10867
  * Cookie source scheme type.
10882
10868
  */
@@ -12088,10 +12074,6 @@ export namespace Network {
12088
12074
  * Cookie Priority type.
12089
12075
  */
12090
12076
  priority?: CookiePriority;
12091
- /**
12092
- * True if cookie is SameParty.
12093
- */
12094
- sameParty?: boolean;
12095
12077
  /**
12096
12078
  * Cookie source scheme type.
12097
12079
  */
@@ -9,10 +9,6 @@
9
9
  * They need remain isolated for importing other function so
10
10
  * bundling them for production does not create issues.
11
11
  */
12
- /* eslint-disable @devtools/no-adopted-style-sheets --
13
- * The scripts in this file aren't executed as part of DevTools front-end,
14
- * but are injected into the page.
15
- **/
16
12
 
17
13
  export const AI_ASSISTANCE_CSS_CLASS_NAME = 'ai-style-change';
18
14
  export const FREESTYLER_WORLD_NAME = 'DevTools AI Assistance';
@@ -100,19 +96,9 @@ export const PAGE_EXPOSED_FUNCTIONS = ['setElementStyles'];
100
96
  /**
101
97
  * Please see fileoverview
102
98
  */
103
- function setupSetElementStyles(prefix: typeof AI_ASSISTANCE_CSS_CLASS_NAME): void {
104
- // Executed in another world
105
- const global = globalThis as unknown as {
106
- freestyler: FreestylerBinding,
107
- setElementStyles: unknown,
108
- };
109
- async function setElementStyles(
110
- el: HTMLElement&{
111
- // eslint-disable-next-line
112
- __freestylerClassName?: `${typeof AI_ASSISTANCE_CSS_CLASS_NAME}-${number}`,
113
- },
114
- styles: Record<string, string>,
115
- ): Promise<void> {
99
+ const setupSetElementStyles = `function setupSetElementStyles(prefix) {
100
+ const global = globalThis;
101
+ async function setElementStyles(el, styles) {
116
102
  let selector = el.tagName.toLowerCase();
117
103
  if (el.id) {
118
104
  selector = '#' + el.id;
@@ -131,7 +117,7 @@ function setupSetElementStyles(prefix: typeof AI_ASSISTANCE_CSS_CLASS_NAME): voi
131
117
 
132
118
  // __freestylerClassName is not exposed to the page due to this being
133
119
  // run in the isolated world.
134
- const className = el.__freestylerClassName ?? `${prefix}-${global.freestyler.id}`;
120
+ const className = el.__freestylerClassName ?? \`\${prefix}-\${global.freestyler.id}\`;
135
121
  el.__freestylerClassName = className;
136
122
  el.classList.add(className);
137
123
 
@@ -140,7 +126,6 @@ function setupSetElementStyles(prefix: typeof AI_ASSISTANCE_CSS_CLASS_NAME): voi
140
126
  // if it's kebab case.
141
127
  el.style.removeProperty(key);
142
128
  // If it's camel case.
143
- // @ts-expect-error this won't throw if wrong
144
129
  el.style[key] = '';
145
130
  }
146
131
 
@@ -168,7 +153,7 @@ function setupSetElementStyles(prefix: typeof AI_ASSISTANCE_CSS_CLASS_NAME): voi
168
153
  continue;
169
154
  }
170
155
 
171
- hasAiStyleChange = rule.selectorText.startsWith(`.${prefix}`);
156
+ hasAiStyleChange = rule.selectorText.startsWith(\`.\${prefix}\`);
172
157
  if (hasAiStyleChange) {
173
158
  stylesheet = sheet;
174
159
  break;
@@ -183,6 +168,6 @@ function setupSetElementStyles(prefix: typeof AI_ASSISTANCE_CSS_CLASS_NAME): voi
183
168
  }
184
169
 
185
170
  global.setElementStyles = setElementStyles;
186
- }
171
+ }`;
187
172
 
188
- export const injectedFunctions = `(${String(setupSetElementStyles)})('${AI_ASSISTANCE_CSS_CLASS_NAME}')`;
173
+ export const injectedFunctions = `(${setupSetElementStyles})('${AI_ASSISTANCE_CSS_CLASS_NAME}')`;
@@ -7400,6 +7400,18 @@ export const NativeFunctions = [
7400
7400
  name: "queryFeatureSupport",
7401
7401
  signatures: [["feature"]]
7402
7402
  },
7403
+ {
7404
+ name: "LanguageModelToolCall",
7405
+ signatures: [["init"]]
7406
+ },
7407
+ {
7408
+ name: "LanguageModelToolSuccess",
7409
+ signatures: [["init"]]
7410
+ },
7411
+ {
7412
+ name: "LanguageModelToolError",
7413
+ signatures: [["init"]]
7414
+ },
7403
7415
  {
7404
7416
  name: "registerAnimator",
7405
7417
  signatures: [["name","animatorCtor"]]
@@ -564,9 +564,7 @@ export class PreloadingSummaryView extends UI.Widget.VBox {
564
564
  this.contentElement.insertBefore(this.warningsContainer, this.contentElement.firstChild);
565
565
  this.warningsView.show(this.warningsContainer);
566
566
 
567
- const usedPreloadingContainer = new UI.Widget.VBox();
568
- usedPreloadingContainer.contentElement.appendChild(this.usedPreloading);
569
- usedPreloadingContainer.show(this.contentElement);
567
+ this.usedPreloading.show(this.contentElement);
570
568
  }
571
569
 
572
570
  override wasShown(): void {
@@ -1,7 +1,6 @@
1
1
  // Copyright 2023 The Chromium Authors
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
- /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
4
 
6
5
  import '../../../../ui/kit/kit.js';
7
6
  import '../../../../ui/components/report_view/report_view.js';
@@ -13,8 +12,6 @@ import type * as Platform from '../../../../core/platform/platform.js';
13
12
  import {assertNotNullOrUndefined} from '../../../../core/platform/platform.js';
14
13
  import * as SDK from '../../../../core/sdk/sdk.js';
15
14
  import * as Protocol from '../../../../generated/protocol.js';
16
- import * as LegacyWrapper from '../../../../ui/components/legacy_wrapper/legacy_wrapper.js';
17
- import * as RenderCoordinator from '../../../../ui/components/render_coordinator/render_coordinator.js';
18
15
  import * as UI from '../../../../ui/legacy/legacy.js';
19
16
  import {html, type LitTemplate, nothing, render} from '../../../../ui/lit/lit.js';
20
17
  import * as VisualLogging from '../../../../ui/visual_logging/visual_logging.js';
@@ -399,18 +396,17 @@ function renderBadge(config: Badge): LitTemplate {
399
396
 
400
397
  type View = (input: ViewInput, output: undefined, target: HTMLElement|ShadowRoot) => void;
401
398
 
402
- const DEFAULT_VIEW: View =
403
- ({speculativeLoadingStatusData, speculationsInitiatedSummaryData}: ViewInput, output, target): void => {
404
- // Disabled until https://crbug.com/1079231 is fixed.
405
- // clang-format off
399
+ const DEFAULT_VIEW: View = (input, _output, target) => {
400
+ // Disabled until https://crbug.com/1079231 is fixed.
401
+ // clang-format off
406
402
  render(html`
407
403
  <style>${usedPreloadingStyles}</style>
408
404
  <devtools-report>
409
- ${renderSpeculativeLoadingStatusForThisPageSections(speculativeLoadingStatusData)}
405
+ ${renderSpeculativeLoadingStatusForThisPageSections(input.speculativeLoadingStatusData)}
410
406
 
411
407
  <devtools-report-divider></devtools-report-divider>
412
408
 
413
- ${renderSpeculationsInitiatedByThisPageSummarySections(speculationsInitiatedSummaryData)}
409
+ ${renderSpeculationsInitiatedByThisPageSummarySections(input.speculationsInitiatedSummaryData)}
414
410
 
415
411
  <devtools-report-divider></devtools-report-divider>
416
412
 
@@ -423,20 +419,19 @@ const DEFAULT_VIEW: View =
423
419
  .context('learn-more')}
424
420
  >${i18nString(UIStrings.learnMore)}</x-link>
425
421
  </devtools-report-section>
426
- </devtools-report>`, target, {host: target instanceof ShadowRoot ? target.host : undefined});
427
- // clang-format on
428
- };
422
+ </devtools-report>`, target);
423
+ // clang-format on
424
+ };
429
425
 
430
426
  /**
431
427
  * TODO(kenoss): Rename this class and file once https://crrev.com/c/4933567 landed.
432
428
  * This also shows summary of speculations initiated by this page.
433
429
  **/
434
- export class UsedPreloadingView extends LegacyWrapper.LegacyWrapper.WrappableComponent<UI.Widget.VBox> {
435
- readonly #shadow = this.attachShadow({mode: 'open'});
430
+ export class UsedPreloadingView extends UI.Widget.VBox {
436
431
  readonly #view: View;
437
432
 
438
433
  constructor(view = DEFAULT_VIEW) {
439
- super();
434
+ super({useShadowDom: true});
440
435
  this.#view = view;
441
436
  }
442
437
 
@@ -448,17 +443,15 @@ export class UsedPreloadingView extends LegacyWrapper.LegacyWrapper.WrappableCom
448
443
 
449
444
  set data(data: UsedPreloadingViewData) {
450
445
  this.#data = data;
451
- void this.#render();
446
+ this.requestUpdate();
452
447
  }
453
448
 
454
- async #render(): Promise<void> {
449
+ override performUpdate(): void {
455
450
  const viewInput: ViewInput = {
456
451
  speculativeLoadingStatusData: this.#getSpeculativeLoadingStatusForThisPageData(),
457
452
  speculationsInitiatedSummaryData: this.#getSpeculationsInitiatedByThisPageSummaryData(),
458
453
  };
459
- await RenderCoordinator.write('UsedPreloadingView render', () => {
460
- this.#view(viewInput, undefined, this.#shadow);
461
- });
454
+ this.#view(viewInput, undefined, this.contentElement);
462
455
  }
463
456
 
464
457
  #isPrerenderLike(speculationAction: Protocol.Preload.SpeculationAction): boolean {
@@ -583,11 +576,3 @@ export class UsedPreloadingView extends LegacyWrapper.LegacyWrapper.WrappableCom
583
576
  return {badges, revealRuleSetView, revealAttemptViewWithFilter};
584
577
  }
585
578
  }
586
-
587
- customElements.define('devtools-resources-used-preloading-view', UsedPreloadingView);
588
-
589
- declare global {
590
- interface HTMLElementTagNameMap {
591
- 'devtools-resources-used-preloading-view': UsedPreloadingView;
592
- }
593
- }
@@ -6,9 +6,10 @@ import * as Common from '../../core/common/common.js';
6
6
  import * as Host from '../../core/host/host.js';
7
7
  import * as i18n from '../../core/i18n/i18n.js';
8
8
  import * as Root from '../../core/root/root.js';
9
+ import * as AiCodeGeneration from '../../models/ai_code_generation/ai_code_generation.js';
9
10
  import * as Snackbars from '../../ui/components/snackbars/snackbars.js';
10
11
  import * as UI from '../../ui/legacy/legacy.js';
11
- import {html, nothing, render} from '../../ui/lit/lit.js';
12
+ import {html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
12
13
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
13
14
 
14
15
  import styles from './aiCodeCompletionTeaser.css.js';
@@ -61,17 +62,32 @@ const UIStringsNotTranslate = {
61
62
  */
62
63
  freDisclaimerTextAiWontAlwaysGetItRight: 'This feature uses AI and won’t always get it right',
63
64
  /**
64
- * @description Second disclaimer item text for the fre dialog.
65
+ * @description Code completion disclaimer item text for the fre dialog.
66
+ */
67
+ freDisclaimerTextAsYouType:
68
+ 'As you type, relevant data is being send to Google to generate code suggestions. Press Tab to accept.',
69
+ /**
70
+ * @description Code generation disclaimer item text for the fre dialog.
71
+ */
72
+ freDisclaimerDescribeCodeInComment:
73
+ 'In Console or Sources, describe the code you need in a comment, then press Ctrl+I to generate it.',
74
+ /**
75
+ * @description Code generation disclaimer item text for the fre dialog.
76
+ */
77
+ freDisclaimerDescribeCodeInCommentForMacOs:
78
+ 'In Console or Sources, describe the code you need in a comment, then press Cmd+I to generate it.',
79
+ /**
80
+ * @description Privacy disclaimer item text for the fre dialog.
65
81
  */
66
82
  freDisclaimerTextPrivacy:
67
83
  'To generate code suggestions, your console input, the history of your current console session, the currently inspected CSS, and the contents of the currently open file are shared with Google. This data may be seen by human reviewers to improve this feature.',
68
84
  /**
69
- * @description Second disclaimer item text for the fre dialog when enterprise logging is off.
85
+ * @description Privacy disclaimer item text for the fre dialog when enterprise logging is off.
70
86
  */
71
87
  freDisclaimerTextPrivacyNoLogging:
72
88
  'To generate code suggestions, your console input, the history of your current console session, the currently inspected CSS, and the contents of the currently open file are shared with Google. This data will not be used to improve Google’s AI models. Your organization may change these settings at any time.',
73
89
  /**
74
- * @description Third disclaimer item text for the fre dialog.
90
+ * @description Last disclaimer item text for the fre dialog.
75
91
  */
76
92
  freDisclaimerTextUseWithCaution: 'Use generated code snippets with caution',
77
93
  /**
@@ -192,15 +208,34 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
192
208
  }
193
209
  }
194
210
 
195
- onAction = async(event: Event): Promise<void> => {
196
- event.preventDefault();
197
- const result = await FreDialog.show({
198
- header: {iconName: 'smart-assistant', text: lockedString(UIStringsNotTranslate.freDisclaimerHeader)},
199
- reminderItems: [
200
- {
201
- iconName: 'psychiatry',
202
- content: lockedString(UIStringsNotTranslate.freDisclaimerTextAiWontAlwaysGetItRight),
203
- },
211
+ #createReminderItems(): Array<{
212
+ iconName: string,
213
+ content: Common.UIString.LocalizedString|LitTemplate,
214
+ }> {
215
+ const reminderItems: Array<{
216
+ iconName: string,
217
+ content: Common.UIString.LocalizedString | LitTemplate,
218
+ }> = [{
219
+ iconName: 'psychiatry',
220
+ content: lockedString(UIStringsNotTranslate.freDisclaimerTextAiWontAlwaysGetItRight),
221
+ }];
222
+
223
+ const devtoolsLocale = i18n.DevToolsLocale.DevToolsLocale.instance();
224
+ if (AiCodeGeneration.AiCodeGeneration.AiCodeGeneration.isAiCodeGenerationEnabled(devtoolsLocale.locale)) {
225
+ reminderItems.push(
226
+ {
227
+ iconName: 'code',
228
+ content: lockedString(UIStringsNotTranslate.freDisclaimerTextAsYouType),
229
+ },
230
+ {
231
+ iconName: 'text-analysis',
232
+ content: Host.Platform.isMac() ?
233
+ lockedString(UIStringsNotTranslate.freDisclaimerDescribeCodeInCommentForMacOs) :
234
+ lockedString(UIStringsNotTranslate.freDisclaimerDescribeCodeInComment),
235
+ });
236
+ }
237
+
238
+ reminderItems.push(
204
239
  {
205
240
  iconName: 'google',
206
241
  content: this.#noLogging ? lockedString(UIStringsNotTranslate.freDisclaimerTextPrivacyNoLogging) :
@@ -217,8 +252,16 @@ export class AiCodeCompletionTeaser extends UI.Widget.Widget {
217
252
  })}
218
253
  >${lockedString(UIStringsNotTranslate.freDisclaimerTextUseWithCaution)}</x-link>`,
219
254
  // clang-format on
220
- }
221
- ],
255
+ });
256
+ return reminderItems;
257
+ }
258
+
259
+ onAction = async(event: Event): Promise<void> => {
260
+ event.preventDefault();
261
+
262
+ const result = await FreDialog.show({
263
+ header: {iconName: 'smart-assistant', text: lockedString(UIStringsNotTranslate.freDisclaimerHeader)},
264
+ reminderItems: this.#createReminderItems(),
222
265
  onLearnMoreClick: () => {
223
266
  void UI.ViewManager.ViewManager.instance().showView('chrome-ai');
224
267
  },
@@ -2,7 +2,7 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
 
5
- import * as Common from '../../core/common/common.js';
5
+ import type * as Common from '../../core/common/common.js';
6
6
  import type * as SDK from '../../core/sdk/sdk.js';
7
7
  import * as UI from '../../ui/legacy/legacy.js';
8
8
 
@@ -10,16 +10,11 @@ import {type ComputedStyleModel, type CSSModelChangedEvent, Events} from './Comp
10
10
 
11
11
  export class ElementsSidebarPane extends UI.Widget.VBox {
12
12
  protected computedStyleModelInternal: ComputedStyleModel;
13
- private readonly updateThrottler: Common.Throttler.Throttler;
14
- private updateWhenVisible: boolean;
15
13
  constructor(computedStyleModel: ComputedStyleModel, delegatesFocus?: boolean) {
16
14
  super({useShadowDom: true, delegatesFocus, classes: ['flex-none']});
17
15
  this.computedStyleModelInternal = computedStyleModel;
18
16
  this.computedStyleModelInternal.addEventListener(Events.CSS_MODEL_CHANGED, this.onCSSModelChanged, this);
19
17
  this.computedStyleModelInternal.addEventListener(Events.COMPUTED_STYLE_CHANGED, this.onComputedStyleChanged, this);
20
-
21
- this.updateThrottler = new Common.Throttler.Throttler(100);
22
- this.updateWhenVisible = false;
23
18
  }
24
19
 
25
20
  node(): SDK.DOMModel.DOMNode|null {
@@ -34,29 +29,10 @@ export class ElementsSidebarPane extends UI.Widget.VBox {
34
29
  return this.computedStyleModelInternal;
35
30
  }
36
31
 
37
- async doUpdate(): Promise<void> {
32
+ override async performUpdate(): Promise<void> {
38
33
  return;
39
34
  }
40
35
 
41
- update(): void {
42
- this.updateWhenVisible = !this.isShowing();
43
- if (this.updateWhenVisible) {
44
- return;
45
- }
46
- void this.updateThrottler.schedule(innerUpdate.bind(this));
47
-
48
- function innerUpdate(this: ElementsSidebarPane): Promise<void> {
49
- return this.isShowing() ? this.doUpdate() : Promise.resolve();
50
- }
51
- }
52
-
53
- override wasShown(): void {
54
- super.wasShown();
55
- if (this.updateWhenVisible) {
56
- this.update();
57
- }
58
- }
59
-
60
36
  onCSSModelChanged(_event: Common.EventTarget.EventTargetEvent<CSSModelChangedEvent|null>): void {
61
37
  }
62
38
 
@@ -2,6 +2,7 @@
2
2
  // Use of this source code is governed by a BSD-style license that can be
3
3
  // found in the LICENSE file.
4
4
  /* eslint-disable @devtools/no-imperative-dom-api */
5
+ /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
6
 
6
7
  /*
7
8
  * Copyright (C) 2007 Apple Inc. All rights reserved.
@@ -35,22 +36,21 @@ import * as Common from '../../core/common/common.js';
35
36
  import * as Platform from '../../core/platform/platform.js';
36
37
  import * as SDK from '../../core/sdk/sdk.js';
37
38
  import * as UI from '../../ui/legacy/legacy.js';
39
+ import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
38
40
  import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
39
41
 
40
42
  import type {ComputedStyleModel} from './ComputedStyleModel.js';
41
43
  import {ElementsSidebarPane} from './ElementsSidebarPane.js';
42
44
  import metricsSidebarPaneStyles from './metricsSidebarPane.css.js';
43
45
 
46
+ const {live} = Directives;
47
+
44
48
  export class MetricsSidebarPane extends ElementsSidebarPane {
45
49
  originalPropertyData: SDK.CSSProperty.CSSProperty|null;
46
50
  previousPropertyDataCandidate: SDK.CSSProperty.CSSProperty|null;
47
51
  private inlineStyle: SDK.CSSStyleDeclaration.CSSStyleDeclaration|null;
48
52
  private highlightMode: string;
49
- private boxElements: Array<{
50
- element: HTMLElement,
51
- name: string,
52
- backgroundColor: string,
53
- }>;
53
+ private computedStyle: Map<string, string>|null;
54
54
  private isEditingMetrics?: boolean;
55
55
 
56
56
  constructor(computedStyleModel: ComputedStyleModel) {
@@ -61,15 +61,15 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
61
61
  this.previousPropertyDataCandidate = null;
62
62
  this.inlineStyle = null;
63
63
  this.highlightMode = '';
64
- this.boxElements = [];
64
+ this.computedStyle = null;
65
65
  this.contentElement.setAttribute('jslog', `${VisualLogging.pane('styles-metrics')}`);
66
66
  }
67
67
 
68
- override doUpdate(): Promise<void> {
68
+ override async performUpdate(): Promise<void> {
69
69
  // "style" attribute might have changed. Update metrics unless they are being edited
70
70
  // (if a CSS property is added, a StyleSheetChanged event is dispatched).
71
71
  if (this.isEditingMetrics) {
72
- return Promise.resolve();
72
+ return await Promise.resolve();
73
73
  }
74
74
 
75
75
  // FIXME: avoid updates of a collapsed pane.
@@ -78,18 +78,20 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
78
78
  if (!node || node.nodeType() !== Node.ELEMENT_NODE || !cssModel) {
79
79
  this.contentElement.removeChildren();
80
80
  this.element.classList.add('collapsed');
81
- return Promise.resolve();
81
+ return await Promise.resolve();
82
82
  }
83
83
 
84
84
  function callback(this: MetricsSidebarPane, style: Map<string, string>|null): void {
85
85
  if (!style || this.node() !== node) {
86
+ this.computedStyle = null;
86
87
  return;
87
88
  }
89
+ this.computedStyle = style;
88
90
  this.updateMetrics(style);
89
91
  }
90
92
 
91
93
  if (!node.id) {
92
- return Promise.resolve();
94
+ return await Promise.resolve();
93
95
  }
94
96
 
95
97
  const promises = [
@@ -100,11 +102,11 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
100
102
  }
101
103
  }),
102
104
  ];
103
- return Promise.all(promises) as unknown as Promise<void>;
105
+ return await (Promise.all(promises) as unknown as Promise<void>);
104
106
  }
105
107
 
106
108
  override onCSSModelChanged(): void {
107
- this.update();
109
+ this.requestUpdate();
108
110
  }
109
111
 
110
112
  /**
@@ -153,47 +155,35 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
153
155
  SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight();
154
156
  }
155
157
 
156
- for (const {element, name, backgroundColor} of this.boxElements) {
157
- const shouldHighlight = !node || mode === 'all' || name === mode;
158
- element.style.backgroundColor = shouldHighlight ? backgroundColor : '';
159
- element.classList.toggle('highlighted', shouldHighlight);
158
+ if (this.computedStyle) {
159
+ this.updateMetrics(this.computedStyle, mode);
160
160
  }
161
161
  }
162
162
 
163
- private updateMetrics(style: Map<string, string>): void {
163
+ private updateMetrics(style: Map<string, string>, highlightedMode = 'all'): void {
164
164
  // Updating with computed style.
165
- const metricsElement = document.createElement('div');
166
- metricsElement.className = 'metrics';
167
165
  const self = this;
168
166
 
169
167
  function createBoxPartElement(
170
- this: MetricsSidebarPane, style: Map<string, string>, name: string, side: string,
171
- suffix: string): HTMLDivElement {
172
- const element = document.createElement('div');
173
- element.className = side;
174
-
168
+ this: MetricsSidebarPane, style: Map<string, string>, name: string, side: string, suffix: string): LitTemplate {
175
169
  const propertyName = (name !== 'position' ? name + '-' : '') + side + suffix;
176
170
  let value = style.get(propertyName);
177
- if (value === undefined) {
178
- return element;
179
- }
180
171
 
181
172
  if (value === '' || (name !== 'position' && value === 'unset')) {
182
173
  value = '\u2012';
183
174
  } else if (name === 'position' && value === 'auto') {
184
175
  value = '\u2012';
185
176
  }
186
- value = value.replace(/px$/, '');
187
- value = Platform.NumberUtilities.toFixedIfFloating(value);
188
-
189
- element.textContent = value;
190
- element.setAttribute('jslog', `${VisualLogging.value(propertyName).track({
191
- dblclick: true,
192
- keydown: 'Enter|Escape|ArrowUp|ArrowDown|PageUp|PageDown',
193
- change: true,
194
- })}`);
195
- element.addEventListener('dblclick', this.startEditing.bind(this, element, name, propertyName, style), false);
196
- return element;
177
+ value = value?.replace(/px$/, '');
178
+ value = value ? Platform.NumberUtilities.toFixedIfFloating(value) : value;
179
+ // clang-format off
180
+ return html`<div class=${side} jslog=${VisualLogging.value(propertyName).track({
181
+ dblclick: true, keydown: 'Enter|Escape|ArrowUp|ArrowDown|PageUp|PageDown', change: true,
182
+ })}
183
+ @dblclick=${(e: Event) => this.startEditing(e.currentTarget, name, propertyName, style)}
184
+ .innerText=${live(value ?? '')}>
185
+ </div>`;
186
+ // clang-format on
197
187
  }
198
188
 
199
189
  function getContentAreaWidthPx(style: Map<string, string>): string {
@@ -263,8 +253,7 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
263
253
  Common.Color.Legacy.fromRGBA([0, 0, 0, 0]),
264
254
  ];
265
255
  const boxLabels = ['content', 'padding', 'border', 'margin', 'position'];
266
- let previousBox: HTMLDivElement|null = null;
267
- this.boxElements = [];
256
+ let previousBox: LitTemplate = nothing;
268
257
  for (let i = 0; i < boxes.length; ++i) {
269
258
  const name = boxes[i];
270
259
  const display = style.get('display');
@@ -282,76 +271,64 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
282
271
  continue;
283
272
  }
284
273
 
285
- const boxElement = document.createElement('div');
286
- boxElement.className = `${name} highlighted`;
274
+ const node = this.node();
275
+ const shouldHighlight = !node || highlightedMode === 'all' || name === highlightedMode;
287
276
  const backgroundColor = boxColors[i].asString(Common.Color.Format.RGBA) || '';
288
- boxElement.style.backgroundColor = backgroundColor;
289
- boxElement.setAttribute('jslog', `${VisualLogging.metricsBox().context(name).track({hover: true})}`);
290
- boxElement.addEventListener(
291
- 'mouseover', this.highlightDOMNode.bind(this, true, name === 'position' ? 'all' : name), false);
292
- this.boxElements.push({element: boxElement, name, backgroundColor});
293
-
294
- if (name === 'content') {
295
- const widthElement = document.createElement('span');
296
- widthElement.textContent = getContentAreaWidthPx(style);
297
- widthElement.addEventListener(
298
- 'dblclick', this.startEditing.bind(this, widthElement, 'width', 'width', style), false);
299
- widthElement.setAttribute('jslog', `${VisualLogging.value('width').track({
300
- dblclick: true,
301
- keydown: 'Enter|Escape|ArrowUp|ArrowDown|PageUp|PageDown',
302
- change: true,
303
- })}`);
304
-
305
- const heightElement = document.createElement('span');
306
- heightElement.textContent = getContentAreaHeightPx(style);
307
- heightElement.addEventListener(
308
- 'dblclick', this.startEditing.bind(this, heightElement, 'height', 'height', style), false);
309
- heightElement.setAttribute('jslog', `${VisualLogging.value('height').track({
310
- dblclick: true,
311
- keydown: 'Enter|Escape|ArrowUp|ArrowDown|PageUp|PageDown',
312
- change: true,
313
- })}`);
314
-
315
- const timesElement = document.createElement('span');
316
- timesElement.textContent = ' × ';
317
-
318
- boxElement.appendChild(widthElement);
319
- boxElement.appendChild(timesElement);
320
- boxElement.appendChild(heightElement);
321
- } else {
322
- const suffix = (name === 'border' ? '-width' : '');
323
277
 
324
- const labelElement = document.createElement('div');
325
- labelElement.className = 'label';
326
- labelElement.textContent = boxLabels[i];
327
- boxElement.appendChild(labelElement);
328
-
329
- boxElement.appendChild(createBoxPartElement.call(this, style, name, 'top', suffix));
330
- boxElement.appendChild(document.createElement('br'));
331
- boxElement.appendChild(createBoxPartElement.call(this, style, name, 'left', suffix));
332
-
333
- if (previousBox) {
334
- boxElement.appendChild(previousBox);
335
- }
336
-
337
- boxElement.appendChild(createBoxPartElement.call(this, style, name, 'right', suffix));
338
- boxElement.appendChild(document.createElement('br'));
339
- boxElement.appendChild(createBoxPartElement.call(this, style, name, 'bottom', suffix));
340
- }
341
-
342
- previousBox = boxElement;
278
+ const suffix = (name === 'border' ? '-width' : '');
279
+ // clang-format off
280
+ const box: LitTemplate = html`
281
+ <div
282
+ class="${name} ${shouldHighlight ? 'highlighted' : ''}"
283
+ style="background-color: ${shouldHighlight ? backgroundColor : ''}"
284
+ jslog=${VisualLogging.metricsBox().context(name).track({hover: true})}
285
+ @mouseover=${this.highlightDOMNode.bind(this, true, name === 'position' ? 'all' : name)}>
286
+ ${name === 'content' ? html`
287
+ <span jslog=${VisualLogging.value('width').track({
288
+ dblclick: true,
289
+ keydown: 'Enter|Escape|ArrowUp|ArrowDown|PageUp|PageDown',
290
+ change: true,
291
+ })}
292
+ @dblclick=${(e: Event) => this.startEditing(e.currentTarget, 'width', 'width', style)}
293
+ .innerText=${live(getContentAreaWidthPx(style))}>
294
+ </span>
295
+ <span> × </span>
296
+ <span jslog=${VisualLogging.value('height').track({
297
+ dblclick: true,
298
+ keydown: 'Enter|Escape|ArrowUp|ArrowDown|PageUp|PageDown',
299
+ change: true,
300
+ })}
301
+ @dblclick=${(e: Event) => this.startEditing(e.currentTarget, 'height', 'height', style)}
302
+ .innerText=${live(getContentAreaHeightPx(style))}>
303
+ </span>` : html`
304
+ <div class="label">${boxLabels[i]}</div>
305
+ ${createBoxPartElement.call(this, style, name, 'top', suffix)}
306
+ <br>
307
+ ${createBoxPartElement.call(this, style, name, 'left', suffix)}
308
+ ${previousBox}
309
+ ${createBoxPartElement.call(this, style, name, 'right', suffix)}
310
+ <br>
311
+ ${createBoxPartElement.call(this, style, name, 'bottom', suffix)}`}
312
+ </div>`;
313
+ // clang-format on
314
+
315
+ previousBox = box;
343
316
  }
344
- if (previousBox) {
345
- metricsElement.appendChild(previousBox);
346
- }
347
- metricsElement.addEventListener('mouseover', this.highlightDOMNode.bind(this, false, 'all'), false);
348
- metricsElement.addEventListener('mouseleave', this.highlightDOMNode.bind(this, false, 'all'), false);
349
- this.contentElement.removeChildren();
350
- this.contentElement.appendChild(metricsElement);
317
+ // clang-format off
318
+ render(html`
319
+ <div class="metrics" @mouseover=${this.highlightDOMNode.bind(this, false, 'all')}
320
+ @mouseleave=${this.highlightDOMNode.bind(this, false, 'all')}>
321
+ ${previousBox}
322
+ </div>`, this.contentElement);
323
+ // clang-format on
351
324
  this.element.classList.remove('collapsed');
352
325
  }
353
326
 
354
- startEditing(targetElement: Element, box: string, styleProperty: string, computedStyle: Map<string, string>): void {
327
+ startEditing(target: EventTarget|null, box: string, styleProperty: string, computedStyle: Map<string, string>): void {
328
+ if (!(target instanceof Element)) {
329
+ return;
330
+ }
331
+ const targetElement = target as Element;
355
332
  if (UI.UIUtils.isBeingEdited(targetElement)) {
356
333
  return;
357
334
  }
@@ -429,7 +406,7 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
429
406
  }
430
407
  }
431
408
  this.editingEnded(element, context);
432
- this.update();
409
+ this.requestUpdate();
433
410
  }
434
411
 
435
412
  private applyUserInput(
@@ -519,7 +496,7 @@ export class MetricsSidebarPane extends ElementsSidebarPane {
519
496
  }
520
497
 
521
498
  if (commitEditor) {
522
- this.update();
499
+ this.requestUpdate();
523
500
  }
524
501
  }
525
502
  }
@@ -208,7 +208,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
208
208
  super(computedStyleModel, true /* delegatesFocus */);
209
209
  this.setMinimumSize(96, 26);
210
210
  this.registerRequiredCSS(stylesSidebarPaneStyles);
211
- Common.Settings.Settings.instance().moduleSetting('text-editor-indent').addChangeListener(this.update.bind(this));
211
+ Common.Settings.Settings.instance().moduleSetting('text-editor-indent').addChangeListener(this.requestUpdate, this);
212
212
  this.toolbarPaneElement = this.createStylesSidebarToolbar();
213
213
  this.noMatchesElement = this.contentElement.createChild('div', 'gray-info-message hidden');
214
214
  this.noMatchesElement.textContent = i18nString(UIStrings.noMatchingSelectorOrStyle);
@@ -330,7 +330,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
330
330
  revealProperty(cssProperty: SDK.CSSProperty.CSSProperty): void {
331
331
  void this.decorator.highlightProperty(cssProperty);
332
332
  this.lastRevealedProperty = cssProperty;
333
- this.update();
333
+ this.requestUpdate();
334
334
  }
335
335
 
336
336
  jumpToProperty(propertyName: string, sectionName?: string, blockName?: string): boolean {
@@ -366,7 +366,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
366
366
  this.#swatchPopoverHelper.hide();
367
367
  this.#updateAbortController?.abort();
368
368
  this.resetCache();
369
- this.update();
369
+ this.requestUpdate();
370
370
  }
371
371
 
372
372
  private sectionsContainerKeyDown(event: Event): void {
@@ -534,7 +534,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
534
534
  this.nodeStylesUpdatedForTest(node, false);
535
535
  }
536
536
 
537
- override async doUpdate(): Promise<void> {
537
+ override async performUpdate(): Promise<void> {
538
538
  this.#updateAbortController?.abort();
539
539
  this.#updateAbortController = new AbortController();
540
540
  await this.#innerDoUpdate(this.#updateAbortController.signal);
@@ -745,7 +745,7 @@ export class StylesSidebarPane extends Common.ObjectWrapper.eventMixin<EventType
745
745
  }
746
746
 
747
747
  this.resetCache();
748
- this.update();
748
+ this.requestUpdate();
749
749
  }
750
750
 
751
751
  #scheduleResetUpdateIfNotEditing(): void {
@@ -108,6 +108,41 @@ export function rotateFlexDirectionIcon(direction: PhysicalDirection): IconInfo
108
108
  };
109
109
  }
110
110
 
111
+ /**
112
+ * Rotates the grid direction icon in such way that it indicates
113
+ * the desired `direction` and the arrow in the icon is always at the bottom
114
+ * or at the right.
115
+ *
116
+ * By default, the icon is pointing top-down with the arrow on the right-hand side.
117
+ */
118
+ export function rotateGridDirectionIcon(direction: PhysicalDirection): IconInfo {
119
+ // Default to LTR.
120
+ let flipX = true;
121
+ let flipY = false;
122
+ let rotate = -90;
123
+
124
+ if (direction === PhysicalDirection.RIGHT_TO_LEFT) {
125
+ rotate = 90;
126
+ flipY = false;
127
+ flipX = false;
128
+ } else if (direction === PhysicalDirection.TOP_TO_BOTTOM) {
129
+ rotate = 0;
130
+ flipX = false;
131
+ flipY = false;
132
+ } else if (direction === PhysicalDirection.BOTTOM_TO_TOP) {
133
+ rotate = 0;
134
+ flipX = false;
135
+ flipY = true;
136
+ }
137
+
138
+ return {
139
+ iconName: 'grid-direction',
140
+ rotate,
141
+ scaleX: flipX ? -1 : 1,
142
+ scaleY: flipY ? -1 : 1,
143
+ };
144
+ }
145
+
111
146
  export function rotateAlignContentIcon(iconName: string, direction: PhysicalDirection): IconInfo {
112
147
  return {
113
148
  iconName,
@@ -156,6 +191,14 @@ function flexDirectionIcon(value: string): (styles: ComputedStyles) => IconInfo
156
191
  return getIcon;
157
192
  }
158
193
 
194
+ function gridDirectionIcon(value: string): (styles: ComputedStyles) => IconInfo {
195
+ function getIcon(computedStyles: ComputedStyles): IconInfo {
196
+ const directions = getPhysicalDirections(computedStyles);
197
+ return rotateGridDirectionIcon(directions[value]);
198
+ }
199
+ return getIcon;
200
+ }
201
+
159
202
  function flexAlignContentIcon(iconName: string): (styles: ComputedStyles) => IconInfo {
160
203
  function getIcon(computedStyles: ComputedStyles): IconInfo {
161
204
  const directions = getPhysicalDirections(computedStyles);
@@ -178,7 +221,9 @@ function flexAlignContentIcon(iconName: string): (styles: ComputedStyles) => Ico
178
221
  function gridAlignContentIcon(iconName: string): (styles: ComputedStyles) => IconInfo {
179
222
  function getIcon(computedStyles: ComputedStyles): IconInfo {
180
223
  const directions = getPhysicalDirections(computedStyles);
181
- return rotateAlignContentIcon(iconName, directions.column);
224
+ const gridAutoFlow = computedStyles.get('grid-auto-flow') || 'row';
225
+ const direction = gridAutoFlow.includes('column') ? directions.row : directions.column;
226
+ return rotateAlignContentIcon(iconName, direction);
182
227
  }
183
228
  return getIcon;
184
229
  }
@@ -194,7 +239,9 @@ function flexJustifyContentIcon(iconName: string): (styles: ComputedStyles) => I
194
239
  function gridJustifyContentIcon(iconName: string): (styles: ComputedStyles) => IconInfo {
195
240
  function getIcon(computedStyles: ComputedStyles): IconInfo {
196
241
  const directions = getPhysicalDirections(computedStyles);
197
- return rotateJustifyContentIcon(iconName, directions.row);
242
+ const gridAutoFlow = computedStyles.get('grid-auto-flow') || 'row';
243
+ const direction = gridAutoFlow.includes('column') ? directions.column : directions.row;
244
+ return rotateJustifyContentIcon(iconName, direction);
198
245
  }
199
246
  return getIcon;
200
247
  }
@@ -202,7 +249,9 @@ function gridJustifyContentIcon(iconName: string): (styles: ComputedStyles) => I
202
249
  function gridJustifyItemsIcon(iconName: string): (styles: ComputedStyles) => IconInfo {
203
250
  function getIcon(computedStyles: ComputedStyles): IconInfo {
204
251
  const directions = getPhysicalDirections(computedStyles);
205
- return rotateJustifyItemsIcon(iconName, directions.row);
252
+ const gridAutoFlow = computedStyles.get('grid-auto-flow') || 'row';
253
+ const direction = gridAutoFlow.includes('column') ? directions.column : directions.row;
254
+ return rotateJustifyItemsIcon(iconName, direction);
206
255
  }
207
256
  return getIcon;
208
257
  }
@@ -229,7 +278,9 @@ function flexAlignItemsIcon(iconName: string): (styles: ComputedStyles) => IconI
229
278
  function gridAlignItemsIcon(iconName: string): (styles: ComputedStyles) => IconInfo {
230
279
  function getIcon(computedStyles: ComputedStyles): IconInfo {
231
280
  const directions = getPhysicalDirections(computedStyles);
232
- return rotateAlignItemsIcon(iconName, directions.column);
281
+ const gridAutoFlow = computedStyles.get('grid-auto-flow') || 'row';
282
+ const direction = gridAutoFlow.includes('column') ? directions.row : directions.column;
283
+ return rotateAlignItemsIcon(iconName, direction);
233
284
  }
234
285
  return getIcon;
235
286
  }
@@ -338,6 +389,8 @@ const flexItemIcons = new Map([
338
389
  ]);
339
390
 
340
391
  const gridContainerIcons = new Map([
392
+ ['grid-auto-flow: row', gridDirectionIcon('row')],
393
+ ['grid-auto-flow: column', gridDirectionIcon('column')],
341
394
  ['align-content: center', gridAlignContentIcon('align-content-center')],
342
395
  ['align-content: space-around', gridAlignContentIcon('align-content-space-around')],
343
396
  ['align-content: space-between', gridAlignContentIcon('align-content-space-between')],
@@ -4,8 +4,10 @@
4
4
  /* eslint-disable @devtools/no-lit-render-outside-of-view */
5
5
 
6
6
  import '../../../ui/kit/kit.js';
7
+ import '../../../ui/legacy/legacy.js';
7
8
 
8
9
  import * as i18n from '../../../core/i18n/i18n.js';
10
+ import * as Input from '../../../ui/components/input/input.js';
9
11
  import * as Lit from '../../../ui/lit/lit.js';
10
12
  import * as VisualLogging from '../../../ui/visual_logging/visual_logging.js';
11
13
 
@@ -25,6 +27,10 @@ const UIStrings = {
25
27
  * @example {row} propertyValue
26
28
  */
27
29
  deselectButton: 'Remove {propertyName}: {propertyValue}',
30
+ /**
31
+ * @description Label for the dense checkbox in the grid-auto-flow editor.
32
+ */
33
+ denseLabel: 'Dense',
28
34
  } as const;
29
35
  const str_ = i18n.i18n.registerUIStrings('panels/elements/components/StylePropertyEditor.ts', UIStrings);
30
36
  const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
@@ -89,6 +95,7 @@ export class StylePropertyEditor extends HTMLElement {
89
95
  // clang-format off
90
96
  render(html`
91
97
  <style>${stylePropertyEditorStyles}</style>
98
+ <style>${Input.checkboxStyles}</style>
92
99
  <div class="container">
93
100
  ${this.editableProperties.map(prop => this.#renderProperty(prop))}
94
101
  </div>
@@ -106,6 +113,12 @@ export class StylePropertyEditor extends HTMLElement {
106
113
  'property-value': true,
107
114
  'not-authored': notAuthored,
108
115
  });
116
+
117
+ // Special handling for grid-auto-flow with dense checkbox
118
+ if (prop.propertyName === 'grid-auto-flow') {
119
+ return this.#renderGridAutoFlowProperty(prop, shownValue, classes);
120
+ }
121
+
109
122
  return html`<div class="row">
110
123
  <div class="property">
111
124
  <span class="property-name">${prop.propertyName}</span>: <span class=${classes}>${shownValue}</span>
@@ -116,6 +129,55 @@ export class StylePropertyEditor extends HTMLElement {
116
129
  </div>`;
117
130
  }
118
131
 
132
+ #renderGridAutoFlowProperty(
133
+ prop: EditableProperty, shownValue: string|undefined,
134
+ classes: ReturnType<typeof Directives.classMap>): Lit.TemplateResult {
135
+ const authoredValue = this.#authoredProperties.get(prop.propertyName);
136
+
137
+ const isDense = authoredValue === 'dense' || authoredValue === 'row dense' || authoredValue === 'column dense';
138
+ const isRow = authoredValue === 'row' || authoredValue === 'row dense';
139
+ const isColumn = authoredValue === 'column' || authoredValue === 'column dense';
140
+
141
+ return html`<div class="row">
142
+ <div class="property">
143
+ <span class="property-name">${prop.propertyName}</span>: <span class=${classes}>${shownValue}</span>
144
+ </div>
145
+ <div class="buttons">
146
+ ${this.#renderButton('row', prop.propertyName, isRow)}
147
+ ${this.#renderButton('column', prop.propertyName, isColumn)}
148
+ <devtools-checkbox
149
+ .checked=${isDense}
150
+ @change=${(e: Event) => this.#onDenseCheckboxChange(e, isRow, isColumn)}
151
+ >
152
+ ${i18nString(UIStrings.denseLabel)}
153
+ </devtools-checkbox>
154
+ </div>
155
+ </div>`;
156
+ }
157
+
158
+ #onDenseCheckboxChange(e: Event, isRow: boolean, isColumn: boolean): void {
159
+ const checked = (e.target as HTMLInputElement).checked;
160
+ const propertyName = 'grid-auto-flow';
161
+ const currentValue = this.#authoredProperties.get(propertyName);
162
+
163
+ let newValue = '';
164
+ if (isRow) {
165
+ newValue = checked ? 'row dense' : 'row';
166
+ } else if (isColumn) {
167
+ newValue = checked ? 'column dense' : 'column';
168
+ } else {
169
+ newValue = checked ? 'dense' : '';
170
+ }
171
+
172
+ if (currentValue) {
173
+ this.dispatchEvent(new PropertyDeselectedEvent(propertyName, currentValue));
174
+ }
175
+
176
+ if (newValue) {
177
+ this.dispatchEvent(new PropertySelectedEvent(propertyName, newValue));
178
+ }
179
+ }
180
+
119
181
  #renderButton(propertyValue: string, propertyName: string, selected = false): Lit.TemplateResult {
120
182
  const query = `${propertyName}: ${propertyValue}`;
121
183
  const iconInfo = this.findIcon(query, this.#computedProperties);
@@ -141,7 +203,30 @@ export class StylePropertyEditor extends HTMLElement {
141
203
  }
142
204
 
143
205
  #onButtonClick(propertyName: string, propertyValue: string, selected: boolean): void {
144
- if (selected) {
206
+ if (propertyName === 'grid-auto-flow') {
207
+ const currentValue = this.#authoredProperties.get(propertyName);
208
+ const isDense = currentValue?.includes('dense') || false;
209
+
210
+ if (selected) {
211
+ const newValue = isDense ? 'dense' : '';
212
+
213
+ if (currentValue) {
214
+ this.dispatchEvent(new PropertyDeselectedEvent(propertyName, currentValue));
215
+ }
216
+
217
+ if (newValue) {
218
+ this.dispatchEvent(new PropertySelectedEvent(propertyName, newValue));
219
+ }
220
+ } else {
221
+ const newValue = isDense ? `${propertyValue} dense` : propertyValue;
222
+
223
+ if (currentValue) {
224
+ this.dispatchEvent(new PropertyDeselectedEvent(propertyName, currentValue));
225
+ }
226
+
227
+ this.dispatchEvent(new PropertySelectedEvent(propertyName, newValue));
228
+ }
229
+ } else if (selected) {
145
230
  this.dispatchEvent(new PropertyDeselectedEvent(propertyName, propertyValue));
146
231
  } else {
147
232
  this.dispatchEvent(new PropertySelectedEvent(propertyName, propertyValue));
@@ -256,6 +341,13 @@ export const FlexboxEditableProperties = [
256
341
  ];
257
342
 
258
343
  export const GridEditableProperties = [
344
+ {
345
+ propertyName: 'grid-auto-flow',
346
+ propertyValues: [
347
+ 'row',
348
+ 'column',
349
+ ],
350
+ },
259
351
  {
260
352
  propertyName: 'align-content',
261
353
  propertyValues: [
@@ -1,7 +1,7 @@
1
1
  Name: Dependencies sourced from the upstream `chromium` repository
2
2
  URL: https://chromium.googlesource.com/chromium/src
3
3
  Version: N/A
4
- Revision: 5dd7406e2cf875f110274e22c3bd287d32086055
4
+ Revision: cd78b67fa4902cc7cdd3a0aa6dfedf054e4b43d1
5
5
  Update Mechanism: Manual (https://crbug.com/428069060)
6
6
  License: BSD-3-Clause
7
7
  License File: LICENSE
@@ -1766,6 +1766,8 @@ export const knownContextValues = new Set([
1766
1766
  'grid-area',
1767
1767
  'grid-auto-columns',
1768
1768
  'grid-auto-flow',
1769
+ 'grid-auto-flow-column',
1770
+ 'grid-auto-flow-row',
1769
1771
  'grid-auto-rows',
1770
1772
  'grid-column',
1771
1773
  'grid-column-end',
package/mcp/mcp.ts CHANGED
@@ -35,6 +35,7 @@ export {
35
35
  export {AgentFocus} from '../front_end/models/ai_assistance/performance/AIContext.js';
36
36
  export {DebuggerWorkspaceBinding} from '../front_end/models/bindings/DebuggerWorkspaceBinding.js';
37
37
  export {CrUXManager} from '../front_end/models/crux-manager/CrUXManager.js';
38
+ export * as Formatter from '../front_end/models/formatter/formatter.js';
38
39
  export {Issue} from '../front_end/models/issues_manager/Issue.js';
39
40
  export {
40
41
  AggregatedIssue,
package/package.json CHANGED
@@ -104,5 +104,5 @@
104
104
  "flat-cache": "6.1.12"
105
105
  }
106
106
  },
107
- "version": "1.0.1568190"
107
+ "version": "1.0.1568864"
108
108
  }