Skip to content

Commit 052d1c7

Browse files
Nancy LiDevtools-frontend LUCI CQ
authored andcommitted
[RPP Icicle blowtorch] Update the name of ignored script
Also including the matched rule in the name so it can be more informative. Screenshots: https://screenshot.googleplex.com/6wQH3mVctUp6bjx Bug:376657746 Change-Id: I403b17f277179ad968bfd8210d457636f8a46df5 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/5987912 Commit-Queue: Nancy Li <[email protected]> Reviewed-by: Paul Irish <[email protected]>
1 parent dae7769 commit 052d1c7

File tree

5 files changed

+151
-13
lines changed

5 files changed

+151
-13
lines changed

front_end/models/bindings/IgnoreListManager.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,12 +219,35 @@ export class IgnoreListManager implements SDK.TargetManager.SDKModelObserver<SDK
219219
if (this.#isIgnoreListedURLCache.has(url)) {
220220
return Boolean(this.#isIgnoreListedURLCache.get(url));
221221
}
222-
const regex = this.getSkipStackFramesPatternSetting().asRegExp();
223-
const isIgnoreListed = (regex && regex.test(url)) || false;
222+
223+
const isIgnoreListed = this.getFirstMatchedRegex(url) !== null;
224224
this.#isIgnoreListedURLCache.set(url, isIgnoreListed);
225225
return isIgnoreListed;
226226
}
227227

