chrome-devtools-frontend 1.0.1650100 → 1.0.1650232
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/host/UserMetrics.ts +0 -15
- package/front_end/core/sdk/CSSMetadata.ts +72 -0
- package/front_end/models/ai_assistance/agents/ExecuteJavascript.ts +13 -4
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +1 -7
- package/front_end/panels/network/RequestConditionsDrawer.ts +236 -198
- package/front_end/panels/network/requestConditionsDrawer.css +3 -0
- package/front_end/panels/whats_new/ReleaseNoteText.ts +12 -6
- package/front_end/panels/whats_new/resources/WNDT.md +8 -7
- package/front_end/third_party/third-party-web/lib/nostats-subset.js +21 -15
- package/front_end/third_party/third-party-web/package/README.md +619 -582
- package/front_end/third_party/third-party-web/package/dist/entities-httparchive-nostats.json +1 -1
- package/front_end/third_party/third-party-web/package/dist/entities-httparchive.json +1 -1
- package/front_end/third_party/third-party-web/package/dist/entities-nostats.json +1 -1
- package/front_end/third_party/third-party-web/package/dist/entities.json +1 -1
- package/front_end/third_party/third-party-web/package/lib/create-entity-finder-api.js +27 -15
- package/front_end/third_party/third-party-web/package/lib/create-entity-finder-api.test.js +14 -0
- package/front_end/third_party/third-party-web/package/lib/entities.test.js +10 -0
- package/front_end/third_party/third-party-web/package/lib/index.test.js +6 -6
- package/front_end/third_party/third-party-web/package/lib/markdown/template.md +1 -3
- package/front_end/third_party/third-party-web/package/package.json +7 -3
- package/front_end/third_party/third-party-web/package.json +1 -1
- package/front_end/ui/components/buttons/floatingButton.css +3 -3
- package/front_end/ui/components/lists/list.css +2 -0
- package/front_end/ui/legacy/ListWidget.ts +8 -5
- package/front_end/ui/legacy/TextPrompt.ts +5 -2
- package/front_end/ui/legacy/textPrompt.css +1 -0
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/package.json +1 -1
|
@@ -1,22 +1,35 @@
|
|
|
1
1
|
const DOMAIN_IN_URL_REGEX = /:\/\/(\S*?)(:\d+)?(\/|$)/
|
|
2
|
-
const DOMAIN_CHARACTERS = /([a-z0-9.-]+\.[a-z0-9]+|localhost)/i
|
|
2
|
+
const DOMAIN_CHARACTERS = /(?:[a-z0-9.-]+\.[a-z0-9]+|localhost)/i
|
|
3
3
|
const IP_REGEX = /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
|
|
4
4
|
const ROOT_DOMAIN_REGEX = /[^.]+\.([^.]+|(gov|com|co|ne)\.\w{2})$/i
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return null
|
|
6
|
+
/**
|
|
7
|
+
* @param {string} originOrURL
|
|
8
|
+
* @return {[string|null, string|null]} - The first item is the root domain, the second item is the domain.
|
|
9
|
+
*/
|
|
10
|
+
function parseDomains(originOrURL) {
|
|
11
|
+
if (typeof originOrURL !== 'string') return [null, null]
|
|
12
|
+
if (originOrURL.length > 10000 || originOrURL.startsWith('data:')) return [null, null]
|
|
13
|
+
let m = originOrURL.match(DOMAIN_IN_URL_REGEX)
|
|
14
|
+
let domain;
|
|
15
|
+
if (m) {
|
|
16
|
+
domain = m[1]
|
|
17
|
+
}
|
|
18
|
+
m = originOrURL.match(DOMAIN_CHARACTERS)
|
|
19
|
+
if (m) {
|
|
20
|
+
domain = m[0]
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (!domain) return [null, null]
|
|
24
|
+
if (IP_REGEX.test(domain)) return [domain, domain]
|
|
25
|
+
m = domain.match(ROOT_DOMAIN_REGEX)
|
|
26
|
+
const rootDomain = m && m[0] || domain;
|
|
27
|
+
|
|
28
|
+
return [rootDomain, domain]
|
|
12
29
|
}
|
|
13
30
|
|
|
14
|
-
function getRootDomain(originOrURL) {
|
|
15
|
-
|
|
16
|
-
if (!domain) return null
|
|
17
|
-
if (IP_REGEX.test(domain)) return domain
|
|
18
|
-
const match = domain.match(ROOT_DOMAIN_REGEX)
|
|
19
|
-
return (match && match[0]) || domain
|
|
31
|
+
function getRootDomain(originOrURL,) {
|
|
32
|
+
return parseDomains(originOrURL)[0];
|
|
20
33
|
}
|
|
21
34
|
|
|
22
35
|
function sliceSubdomainFromDomain(domain, rootDomain) {
|
|
@@ -28,8 +41,7 @@ function sliceSubdomainFromDomain(domain, rootDomain) {
|
|
|
28
41
|
}
|
|
29
42
|
|
|
30
43
|
function getEntityInDataset(entityByDomain, entityBySubDomain, entityByRootDomain, originOrURL) {
|
|
31
|
-
const domain =
|
|
32
|
-
const rootDomain = getRootDomain(domain)
|
|
44
|
+
const [rootDomain, domain] = parseDomains(originOrURL);
|
|
33
45
|
if (!domain || !rootDomain) return undefined
|
|
34
46
|
if (entityByDomain.has(domain)) return entityByDomain.get(domain)
|
|
35
47
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
1
3
|
const {createAPIFromDataset} = require('./create-entity-finder-api.js')
|
|
2
4
|
|
|
3
5
|
describe('getEntity', () => {
|
|
@@ -41,4 +43,16 @@ describe('getEntity', () => {
|
|
|
41
43
|
expect(api.getEntity('https://bar.example.co.uk/path').name).toEqual('Domain')
|
|
42
44
|
expect(api.getEntity('https://baz.bar.example.co.uk/path').name).toEqual('Domain')
|
|
43
45
|
})
|
|
46
|
+
|
|
47
|
+
it.skip('stress test', () => {
|
|
48
|
+
const urls = fs
|
|
49
|
+
.readFileSync(path.join(__dirname, '../data/random-urls.txt'), 'utf8')
|
|
50
|
+
.split('\n')
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
console.time('getEntity')
|
|
53
|
+
for (let i = 0; i < 1_000_000; i++) {
|
|
54
|
+
api.getEntity(urls[i % urls.length])
|
|
55
|
+
}
|
|
56
|
+
console.timeEnd('getEntity')
|
|
57
|
+
})
|
|
44
58
|
})
|
|
@@ -24,4 +24,14 @@ describe('Entities', () => {
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
})
|
|
27
|
+
|
|
28
|
+
it('should not have commas within a domain', () => {
|
|
29
|
+
for (const entity of entities) {
|
|
30
|
+
for (const domain of entity.domains) {
|
|
31
|
+
// A domain can be `*.maxymiser.net` or `maxymiser.hs.llnwd.net`
|
|
32
|
+
// A domain can't be `*.maxymiser.net, maxymiser.hs.llnwd.net`
|
|
33
|
+
expect(domain).toEqual(expect.not.stringContaining(','))
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
})
|
|
27
37
|
})
|
|
@@ -59,7 +59,7 @@ describe('getEntity', () => {
|
|
|
59
59
|
it('works for direct domain usage', () => {
|
|
60
60
|
expect(getEntity('https://js.connect.facebook.net/lib.js')).toMatchInlineSnapshot(`
|
|
61
61
|
Object {
|
|
62
|
-
"averageExecutionTime":
|
|
62
|
+
"averageExecutionTime": 513.7506757503379,
|
|
63
63
|
"categories": Array [
|
|
64
64
|
"social",
|
|
65
65
|
],
|
|
@@ -103,8 +103,8 @@ describe('getEntity', () => {
|
|
|
103
103
|
],
|
|
104
104
|
},
|
|
105
105
|
],
|
|
106
|
-
"totalExecutionTime":
|
|
107
|
-
"totalOccurrences":
|
|
106
|
+
"totalExecutionTime": 2901178836,
|
|
107
|
+
"totalOccurrences": 5647056,
|
|
108
108
|
}
|
|
109
109
|
`)
|
|
110
110
|
})
|
|
@@ -112,7 +112,7 @@ describe('getEntity', () => {
|
|
|
112
112
|
it('works for inferred domain usage', () => {
|
|
113
113
|
expect(getEntity('https://unknown.typekit.net/fonts.css')).toMatchInlineSnapshot(`
|
|
114
114
|
Object {
|
|
115
|
-
"averageExecutionTime":
|
|
115
|
+
"averageExecutionTime": 691.2697157512289,
|
|
116
116
|
"categories": Array [
|
|
117
117
|
"cdn",
|
|
118
118
|
],
|
|
@@ -129,8 +129,8 @@ describe('getEntity', () => {
|
|
|
129
129
|
"homepage": "https://fonts.adobe.com/",
|
|
130
130
|
"name": "Adobe TypeKit",
|
|
131
131
|
"products": Array [],
|
|
132
|
-
"totalExecutionTime":
|
|
133
|
-
"totalOccurrences":
|
|
132
|
+
"totalExecutionTime": 142315844,
|
|
133
|
+
"totalOccurrences": 205876,
|
|
134
134
|
}
|
|
135
135
|
`)
|
|
136
136
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "third-party-web",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.2",
|
|
4
4
|
"description": "Categorized data on third party entities on the web.",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -23,6 +23,10 @@
|
|
|
23
23
|
"url": "https://github.com/patrickhulce/third-party-web.git"
|
|
24
24
|
},
|
|
25
25
|
"license": "MIT",
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"registry": "https://registry.npmjs.org/",
|
|
28
|
+
"provenance": true
|
|
29
|
+
},
|
|
26
30
|
"devDependencies": {
|
|
27
31
|
"@google-cloud/bigquery": "^7.9.0",
|
|
28
32
|
"chart.js": "^2.9.4",
|
|
@@ -33,7 +37,7 @@
|
|
|
33
37
|
"lodash": "^4.17.15",
|
|
34
38
|
"prettier": "^1.18.2",
|
|
35
39
|
"prompts": "^2.4.2",
|
|
36
|
-
"semantic-release": "^
|
|
40
|
+
"semantic-release": "^25.0.3"
|
|
37
41
|
},
|
|
38
42
|
"config": {
|
|
39
43
|
"exportAliases": {
|
|
@@ -42,5 +46,5 @@
|
|
|
42
46
|
"httparchive-subset": "./lib/subsets/httparchive.js"
|
|
43
47
|
}
|
|
44
48
|
},
|
|
45
|
-
"packageManager": "yarn@4.
|
|
49
|
+
"packageManager": "yarn@4.10.3"
|
|
46
50
|
}
|
|
@@ -27,7 +27,7 @@ button {
|
|
|
27
27
|
background-color: var(--sys-color-tonal-container);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
:host-context(.theme-with-dark-background)
|
|
30
|
+
:host-context(.theme-with-dark-background) &:not(:disabled) {
|
|
31
31
|
background-color: var(--sys-color-primary);
|
|
32
32
|
}
|
|
33
33
|
|
|
@@ -36,11 +36,11 @@ button {
|
|
|
36
36
|
height: var(--sys-size-7);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
:host-context(:not(.theme-with-dark-background)) &:not(:disabled) > devtools-icon {
|
|
40
40
|
color: var(--sys-color-on-tonal-container);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
:host-context(.theme-with-dark-background) &:not(:disabled) > devtools-icon {
|
|
44
44
|
color: var(--sys-color-on-primary);
|
|
45
45
|
}
|
|
46
46
|
|
|
@@ -9,7 +9,7 @@ import './Toolbar.js';
|
|
|
9
9
|
import * as i18n from '../../core/i18n/i18n.js';
|
|
10
10
|
import * as Platform from '../../core/platform/platform.js';
|
|
11
11
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
12
|
-
import {html, render} from '../lit/lit.js';
|
|
12
|
+
import {html, nothing, render} from '../lit/lit.js';
|
|
13
13
|
import * as VisualLogging from '../visual_logging/visual_logging.js';
|
|
14
14
|
|
|
15
15
|
import * as ARIAUtils from './ARIAUtils.js';
|
|
@@ -107,6 +107,7 @@ export class ListWidget<T> extends VBox {
|
|
|
107
107
|
updateItem(index: number, newItem: T, editable: boolean, focusable = true, controlLabels: {
|
|
108
108
|
edit?: string,
|
|
109
109
|
delete?: string,
|
|
110
|
+
hideEdit?: boolean,
|
|
110
111
|
} = {}): void {
|
|
111
112
|
if (index < 0 || index >= this.#items.length) {
|
|
112
113
|
this.appendItem(newItem, editable, focusable, controlLabels);
|
|
@@ -130,7 +131,8 @@ export class ListWidget<T> extends VBox {
|
|
|
130
131
|
}
|
|
131
132
|
}
|
|
132
133
|
|
|
133
|
-
appendItem(item: T, editable: boolean, focusable = true,
|
|
134
|
+
appendItem(item: T, editable: boolean, focusable = true,
|
|
135
|
+
controlLabels: {edit?: string, delete?: string, hideEdit?: boolean} = {}): void {
|
|
134
136
|
if (this.lastSeparator && this.#items.length) {
|
|
135
137
|
const element = document.createElement('div');
|
|
136
138
|
element.classList.add('list-separator');
|
|
@@ -204,7 +206,8 @@ export class ListWidget<T> extends VBox {
|
|
|
204
206
|
this.updatePlaceholder();
|
|
205
207
|
}
|
|
206
208
|
|
|
207
|
-
private createControls(item: T, element: HTMLElement,
|
|
209
|
+
private createControls(item: T, element: HTMLElement,
|
|
210
|
+
controlLabels: {edit?: string, delete?: string, hideEdit?: boolean}): Element {
|
|
208
211
|
const controls = document.createElement('div');
|
|
209
212
|
controls.classList.add('controls-container');
|
|
210
213
|
controls.classList.add('fill');
|
|
@@ -214,12 +217,12 @@ export class ListWidget<T> extends VBox {
|
|
|
214
217
|
<div class="controls-gradient"></div>
|
|
215
218
|
<div class="controls-buttons">
|
|
216
219
|
<devtools-toolbar>
|
|
217
|
-
|
|
220
|
+
${controlLabels?.hideEdit ? nothing : html`<devtools-button class=toolbar-button
|
|
218
221
|
.iconName=${'edit'}
|
|
219
222
|
.jslogContext=${'edit-item'}
|
|
220
223
|
.title=${controlLabels?.edit ?? i18nString(UIStrings.editString)}
|
|
221
224
|
.variant=${Buttons.Button.Variant.ICON}
|
|
222
|
-
@click=${onEditClicked}></devtools-button
|
|
225
|
+
@click=${onEditClicked}></devtools-button>`}
|
|
223
226
|
<devtools-button class=toolbar-button
|
|
224
227
|
.iconName=${'bin'}
|
|
225
228
|
.jslogContext=${'remove-item'}
|
|
@@ -226,11 +226,12 @@ export class TextPromptElement extends HTMLElement {
|
|
|
226
226
|
#done(e: Event, commit: boolean): void {
|
|
227
227
|
const target = e.target as HTMLElement;
|
|
228
228
|
const text = target.textContent || '';
|
|
229
|
-
this.#internals.setValidity({});
|
|
230
229
|
if (commit) {
|
|
231
230
|
const validationMessage = this.#validator?.(text) ?? '';
|
|
232
231
|
if (validationMessage) {
|
|
233
232
|
this.#internals.setValidity({customError: true}, validationMessage, this.#entrypoint);
|
|
233
|
+
} else {
|
|
234
|
+
this.#internals.setValidity({});
|
|
234
235
|
}
|
|
235
236
|
|
|
236
237
|
if (!this.#internals.reportValidity()) {
|
|
@@ -239,6 +240,7 @@ export class TextPromptElement extends HTMLElement {
|
|
|
239
240
|
|
|
240
241
|
this.dispatchEvent(new TextPromptElement.CommitEvent(text));
|
|
241
242
|
} else {
|
|
243
|
+
this.#internals.setValidity({});
|
|
242
244
|
this.dispatchEvent(new TextPromptElement.CancelEvent());
|
|
243
245
|
}
|
|
244
246
|
e.consume();
|
|
@@ -248,12 +250,13 @@ export class TextPromptElement extends HTMLElement {
|
|
|
248
250
|
if (event.handled || !(event instanceof KeyboardEvent)) {
|
|
249
251
|
return;
|
|
250
252
|
}
|
|
251
|
-
this.#internals.setValidity({});
|
|
252
253
|
|
|
253
254
|
if (event.key === 'Enter') {
|
|
254
255
|
this.#done(event, /* commit=*/ true);
|
|
255
256
|
} else if (Platform.KeyboardUtilities.isEscKey(event)) {
|
|
256
257
|
this.#done(event, /* commit=*/ false);
|
|
258
|
+
} else {
|
|
259
|
+
this.#internals.setValidity({});
|
|
257
260
|
}
|
|
258
261
|
}
|
|
259
262
|
|
package/package.json
CHANGED