{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/helpers.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n\nimport type * as Platform from '../../../core/platform/platform.js';\nimport * as ThirdPartyWeb from '../../../third_party/third-party-web/third-party-web.js';\nimport * as Types from '../types/types.js';\n\nimport type {TraceEventsForNetworkRequest} from './NetworkRequestsHandler.js';\nimport type {ParsedTrace} from './types.js';\n\nexport type Entity = typeof ThirdPartyWeb.ThirdPartyWeb.entities[number]&{\n isUnrecognized?: boolean,\n};\n\nexport interface EntityMappings {\n createdEntityCache: Map;\n entityByEvent: Map;\n eventsByEntity: Map;\n entityByUrlCache: Map;\n}\n\nexport function getEntityForEvent(event: Types.Events.Event, entityMappings: EntityMappings): Entity|undefined {\n const url = getNonResolvedURL(event);\n if (!url) {\n return;\n }\n return getEntityForUrl(url, entityMappings);\n}\n\nexport function getEntityForUrl(url: string, entityMappings: EntityMappings): Entity|undefined {\n const cachedByUrl = entityMappings.entityByUrlCache.get(url);\n if (cachedByUrl) {\n return cachedByUrl;\n }\n const entity = ThirdPartyWeb.ThirdPartyWeb.getEntity(url) ?? makeUpEntity(entityMappings.createdEntityCache, url);\n if (entity) {\n entityMappings.entityByUrlCache.set(url, entity);\n }\n return entity;\n}\n\nexport function getNonResolvedURL(\n entry: Types.Events.Event, parsedTrace?: ParsedTrace): Platform.DevToolsPath.UrlString|null {\n if (Types.Events.isProfileCall(entry)) {\n return entry.callFrame.url as Platform.DevToolsPath.UrlString;\n }\n\n if (Types.Events.isSyntheticNetworkRequest(entry)) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n if (Types.Events.isParseAuthorStyleSheetEvent(entry) && entry.args) {\n return entry.args.data.stylesheetUrl as Platform.DevToolsPath.UrlString;\n }\n\n if (entry.args?.data?.stackTrace && entry.args.data.stackTrace.length > 0) {\n return entry.args.data.stackTrace[0].url as Platform.DevToolsPath.UrlString;\n }\n\n // ParseHTML events store the URL under beginData, not data.\n if (Types.Events.isParseHTML(entry)) {\n return entry.args.beginData.url as Platform.DevToolsPath.UrlString;\n }\n\n if (parsedTrace) {\n // DecodeImage events use the URL from the relevant PaintImage event.\n if (Types.Events.isDecodeImage(entry)) {\n const paintEvent = parsedTrace.ImagePainting.paintImageForEvent.get(entry);\n return paintEvent ? getNonResolvedURL(paintEvent, parsedTrace) : null;\n }\n\n // DrawLazyPixelRef events use the URL from the relevant PaintImage event.\n if (Types.Events.isDrawLazyPixelRef(entry) && entry.args?.LazyPixelRef) {\n const paintEvent = parsedTrace.ImagePainting.paintImageByDrawLazyPixelRef.get(entry.args.LazyPixelRef);\n return paintEvent ? getNonResolvedURL(paintEvent, parsedTrace) : null;\n }\n }\n\n // For all other events, try to see if the URL is provided, else return null.\n if (entry.args?.data?.url) {\n return entry.args.data.url as Platform.DevToolsPath.UrlString;\n }\n\n // Many events don't have a url, but are associated with a request. Use the\n // request's url.\n const requestId = (entry.args?.data as {requestId?: string})?.requestId;\n if (parsedTrace && requestId) {\n const url = parsedTrace.NetworkRequests.byId.get(requestId)?.args.data.url;\n if (url) {\n return url as Platform.DevToolsPath.UrlString;\n }\n }\n\n return null;\n}\n\nexport function makeUpEntity(entityCache: Map, url: string): Entity|undefined {\n if (url.startsWith('chrome-extension:')) {\n return makeUpChromeExtensionEntity(entityCache, url);\n }\n\n // Make up an entity only for valid http/https URLs.\n if (!url.startsWith('http')) {\n return;\n }\n\n // NOTE: Lighthouse uses a tld database to determine the root domain, but here\n // we are using third party web's database. Doesn't really work for the case of classifying\n // domains 3pweb doesn't know about, so it will just give us a guess.\n const rootDomain = ThirdPartyWeb.ThirdPartyWeb.getRootDomain(url);\n if (!rootDomain) {\n return;\n }\n\n if (entityCache.has(rootDomain)) {\n return entityCache.get(rootDomain);\n }\n\n const unrecognizedEntity = {\n name: rootDomain,\n company: rootDomain,\n category: '',\n categories: [],\n domains: [rootDomain],\n averageExecutionTime: 0,\n totalExecutionTime: 0,\n totalOccurrences: 0,\n isUnrecognized: true,\n };\n entityCache.set(rootDomain, unrecognizedEntity);\n return unrecognizedEntity;\n}\n\nfunction getChromeExtensionOrigin(url: URL): string {\n return url.protocol + '//' + url.host;\n}\n\nfunction makeUpChromeExtensionEntity(entityCache: Map, url: string, extensionName?: string): Entity {\n const parsedUrl = new URL(url);\n const origin = getChromeExtensionOrigin(parsedUrl);\n const host = new URL(origin).host;\n const name = extensionName || host;\n\n const cachedEntity = entityCache.get(origin);\n if (cachedEntity) {\n return cachedEntity;\n }\n\n const chromeExtensionEntity = {\n name,\n company: name,\n category: 'Chrome Extension',\n homepage: 'https://chromewebstore.google.com/detail/' + host,\n categories: [],\n domains: [origin],\n averageExecutionTime: 0,\n totalExecutionTime: 0,\n totalOccurrences: 0,\n };\n\n entityCache.set(origin, chromeExtensionEntity);\n return chromeExtensionEntity;\n}\n\nexport function addEventToEntityMapping(event: Types.Events.Event, entityMappings: EntityMappings): void {\n // As we share the entityMappings between Network and Renderer... We can have ResourceSendRequest events passed in here\n // that were already mapped in Network. So, to avoid mapping twice, we always check that we didn't yet.\n if (entityMappings.entityByEvent.has(event)) {\n return;\n }\n\n const entity = getEntityForEvent(event, entityMappings);\n if (!entity) {\n return;\n }\n\n const mappedEvents = entityMappings.eventsByEntity.get(entity);\n if (mappedEvents) {\n mappedEvents.push(event);\n } else {\n entityMappings.eventsByEntity.set(entity, [event]);\n }\n entityMappings.entityByEvent.set(event, entity);\n}\n\n// A slight upgrade of addEventToEntityMapping to handle the sub-events of a network request.\nexport function addNetworkRequestToEntityMapping(\n networkRequest: Types.Events.SyntheticNetworkRequest, entityMappings: EntityMappings,\n requestTraceEvents: TraceEventsForNetworkRequest): void {\n const entity = getEntityForEvent(networkRequest, entityMappings);\n if (!entity) {\n return;\n }\n // In addition to mapping the network request, we'll also assign this entity to its \"child\" instant events like receiveData, willSendRequest, finishLoading, etc,\n const eventsToMap = [networkRequest, ...Object.values(requestTraceEvents).flat()];\n const mappedEvents = entityMappings.eventsByEntity.get(entity);\n if (mappedEvents) {\n mappedEvents.push(...eventsToMap);\n } else {\n entityMappings.eventsByEntity.set(entity, eventsToMap);\n }\n for (const evt of eventsToMap) {\n entityMappings.entityByEvent.set(evt, entity);\n }\n}\n"]}