chrome-devtools-frontend 1.0.1530564 → 1.0.1531367
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.
- package/front_end/core/sdk/NetworkManager.ts +155 -41
- package/front_end/core/sdk/SourceMap.ts +6 -1
- package/front_end/core/sdk/SourceMapScopesInfo.ts +73 -7
- package/front_end/models/ai_assistance/data_formatters/PerformanceTraceFormatterBounds.snapshot.txt +4 -0
- package/front_end/models/bindings/CompilerScriptMapping.ts +16 -14
- package/front_end/models/javascript_metadata/NativeFunctions.js +7 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +1 -1
- package/front_end/panels/console/ConsoleInsightTeaser.ts +111 -60
- package/front_end/panels/console/ConsoleSidebar.ts +3 -3
- package/front_end/panels/network/BlockedURLsPane.ts +30 -6
- package/front_end/panels/network/NetworkLogView.ts +135 -33
- package/front_end/panels/network/blockedURLsPane.css +5 -0
- package/front_end/panels/sources/sources-meta.ts +1 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/visual_logging/KnownContextValues.ts +5 -0
- package/package.json +1 -1
|
@@ -531,7 +531,7 @@ export const Fast4GConditions: Conditions = {
|
|
|
531
531
|
targetLatency: fast4GTargetLatency,
|
|
532
532
|
};
|
|
533
533
|
|
|
534
|
-
const MAX_EAGER_POST_REQUEST_BODY_LENGTH = 64 * 1024;
|
|
534
|
+
const MAX_EAGER_POST_REQUEST_BODY_LENGTH = 64 * 1024; // bytes
|
|
535
535
|
const MAX_RESPONSE_BODY_TOTAL_BUFFER_LENGTH = 250 * 1024 * 1024; // bytes
|
|
536
536
|
|
|
537
537
|
export class FetchDispatcher implements ProtocolProxyApi.FetchDispatcher {
|
|
@@ -1566,11 +1566,12 @@ export class NetworkDispatcher implements ProtocolProxyApi.NetworkDispatcher {
|
|
|
1566
1566
|
}
|
|
1567
1567
|
}
|
|
1568
1568
|
|
|
1569
|
-
type RequestConditionsSetting = {
|
|
1569
|
+
export type RequestConditionsSetting = {
|
|
1570
1570
|
url: string,
|
|
1571
1571
|
enabled: boolean,
|
|
1572
1572
|
}|{
|
|
1573
1573
|
urlPattern: URLPatternConstructorString,
|
|
1574
|
+
conditions: ThrottlingConditionKey,
|
|
1574
1575
|
enabled: boolean,
|
|
1575
1576
|
};
|
|
1576
1577
|
|
|
@@ -1648,21 +1649,40 @@ export class RequestURLPattern {
|
|
|
1648
1649
|
export class RequestCondition extends Common.ObjectWrapper.ObjectWrapper<RequestCondition.EventTypes> {
|
|
1649
1650
|
#pattern: RequestURLPattern|{wildcardURL: string, upgradedPattern?: RequestURLPattern};
|
|
1650
1651
|
#enabled: boolean;
|
|
1652
|
+
#conditions: ThrottlingConditions;
|
|
1651
1653
|
|
|
1652
|
-
|
|
1653
|
-
super();
|
|
1654
|
+
static createFromSetting(setting: RequestConditionsSetting): RequestCondition {
|
|
1654
1655
|
if ('urlPattern' in setting) {
|
|
1655
|
-
|
|
1656
|
+
const pattern = RequestURLPattern.create(setting.urlPattern) ?? {
|
|
1656
1657
|
wildcardURL: setting.urlPattern,
|
|
1657
1658
|
upgradedPattern: RequestURLPattern.upgradeFromWildcard(setting.urlPattern) ?? undefined,
|
|
1658
1659
|
};
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1660
|
+
|
|
1661
|
+
const conditions = getPredefinedOrBlockingCondition(setting.conditions) ??
|
|
1662
|
+
customUserNetworkConditionsSetting().get().find(condition => condition.key === setting.conditions) ??
|
|
1663
|
+
NoThrottlingConditions;
|
|
1664
|
+
|
|
1665
|
+
return new this(pattern, setting.enabled, conditions);
|
|
1664
1666
|
}
|
|
1665
|
-
|
|
1667
|
+
|
|
1668
|
+
const pattern = {
|
|
1669
|
+
wildcardURL: setting.url,
|
|
1670
|
+
upgradedPattern: RequestURLPattern.upgradeFromWildcard(setting.url) ?? undefined
|
|
1671
|
+
};
|
|
1672
|
+
return new this(pattern, setting.enabled, BlockingConditions);
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
static create(pattern: RequestURLPattern, conditions: ThrottlingConditions): RequestCondition {
|
|
1676
|
+
return new this(pattern, /* enabled=*/ true, conditions);
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
private constructor(
|
|
1680
|
+
pattern: RequestURLPattern|{wildcardURL: string, upgradedPattern?: RequestURLPattern}, enabled: boolean,
|
|
1681
|
+
conditions: ThrottlingConditions) {
|
|
1682
|
+
super();
|
|
1683
|
+
this.#pattern = pattern;
|
|
1684
|
+
this.#enabled = enabled;
|
|
1685
|
+
this.#conditions = conditions;
|
|
1666
1686
|
}
|
|
1667
1687
|
|
|
1668
1688
|
get constructorString(): string|undefined {
|
|
@@ -1705,10 +1725,24 @@ export class RequestCondition extends Common.ObjectWrapper.ObjectWrapper<Request
|
|
|
1705
1725
|
this.dispatchEventToListeners(RequestCondition.Events.REQUEST_CONDITION_CHANGED);
|
|
1706
1726
|
}
|
|
1707
1727
|
|
|
1728
|
+
get conditions(): ThrottlingConditions {
|
|
1729
|
+
return this.#conditions;
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
set conditions(conditions: ThrottlingConditions) {
|
|
1733
|
+
this.#conditions = conditions;
|
|
1734
|
+
this.dispatchEventToListeners(RequestCondition.Events.REQUEST_CONDITION_CHANGED);
|
|
1735
|
+
}
|
|
1736
|
+
|
|
1708
1737
|
toSetting(): RequestConditionsSetting {
|
|
1709
1738
|
const enabled = this.enabled;
|
|
1710
|
-
|
|
1711
|
-
|
|
1739
|
+
if (this.#pattern instanceof RequestURLPattern) {
|
|
1740
|
+
return {enabled, urlPattern: this.#pattern.constructorString, conditions: this.#conditions.key};
|
|
1741
|
+
}
|
|
1742
|
+
if (this.#conditions !== BlockingConditions && this.#pattern.upgradedPattern) {
|
|
1743
|
+
return {enabled, urlPattern: this.#pattern.upgradedPattern.constructorString, conditions: this.#conditions.key};
|
|
1744
|
+
}
|
|
1745
|
+
return {enabled, url: this.#pattern.wildcardURL};
|
|
1712
1746
|
}
|
|
1713
1747
|
|
|
1714
1748
|
get originalOrUpgradedURLPattern(): URLPattern|undefined {
|
|
@@ -1729,20 +1763,41 @@ export namespace RequestCondition {
|
|
|
1729
1763
|
export class RequestConditions extends Common.ObjectWrapper.ObjectWrapper<RequestConditions.EventTypes> {
|
|
1730
1764
|
readonly #setting =
|
|
1731
1765
|
Common.Settings.Settings.instance().createSetting<RequestConditionsSetting[]>('network-blocked-patterns', []);
|
|
1732
|
-
readonly #
|
|
1766
|
+
readonly #conditionsEnabledSetting =
|
|
1767
|
+
Common.Settings.Settings.instance().moduleSetting<boolean>('request-blocking-enabled');
|
|
1768
|
+
readonly #conditions: RequestCondition[] = [];
|
|
1733
1769
|
|
|
1734
1770
|
constructor() {
|
|
1735
1771
|
super();
|
|
1736
|
-
|
|
1772
|
+
for (const condition of this.#setting.get()) {
|
|
1773
|
+
try {
|
|
1774
|
+
this.#conditions.push(RequestCondition.createFromSetting(condition));
|
|
1775
|
+
} catch (e) {
|
|
1776
|
+
console.error('Error loading throttling settings: ', e);
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1737
1779
|
for (const condition of this.#conditions) {
|
|
1738
1780
|
condition.addEventListener(RequestCondition.Events.REQUEST_CONDITION_CHANGED, this.#conditionsChanged, this);
|
|
1739
1781
|
}
|
|
1782
|
+
this.#conditionsEnabledSetting.addChangeListener(
|
|
1783
|
+
() => this.dispatchEventToListeners(RequestConditions.Events.REQUEST_CONDITIONS_CHANGED));
|
|
1740
1784
|
}
|
|
1741
1785
|
|
|
1742
1786
|
get count(): number {
|
|
1743
1787
|
return this.#conditions.length;
|
|
1744
1788
|
}
|
|
1745
1789
|
|
|
1790
|
+
get conditionsEnabled(): boolean {
|
|
1791
|
+
return this.#conditionsEnabledSetting.get();
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
set conditionsEnabled(enabled: boolean) {
|
|
1795
|
+
if (this.#conditionsEnabledSetting.get() === enabled) {
|
|
1796
|
+
return;
|
|
1797
|
+
}
|
|
1798
|
+
this.#conditionsEnabledSetting.set(enabled);
|
|
1799
|
+
}
|
|
1800
|
+
|
|
1746
1801
|
findCondition(pattern: string): RequestCondition|undefined {
|
|
1747
1802
|
if (Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled) {
|
|
1748
1803
|
return this.#conditions.find(condition => condition.constructorString === pattern);
|
|
@@ -1756,6 +1811,9 @@ export class RequestConditions extends Common.ObjectWrapper.ObjectWrapper<Reques
|
|
|
1756
1811
|
|
|
1757
1812
|
add(...conditions: RequestCondition[]): void {
|
|
1758
1813
|
this.#conditions.push(...conditions);
|
|
1814
|
+
for (const condition of conditions) {
|
|
1815
|
+
condition.addEventListener(RequestCondition.Events.REQUEST_CONDITION_CHANGED, this.#conditionsChanged, this);
|
|
1816
|
+
}
|
|
1759
1817
|
this.#conditionsChanged();
|
|
1760
1818
|
}
|
|
1761
1819
|
|
|
@@ -1765,7 +1823,7 @@ export class RequestConditions extends Common.ObjectWrapper.ObjectWrapper<Reques
|
|
|
1765
1823
|
return;
|
|
1766
1824
|
}
|
|
1767
1825
|
condition.removeEventListener(RequestCondition.Events.REQUEST_CONDITION_CHANGED, this.#conditionsChanged, this);
|
|
1768
|
-
this.#conditions.splice(index);
|
|
1826
|
+
this.#conditions.splice(index, 1);
|
|
1769
1827
|
this.#conditionsChanged();
|
|
1770
1828
|
}
|
|
1771
1829
|
|
|
@@ -1786,18 +1844,69 @@ export class RequestConditions extends Common.ObjectWrapper.ObjectWrapper<Reques
|
|
|
1786
1844
|
return this.#conditions.values();
|
|
1787
1845
|
}
|
|
1788
1846
|
|
|
1789
|
-
applyConditions(...agents: ProtocolProxyApi.NetworkApi[]):
|
|
1847
|
+
applyConditions(offline: boolean, globalConditions: Conditions|null, ...agents: ProtocolProxyApi.NetworkApi[]):
|
|
1848
|
+
boolean {
|
|
1849
|
+
function isNonBlockingCondition(condition: ThrottlingConditions): condition is Conditions {
|
|
1850
|
+
return !('block' in condition);
|
|
1851
|
+
}
|
|
1790
1852
|
if (Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled) {
|
|
1791
|
-
const urlPatterns
|
|
1792
|
-
|
|
1853
|
+
const urlPatterns: Protocol.Network.BlockPattern[] = [];
|
|
1854
|
+
const matchedNetworkConditions: Protocol.Network.NetworkConditions[] = [];
|
|
1855
|
+
if (this.conditionsEnabled) {
|
|
1856
|
+
for (const condition of this.#conditions) {
|
|
1857
|
+
const urlPattern = condition.constructorString;
|
|
1858
|
+
const conditions = condition.conditions;
|
|
1859
|
+
if (!condition.enabled || !urlPattern || conditions === NoThrottlingConditions) {
|
|
1860
|
+
continue;
|
|
1861
|
+
}
|
|
1862
|
+
const block = !isNonBlockingCondition(conditions);
|
|
1863
|
+
urlPatterns.push({urlPattern, block});
|
|
1864
|
+
if (!block) {
|
|
1865
|
+
matchedNetworkConditions.push({
|
|
1866
|
+
urlPattern,
|
|
1867
|
+
latency: conditions.latency,
|
|
1868
|
+
downloadThroughput: conditions.download < 0 ? 0 : conditions.download,
|
|
1869
|
+
uploadThroughput: conditions.upload < 0 ? 0 : conditions.upload,
|
|
1870
|
+
packetLoss: (conditions.packetLoss ?? 0) < 0 ? 0 : conditions.packetLoss,
|
|
1871
|
+
packetQueueLength: conditions.packetQueueLength,
|
|
1872
|
+
packetReordering: conditions.packetReordering,
|
|
1873
|
+
connectionType: NetworkManager.connectionType(conditions),
|
|
1874
|
+
});
|
|
1875
|
+
}
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
if (globalConditions) {
|
|
1879
|
+
matchedNetworkConditions.push({
|
|
1880
|
+
urlPattern: '',
|
|
1881
|
+
latency: globalConditions.latency,
|
|
1882
|
+
downloadThroughput: globalConditions.download < 0 ? 0 : globalConditions.download,
|
|
1883
|
+
uploadThroughput: globalConditions.upload < 0 ? 0 : globalConditions.upload,
|
|
1884
|
+
packetLoss: (globalConditions.packetLoss ?? 0) < 0 ? 0 : globalConditions.packetLoss,
|
|
1885
|
+
packetQueueLength: globalConditions.packetQueueLength,
|
|
1886
|
+
packetReordering: globalConditions.packetReordering,
|
|
1887
|
+
connectionType: NetworkManager.connectionType(globalConditions),
|
|
1888
|
+
});
|
|
1889
|
+
}
|
|
1890
|
+
}
|
|
1793
1891
|
|
|
1794
1892
|
for (const agent of agents) {
|
|
1795
1893
|
void agent.invoke_setBlockedURLs({urlPatterns});
|
|
1894
|
+
void agent.invoke_emulateNetworkConditionsByRule({offline, matchedNetworkConditions});
|
|
1895
|
+
void agent.invoke_overrideNetworkState({
|
|
1896
|
+
offline,
|
|
1897
|
+
latency: globalConditions?.latency ?? 0,
|
|
1898
|
+
downloadThroughput: !globalConditions || globalConditions.download < 0 ? 0 : globalConditions.download,
|
|
1899
|
+
uploadThroughput: !globalConditions || globalConditions.upload < 0 ? 0 : globalConditions.upload,
|
|
1900
|
+
});
|
|
1796
1901
|
}
|
|
1797
1902
|
return urlPatterns.length > 0;
|
|
1798
1903
|
}
|
|
1799
|
-
|
|
1800
|
-
|
|
1904
|
+
|
|
1905
|
+
const urls = this.conditionsEnabled ?
|
|
1906
|
+
this.#conditions.filter(condition => condition.enabled && condition.wildcardURL)
|
|
1907
|
+
.map(condition => condition.wildcardURL as string) :
|
|
1908
|
+
[];
|
|
1909
|
+
|
|
1801
1910
|
for (const agent of agents) {
|
|
1802
1911
|
void agent.invoke_setBlockedURLs({urls});
|
|
1803
1912
|
}
|
|
@@ -1826,8 +1935,6 @@ export class MultitargetNetworkManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
1826
1935
|
readonly inflightMainResourceRequests = new Map<string, NetworkRequest>();
|
|
1827
1936
|
#networkConditions: Conditions = NoThrottlingConditions;
|
|
1828
1937
|
#updatingInterceptionPatternsPromise: Promise<void>|null = null;
|
|
1829
|
-
readonly #blockingEnabledSetting =
|
|
1830
|
-
Common.Settings.Settings.instance().moduleSetting<boolean>('request-blocking-enabled');
|
|
1831
1938
|
readonly #requestConditions = new RequestConditions();
|
|
1832
1939
|
readonly #urlsForRequestInterceptor:
|
|
1833
1940
|
Platform.MapUtilities.Multimap<(arg0: InterceptedRequest) => Promise<void>, InterceptionPattern> =
|
|
@@ -1844,7 +1951,6 @@ export class MultitargetNetworkManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
1844
1951
|
this.updateBlockedPatterns();
|
|
1845
1952
|
this.dispatchEventToListeners(MultitargetNetworkManager.Events.BLOCKED_PATTERNS_CHANGED);
|
|
1846
1953
|
};
|
|
1847
|
-
this.#blockingEnabledSetting.addChangeListener(blockedPatternChanged);
|
|
1848
1954
|
this.#requestConditions.addEventListener(
|
|
1849
1955
|
RequestConditions.Events.REQUEST_CONDITIONS_CHANGED, blockedPatternChanged);
|
|
1850
1956
|
this.updateBlockedPatterns();
|
|
@@ -1914,7 +2020,8 @@ export class MultitargetNetworkManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
1914
2020
|
void networkAgent.invoke_setUserAgentOverride(
|
|
1915
2021
|
{userAgent: this.currentUserAgent(), userAgentMetadata: this.#userAgentMetadataOverride || undefined});
|
|
1916
2022
|
}
|
|
1917
|
-
this.#requestConditions.applyConditions(
|
|
2023
|
+
this.#requestConditions.applyConditions(
|
|
2024
|
+
this.isOffline(), this.isThrottling() ? this.#networkConditions : null, networkAgent);
|
|
1918
2025
|
if (this.isIntercepting()) {
|
|
1919
2026
|
void fetchAgent.invoke_enable({patterns: this.#urlsForRequestInterceptor.valuesArray()});
|
|
1920
2027
|
}
|
|
@@ -1925,7 +2032,7 @@ export class MultitargetNetworkManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
1925
2032
|
}
|
|
1926
2033
|
this.#networkAgents.add(networkAgent);
|
|
1927
2034
|
this.#fetchAgents.add(fetchAgent);
|
|
1928
|
-
if (this.isThrottling()) {
|
|
2035
|
+
if (this.isThrottling() && !Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled) {
|
|
1929
2036
|
this.updateNetworkConditions(networkAgent);
|
|
1930
2037
|
}
|
|
1931
2038
|
}
|
|
@@ -1953,8 +2060,13 @@ export class MultitargetNetworkManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
1953
2060
|
|
|
1954
2061
|
setNetworkConditions(conditions: Conditions): void {
|
|
1955
2062
|
this.#networkConditions = conditions;
|
|
1956
|
-
|
|
1957
|
-
this.
|
|
2063
|
+
if (Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled) {
|
|
2064
|
+
this.#requestConditions.applyConditions(
|
|
2065
|
+
this.isOffline(), this.isThrottling() ? this.#networkConditions : null, ...this.#networkAgents);
|
|
2066
|
+
} else {
|
|
2067
|
+
for (const agent of this.#networkAgents) {
|
|
2068
|
+
this.updateNetworkConditions(agent);
|
|
2069
|
+
}
|
|
1958
2070
|
}
|
|
1959
2071
|
this.dispatchEventToListeners(MultitargetNetworkManager.Events.CONDITIONS_CHANGED);
|
|
1960
2072
|
}
|
|
@@ -2058,12 +2170,16 @@ export class MultitargetNetworkManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
2058
2170
|
return this.#requestConditions;
|
|
2059
2171
|
}
|
|
2060
2172
|
|
|
2061
|
-
|
|
2062
|
-
return this.#
|
|
2173
|
+
isBlocking(): boolean {
|
|
2174
|
+
return this.#isBlocking && this.requestConditions.conditionsEnabled;
|
|
2063
2175
|
}
|
|
2064
2176
|
|
|
2065
|
-
|
|
2066
|
-
|
|
2177
|
+
/**
|
|
2178
|
+
* @deprecated Kept for layout tests
|
|
2179
|
+
* TODO(pfaffe) remove
|
|
2180
|
+
*/
|
|
2181
|
+
private setBlockingEnabled(enabled: boolean): void {
|
|
2182
|
+
this.requestConditions.conditionsEnabled = enabled;
|
|
2067
2183
|
}
|
|
2068
2184
|
|
|
2069
2185
|
/**
|
|
@@ -2072,18 +2188,12 @@ export class MultitargetNetworkManager extends Common.ObjectWrapper.ObjectWrappe
|
|
|
2072
2188
|
*/
|
|
2073
2189
|
private setBlockedPatterns(patterns: Array<{url: string, enabled: boolean}>): void {
|
|
2074
2190
|
this.requestConditions.clear();
|
|
2075
|
-
this.requestConditions.add(...patterns.map(pattern =>
|
|
2076
|
-
}
|
|
2077
|
-
|
|
2078
|
-
setBlockingEnabled(enabled: boolean): void {
|
|
2079
|
-
if (this.#blockingEnabledSetting.get() === enabled) {
|
|
2080
|
-
return;
|
|
2081
|
-
}
|
|
2082
|
-
this.#blockingEnabledSetting.set(enabled);
|
|
2191
|
+
this.requestConditions.add(...patterns.map(pattern => RequestCondition.createFromSetting(pattern)));
|
|
2083
2192
|
}
|
|
2084
2193
|
|
|
2085
2194
|
private updateBlockedPatterns(): void {
|
|
2086
|
-
this.#isBlocking = this.#requestConditions.applyConditions(
|
|
2195
|
+
this.#isBlocking = this.#requestConditions.applyConditions(
|
|
2196
|
+
this.isOffline(), this.isThrottling() ? this.#networkConditions : null, ...this.#networkAgents);
|
|
2087
2197
|
}
|
|
2088
2198
|
|
|
2089
2199
|
isIntercepting(): boolean {
|
|
@@ -2544,6 +2654,10 @@ export function getPredefinedCondition(key: ThrottlingConditionKey): Conditions|
|
|
|
2544
2654
|
return THROTTLING_CONDITIONS_LOOKUP.get(key) ?? null;
|
|
2545
2655
|
}
|
|
2546
2656
|
|
|
2657
|
+
export function getPredefinedOrBlockingCondition(key: ThrottlingConditionKey): ThrottlingConditions|null {
|
|
2658
|
+
return key === PredefinedThrottlingConditionKey.BLOCKING ? BlockingConditions : getPredefinedCondition(key);
|
|
2659
|
+
}
|
|
2660
|
+
|
|
2547
2661
|
export type ThrottlingConditions = Conditions|{
|
|
2548
2662
|
readonly key: ThrottlingConditionKey,
|
|
2549
2663
|
block: true,
|
|
@@ -12,7 +12,7 @@ import type {CallFrame, ScopeChainEntry} from './DebuggerModel.js';
|
|
|
12
12
|
import {scopeTreeForScript} from './ScopeTreeCache.js';
|
|
13
13
|
import type {Script} from './Script.js';
|
|
14
14
|
import {buildOriginalScopes, decodePastaRanges, type NamedFunctionRange} from './SourceMapFunctionRanges.js';
|
|
15
|
-
import {SourceMapScopesInfo} from './SourceMapScopesInfo.js';
|
|
15
|
+
import {SourceMapScopesInfo, type TranslatedFrame} from './SourceMapScopesInfo.js';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Type of the base source map JSON object, which contains the sources and the mappings at the very least, plus
|
|
@@ -789,6 +789,11 @@ export class SourceMap {
|
|
|
789
789
|
this.#ensureSourceMapProcessed();
|
|
790
790
|
return this.#scopesInfo?.hasInlinedFrames(generatedLine, generatedColumn) ?? false;
|
|
791
791
|
}
|
|
792
|
+
|
|
793
|
+
translateCallSite(generatedLine: number, generatedColumn: number): TranslatedFrame[] {
|
|
794
|
+
this.#ensureSourceMapProcessed();
|
|
795
|
+
return this.#scopesInfo?.translateCallSite(generatedLine, generatedColumn) ?? [];
|
|
796
|
+
}
|
|
792
797
|
}
|
|
793
798
|
|
|
794
799
|
const VLQ_BASE_SHIFT = 5;
|
|
@@ -113,6 +113,10 @@ export class SourceMapScopesInfo {
|
|
|
113
113
|
*/
|
|
114
114
|
isOutlinedFrame(generatedLine: number, generatedColumn: number): boolean {
|
|
115
115
|
const rangeChain = this.#findGeneratedRangeChain(generatedLine, generatedColumn);
|
|
116
|
+
return this.#isOutlinedFrame(rangeChain);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
#isOutlinedFrame(rangeChain: ScopesCodec.GeneratedRange[]): boolean {
|
|
116
120
|
for (let i = rangeChain.length - 1; i >= 0; --i) {
|
|
117
121
|
if (rangeChain[i].isStackFrame) {
|
|
118
122
|
return rangeChain[i].isHidden;
|
|
@@ -372,13 +376,7 @@ export class SourceMapScopesInfo {
|
|
|
372
376
|
.at(-1);
|
|
373
377
|
}
|
|
374
378
|
|
|
375
|
-
|
|
376
|
-
for (let originalScope = originalInnerMostScope; originalScope; originalScope = originalScope.parent) {
|
|
377
|
-
if (originalScope.isStackFrame) {
|
|
378
|
-
return originalScope.name ?? '';
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
return null;
|
|
379
|
+
return this.#findFunctionNameInOriginalScopeChain(originalInnerMostScope) ?? null;
|
|
382
380
|
}
|
|
383
381
|
|
|
384
382
|
/**
|
|
@@ -404,6 +402,74 @@ export class SourceMapScopesInfo {
|
|
|
404
402
|
|
|
405
403
|
return result;
|
|
406
404
|
}
|
|
405
|
+
|
|
406
|
+
#findFunctionNameInOriginalScopeChain(innerOriginalScope: ScopesCodec.OriginalScope|undefined): string|null {
|
|
407
|
+
for (let originalScope = innerOriginalScope; originalScope; originalScope = originalScope.parent) {
|
|
408
|
+
if (originalScope.isStackFrame) {
|
|
409
|
+
return originalScope.name ?? '';
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
/**
|
|
416
|
+
* Returns one or more original stack frames for this single "raw frame" or call-site.
|
|
417
|
+
*
|
|
418
|
+
* @returns An empty array if no mapping at the call-site was found, or the resulting frames
|
|
419
|
+
* in top-to-bottom order in case of inlining.
|
|
420
|
+
* @throws If this range is marked "hidden". Outlining needs to be handled externally as
|
|
421
|
+
* outlined function segments in stack traces can span across bundles.
|
|
422
|
+
*/
|
|
423
|
+
translateCallSite(generatedLine: number, generatedColumn: number): TranslatedFrame[] {
|
|
424
|
+
const rangeChain = this.#findGeneratedRangeChain(generatedLine, generatedColumn);
|
|
425
|
+
if (this.#isOutlinedFrame(rangeChain)) {
|
|
426
|
+
throw new Error('SourceMapScopesInfo is unable to translate an outlined function by itself');
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const mapping = this.#sourceMap.findEntry(generatedLine, generatedColumn);
|
|
430
|
+
if (mapping?.sourceIndex === undefined) {
|
|
431
|
+
return [];
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
// The top-most frame is translated the same even if we have inlined functions.
|
|
435
|
+
const result: TranslatedFrame[] = [{
|
|
436
|
+
line: mapping.sourceLineNumber,
|
|
437
|
+
column: mapping.sourceColumnNumber,
|
|
438
|
+
name: this.findOriginalFunctionName({line: generatedLine, column: generatedColumn}) ?? undefined,
|
|
439
|
+
url: mapping.sourceURL,
|
|
440
|
+
}];
|
|
441
|
+
|
|
442
|
+
// Walk the range chain inside out until we find a generated function and for each inlined function add a frame.
|
|
443
|
+
for (let i = rangeChain.length - 1; i >= 0 && !rangeChain[i].isStackFrame; --i) {
|
|
444
|
+
const range = rangeChain[i];
|
|
445
|
+
if (!range.callSite) {
|
|
446
|
+
continue;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const originalScopeChain = this.#findOriginalScopeChain(range.callSite);
|
|
450
|
+
result.push({
|
|
451
|
+
line: range.callSite.line,
|
|
452
|
+
column: range.callSite.column,
|
|
453
|
+
name: this.#findFunctionNameInOriginalScopeChain(originalScopeChain.at(-1)) ?? undefined,
|
|
454
|
+
url: this.#sourceMap.sourceURLForSourceIndex(range.callSite.sourceIndex),
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
return result;
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Represents a stack frame in original terms. It closely aligns with StackTrace.StackTrace.Frame,
|
|
464
|
+
* but since we can't import that type here we mirror it here somewhat.
|
|
465
|
+
*
|
|
466
|
+
* Equivalent to Pick<StackTrace.StackTrace.Frame, 'line'|'column'|'name'|'url'>.
|
|
467
|
+
*/
|
|
468
|
+
export interface TranslatedFrame {
|
|
469
|
+
line: number;
|
|
470
|
+
column: number;
|
|
471
|
+
name?: string;
|
|
472
|
+
url?: Platform.DevToolsPath.UrlString;
|
|
407
473
|
}
|
|
408
474
|
|
|
409
475
|
/**
|
|
@@ -296,28 +296,30 @@ export class CompilerScriptMapping implements DebuggerSourceMapping {
|
|
|
296
296
|
const {sourceMap, script} = sourceMapAndScript;
|
|
297
297
|
const {lineNumber, columnNumber} = script.relativeLocationToRawLocation(frame);
|
|
298
298
|
|
|
299
|
-
if (!sourceMap.
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (!mapping?.sourceURL) {
|
|
299
|
+
if (!sourceMap.isOutlinedFrame(lineNumber, columnNumber)) {
|
|
300
|
+
const frames = sourceMap.translateCallSite(lineNumber, columnNumber);
|
|
301
|
+
if (!frames.length) {
|
|
303
302
|
return false;
|
|
304
303
|
}
|
|
305
304
|
|
|
306
|
-
const originalName = sourceMap.findOriginalFunctionName({line: lineNumber, column: columnNumber});
|
|
307
305
|
rawFrames.shift();
|
|
306
|
+
const result: typeof translatedFrames[0] = [];
|
|
307
|
+
translatedFrames.push(result);
|
|
308
|
+
|
|
308
309
|
const project = this.#sourceMapToProject.get(sourceMap);
|
|
309
|
-
const
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
310
|
+
for (const frame of frames) {
|
|
311
|
+
// Switch out url for UISourceCode where we have it.
|
|
312
|
+
const uiSourceCode = frame.url ? project?.uiSourceCodeForURL(frame.url) : undefined;
|
|
313
|
+
result.push({
|
|
314
|
+
...frame,
|
|
315
|
+
url: uiSourceCode ? undefined : frame.url,
|
|
316
|
+
uiSourceCode: uiSourceCode ?? undefined,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
317
320
|
return true;
|
|
318
321
|
}
|
|
319
322
|
|
|
320
|
-
// TODO(crbug.com/433162438): Expand inlined frames.
|
|
321
323
|
// TODO(crbug.com/433162438): Consolidate outlined frames.
|
|
322
324
|
return false;
|
|
323
325
|
}
|
|
@@ -6041,7 +6041,13 @@ export const NativeFunctions = [
|
|
|
6041
6041
|
},
|
|
6042
6042
|
{
|
|
6043
6043
|
name: "waitUntil",
|
|
6044
|
-
signatures: [["f"]]
|
|
6044
|
+
signatures: [["f"]],
|
|
6045
|
+
receivers: ["ExtendableEvent"]
|
|
6046
|
+
},
|
|
6047
|
+
{
|
|
6048
|
+
name: "waitUntil",
|
|
6049
|
+
signatures: [["promise"]],
|
|
6050
|
+
receivers: ["ViewTransition"]
|
|
6045
6051
|
},
|
|
6046
6052
|
{
|
|
6047
6053
|
name: "respondWith",
|
|
@@ -1187,7 +1187,7 @@ export class AiAssistancePanel extends UI.Panel.Panel {
|
|
|
1187
1187
|
|
|
1188
1188
|
contextMenu.defaultSection().appendCheckboxItem(title, () => {
|
|
1189
1189
|
void this.#openHistoricConversation(conversation);
|
|
1190
|
-
}, {checked: (this.#conversation === conversation)});
|
|
1190
|
+
}, {checked: (this.#conversation === conversation), jslogContext: 'freestyler.history-item'});
|
|
1191
1191
|
}
|
|
1192
1192
|
|
|
1193
1193
|
const historyEmpty = contextMenu.defaultSection().items.length === 0;
|
|
@@ -61,6 +61,10 @@ const UIStringsNotTranslate = {
|
|
|
61
61
|
* @description Header text during loading state while an AI summary is being generated
|
|
62
62
|
*/
|
|
63
63
|
summarizing: 'Summarizing…',
|
|
64
|
+
/**
|
|
65
|
+
* @description Header text during longer lasting loading state while an AI summary is being generated
|
|
66
|
+
*/
|
|
67
|
+
summarizingTakesABitLonger: 'Summarizing takes a bit longer…',
|
|
64
68
|
/**
|
|
65
69
|
* @description Label for an animation shown while an AI response is being generated
|
|
66
70
|
*/
|
|
@@ -77,6 +81,10 @@ const UIStringsNotTranslate = {
|
|
|
77
81
|
* @description Aria-label for an infor-button triggering a tooltip with more info about data usage
|
|
78
82
|
*/
|
|
79
83
|
learnDataUsage: 'Learn more about how your data is used',
|
|
84
|
+
/**
|
|
85
|
+
* @description Header text if there was an error during AI summary generation
|
|
86
|
+
*/
|
|
87
|
+
summaryNotAvailable: 'Summary not available',
|
|
80
88
|
} as const;
|
|
81
89
|
|
|
82
90
|
const lockedString = i18n.i18n.lockedString;
|
|
@@ -84,6 +92,7 @@ const lockedString = i18n.i18n.lockedString;
|
|
|
84
92
|
const CODE_SNIPPET_WARNING_URL = 'https://support.google.com/legal/answer/13505487';
|
|
85
93
|
const DATA_USAGE_URL = 'https://developer.chrome.com/docs/devtools/ai-assistance/get-started#data-use';
|
|
86
94
|
const EXPLAIN_TEASER_ACTION_ID = 'explain.console-message.teaser';
|
|
95
|
+
const SLOW_GENERATION_CUTOFF_MILLISECONDS = 3500;
|
|
87
96
|
|
|
88
97
|
interface ViewInput {
|
|
89
98
|
onTellMeMoreClick: (event: Event) => void;
|
|
@@ -95,6 +104,8 @@ interface ViewInput {
|
|
|
95
104
|
isInactive: boolean;
|
|
96
105
|
dontShowChanged: (e: Event) => void;
|
|
97
106
|
hasTellMeMoreButton: boolean;
|
|
107
|
+
isSlowGeneration: boolean;
|
|
108
|
+
isError: boolean;
|
|
98
109
|
}
|
|
99
110
|
|
|
100
111
|
export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLElement): void => {
|
|
@@ -104,6 +115,51 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
104
115
|
}
|
|
105
116
|
|
|
106
117
|
const showPlaceholder = !Boolean(input.mainText);
|
|
118
|
+
const renderFooter = (): Lit.LitTemplate => {
|
|
119
|
+
// clang-format off
|
|
120
|
+
return html`
|
|
121
|
+
<div class="tooltip-footer">
|
|
122
|
+
${input.hasTellMeMoreButton ? html`
|
|
123
|
+
<devtools-button
|
|
124
|
+
title=${lockedString(UIStringsNotTranslate.tellMeMore)}
|
|
125
|
+
.jslogContext=${'insights-teaser-tell-me-more'},
|
|
126
|
+
.variant=${Buttons.Button.Variant.PRIMARY}
|
|
127
|
+
@click=${input.onTellMeMoreClick}
|
|
128
|
+
>
|
|
129
|
+
<devtools-icon class="lightbulb-icon" name="lightbulb-spark"></devtools-icon>
|
|
130
|
+
${lockedString(UIStringsNotTranslate.tellMeMore)}
|
|
131
|
+
</devtools-button>
|
|
132
|
+
` : Lit.nothing}
|
|
133
|
+
${showPlaceholder ? Lit.nothing : html`
|
|
134
|
+
<devtools-button
|
|
135
|
+
.iconName=${'info'}
|
|
136
|
+
.variant=${Buttons.Button.Variant.ICON}
|
|
137
|
+
aria-details=${'teaser-info-tooltip-' + input.uuid}
|
|
138
|
+
aria-label=${lockedString(UIStringsNotTranslate.learnDataUsage)}
|
|
139
|
+
></devtools-button>
|
|
140
|
+
<devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
|
|
141
|
+
<div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
|
|
142
|
+
<div class="learn-more">
|
|
143
|
+
<x-link
|
|
144
|
+
class="devtools-link"
|
|
145
|
+
title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
|
|
146
|
+
href=${DATA_USAGE_URL}
|
|
147
|
+
jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
|
|
148
|
+
>${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
|
|
149
|
+
</div>
|
|
150
|
+
</devtools-tooltip>
|
|
151
|
+
`}
|
|
152
|
+
<devtools-checkbox
|
|
153
|
+
aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
|
|
154
|
+
@change=${input.dontShowChanged}
|
|
155
|
+
jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
|
|
156
|
+
${lockedString(UIStringsNotTranslate.dontShow)}
|
|
157
|
+
</devtools-checkbox>
|
|
158
|
+
</div>
|
|
159
|
+
`;
|
|
160
|
+
// clang-format on
|
|
161
|
+
};
|
|
162
|
+
|
|
107
163
|
// clang-format off
|
|
108
164
|
render(html`
|
|
109
165
|
<style>${consoleInsightTeaserStyles}</style>
|
|
@@ -115,64 +171,36 @@ export const DEFAULT_VIEW = (input: ViewInput, _output: undefined, target: HTMLE
|
|
|
115
171
|
prefer-span-left
|
|
116
172
|
>
|
|
117
173
|
<div class="teaser-tooltip-container">
|
|
118
|
-
${
|
|
119
|
-
<h2>${lockedString(UIStringsNotTranslate.
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
<
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
${lockedString(UIStringsNotTranslate.tellMeMore)}
|
|
149
|
-
</devtools-button>
|
|
150
|
-
` : Lit.nothing}
|
|
151
|
-
<devtools-button
|
|
152
|
-
.iconName=${'info'}
|
|
153
|
-
.variant=${Buttons.Button.Variant.ICON}
|
|
154
|
-
aria-details=${'teaser-info-tooltip-' + input.uuid}
|
|
155
|
-
aria-label=${lockedString(UIStringsNotTranslate.learnDataUsage)}
|
|
156
|
-
></devtools-button>
|
|
157
|
-
<devtools-tooltip id=${'teaser-info-tooltip-' + input.uuid} variant="rich">
|
|
158
|
-
<div class="info-tooltip-text">${lockedString(UIStringsNotTranslate.infoTooltipText)}</div>
|
|
159
|
-
<div class="learn-more">
|
|
160
|
-
<x-link
|
|
161
|
-
class="devtools-link"
|
|
162
|
-
title=${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}
|
|
163
|
-
href=${DATA_USAGE_URL}
|
|
164
|
-
jslog=${VisualLogging.link().track({click: true, keydown:'Enter|Space'}).context('explain.teaser.learn-more')}
|
|
165
|
-
>${lockedString(UIStringsNotTranslate.learnMoreAboutAiSummaries)}</x-link>
|
|
166
|
-
</div>
|
|
167
|
-
</devtools-tooltip>
|
|
168
|
-
<devtools-checkbox
|
|
169
|
-
aria-label=${lockedString(UIStringsNotTranslate.dontShow)}
|
|
170
|
-
@change=${input.dontShowChanged}
|
|
171
|
-
jslog=${VisualLogging.toggle('explain.teaser.dont-show').track({ change: true })}>
|
|
172
|
-
${lockedString(UIStringsNotTranslate.dontShow)}
|
|
173
|
-
</devtools-checkbox>
|
|
174
|
-
</div>
|
|
175
|
-
`}
|
|
174
|
+
${input.isError ? html`
|
|
175
|
+
<h2>${lockedString(UIStringsNotTranslate.summaryNotAvailable)}</h2>
|
|
176
|
+
` :
|
|
177
|
+
showPlaceholder ? html`
|
|
178
|
+
<h2>${input.isSlowGeneration ?
|
|
179
|
+
lockedString(UIStringsNotTranslate.summarizingTakesABitLonger) :
|
|
180
|
+
lockedString(UIStringsNotTranslate.summarizing)
|
|
181
|
+
}</h2>
|
|
182
|
+
<div
|
|
183
|
+
role="presentation"
|
|
184
|
+
aria-label=${lockedString(UIStringsNotTranslate.loading)}
|
|
185
|
+
class="loader"
|
|
186
|
+
style="clip-path: url(${'#clipPath-' + input.uuid});"
|
|
187
|
+
>
|
|
188
|
+
<svg width="100%" height="52">
|
|
189
|
+
<defs>
|
|
190
|
+
<clipPath id=${'clipPath-' + input.uuid}>
|
|
191
|
+
<rect x="0" y="0" width="100%" height="12" rx="8"></rect>
|
|
192
|
+
<rect x="0" y="20" width="100%" height="12" rx="8"></rect>
|
|
193
|
+
<rect x="0" y="40" width="100%" height="12" rx="8"></rect>
|
|
194
|
+
</clipPath>
|
|
195
|
+
</defs>
|
|
196
|
+
</svg>
|
|
197
|
+
</div>
|
|
198
|
+
` : html`
|
|
199
|
+
<h2>${input.headerText}</h2>
|
|
200
|
+
<div>${input.mainText}</div>
|
|
201
|
+
`
|
|
202
|
+
}
|
|
203
|
+
${input.isError || input.isSlowGeneration || !showPlaceholder ? renderFooter() : Lit.nothing}
|
|
176
204
|
</div>
|
|
177
205
|
</devtools-tooltip>
|
|
178
206
|
`, target);
|
|
@@ -192,6 +220,9 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
192
220
|
#consoleViewMessage: ConsoleViewMessage;
|
|
193
221
|
#isInactive = false;
|
|
194
222
|
#abortController: null|AbortController = null;
|
|
223
|
+
#isSlow = false;
|
|
224
|
+
#timeoutId: ReturnType<typeof setTimeout>|null = null;
|
|
225
|
+
#isError = false;
|
|
195
226
|
|
|
196
227
|
constructor(uuid: string, consoleViewMessage: ConsoleViewMessage, element?: HTMLElement, view?: View) {
|
|
197
228
|
super(element);
|
|
@@ -285,6 +316,9 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
285
316
|
this.#abortController.abort();
|
|
286
317
|
}
|
|
287
318
|
this.#isGenerating = false;
|
|
319
|
+
if (this.#timeoutId) {
|
|
320
|
+
clearTimeout(this.#timeoutId);
|
|
321
|
+
}
|
|
288
322
|
}
|
|
289
323
|
|
|
290
324
|
setInactive(isInactive: boolean): void {
|
|
@@ -295,8 +329,14 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
295
329
|
this.requestUpdate();
|
|
296
330
|
}
|
|
297
331
|
|
|
332
|
+
#setSlow(): void {
|
|
333
|
+
this.#isSlow = true;
|
|
334
|
+
this.requestUpdate();
|
|
335
|
+
}
|
|
336
|
+
|
|
298
337
|
async #generateTeaserText(): Promise<void> {
|
|
299
338
|
this.#isGenerating = true;
|
|
339
|
+
this.#timeoutId = setTimeout(this.#setSlow.bind(this), SLOW_GENERATION_CUTOFF_MILLISECONDS);
|
|
300
340
|
let teaserText = '';
|
|
301
341
|
try {
|
|
302
342
|
for await (const chunk of this.#getOnDeviceInsight()) {
|
|
@@ -306,12 +346,16 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
306
346
|
// Ignore `AbortError` errors, which are thrown on mouse leave.
|
|
307
347
|
if (err.name !== 'AbortError') {
|
|
308
348
|
console.error(err.name, err.message);
|
|
349
|
+
this.#isError = true;
|
|
309
350
|
}
|
|
310
351
|
this.#isGenerating = false;
|
|
352
|
+
clearTimeout(this.#timeoutId);
|
|
353
|
+
this.requestUpdate();
|
|
311
354
|
return;
|
|
312
355
|
}
|
|
313
356
|
|
|
314
|
-
|
|
357
|
+
clearTimeout(this.#timeoutId);
|
|
358
|
+
this.#isGenerating = false;
|
|
315
359
|
let responseObject = {
|
|
316
360
|
header: null,
|
|
317
361
|
explanation: null,
|
|
@@ -320,10 +364,15 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
320
364
|
responseObject = JSON.parse(teaserText);
|
|
321
365
|
} catch (err) {
|
|
322
366
|
console.error(err.name, err.message);
|
|
367
|
+
this.#isError = true;
|
|
368
|
+
this.requestUpdate();
|
|
369
|
+
return;
|
|
323
370
|
}
|
|
324
371
|
this.#headerText = responseObject.header || '';
|
|
325
372
|
this.#mainText = responseObject.explanation || '';
|
|
326
|
-
this.#
|
|
373
|
+
if (!this.#headerText || !this.#mainText) {
|
|
374
|
+
this.#isError = true;
|
|
375
|
+
}
|
|
327
376
|
this.requestUpdate();
|
|
328
377
|
}
|
|
329
378
|
|
|
@@ -373,6 +422,8 @@ export class ConsoleInsightTeaser extends UI.Widget.Widget {
|
|
|
373
422
|
!Common.Settings.Settings.instance().moduleSetting('console-insight-teasers-enabled').get(),
|
|
374
423
|
dontShowChanged: this.#dontShowChanged.bind(this),
|
|
375
424
|
hasTellMeMoreButton: this.#hasTellMeMoreButton(),
|
|
425
|
+
isSlowGeneration: this.#isSlow,
|
|
426
|
+
isError: this.#isError,
|
|
376
427
|
},
|
|
377
428
|
undefined, this.contentElement);
|
|
378
429
|
}
|
|
@@ -52,7 +52,7 @@ const str_ = i18n.i18n.registerUIStrings('panels/console/ConsoleSidebar.ts', UIS
|
|
|
52
52
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
53
53
|
const {render, html, nothing, Directives} = Lit;
|
|
54
54
|
|
|
55
|
-
const enum GroupName {
|
|
55
|
+
export const enum GroupName {
|
|
56
56
|
CONSOLE_API = 'user message',
|
|
57
57
|
ALL = 'message',
|
|
58
58
|
ERROR = 'error',
|
|
@@ -112,7 +112,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
112
112
|
<ul role="group" hidden>
|
|
113
113
|
${group.urlGroups.values().map(urlGroup => html`
|
|
114
114
|
<li
|
|
115
|
-
${Directives.ref(element => element && nodeFilterMap.set(element,
|
|
115
|
+
${Directives.ref(element => element && nodeFilterMap.set(element, urlGroup.filter))}
|
|
116
116
|
role="treeitem"
|
|
117
117
|
?selected=${urlGroup.filter === input.selectedFilter}
|
|
118
118
|
title=${urlGroup.url ?? ''}>
|
|
@@ -126,7 +126,7 @@ export const DEFAULT_VIEW: View = (input, output, target) => {
|
|
|
126
126
|
target);
|
|
127
127
|
};
|
|
128
128
|
|
|
129
|
-
class ConsoleFilterGroup {
|
|
129
|
+
export class ConsoleFilterGroup {
|
|
130
130
|
readonly urlGroups = new Map<string|null, {filter: ConsoleFilter, url: string|null, count: number}>();
|
|
131
131
|
messageCount = 0;
|
|
132
132
|
readonly name: GroupName;
|
|
@@ -17,6 +17,7 @@ import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
|
17
17
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
18
18
|
import {Directives, html, type LitTemplate, nothing, render} from '../../ui/lit/lit.js';
|
|
19
19
|
import * as VisualLogging from '../../ui/visual_logging/visual_logging.js';
|
|
20
|
+
import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
|
|
20
21
|
|
|
21
22
|
import blockedURLsPaneStyles from './blockedURLsPane.css.js';
|
|
22
23
|
|
|
@@ -192,7 +193,7 @@ export class BlockedURLsPane extends UI.Widget.VBox implements
|
|
|
192
193
|
}
|
|
193
194
|
|
|
194
195
|
override performUpdate(): void {
|
|
195
|
-
const enabled = this.manager.
|
|
196
|
+
const enabled = this.manager.requestConditions.conditionsEnabled;
|
|
196
197
|
this.list.element.classList.toggle('blocking-disabled', !enabled && Boolean(this.manager.requestConditions.count));
|
|
197
198
|
|
|
198
199
|
const input: ViewInput = {
|
|
@@ -205,9 +206,11 @@ export class BlockedURLsPane extends UI.Widget.VBox implements
|
|
|
205
206
|
}
|
|
206
207
|
|
|
207
208
|
addPattern(): void {
|
|
208
|
-
this.manager.
|
|
209
|
+
this.manager.requestConditions.conditionsEnabled = true;
|
|
209
210
|
this.list.addNewItem(
|
|
210
|
-
0,
|
|
211
|
+
0,
|
|
212
|
+
SDK.NetworkManager.RequestCondition.createFromSetting(
|
|
213
|
+
{url: Platform.DevToolsPath.EmptyUrlString, enabled: true}));
|
|
211
214
|
}
|
|
212
215
|
|
|
213
216
|
removeAllPatterns(): void {
|
|
@@ -224,6 +227,11 @@ export class BlockedURLsPane extends UI.Widget.VBox implements
|
|
|
224
227
|
condition.enabled = !condition.enabled;
|
|
225
228
|
}
|
|
226
229
|
};
|
|
230
|
+
const onConditionsChanged = (conditions: SDK.NetworkManager.ThrottlingConditions): void => {
|
|
231
|
+
if (editable) {
|
|
232
|
+
condition.conditions = conditions;
|
|
233
|
+
}
|
|
234
|
+
};
|
|
227
235
|
|
|
228
236
|
const {enabled, originalOrUpgradedURLPattern, constructorStringOrWildcardURL, wildcardURL} = condition;
|
|
229
237
|
|
|
@@ -237,6 +245,17 @@ export class BlockedURLsPane extends UI.Widget.VBox implements
|
|
|
237
245
|
?checked=${enabled}
|
|
238
246
|
?disabled=${!editable || !originalOrUpgradedURLPattern}
|
|
239
247
|
.jslog=${VisualLogging.toggle().track({ change: true })}>
|
|
248
|
+
<devtools-widget
|
|
249
|
+
class=conditions-selector
|
|
250
|
+
?disabled=${!editable}
|
|
251
|
+
.widgetConfig=${UI.Widget.widgetConfig(
|
|
252
|
+
MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelectorWidget, {
|
|
253
|
+
variant:
|
|
254
|
+
MobileThrottling.NetworkThrottlingSelector.NetworkThrottlingSelect.Variant.INDIVIDUAL_REQUEST_CONDITIONS,
|
|
255
|
+
jslogContext: 'request-conditions',
|
|
256
|
+
onConditionsChanged,
|
|
257
|
+
currentConditions: condition.conditions,
|
|
258
|
+
})}></devtools-widget>
|
|
240
259
|
${originalOrUpgradedURLPattern ? html`
|
|
241
260
|
<devtools-tooltip variant=rich jslogcontext=url-pattern id=url-pattern-${index}>
|
|
242
261
|
<div>hash: ${originalOrUpgradedURLPattern.hash}</div>
|
|
@@ -267,7 +286,12 @@ export class BlockedURLsPane extends UI.Widget.VBox implements
|
|
|
267
286
|
: i18nString(UIStrings.patternFailedToParse)}
|
|
268
287
|
${learnMore()}
|
|
269
288
|
</devtools-tooltip>`: nothing}
|
|
270
|
-
<div
|
|
289
|
+
<div
|
|
290
|
+
@click=${toggle}
|
|
291
|
+
class=blocked-url-label
|
|
292
|
+
aria-details=url-pattern-${index}>
|
|
293
|
+
${constructorStringOrWildcardURL}
|
|
294
|
+
</div>
|
|
271
295
|
<div class=blocked-url-count>${i18nString(UIStrings.dBlocked, {PH1: count})}</div>`,
|
|
272
296
|
// clang-format on
|
|
273
297
|
element);
|
|
@@ -290,7 +314,7 @@ export class BlockedURLsPane extends UI.Widget.VBox implements
|
|
|
290
314
|
}
|
|
291
315
|
|
|
292
316
|
private toggleEnabled(): void {
|
|
293
|
-
this.manager.
|
|
317
|
+
this.manager.requestConditions.conditionsEnabled = !this.manager.requestConditions.conditionsEnabled;
|
|
294
318
|
this.update();
|
|
295
319
|
}
|
|
296
320
|
|
|
@@ -368,7 +392,7 @@ export class BlockedURLsPane extends UI.Widget.VBox implements
|
|
|
368
392
|
}
|
|
369
393
|
|
|
370
394
|
update(): void {
|
|
371
|
-
const enabled = this.manager.
|
|
395
|
+
const enabled = this.manager.requestConditions.conditionsEnabled;
|
|
372
396
|
this.list.clear();
|
|
373
397
|
for (const pattern of this.manager.requestConditions.conditions) {
|
|
374
398
|
if (Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled || pattern.wildcardURL) {
|
|
@@ -432,6 +432,27 @@ const UIStrings = {
|
|
|
432
432
|
* @description A context menu item in the Network Log View of the Network panel
|
|
433
433
|
*/
|
|
434
434
|
clearBrowserCookies: 'Clear browser cookies',
|
|
435
|
+
/**
|
|
436
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
437
|
+
*/
|
|
438
|
+
throttleRequests: 'Throttle requests',
|
|
439
|
+
/**
|
|
440
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
441
|
+
*/
|
|
442
|
+
throttleRequestUrl: 'Throttle request URL',
|
|
443
|
+
/**
|
|
444
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
445
|
+
* @example {example.com} PH1
|
|
446
|
+
*/
|
|
447
|
+
unthrottleS: 'Stop throttling {PH1}',
|
|
448
|
+
/**
|
|
449
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
450
|
+
*/
|
|
451
|
+
throttleRequestDomain: 'Throttle request domain',
|
|
452
|
+
/**
|
|
453
|
+
* @description A context menu item in the Network Log View of the Network panel
|
|
454
|
+
*/
|
|
455
|
+
blockRequests: 'Block requests',
|
|
435
456
|
/**
|
|
436
457
|
* @description A context menu item in the Network Log View of the Network panel
|
|
437
458
|
*/
|
|
@@ -1849,43 +1870,124 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
1849
1870
|
const maxBlockedURLLength = 20;
|
|
1850
1871
|
const manager = SDK.NetworkManager.MultitargetNetworkManager.instance();
|
|
1851
1872
|
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1873
|
+
if (!Root.Runtime.hostConfig.devToolsIndividualRequestThrottling?.enabled) {
|
|
1874
|
+
function addBlockedURL(url: string): void {
|
|
1875
|
+
manager.requestConditions.add(SDK.NetworkManager.RequestCondition.createFromSetting(
|
|
1876
|
+
{enabled: true, url: url as Platform.DevToolsPath.UrlString}));
|
|
1877
|
+
manager.requestConditions.conditionsEnabled = true;
|
|
1878
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1879
|
+
}
|
|
1858
1880
|
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1881
|
+
function removeBlockedURL(url: string): void {
|
|
1882
|
+
const entry = manager.requestConditions.findCondition(url);
|
|
1883
|
+
if (entry) {
|
|
1884
|
+
manager.requestConditions.delete(entry);
|
|
1885
|
+
}
|
|
1886
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1863
1887
|
}
|
|
1864
|
-
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1865
|
-
}
|
|
1866
1888
|
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1889
|
+
const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
|
|
1890
|
+
if (urlWithoutScheme && !manager.requestConditions.has(urlWithoutScheme)) {
|
|
1891
|
+
contextMenu.debugSection().appendItem(
|
|
1892
|
+
i18nString(UIStrings.blockRequestUrl), addBlockedURL.bind(null, urlWithoutScheme),
|
|
1893
|
+
{jslogContext: 'block-request-url'});
|
|
1894
|
+
} else if (urlWithoutScheme) {
|
|
1895
|
+
const croppedURL = Platform.StringUtilities.trimMiddle(urlWithoutScheme, maxBlockedURLLength);
|
|
1896
|
+
contextMenu.debugSection().appendItem(
|
|
1897
|
+
i18nString(UIStrings.unblockS, {PH1: croppedURL}), removeBlockedURL.bind(null, urlWithoutScheme),
|
|
1898
|
+
{jslogContext: 'unblock'});
|
|
1899
|
+
}
|
|
1878
1900
|
|
|
1879
|
-
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1901
|
+
const domain = request.parsedURL.domain();
|
|
1902
|
+
if (domain && !manager.requestConditions.has(domain)) {
|
|
1903
|
+
contextMenu.debugSection().appendItem(
|
|
1904
|
+
i18nString(UIStrings.blockRequestDomain), addBlockedURL.bind(null, domain),
|
|
1905
|
+
{jslogContext: 'block-request-domain'});
|
|
1906
|
+
} else if (domain) {
|
|
1907
|
+
const croppedDomain = Platform.StringUtilities.trimMiddle(domain, maxBlockedURLLength);
|
|
1908
|
+
contextMenu.debugSection().appendItem(
|
|
1909
|
+
i18nString(UIStrings.unblockS, {PH1: croppedDomain}), removeBlockedURL.bind(null, domain),
|
|
1910
|
+
{jslogContext: 'unblock'});
|
|
1911
|
+
}
|
|
1912
|
+
} else {
|
|
1913
|
+
function removeRequestCondition(pattern: SDK.NetworkManager.RequestURLPattern): void {
|
|
1914
|
+
const entry = manager.requestConditions.findCondition(pattern.constructorString);
|
|
1915
|
+
if (entry) {
|
|
1916
|
+
manager.requestConditions.delete(entry);
|
|
1917
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
|
|
1921
|
+
function addRequestCondition(
|
|
1922
|
+
pattern: SDK.NetworkManager.RequestURLPattern,
|
|
1923
|
+
conditions: SDK.NetworkManager.ThrottlingConditions,
|
|
1924
|
+
): void {
|
|
1925
|
+
const entry = manager.requestConditions.findCondition(pattern.constructorString);
|
|
1926
|
+
if (entry) {
|
|
1927
|
+
entry.conditions = conditions;
|
|
1928
|
+
} else {
|
|
1929
|
+
manager.requestConditions.add(SDK.NetworkManager.RequestCondition.create(pattern, conditions));
|
|
1930
|
+
}
|
|
1931
|
+
manager.requestConditions.conditionsEnabled = true;
|
|
1932
|
+
void UI.ViewManager.ViewManager.instance().showView('network.blocked-urls');
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
const blockingMenu =
|
|
1936
|
+
contextMenu.debugSection().appendSubMenuItem(i18nString(UIStrings.blockRequests), /* disabled=*/ true);
|
|
1937
|
+
const throttlingMenu =
|
|
1938
|
+
contextMenu.debugSection().appendSubMenuItem(i18nString(UIStrings.throttleRequests), /* disabled=*/ true);
|
|
1939
|
+
|
|
1940
|
+
const urlWithoutScheme = request.parsedURL.urlWithoutScheme();
|
|
1941
|
+
const urlPattern = urlWithoutScheme &&
|
|
1942
|
+
SDK.NetworkManager.RequestURLPattern.create(
|
|
1943
|
+
`*://${urlWithoutScheme}` as SDK.NetworkManager.URLPatternConstructorString);
|
|
1944
|
+
if (urlPattern) {
|
|
1945
|
+
throttlingMenu.setEnabled(true);
|
|
1946
|
+
blockingMenu.setEnabled(true);
|
|
1947
|
+
const existingConditions = manager.requestConditions.findCondition(urlPattern.constructorString);
|
|
1948
|
+
const isBlocking = existingConditions?.conditions === SDK.NetworkManager.BlockingConditions;
|
|
1949
|
+
const isThrottling = existingConditions &&
|
|
1950
|
+
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1951
|
+
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1952
|
+
blockingMenu.debugSection().appendItem(
|
|
1953
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: urlPattern.constructorString}) :
|
|
1954
|
+
i18nString(UIStrings.blockRequestUrl),
|
|
1955
|
+
() => isBlocking ? removeRequestCondition(urlPattern) :
|
|
1956
|
+
addRequestCondition(urlPattern, SDK.NetworkManager.BlockingConditions),
|
|
1957
|
+
{jslogContext: 'block-request-url'});
|
|
1958
|
+
throttlingMenu.debugSection().appendItem(
|
|
1959
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: urlPattern.constructorString}) :
|
|
1960
|
+
i18nString(UIStrings.throttleRequestUrl),
|
|
1961
|
+
() => isThrottling ? removeRequestCondition(urlPattern) :
|
|
1962
|
+
addRequestCondition(urlPattern, SDK.NetworkManager.Slow3GConditions),
|
|
1963
|
+
{jslogContext: 'throttle-request-url'});
|
|
1964
|
+
}
|
|
1965
|
+
|
|
1966
|
+
const domain = request.parsedURL.domain();
|
|
1967
|
+
const domainPattern = domain &&
|
|
1968
|
+
SDK.NetworkManager.RequestURLPattern.create(
|
|
1969
|
+
`*://${domain}` as SDK.NetworkManager.URLPatternConstructorString);
|
|
1970
|
+
if (domainPattern) {
|
|
1971
|
+
throttlingMenu.setEnabled(true);
|
|
1972
|
+
blockingMenu.setEnabled(true);
|
|
1973
|
+
const existingConditions = manager.requestConditions.findCondition(domainPattern.constructorString);
|
|
1974
|
+
const isBlocking = existingConditions?.conditions === SDK.NetworkManager.BlockingConditions;
|
|
1975
|
+
const isThrottling = existingConditions &&
|
|
1976
|
+
existingConditions.conditions !== SDK.NetworkManager.BlockingConditions &&
|
|
1977
|
+
existingConditions.conditions !== SDK.NetworkManager.NoThrottlingConditions;
|
|
1978
|
+
blockingMenu.debugSection().appendItem(
|
|
1979
|
+
isBlocking ? i18nString(UIStrings.unblockS, {PH1: domainPattern.constructorString}) :
|
|
1980
|
+
i18nString(UIStrings.blockRequestDomain),
|
|
1981
|
+
() => isBlocking ? removeRequestCondition(domainPattern) :
|
|
1982
|
+
addRequestCondition(domainPattern, SDK.NetworkManager.BlockingConditions),
|
|
1983
|
+
{jslogContext: 'block-request-domain'});
|
|
1984
|
+
throttlingMenu.debugSection().appendItem(
|
|
1985
|
+
isThrottling ? i18nString(UIStrings.unthrottleS, {PH1: domainPattern.constructorString}) :
|
|
1986
|
+
i18nString(UIStrings.throttleRequestDomain),
|
|
1987
|
+
() => isThrottling ? removeRequestCondition(domainPattern) :
|
|
1988
|
+
addRequestCondition(domainPattern, SDK.NetworkManager.Slow3GConditions),
|
|
1989
|
+
{jslogContext: 'throttle-request-domain'});
|
|
1990
|
+
}
|
|
1889
1991
|
}
|
|
1890
1992
|
|
|
1891
1993
|
if (SDK.NetworkManager.NetworkManager.canReplayRequest(request)) {
|
|
@@ -516,6 +516,7 @@ UI.ViewManager.registerViewExtension({
|
|
|
516
516
|
title: i18nLazyString(UIStrings.workspace),
|
|
517
517
|
order: 3,
|
|
518
518
|
persistence: UI.ViewManager.ViewPersistence.PERMANENT,
|
|
519
|
+
condition: () => !Root.Runtime.Runtime.isTraceApp(),
|
|
519
520
|
async loadView() {
|
|
520
521
|
const Sources = await loadSourcesModule();
|
|
521
522
|
return new Sources.SourcesNavigator.FilesNavigatorView();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: https://source.chromium.org/chromium/chromium/src/+/main:components/variations/proto/devtools/
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: 8e79193039bf1dd9a37c1b3c443dd8159e02c194
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|
|
@@ -575,6 +575,7 @@ export const knownContextValues = new Set([
|
|
|
575
575
|
'black-berry-play-book-2.1',
|
|
576
576
|
'blackbox',
|
|
577
577
|
'ble',
|
|
578
|
+
'block',
|
|
578
579
|
'block-ellipsis',
|
|
579
580
|
'block-request-domain',
|
|
580
581
|
'block-request-url',
|
|
@@ -1688,6 +1689,7 @@ export const knownContextValues = new Set([
|
|
|
1688
1689
|
'freestyler.feedback',
|
|
1689
1690
|
'freestyler.help',
|
|
1690
1691
|
'freestyler.history',
|
|
1692
|
+
'freestyler.history-item',
|
|
1691
1693
|
'freestyler.main-menu',
|
|
1692
1694
|
'freestyler.new-chat',
|
|
1693
1695
|
'freestyler.send-feedback',
|
|
@@ -3082,6 +3084,7 @@ export const knownContextValues = new Set([
|
|
|
3082
3084
|
'request-animation-frame.callback',
|
|
3083
3085
|
'request-blocking-enabled',
|
|
3084
3086
|
'request-blocking-enabled-true',
|
|
3087
|
+
'request-conditions',
|
|
3085
3088
|
'request-details',
|
|
3086
3089
|
'request-header',
|
|
3087
3090
|
'request-header-accept',
|
|
@@ -3745,6 +3748,8 @@ export const knownContextValues = new Set([
|
|
|
3745
3748
|
'third-party-tree',
|
|
3746
3749
|
'third-property',
|
|
3747
3750
|
'this-origin',
|
|
3751
|
+
'throttle-request-domain',
|
|
3752
|
+
'throttle-request-url',
|
|
3748
3753
|
'throttling-conditions',
|
|
3749
3754
|
'throttling.calibrate',
|
|
3750
3755
|
'throttling.calibrate-cancel',
|
package/package.json
CHANGED