228+
getFirstMatchedRegex(url: Platform.DevToolsPath.UrlString): RegExp|null {
229+
if (!url) {
230+
return null;
231+
}
232+
const regexPatterns = this.getSkipStackFramesPatternSetting().getAsArray();
233+
const regexValue = this.urlToRegExpString(url);
234+
if (!regexValue) {
235+
return null;
236+
}
237+
238+
for (let i = 0; i < regexPatterns.length; ++i) {
239+
const item = regexPatterns[i];
240+
if (item.disabled || item.disabledForUrl === url) {
241+
continue;
242+
}
243+
const regex = new RegExp(item.pattern);
244+
if (regex.test(url)) {
245+
return regex;
246+
}
247+
}
248+
return null;
249+
}
250+
228251
private sourceMapAttached(
229252
event: Common.EventTarget.EventTargetEvent<{client: SDK.Script.Script, sourceMap: SDK.SourceMap.SourceMap}>):
230253
void {

front_end/panels/timeline/ThreadAppender.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ import * as Utils from './utils/utils.js';
2929

3030
const UIStrings = {
3131
/**
32-
*@description Text shown for an entry in the flame chart that is ignored because it matches
32+
* @description Text shown for an entry in the flame chart that is ignored because it matches
3333
* a predefined ignore list.
34+
* @example {/analytics\.js$} rule
3435
*/
35-
onIgnoreList: 'On ignore list',
36+
onIgnoreList: 'On ignore list ({rule})',
3637
/**
3738
* @description Refers to the "Main frame", meaning the top level frame. See https://www.w3.org/TR/html401/present/frames.html
3839
* @example{example.com} PH1
@@ -571,7 +572,8 @@ export class ThreadAppender implements TrackAppender {
571572
*/
572573
titleForEvent(entry: Trace.Types.Events.Event): string {
573574
if (Utils.IgnoreList.isIgnoreListedEntry(entry)) {
574-
return i18nString(UIStrings.onIgnoreList);
575+
const rule = Utils.IgnoreList.getIgnoredReasonString(entry);
576+
return i18nString(UIStrings.onIgnoreList, {rule});
575577
}
576578
return Utils.EntryName.nameForEntry(entry, this.#parsedTrace);
577579
}

front_end/panels/timeline/track_appenders/ThreadAppender.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ describeWithEnvironment('ThreadAppender', function() {
481481
assert.deepEqual(flameChartData.entryStartTimes, [0.1, 0.1, 0.1, 0.2]);
482482
assert.deepEqual(flameChartData.entryTotalTimes, [0.2, 0.1, 0.025, 0.1]);
483483
assert.strictEqual(threadAppenders.length, 1);
484-
assert.strictEqual(threadAppenders[0].titleForEvent(callFrameB), 'On ignore list');
484+
assert.strictEqual(threadAppenders[0].titleForEvent(callFrameB), 'On ignore list (\\\/bundled\\.js$)');
485485
});
486486
});
487487
describe('showAllEvents', () => {

front_end/panels/timeline/utils/IgnoreList.test.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44

55
import * as Common from '../../../core/common/common.js';
66
import type * as Platform from '../../../core/platform/platform.js';
7+
import * as SDK from '../../../core/sdk/sdk.js';
78
import * as Bindings from '../../../models/bindings/bindings.js';
89
import * as Trace from '../../../models/trace/trace.js';
10+
import * as Workspace from '../../../models/workspace/workspace.js';
911
import {
1012
describeWithMockConnection,
1113
} from '../../../testing/MockConnection.js';
@@ -89,6 +91,8 @@ describeWithMockConnection('isIgnoreListedEntry', () => {
8991

9092
ignoreKnownThirdPartySetting.set(true);
9193
assert.isTrue(Utils.IgnoreList.isIgnoreListedEntry(profileCallWithMappings));
94+
assert.strictEqual(
95+
'Marked with ignoreList in source map', Utils.IgnoreList.getIgnoredReasonString(profileCallWithMappings));
9296

9397
ignoreKnownThirdPartySetting.set(false);
9498
assert.isFalse(Utils.IgnoreList.isIgnoreListedEntry(profileCallWithMappings));
@@ -130,11 +134,59 @@ describeWithMockConnection('isIgnoreListedEntry', () => {
130134

131135
ignoreContentScriptSetting.set(true);
132136
assert.isTrue(Utils.IgnoreList.isIgnoreListedEntry(profileCallWithContentScript));
137+
assert.strictEqual('Content script', Utils.IgnoreList.getIgnoredReasonString(profileCallWithContentScript));
133138

134139
ignoreContentScriptSetting.set(false);
135140
assert.isFalse(Utils.IgnoreList.isIgnoreListedEntry(profileCallWithContentScript));
136141

137142
// restore to the original value.
138143
ignoreContentScriptSetting.set(ignoreContentScriptSettingValue);
139144
});
145+
146+
it('get the first matched rule for the ignored script', async () => {
147+
const targetManager = SDK.TargetManager.TargetManager.instance();
148+
const workspace = Workspace.Workspace.WorkspaceImpl.instance({forceNew: true});
149+
const resourceMapping = new Bindings.ResourceMapping.ResourceMapping(targetManager, workspace);
150+
const debuggerWorkspaceBinding = Bindings.DebuggerWorkspaceBinding.DebuggerWorkspaceBinding.instance(
151+
{forceNew: true, resourceMapping, targetManager});
152+
Bindings.IgnoreListManager.IgnoreListManager.instance({
153+
forceNew: true,
154+
debuggerWorkspaceBinding,
155+
});
156+
ignoreRegex('youtube*');
157+
const url = 'https://www.youtube.com/s/desktop/2ebf714b/jsbin/desktop_polymer.vflset/desktop_polymer.js' as
158+
Platform.DevToolsPath.UrlString;
159+
Bindings.IgnoreListManager.IgnoreListManager.instance().ignoreListURL(url);
160+
161+
const entry = makeProfileCall(
162+
'function name', 10, 100, Trace.Types.Events.ProcessID(1), Trace.Types.Events.ThreadID(1), /* nodeId= */ 1,
163+
url);
164+
// There are two matched rules (in order)
165+
// - youtube*
166+
// - \\/desktop_polymer\\.js$ (generated by the URL)
167+
// So the first matched one is `youtube*`
168+
assert.strictEqual('youtube*', Utils.IgnoreList.getIgnoredReasonString(entry));
169+
170+
unignoreRegex('youtube*');
171+
// Now There is only one matched rule.
172+
assert.strictEqual('\\/desktop_polymer\\.js$', Utils.IgnoreList.getIgnoredReasonString(entry));
173+
});
140174
});
175+
176+
function ignoreRegex(regexValue: string): void {
177+
const regexPatterns =
178+
(Common.Settings.Settings.instance().moduleSetting('skip-stack-frames-pattern') as Common.Settings.RegExpSetting)
179+
.getAsArray();
180+
regexPatterns.push({pattern: regexValue, disabled: false});
181+
}
182+
183+
function unignoreRegex(regexValue: string): void {
184+
const regexPatterns =
185+
(Common.Settings.Settings.instance().moduleSetting('skip-stack-frames-pattern') as Common.Settings.RegExpSetting)
186+
.getAsArray();
187+
const result =
188+
regexPatterns.filter(regexPattern => regexPattern.pattern !== regexValue) as Common.Settings.RegExpSettingItem[];
189+
190+
(Common.Settings.Settings.instance().moduleSetting('skip-stack-frames-pattern') as Common.Settings.RegExpSetting)
191+
.setAsArray(result);
192+
}

front_end/panels/timeline/utils/IgnoreList.ts

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,37 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5+
import * as i18n from '../../../core/i18n/i18n.js';
56
import type * as Platform from '../../../core/platform/platform.js';
67
import * as Bindings from '../../../models/bindings/bindings.js';
78
import * as Trace from '../../../models/trace/trace.js';
89

910
import {SourceMapsResolver} from './SourceMapsResolver.js';
1011

11-
export function isIgnoreListedEntry(entry: Trace.Types.Events.Event): boolean {
12-
if (!Trace.Types.Events.isProfileCall(entry)) {
13-
return false;
14-
}
12+
const UIStrings = {
13+
/**
14+
* @description Refers to when skipping content scripts is enabled and the current script is ignored because it's a content script.
15+
*/
16+
skipContentScripts: 'Content script',
17+
/**
18+
* @description Refers to when skipping known third party scripts is enabled and the current script is ignored because it's a known third party script.
19+
*/
20+
skip3rdPartyScripts: 'Marked with ignoreList in source map',
21+
/**
22+
* @description Refers to when skipping anonymous scripts is enabled and the current script is ignored because is an anonymous script.
23+
*/
24+
skipAnonymousScripts: 'Anonymous script',
25+
/**
26+
* @description Refers to when the current script is ignored because of an unknown rule.
27+
*/
28+
unknown: 'Unknown',
29+
};
30+
31+
const str_ = i18n.i18n.registerUIStrings('panels/timeline/utils/IgnoreList.ts', UIStrings);
32+
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
33+
34+
function getUrlAndIgnoreListOptions(entry: Trace.Types.Events.SyntheticProfileCall):
35+
{url: Platform.DevToolsPath.UrlString, ignoreListOptions: Bindings.IgnoreListManager.IgnoreListGeneralRules} {
1536
const rawUrl = entry.callFrame.url as Platform.DevToolsPath.UrlString;
1637

1738
const sourceMappedData = SourceMapsResolver.resolvedCodeLocationForEntry(entry);
@@ -21,11 +42,51 @@ export function isIgnoreListedEntry(entry: Trace.Types.Events.Event): boolean {
2142
const isKnownThirdParty = uiSourceCode?.isKnownThirdParty();
2243
const isContentScript = script?.isContentScript();
2344
const ignoreListOptions: Bindings.IgnoreListManager.IgnoreListGeneralRules = {isContentScript, isKnownThirdParty};
24-
const urlToUse = resolvedUrl || rawUrl;
25-
return isIgnoreListedURL(urlToUse, ignoreListOptions);
45+
const url = resolvedUrl || rawUrl;
46+
return {url, ignoreListOptions};
2647
}
2748

28-
export function isIgnoreListedURL(
49+
export function isIgnoreListedEntry(entry: Trace.Types.Events.Event): boolean {
50+
if (!Trace.Types.Events.isProfileCall(entry)) {
51+
return false;
52+
}
53+
const {url, ignoreListOptions} = getUrlAndIgnoreListOptions(entry);
54+
return isIgnoreListedURL(url, ignoreListOptions);
55+
}
56+
57+
function isIgnoreListedURL(
2958
url: Platform.DevToolsPath.UrlString, options?: Bindings.IgnoreListManager.IgnoreListGeneralRules): boolean {
3059
return Bindings.IgnoreListManager.IgnoreListManager.instance().isUserIgnoreListedURL(url, options);
3160
}
61+
62+
/**
63+
* Returns the ignore reason for the given entry.
64+
*
65+
* This function should be called when `isIgnoreListedEntry(entry)` is true
66+
*/
67+
export function getIgnoredReasonString(entry: Trace.Types.Events.Event): string {
68+
if (!Trace.Types.Events.isProfileCall(entry)) {
69+
console.warn('Ignore list feature should only support ProfileCall.');
70+
return '';
71+
}
72+
const {url, ignoreListOptions} = getUrlAndIgnoreListOptions(entry);
73+
74+
const ignoreListMgr = Bindings.IgnoreListManager.IgnoreListManager.instance();
75+
if (ignoreListOptions.isContentScript && ignoreListMgr.skipContentScripts) {
76+
return i18nString(UIStrings.skipContentScripts);
77+
}
78+
if (ignoreListOptions.isKnownThirdParty && ignoreListMgr.automaticallyIgnoreListKnownThirdPartyScripts) {
79+
return i18nString(UIStrings.skip3rdPartyScripts);
80+
}
81+
82+
if (!url) {
83+
if (ignoreListMgr.skipAnonymousScripts) {
84+
return i18nString(UIStrings.skipAnonymousScripts);
85+
}
86+
// This branch shouldn't be reached because when |skipAnonymousScripts| is false, this url is not ignored.
87+
// So just return empty string to make the type check work.
88+
return '';
89+
}
90+
const regex = ignoreListMgr.getFirstMatchedRegex(url);
91+
return regex ? regex.source : i18nString(UIStrings.unknown);
92+
}

0 commit comments

Comments
 (0)