chrome-devtools-frontend 1.0.1642246 → 1.0.1642899
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/SECURITY.md +1 -0
- package/front_end/core/host/UserMetrics.ts +2 -1
- package/front_end/core/sdk/CSSMatchedStyles.ts +55 -26
- package/front_end/core/sdk/CSSRule.ts +1 -0
- package/front_end/core/sdk/DebuggerModel.ts +5 -0
- package/front_end/entrypoints/greendev_floaty/FloatyEntrypoint.ts +4 -3
- package/front_end/entrypoints/greendev_floaty/greendev_floaty.ts +4 -3
- package/front_end/entrypoints/heap_snapshot_worker/HeapSnapshot.ts +11 -0
- package/front_end/models/ai_assistance/AiAgent2.ts +80 -16
- package/front_end/models/ai_assistance/AiConversation.ts +3 -2
- package/front_end/models/ai_assistance/README.md +8 -0
- package/front_end/models/ai_assistance/agents/AccessibilityAgent.ts +50 -39
- package/front_end/models/ai_assistance/agents/AiAgent.ts +17 -6
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +2 -2
- package/front_end/models/ai_assistance/agents/PerformanceAgent.ts +195 -147
- package/front_end/models/ai_assistance/agents/StylingAgent.snapshot.txt +1 -26
- package/front_end/models/ai_assistance/agents/StylingAgent.ts +24 -309
- package/front_end/models/ai_assistance/ai_assistance.ts +8 -0
- package/front_end/models/ai_assistance/contexts/DOMNodeContext.snapshot.txt +51 -0
- package/front_end/models/ai_assistance/contexts/DOMNodeContext.ts +200 -0
- package/front_end/models/ai_assistance/data_formatters/NetworkRequestFormatter.ts +13 -12
- package/front_end/models/ai_assistance/skills/styling.md +36 -2
- package/front_end/models/ai_assistance/tools/GetStyles.ts +137 -0
- package/front_end/models/ai_assistance/tools/Tool.ts +55 -0
- package/front_end/models/ai_assistance/tools/ToolRegistry.ts +34 -0
- package/front_end/models/heap_snapshot/HeapSnapshotProxy.ts +4 -0
- package/front_end/models/javascript_metadata/NativeFunctions.js +16 -0
- package/front_end/models/lighthouse/LighthouseReporterTypes.ts +5 -0
- package/front_end/models/live-metrics/LiveMetrics.ts +24 -13
- package/front_end/models/stack_trace/DetailedErrorStackParser.ts +2 -2
- package/front_end/models/stack_trace/StackTrace.ts +4 -1
- package/front_end/models/stack_trace/StackTraceImpl.ts +9 -2
- package/front_end/models/stack_trace/StackTraceModel.ts +17 -4
- package/front_end/models/stack_trace/Trie.ts +1 -1
- package/front_end/panels/ai_assistance/AiAssistancePanel.ts +19 -15
- package/front_end/panels/ai_assistance/ai_assistance-meta.ts +16 -0
- package/front_end/panels/ai_assistance/components/ChatInput.ts +2 -2
- package/front_end/panels/application/DOMStorageItemsView.ts +4 -0
- package/front_end/panels/application/KeyValueStorageItemsView.ts +39 -7
- package/front_end/panels/common/ExtensionServer.ts +26 -15
- package/front_end/panels/console/SymbolizedErrorWidget.ts +96 -2
- package/front_end/panels/console/symbolizedErrorWidget.css +48 -0
- package/front_end/panels/elements/StandaloneStylesContainer.ts +1 -1
- package/front_end/panels/elements/StylePropertiesSection.ts +8 -0
- package/front_end/panels/elements/StylePropertyHighlighter.ts +4 -2
- package/front_end/panels/elements/StylePropertyTreeElement.ts +6 -5
- package/front_end/panels/elements/StylesContainer.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +4 -4
- package/front_end/panels/layer_viewer/PaintProfilerView.ts +106 -132
- package/front_end/panels/lighthouse/LighthousePanel.ts +4 -3
- package/front_end/panels/network/NetworkLogView.ts +3 -0
- package/front_end/panels/network/networkLogView.css +0 -15
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/ui/legacy/components/cookie_table/CookiesTable.ts +36 -3
- package/front_end/ui/legacy/components/data_grid/dataGridAiButton.css +20 -0
- package/front_end/ui/legacy/components/utils/Linkifier.ts +19 -4
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/front_end/ui/visual_logging/LoggingDriver.ts +13 -0
- package/package.json +1 -1
|
@@ -11,9 +11,13 @@ import type * as SDK from '../../core/sdk/sdk.js';
|
|
|
11
11
|
import type * as Protocol from '../../generated/protocol.js';
|
|
12
12
|
import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
|
|
13
13
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
14
|
+
import * as Lit from '../../ui/lit/lit.js';
|
|
14
15
|
|
|
15
16
|
import paintProfilerStyles from './paintProfiler.css.js';
|
|
16
17
|
|
|
18
|
+
const {html, render, nothing} = Lit;
|
|
19
|
+
const {repeat} = Lit.Directives;
|
|
20
|
+
|
|
17
21
|
const UIStrings = {
|
|
18
22
|
/**
|
|
19
23
|
* @description Text to indicate the progress of a profile
|
|
@@ -397,161 +401,131 @@ export interface EventTypes {
|
|
|
397
401
|
[Events.WINDOW_CHANGED]: void;
|
|
398
402
|
}
|
|
399
403
|
|
|
400
|
-
export
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
private readonly treeItemCache: Map<SDK.PaintProfiler.PaintProfilerLogItem, LogTreeElement>;
|
|
404
|
-
private selectionWindow?: {left: number, right: number}|null;
|
|
405
|
-
constructor() {
|
|
406
|
-
super();
|
|
407
|
-
this.setMinimumSize(100, 25);
|
|
408
|
-
this.element.classList.add('overflow-auto');
|
|
409
|
-
|
|
410
|
-
this.treeOutline = new UI.TreeOutline.TreeOutlineInShadow();
|
|
411
|
-
UI.ARIAUtils.setLabel(this.treeOutline.contentElement, i18nString(UIStrings.commandLog));
|
|
412
|
-
this.element.appendChild(this.treeOutline.element);
|
|
413
|
-
this.setDefaultFocusedElement(this.treeOutline.contentElement);
|
|
414
|
-
|
|
415
|
-
this.log = [];
|
|
416
|
-
this.treeItemCache = new Map();
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
setCommandLog(log: SDK.PaintProfiler.PaintProfilerLogItem[]): void {
|
|
420
|
-
this.log = log;
|
|
404
|
+
export interface CommandLogViewInput {
|
|
405
|
+
visibleLogItems: SDK.PaintProfiler.PaintProfilerLogItem[];
|
|
406
|
+
}
|
|
421
407
|
|
|
422
|
-
|
|
408
|
+
function paramToString(param: SDK.PaintProfiler.RawPaintProfilerLogItemParamValue, name: string): string {
|
|
409
|
+
if (typeof param !== 'object') {
|
|
410
|
+
return typeof param === 'string' && param.length > 100 ? name : JSON.stringify(param);
|
|
423
411
|
}
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
}
|
|
431
|
-
|
|
412
|
+
let str = '';
|
|
413
|
+
let keyCount = 0;
|
|
414
|
+
for (const key in param) {
|
|
415
|
+
const paramKey = param[key];
|
|
416
|
+
if (++keyCount > 4 || typeof paramKey === 'object' || (typeof paramKey === 'string' && paramKey.length > 100)) {
|
|
417
|
+
return name;
|
|
418
|
+
}
|
|
419
|
+
if (str) {
|
|
420
|
+
str += ', ';
|
|
432
421
|
}
|
|
433
|
-
|
|
422
|
+
str += paramKey;
|
|
434
423
|
}
|
|
424
|
+
return str;
|
|
425
|
+
}
|
|
435
426
|
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
427
|
+
function paramsToString(params: SDK.PaintProfiler.RawPaintProfilerLogItemParams|null): string {
|
|
428
|
+
let str = '';
|
|
429
|
+
for (const key in params) {
|
|
430
|
+
if (str) {
|
|
431
|
+
str += ', ';
|
|
432
|
+
}
|
|
433
|
+
str += paramToString(params[key], key);
|
|
439
434
|
}
|
|
435
|
+
return str;
|
|
436
|
+
}
|
|
440
437
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
438
|
+
function renderProperty(name: string, value: SDK.PaintProfiler.RawPaintProfilerLogItemParamValue): Lit.LitTemplate {
|
|
439
|
+
const isObject = value !== null && typeof value === 'object';
|
|
440
|
+
|
|
441
|
+
// clang-format off
|
|
442
|
+
return html`
|
|
443
|
+
<li role="treeitem">
|
|
444
|
+
<span>${name}: </span>${
|
|
445
|
+
isObject ? html`
|
|
446
|
+
<ul role="group">
|
|
447
|
+
${Object.entries(value).map(([key, val]) => renderProperty(key, val))}
|
|
448
|
+
</ul>` : html`
|
|
449
|
+
<span>${JSON.stringify(value)}</span>`
|
|
451
450
|
}
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
const child = root.lastChild() as LogTreeElement;
|
|
456
|
-
if (!child || child.logItem.commandIndex < this.selectionWindow.right) {
|
|
457
|
-
break;
|
|
458
|
-
}
|
|
459
|
-
root.removeChildAtIndex(root.children().length - 1);
|
|
460
|
-
}
|
|
461
|
-
for (let i = this.selectionWindow.left, right = this.selectionWindow.right; i < right; ++i) {
|
|
462
|
-
this.appendLogItem(this.log[i]);
|
|
463
|
-
}
|
|
464
|
-
return Promise.resolve();
|
|
465
|
-
}
|
|
451
|
+
</li>
|
|
452
|
+
`;
|
|
453
|
+
// clang-format on
|
|
466
454
|
}
|
|
467
455
|
|
|
468
|
-
|
|
469
|
-
|
|
456
|
+
function renderLogItem(logItem: SDK.PaintProfiler.PaintProfilerLogItem): Lit.LitTemplate {
|
|
457
|
+
const hasParams = Boolean(logItem.params && Object.keys(logItem.params).length > 0);
|
|
458
|
+
const titleText = logItem.method + '(' + paramsToString(logItem.params) + ')';
|
|
459
|
+
|
|
460
|
+
// clang-format off
|
|
461
|
+
return html`
|
|
462
|
+
<li role="treeitem">
|
|
463
|
+
${titleText}
|
|
464
|
+
${hasParams ? html`
|
|
465
|
+
<ul role="group">
|
|
466
|
+
${Object.entries(logItem.params || {}).map(([key, val]) => renderProperty(key, val))}
|
|
467
|
+
</ul>` : nothing}
|
|
468
|
+
</li>
|
|
469
|
+
`;
|
|
470
|
+
// clang-format on
|
|
471
|
+
}
|
|
470
472
|
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
473
|
+
// clang-format off
|
|
474
|
+
export const COMMAND_LOG_DEFAULT_VIEW = (input: CommandLogViewInput, _output: undefined, target: HTMLElement): void => {
|
|
475
|
+
render(html`
|
|
476
|
+
<div class="overflow-auto flex-auto vbox">
|
|
477
|
+
<devtools-tree
|
|
478
|
+
autofocus
|
|
479
|
+
aria-label=${i18nString(UIStrings.commandLog)}
|
|
480
|
+
.template=${html`
|
|
481
|
+
<ul role="tree">
|
|
482
|
+
${repeat(input.visibleLogItems,
|
|
483
|
+
item => item.commandIndex,
|
|
484
|
+
item => renderLogItem(item))}
|
|
485
|
+
</ul>`}>
|
|
486
|
+
</devtools-tree>
|
|
487
|
+
</div>`,
|
|
488
|
+
target);
|
|
489
|
+
};
|
|
490
|
+
// clang-format on
|
|
491
|
+
|
|
492
|
+
type CommandLogView = typeof COMMAND_LOG_DEFAULT_VIEW;
|
|
475
493
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
494
|
+
export class PaintProfilerCommandLogView extends UI.Widget.VBox {
|
|
495
|
+
private log: SDK.PaintProfiler.PaintProfilerLogItem[];
|
|
496
|
+
private selectionWindow?: {left: number, right: number}|null;
|
|
497
|
+
readonly #view: CommandLogView;
|
|
479
498
|
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
}
|
|
499
|
+
constructor(element?: HTMLElement, view: CommandLogView = COMMAND_LOG_DEFAULT_VIEW) {
|
|
500
|
+
super(element);
|
|
501
|
+
this.#view = view;
|
|
502
|
+
this.setMinimumSize(100, 25);
|
|
485
503
|
|
|
486
|
-
|
|
487
|
-
if (typeof param !== 'object') {
|
|
488
|
-
return typeof param === 'string' && param.length > 100 ? name : JSON.stringify(param);
|
|
489
|
-
}
|
|
490
|
-
let str = '';
|
|
491
|
-
let keyCount = 0;
|
|
492
|
-
for (const key in param) {
|
|
493
|
-
const paramKey = param[key];
|
|
494
|
-
if (++keyCount > 4 || paramKey === 'object' || (paramKey === 'string' && paramKey.length > 100)) {
|
|
495
|
-
return name;
|
|
496
|
-
}
|
|
497
|
-
if (str) {
|
|
498
|
-
str += ', ';
|
|
499
|
-
}
|
|
500
|
-
str += paramKey;
|
|
501
|
-
}
|
|
502
|
-
return str;
|
|
504
|
+
this.log = [];
|
|
503
505
|
}
|
|
504
506
|
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
if (str) {
|
|
509
|
-
str += ', ';
|
|
510
|
-
}
|
|
511
|
-
str += this.paramToString(params[key], key);
|
|
512
|
-
}
|
|
513
|
-
return str;
|
|
507
|
+
override wasShown(): void {
|
|
508
|
+
super.wasShown();
|
|
509
|
+
this.requestUpdate();
|
|
514
510
|
}
|
|
515
511
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
this.title = title;
|
|
512
|
+
setCommandLog(log: SDK.PaintProfiler.PaintProfilerLogItem[]): void {
|
|
513
|
+
this.log = log;
|
|
514
|
+
this.updateWindow({left: 0, right: this.log.length});
|
|
520
515
|
}
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
export class LogPropertyTreeElement extends UI.TreeOutline.TreeElement {
|
|
524
|
-
private property: {name: string, value: SDK.PaintProfiler.RawPaintProfilerLogItemParamValue};
|
|
525
516
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
this.
|
|
517
|
+
updateWindow(selectionWindow: {left: number, right: number}|null): void {
|
|
518
|
+
this.selectionWindow = selectionWindow;
|
|
519
|
+
this.requestUpdate();
|
|
529
520
|
}
|
|
530
521
|
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
element.appendChild(treeElement);
|
|
536
|
-
if (value && typeof value === 'object') {
|
|
537
|
-
for (const property in value) {
|
|
538
|
-
LogPropertyTreeElement.appendLogPropertyItem(treeElement, property, value[property]);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
}
|
|
522
|
+
override performUpdate(): Promise<void> {
|
|
523
|
+
const visibleLogItems = this.selectionWindow && this.log.length ?
|
|
524
|
+
this.log.slice(this.selectionWindow.left, this.selectionWindow.right) :
|
|
525
|
+
[];
|
|
542
526
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
const nameElement = title.createChild('span', 'name');
|
|
546
|
-
nameElement.textContent = this.property.name;
|
|
547
|
-
const separatorElement = title.createChild('span', 'separator');
|
|
548
|
-
separatorElement.textContent = ': ';
|
|
549
|
-
if (this.property.value === null || typeof this.property.value !== 'object') {
|
|
550
|
-
const valueElement = title.createChild('span', 'value');
|
|
551
|
-
valueElement.textContent = JSON.stringify(this.property.value);
|
|
552
|
-
valueElement.classList.add('cm-js-' + (this.property.value === null ? 'null' : typeof this.property.value));
|
|
553
|
-
}
|
|
554
|
-
this.title = title;
|
|
527
|
+
this.#view({visibleLogItems}, undefined, this.contentElement);
|
|
528
|
+
return Promise.resolve();
|
|
555
529
|
}
|
|
556
530
|
}
|
|
557
531
|
|
|
@@ -374,11 +374,12 @@ export class LighthousePanel extends UI.Panel.Panel {
|
|
|
374
374
|
}
|
|
375
375
|
|
|
376
376
|
private loadedFromFile(report: string): void {
|
|
377
|
-
const data = JSON.parse(report);
|
|
378
|
-
if (!data
|
|
377
|
+
const data = JSON.parse(report) as LighthouseModel.ReporterTypes.ReportJSON;
|
|
378
|
+
if (!data.lighthouseVersion) {
|
|
379
379
|
return;
|
|
380
380
|
}
|
|
381
|
-
|
|
381
|
+
data.isImported = true;
|
|
382
|
+
this.buildReportUI(data);
|
|
382
383
|
}
|
|
383
384
|
|
|
384
385
|
override elementsToRestoreScrollPositionsFor(): Element[] {
|
|
@@ -54,6 +54,8 @@ import * as Adorners from '../../ui/components/adorners/adorners.js';
|
|
|
54
54
|
import * as Buttons from '../../ui/components/buttons/buttons.js';
|
|
55
55
|
import * as RenderCoordinator from '../../ui/components/render_coordinator/render_coordinator.js';
|
|
56
56
|
import * as DataGrid from '../../ui/legacy/components/data_grid/data_grid.js';
|
|
57
|
+
// eslint-disable-next-line @devtools/es-modules-import
|
|
58
|
+
import dataGridAiButtonStyles from '../../ui/legacy/components/data_grid/dataGridAiButton.css.js';
|
|
57
59
|
import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
|
|
58
60
|
import * as Components from '../../ui/legacy/components/utils/utils.js';
|
|
59
61
|
import * as UI from '../../ui/legacy/legacy.js';
|
|
@@ -560,6 +562,7 @@ export class NetworkLogView extends Common.ObjectWrapper.eventMixin<EventTypes,
|
|
|
560
562
|
networkLogLargeRowsSetting: Common.Settings.Setting<boolean>) {
|
|
561
563
|
super();
|
|
562
564
|
this.registerRequiredCSS(networkLogViewStyles);
|
|
565
|
+
this.registerRequiredCSS(dataGridAiButtonStyles);
|
|
563
566
|
this.setMinimumSize(50, 64);
|
|
564
567
|
|
|
565
568
|
this.element.id = 'network-container';
|
|
@@ -268,21 +268,6 @@ td.time-column {
|
|
|
268
268
|
vertical-align: sub;
|
|
269
269
|
}
|
|
270
270
|
|
|
271
|
-
.data-grid-data-grid-node .ai-button-container {
|
|
272
|
-
display: none;
|
|
273
|
-
float: right;
|
|
274
|
-
|
|
275
|
-
devtools-floating-button {
|
|
276
|
-
position: absolute;
|
|
277
|
-
z-index: 999;
|
|
278
|
-
margin-left: -17px;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
.data-grid-data-grid-node:hover .ai-button-container {
|
|
283
|
-
display: inline-flex;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
271
|
.image-network-icon-preview {
|
|
287
272
|
inset: 0;
|
|
288
273
|
margin: auto;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Name: Dependencies sourced from the upstream `chromium` repository
|
|
2
2
|
URL: Internal
|
|
3
3
|
Version: N/A
|
|
4
|
-
Revision:
|
|
4
|
+
Revision: 2d046db188ecad76b2859f8baeb9685cb8fe9c08
|
|
5
5
|
Update Mechanism: Manual (https://crbug.com/428069060)
|
|
6
6
|
License: BSD-3-Clause
|
|
7
7
|
License File: LICENSE
|
|
@@ -34,6 +34,7 @@
|
|
|
34
34
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
35
35
|
*/
|
|
36
36
|
import '../data_grid/data_grid.js';
|
|
37
|
+
import '../../../components/buttons/buttons.js';
|
|
37
38
|
|
|
38
39
|
import * as Common from '../../../../core/common/common.js';
|
|
39
40
|
import * as i18n from '../../../../core/i18n/i18n.js';
|
|
@@ -43,12 +44,15 @@ import type * as Protocol from '../../../../generated/protocol.js';
|
|
|
43
44
|
import * as IssuesManager from '../../../../models/issues_manager/issues_manager.js';
|
|
44
45
|
import * as NetworkForward from '../../../../panels/network/forward/forward.js';
|
|
45
46
|
import {Icon} from '../../../kit/kit.js';
|
|
46
|
-
import {Directives, html, render} from '../../../lit/lit.js';
|
|
47
|
+
import {Directives, html, nothing, render} from '../../../lit/lit.js';
|
|
47
48
|
import * as UI from '../../legacy.js';
|
|
49
|
+
import dataGridAiButtonStyles from '../data_grid/dataGridAiButton.css.js';
|
|
48
50
|
|
|
49
51
|
import cookiesTableStyles from './cookiesTable.css.js';
|
|
50
52
|
|
|
51
|
-
|
|
53
|
+
const STORAGE_FLOATING_BUTTON_ACTION_ID = 'ai-assistance.storage-floating-button';
|
|
54
|
+
|
|
55
|
+
export interface ViewInput {
|
|
52
56
|
data: CookieData[];
|
|
53
57
|
selectedKey?: string;
|
|
54
58
|
editable?: boolean;
|
|
@@ -61,6 +65,9 @@ interface ViewInput {
|
|
|
61
65
|
onDelete: (data: CookieData) => void;
|
|
62
66
|
onContextMenu: (data: CookieData, menu: UI.ContextMenu.ContextMenu) => void;
|
|
63
67
|
onSelect: (key: string|undefined) => void;
|
|
68
|
+
showAiButton?: boolean;
|
|
69
|
+
aiButtonTitle?: string;
|
|
70
|
+
onAiButtonClick?: (cookie: CookieData, event: Event) => void;
|
|
64
71
|
}
|
|
65
72
|
type ViewFunction = (input: ViewInput, output: object, target: HTMLElement) => void;
|
|
66
73
|
type AttributeWithIcon = SDK.Cookie.Attribute.NAME|SDK.Cookie.Attribute.VALUE|SDK.Cookie.Attribute.DOMAIN|
|
|
@@ -219,6 +226,7 @@ export class CookiesTable extends UI.Widget.VBox {
|
|
|
219
226
|
@deselect=${() => input.onSelect(undefined)}
|
|
220
227
|
>
|
|
221
228
|
<table>
|
|
229
|
+
${input.showAiButton ? html`<style>${dataGridAiButtonStyles}</style>` : nothing}
|
|
222
230
|
<tr>
|
|
223
231
|
<th id=${SDK.Cookie.Attribute.NAME} sortable ?disclosure=${input.editable} ?editable=${input.editable} long weight="24">
|
|
224
232
|
${i18nString(UIStrings.name)}
|
|
@@ -275,7 +283,15 @@ export class CookiesTable extends UI.Widget.VBox {
|
|
|
275
283
|
@delete=${()=> input.onDelete(cookie)}
|
|
276
284
|
@contextmenu=${(e: CustomEvent<UI.ContextMenu.ContextMenu>) => input.onContextMenu(cookie, e.detail)}
|
|
277
285
|
@select=${() => input.onSelect(cookie.key)}>
|
|
278
|
-
<td>${
|
|
286
|
+
<td>${input.showAiButton && !Boolean(cookie['http-only']) ? html`
|
|
287
|
+
<span class="ai-button-container">
|
|
288
|
+
<devtools-floating-button
|
|
289
|
+
icon-name=${Root.Runtime.hostConfig.devToolsGeminiRebranding?.enabled ? 'spark' : 'smart-assistant'}
|
|
290
|
+
title=${ifDefined(input.aiButtonTitle)}
|
|
291
|
+
@click=${(e: Event) => input.onAiButtonClick?.(cookie, e)}
|
|
292
|
+
></devtools-floating-button>
|
|
293
|
+
</span>
|
|
294
|
+
` : nothing}${cookie.icons?.name}${cookie.name}</td>
|
|
279
295
|
<td>${cookie.value}</td>
|
|
280
296
|
<td>${cookie.icons?.domain}${cookie.domain}</td>
|
|
281
297
|
<td>${cookie.icons?.path}${cookie.path}</td>
|
|
@@ -404,6 +420,19 @@ export class CookiesTable extends UI.Widget.VBox {
|
|
|
404
420
|
onDelete: this.onDeleteCookie.bind(this),
|
|
405
421
|
onSelect: this.onSelect.bind(this),
|
|
406
422
|
onContextMenu: this.populateContextMenu.bind(this),
|
|
423
|
+
showAiButton: this.isAiButtonEnabled(),
|
|
424
|
+
aiButtonTitle: this.isAiButtonEnabled() &&
|
|
425
|
+
UI.ActionRegistry.ActionRegistry.instance().hasAction(STORAGE_FLOATING_BUTTON_ACTION_ID) ?
|
|
426
|
+
UI.ActionRegistry.ActionRegistry.instance().getAction(STORAGE_FLOATING_BUTTON_ACTION_ID).title() :
|
|
427
|
+
undefined,
|
|
428
|
+
onAiButtonClick: (cookie: CookieData, event: Event) => {
|
|
429
|
+
event.stopPropagation();
|
|
430
|
+
this.onSelect(cookie.key);
|
|
431
|
+
const actionRegistry = UI.ActionRegistry.ActionRegistry.instance();
|
|
432
|
+
if (actionRegistry.hasAction(STORAGE_FLOATING_BUTTON_ACTION_ID)) {
|
|
433
|
+
void actionRegistry.getAction(STORAGE_FLOATING_BUTTON_ACTION_ID).execute();
|
|
434
|
+
}
|
|
435
|
+
},
|
|
407
436
|
};
|
|
408
437
|
const output = {};
|
|
409
438
|
this.view(input, output, this.element);
|
|
@@ -414,6 +443,10 @@ export class CookiesTable extends UI.Widget.VBox {
|
|
|
414
443
|
this.#selectedCallback?.(this.selectedCookie());
|
|
415
444
|
}
|
|
416
445
|
|
|
446
|
+
private isAiButtonEnabled(): boolean {
|
|
447
|
+
return UI.ActionRegistry.ActionRegistry.instance().hasAction(STORAGE_FLOATING_BUTTON_ACTION_ID);
|
|
448
|
+
}
|
|
449
|
+
|
|
417
450
|
private onDeleteCookie(data: CookieData): void {
|
|
418
451
|
const cookie = this.cookies.find(cookie => cookie.key() === data.key);
|
|
419
452
|
if (cookie && this.#deleteCallback) {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2026 The Chromium Authors
|
|
3
|
+
* Use of this source code is governed by a BSD-style license that can be
|
|
4
|
+
* found in the LICENSE file.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
.data-grid-data-grid-node .ai-button-container {
|
|
8
|
+
display: none;
|
|
9
|
+
float: right;
|
|
10
|
+
|
|
11
|
+
devtools-floating-button {
|
|
12
|
+
position: absolute;
|
|
13
|
+
z-index: 999;
|
|
14
|
+
margin-left: -17px;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.data-grid-data-grid-node:hover .ai-button-container {
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
}
|
|
@@ -399,7 +399,12 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
399
399
|
jslogContext: options?.jslogContext || 'script-location',
|
|
400
400
|
omitOrigin: options?.omitOrigin,
|
|
401
401
|
} satisfies LinkifyURLOptions;
|
|
402
|
-
const
|
|
402
|
+
const fallbackOptions = {
|
|
403
|
+
...linkifyURLOptions,
|
|
404
|
+
showColumnNumber: frame.isWasm || Boolean(options?.showColumnNumber),
|
|
405
|
+
omitLineAndRenderColumnAsHex: frame.isWasm,
|
|
406
|
+
};
|
|
407
|
+
const fallbackAnchor = Linkifier.linkifyURL(frame.url as Platform.DevToolsPath.UrlString, fallbackOptions);
|
|
403
408
|
if (!frame.uiSourceCode) {
|
|
404
409
|
const isIgnoreListed = (options?.ignoreListManager ?? Workspace.IgnoreListManager.IgnoreListManager.instance())
|
|
405
410
|
.isUserIgnoreListedURL(frame.url as Platform.DevToolsPath.UrlString);
|
|
@@ -602,6 +607,11 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
602
607
|
const maxLength = options.maxLength || UI.UIUtils.MaxLengthForDisplayedURLs;
|
|
603
608
|
const bypassURLTrimming = options.bypassURLTrimming;
|
|
604
609
|
const omitOrigin = options.omitOrigin;
|
|
610
|
+
const omitLineAndRenderColumnAsHex = options.omitLineAndRenderColumnAsHex;
|
|
611
|
+
|
|
612
|
+
if (omitLineAndRenderColumnAsHex && showColumnNumber === false) {
|
|
613
|
+
throw new Error('omitLineAndRenderColumnAsHex requires showColumnNumber to not be explicitly false');
|
|
614
|
+
}
|
|
605
615
|
|
|
606
616
|
if (!url || Common.ParsedURL.schemeIs(url, 'javascript:')) {
|
|
607
617
|
// clang-format off
|
|
@@ -619,7 +629,11 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
619
629
|
}
|
|
620
630
|
}
|
|
621
631
|
|
|
622
|
-
if (
|
|
632
|
+
if (omitLineAndRenderColumnAsHex && !text) {
|
|
633
|
+
if (typeof columnNumber === 'number') {
|
|
634
|
+
linkText += ':0x' + columnNumber.toString(16);
|
|
635
|
+
}
|
|
636
|
+
} else if (typeof lineNumber === 'number' && !text) {
|
|
623
637
|
linkText += ':' + (lineNumber + 1);
|
|
624
638
|
if (showColumnNumber && typeof columnNumber === 'number') {
|
|
625
639
|
linkText += ':' + (columnNumber + 1);
|
|
@@ -947,7 +961,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
947
961
|
}
|
|
948
962
|
|
|
949
963
|
for (const registration of linkHandlers.values().filter(r => r.handler)) {
|
|
950
|
-
const {title, handler, shouldHandleOpenResource} = registration;
|
|
964
|
+
const {title, origin, handler, shouldHandleOpenResource} = registration;
|
|
951
965
|
if (url && !shouldHandleOpenResource(url, specificSchemeHandlers)) {
|
|
952
966
|
continue;
|
|
953
967
|
}
|
|
@@ -957,7 +971,7 @@ export class Linkifier extends Common.ObjectWrapper.ObjectWrapper<EventTypes> im
|
|
|
957
971
|
jslogContext: 'open-using',
|
|
958
972
|
handler: handler.bind(null, contentProviderOrUrl, lineNumber, columnNumber),
|
|
959
973
|
};
|
|
960
|
-
if (
|
|
974
|
+
if (origin === Linkifier.linkHandlerSetting().get()) {
|
|
961
975
|
result.unshift(action);
|
|
962
976
|
} else {
|
|
963
977
|
result.push(action);
|
|
@@ -1182,6 +1196,7 @@ export interface LinkifyURLOptions {
|
|
|
1182
1196
|
jslogContext?: string;
|
|
1183
1197
|
omitOrigin?: boolean;
|
|
1184
1198
|
onRef?: (el: HTMLElement) => void;
|
|
1199
|
+
omitLineAndRenderColumnAsHex?: boolean;
|
|
1185
1200
|
}
|
|
1186
1201
|
|
|
1187
1202
|
export interface LinkifyOptions {
|
|
@@ -362,6 +362,7 @@ export const knownContextValues = new Set([
|
|
|
362
362
|
'ai-assistance-v2-opt-in-change-dialog-seen',
|
|
363
363
|
'ai-assistance-v2-opt-in.got-it',
|
|
364
364
|
'ai-assistance-v2-opt-in.manage-settings',
|
|
365
|
+
'ai-assistance.storage-floating-button',
|
|
365
366
|
'ai-code-completion-citations',
|
|
366
367
|
'ai-code-completion-citations.citation-link',
|
|
367
368
|
'ai-code-completion-disclaimer',
|
|
@@ -80,6 +80,12 @@ export async function addDocument(document: Document): Promise<void> {
|
|
|
80
80
|
}
|
|
81
81
|
document.addEventListener('visibilitychange', scheduleProcessing);
|
|
82
82
|
document.addEventListener('scroll', scheduleProcessing);
|
|
83
|
+
const resizeListener = (): void => {
|
|
84
|
+
viewportRects.delete(document);
|
|
85
|
+
scheduleProcessing();
|
|
86
|
+
};
|
|
87
|
+
document.defaultView?.addEventListener('resize', resizeListener);
|
|
88
|
+
resizeListeners.set(document, resizeListener);
|
|
83
89
|
observeMutations([document.body]);
|
|
84
90
|
}
|
|
85
91
|
|
|
@@ -90,12 +96,18 @@ export async function stopLogging(): Promise<void> {
|
|
|
90
96
|
for (const document of documents) {
|
|
91
97
|
document.removeEventListener('visibilitychange', scheduleProcessing);
|
|
92
98
|
document.removeEventListener('scroll', scheduleProcessing);
|
|
99
|
+
const resizeListener = resizeListeners.get(document);
|
|
100
|
+
if (resizeListener) {
|
|
101
|
+
document.defaultView?.removeEventListener('resize', resizeListener);
|
|
102
|
+
resizeListeners.delete(document);
|
|
103
|
+
}
|
|
93
104
|
}
|
|
94
105
|
mutationObserver.disconnect();
|
|
95
106
|
resizeObserver.disconnect();
|
|
96
107
|
intersectionObserver.disconnect();
|
|
97
108
|
documents.length = 0;
|
|
98
109
|
viewportRects.clear();
|
|
110
|
+
resizeListeners.clear();
|
|
99
111
|
processingThrottler = noOpThrottler;
|
|
100
112
|
pendingResize.clear();
|
|
101
113
|
pendingChange.clear();
|
|
@@ -130,6 +142,7 @@ export function scheduleProcessing(): void {
|
|
|
130
142
|
}
|
|
131
143
|
|
|
132
144
|
const viewportRects = new Map<Document, DOMRect>();
|
|
145
|
+
const resizeListeners = new Map<Document, () => void>();
|
|
133
146
|
const viewportRectFor = (element: Element): DOMRect => {
|
|
134
147
|
const ownerDocument = element.ownerDocument;
|
|
135
148
|
const viewportRect = viewportRects.get(ownerDocument) ||
|
package/package.json
CHANGED