import{IssuesManager}from'../browser_sdk/browser_sdk.js';import{ObjectWrapper,EventTarget,Linkifier}from'../common/common.js';import{Issue,NetworkLog,SDKModel,DOMModel,MixedContentIssue,ResourceTreeModel}from'../sdk/sdk.js';import{TreeOutline,UIUtils,Tooltip,Icon,XLink,Widget,Toolbar,Infobar,ViewManager}from'../ui/ui.js';import{Linkifier as Linkifier$1}from'../components/components.js';import{Adorner}from'../elements/elements.js';import{NetworkPanel,NetworkItemView}from'../network/network.js';class AggregatedIssue extends Issue.Issue{constructor(code){super(code);this._cookies=new Map();this._requests=new Map();this._representative=null;this._mixedContents=new Map();this._aggregatedIssuesCount=0;}
primaryKey(){throw new Error('This should never be called');}
cookies(){return Array.from(this._cookies.values()).map(x=>x.cookie);}
cookiesWithRequestIndicator(){return this._cookies.values();}
mixedContents(){return this._mixedContents.values();}
requests(){return this._requests.values();}
getDescription(){if(this._representative){return this._representative.getDescription();}
return null;}
getCategory(){if(this._representative){return this._representative.getCategory();}
return Issue.IssueCategory.Other;}
getAggregatedIssuesCount(){return this._aggregatedIssuesCount;}
_keyForCookie(cookie){const{domain,path,name}=cookie;return`${domain};${path};${name}`;}
addInstance(issue){this._aggregatedIssuesCount++;if(!this._representative){this._representative=issue;}
let hasRequest=false;for(const request of issue.requests()){hasRequest=true;if(!this._requests.has(request.requestId)){this._requests.set(request.requestId,request);}}
for(const cookie of issue.cookies()){const key=this._keyForCookie(cookie);if(!this._cookies.has(key)){this._cookies.set(key,{cookie,hasRequest});}}
for(const mixedContent of issue.mixedContents()){const key=JSON.stringify(mixedContent);this._mixedContents.set(key,mixedContent);}}}
class IssueAggregator extends ObjectWrapper.ObjectWrapper{constructor(issuesManager){super();this._aggregatedIssuesByCode=new Map();this._issuesManager=issuesManager;this._issuesManager.addEventListener(IssuesManager.Events.IssueAdded,this._onIssueAdded,this);this._issuesManager.addEventListener(IssuesManager.Events.FullUpdateRequired,this._onFullUpdateRequired,this);for(const issue of this._issuesManager.issues()){this._aggregateIssue(issue);}}
_onIssueAdded(event){const{issue}=(event.data);this._aggregateIssue(issue);}
_onFullUpdateRequired(){this._aggregatedIssuesByCode.clear();for(const issue of this._issuesManager.issues()){this._aggregateIssue(issue);}
this.dispatchEventToListeners(Events.FullUpdateRequired);}
_aggregateIssue(issue){let aggregatedIssue=this._aggregatedIssuesByCode.get(issue.code());if(!aggregatedIssue){aggregatedIssue=new AggregatedIssue(issue.code());this._aggregatedIssuesByCode.set(issue.code(),aggregatedIssue);}
aggregatedIssue.addInstance(issue);this.dispatchEventToListeners(Events.AggregatedIssueUpdated,aggregatedIssue);return aggregatedIssue;}
aggregatedIssues(){return this._aggregatedIssuesByCode.values();}
numberOfAggregatedIssues(){return this._aggregatedIssuesByCode.size;}}
const Events={AggregatedIssueUpdated:Symbol('AggregatedIssueUpdated'),FullUpdateRequired:Symbol('FullUpdateRequired'),};var IssueAggregator$1=Object.freeze({__proto__:null,AggregatedIssue:AggregatedIssue,IssueAggregator:IssueAggregator,Events:Events});const extractShortPath=path=>{return(/[^/]+$/.exec(path)||/[^/]+\/$/.exec(path)||[''])[0];};class AffectedResourcesView extends TreeOutline.TreeElement{constructor(parent,resourceName){super();this.toggleOnClick=true;this._parent=parent;this._resourceName=resourceName;this._affectedResourcesCountElement=this.createAffectedResourcesCounter();this._affectedResources=this.createAffectedResources();this._affectedResourcesCount=0;this._listener=null;this._unresolvedRequestIds=new Set();}
createAffectedResourcesCounter(){const counterLabel=document.createElement('div');counterLabel.classList.add('affected-resource-label');this.listItemElement.appendChild(counterLabel);return counterLabel;}
createAffectedResources(){const body=new TreeOutline.TreeElement();const affectedResources=document.createElement('table');affectedResources.classList.add('affected-resource-list');body.listItemElement.appendChild(affectedResources);this.appendChild(body);return affectedResources;}
getResourceName(count){if(count===1){return this._resourceName.singular;}
return this._resourceName.plural;}
updateAffectedResourceCount(count){this._affectedResourcesCount=count;this._affectedResourcesCountElement.textContent=`${count} ${this.getResourceName(count)}`;this.hidden=this._affectedResourcesCount===0;this._parent.updateAffectedResourceVisibility();}
isEmpty(){return this._affectedResourcesCount===0;}
clear(){this._affectedResources.textContent='';}
_resolveRequestId(requestId){const requests=self.SDK.networkLog.requestsForId(requestId);if(!requests.length){this._unresolvedRequestIds.add(requestId);if(!this._listener){this._listener=self.SDK.networkLog.addEventListener(NetworkLog.Events.RequestAdded,this._onRequestAdded,this);}}
return requests;}
_onRequestAdded(event){const request=(event.data);const requestWasUnresolved=this._unresolvedRequestIds.delete(request.requestId());if(this._unresolvedRequestIds.size===0&&this._listener){EventTarget.EventTarget.removeEventListeners([this._listener]);this._listener=null;}
if(requestWasUnresolved){this.update();}}
update(){throw new Error('This should never be called, did you forget to override?');}}
class AffectedElementsView extends AffectedResourcesView{constructor(parent,issue){super(parent,{singular:ls`element`,plural:ls`elements`});this._issue=issue;}
async _appendAffectedElements(affectedElements){let count=0;for(const element of affectedElements){await this._appendAffectedElement(element);count++;}
this.updateAffectedResourceCount(count);}
async _appendAffectedElement({backendNodeId,nodeName}){const mainTarget=(SDKModel.TargetManager.instance().mainTarget());const deferredDOMNode=new DOMModel.DeferredDOMNode(mainTarget,backendNodeId);const anchorElement=await Linkifier.Linkifier.linkify(deferredDOMNode);anchorElement.textContent=nodeName;const cellElement=document.createElement('td');cellElement.classList.add('affected-resource-element','devtools-link');cellElement.appendChild(anchorElement);const rowElement=document.createElement('tr');rowElement.appendChild(cellElement);this._affectedResources.appendChild(rowElement);}
update(){this.clear();this._appendAffectedElements(this._issue.elements());}}
class AffectedCookiesView extends AffectedResourcesView{constructor(parent,issue){super(parent,{singular:ls`cookie`,plural:ls`cookies`});this._issue=issue;}
_appendAffectedCookies(cookies){const header=document.createElement('tr');const name=document.createElement('td');name.classList.add('affected-resource-header');name.textContent='Name';header.appendChild(name);const info=document.createElement('td');info.classList.add('affected-resource-header');info.classList.add('affected-resource-cookie-info-header');info.textContent=ls`Domain`+' & '+ls`Path`;header.appendChild(info);this._affectedResources.appendChild(header);let count=0;for(const cookie of cookies){count++;this.appendAffectedCookie(cookie.cookie,cookie.hasRequest);}
this.updateAffectedResourceCount(count);}
appendAffectedCookie(cookie,hasAssociatedRequest){const element=document.createElement('tr');element.classList.add('affected-resource-cookie');const name=document.createElement('td');if(hasAssociatedRequest){name.appendChild(UIUtils.createTextButton(cookie.name,()=>{NetworkPanel.NetworkPanel.revealAndFilter([{filterType:'cookie-domain',filterValue:cookie.domain,},{filterType:'cookie-name',filterValue:cookie.name,},{filterType:'cookie-path',filterValue:cookie.path,}]);},'link-style devtools-link'));}else{name.textContent=cookie.name;}
const info=document.createElement('td');info.classList.add('affected-resource-cookie-info');info.textContent=`${cookie.domain}${cookie.path}`;element.appendChild(name);element.appendChild(info);this._affectedResources.appendChild(element);}
update(){this.clear();this._appendAffectedCookies(this._issue.cookiesWithRequestIndicator());}}
class AffectedRequestsView extends AffectedResourcesView{constructor(parent,issue){super(parent,{singular:ls`request`,plural:ls`requests`});this._issue=issue;}
_appendAffectedRequests(affectedRequests){let count=0;for(const affectedRequest of affectedRequests){for(const request of this._resolveRequestId(affectedRequest.requestId)){count++;this._appendNetworkRequest(request);}}
this.updateAffectedResourceCount(count);}
_appendNetworkRequest(request){const nameText=request.name().trimMiddle(100);const nameElement=document.createElement('td');const tab=issueTypeToNetworkHeaderMap.get(this._issue.getCategory())||NetworkItemView.Tabs.Headers;nameElement.appendChild(UIUtils.createTextButton(nameText,()=>{NetworkPanel.NetworkPanel.selectAndShowRequest(request,tab);},'link-style devtools-link'));const element=document.createElement('tr');element.classList.add('affected-resource-request');element.appendChild(nameElement);this._affectedResources.appendChild(element);}
update(){this.clear();this._appendAffectedRequests(this._issue.requests());}}
class AffectedSourcesView extends AffectedResourcesView{constructor(parent,issue){super(parent,{singular:ls`source`,plural:ls`sources`});this._issue=issue;}
_appendAffectedSources(affectedSources){let count=0;for(const source of affectedSources){this._appendAffectedSource(source);count++;}
this.updateAffectedResourceCount(count);}
_appendAffectedSource({url,lineNumber,columnNumber}){const cellElement=document.createElement('td');const linkifierURLOptions=({columnNumber,lineNumber,tabStop:true});const anchorElement=Linkifier$1.Linkifier.linkifyURL(url,linkifierURLOptions);cellElement.appendChild(anchorElement);const rowElement=document.createElement('tr');rowElement.classList.add('affected-resource-source');rowElement.appendChild(cellElement);this._affectedResources.appendChild(rowElement);}
update(){this.clear();this._appendAffectedSources(this._issue.sources());}}
const issueTypeToNetworkHeaderMap=new Map([[Issue.IssueCategory.SameSiteCookie,NetworkItemView.Tabs.Cookies],[Issue.IssueCategory.CrossOriginEmbedderPolicy,NetworkItemView.Tabs.Headers],[Issue.IssueCategory.MixedContent,NetworkItemView.Tabs.Headers]]);class AffectedMixedContentView extends AffectedResourcesView{constructor(parent,issue){super(parent,{singular:ls`resource`,plural:ls`resources`});this._issue=issue;}
_appendAffectedMixedContents(mixedContents){const header=document.createElement('tr');const name=document.createElement('td');name.classList.add('affected-resource-header');name.textContent=ls`Name`;header.appendChild(name);const info=document.createElement('td');info.classList.add('affected-resource-header');info.textContent=ls`Restriction Status`;header.appendChild(info);this._affectedResources.appendChild(header);let count=0;for(const mixedContent of mixedContents){if(mixedContent.request){this._resolveRequestId(mixedContent.request.requestId).forEach(networkRequest=>{this.appendAffectedMixedContent(mixedContent,networkRequest);count++;});}else{this.appendAffectedMixedContent(mixedContent);count++;}}
this.updateAffectedResourceCount(count);}
appendAffectedMixedContent(mixedContent,maybeRequest=null){const element=document.createElement('tr');element.classList.add('affected-resource-mixed-content');const filename=extractShortPath(mixedContent.insecureURL);const name=document.createElement('td');if(maybeRequest){const request=maybeRequest;const tab=issueTypeToNetworkHeaderMap.get(this._issue.getCategory())||NetworkItemView.Tabs.Headers;name.appendChild(UIUtils.createTextButton(filename,()=>{NetworkPanel.NetworkPanel.selectAndShowRequest(request,tab);},'link-style devtools-link'));}else{name.classList.add('affected-resource-mixed-content-info');name.textContent=filename;}
Tooltip.Tooltip.install(name,mixedContent.insecureURL);element.appendChild(name);const status=document.createElement('td');status.classList.add('affected-resource-mixed-content-info');status.textContent=MixedContentIssue.MixedContentIssue.translateStatus(mixedContent.resolutionStatus);element.appendChild(status);this._affectedResources.appendChild(element);}
update(){this.clear();this._appendAffectedMixedContents(this._issue.mixedContents());}}
class IssueView extends TreeOutline.TreeElement{constructor(parent,issue,description){super();this._parent=parent;this._issue=issue;this._description=description;this.toggleOnClick=true;this.listItemElement.classList.add('issue');this.childrenListElement.classList.add('body');this._affectedResources=this._createAffectedResources();this._affectedCookiesView=new AffectedCookiesView(this,this._issue);this._affectedElementsView=new AffectedElementsView(this,this._issue);this._affectedRequestsView=new AffectedRequestsView(this,this._issue);this._affectedMixedContentView=new AffectedMixedContentView(this,this._issue);this._affectedSourcesView=new AffectedSourcesView(this,this._issue);this._aggregatedIssuesCount=null;}
onattach(){this._appendHeader();this._createBody();this.appendChild(this._affectedResources);this.appendAffectedResource(this._affectedCookiesView);this._affectedCookiesView.update();this.appendAffectedResource(this._affectedElementsView);this._affectedElementsView.update();this.appendAffectedResource(this._affectedRequestsView);this._affectedRequestsView.update();this.appendAffectedResource(this._affectedMixedContentView);this._affectedMixedContentView.update();this.appendAffectedResource(this._affectedSourcesView);this._affectedSourcesView.update();this._createReadMoreLinks();this.updateAffectedResourceVisibility();}
appendAffectedResource(resource){this._affectedResources.appendChild(resource);}
_appendHeader(){const header=document.createElement('div');header.classList.add('header');const icon=Icon.Icon.create('largeicon-breaking-change','icon');this._aggregatedIssuesCount=(document.createElement('span'));const countAdorner=Adorner.Adorner.create(this._aggregatedIssuesCount,'countWrapper');countAdorner.classList.add('aggregated-issues-count');this._aggregatedIssuesCount.textContent=`${this._issue.getAggregatedIssuesCount()}`;header.appendChild(icon);header.appendChild(countAdorner);const title=document.createElement('div');title.classList.add('title');title.textContent=this._description.title;header.appendChild(title);this.listItemElement.appendChild(header);}
_updateAggregatedIssuesCount(){if(this._aggregatedIssuesCount){this._aggregatedIssuesCount.textContent=`${this._issue.getAggregatedIssuesCount()}`;}}
updateAffectedResourceVisibility(){const noCookies=!this._affectedCookiesView||this._affectedCookiesView.isEmpty();const noElements=!this._affectedElementsView||this._affectedElementsView.isEmpty();const noRequests=!this._affectedRequestsView||this._affectedRequestsView.isEmpty();const noMixedContent=!this._affectedMixedContentView||this._affectedMixedContentView.isEmpty();const noSources=!this._affectedSourcesView||this._affectedSourcesView.isEmpty();const noResources=noCookies&&noElements&&noRequests&&noMixedContent&&noSources;this._affectedResources.hidden=noResources;}
_createAffectedResources(){const wrapper=new TreeOutline.TreeElement();wrapper.setCollapsible(false);wrapper.setExpandable(true);wrapper.expand();wrapper.selectable=false;wrapper.listItemElement.classList.add('affected-resources-label');wrapper.listItemElement.textContent=ls`Affected Resources`;wrapper.childrenListElement.classList.add('affected-resources');return wrapper;}
_createBody(){const messageElement=new TreeOutline.TreeElement();messageElement.setCollapsible(false);messageElement.selectable=false;const message=this._description.message();messageElement.listItemElement.appendChild(message);this.appendChild(messageElement);}
_createReadMoreLinks(){if(this._description.links.length===0){return;}
const linkWrapper=new TreeOutline.TreeElement();linkWrapper.setCollapsible(false);linkWrapper.listItemElement.classList.add('link-wrapper');const linkList=linkWrapper.listItemElement.createChild('ul','link-list');for(const description of this._description.links){const link=XLink.XLink.create(description.link,ls`Learn more: ${description.linkTitle}`,'link');const linkIcon=Icon.Icon.create('largeicon-link','link-icon');link.prepend(linkIcon);const linkListItem=linkList.createChild('li');linkListItem.appendChild(link);}
this.appendChild(linkWrapper);}
update(){this._affectedCookiesView.update();this._affectedRequestsView.update();this._affectedMixedContentView.update();this._affectedSourcesView.update();this.updateAffectedResourceVisibility();this._updateAggregatedIssuesCount();}
toggle(expand){if(expand||(expand===undefined&&!this.expanded)){this.expand();}else{this.collapse();}}}
class IssuesPaneImpl extends Widget.VBox{constructor(){super(true);this.registerRequiredCSS('issues/issuesPane.css');this.contentElement.classList.add('issues-pane');this._issueViews=new Map();const{toolbarContainer,updateToolbarIssuesCount}=this._createToolbars();this._issuesToolbarContainer=toolbarContainer;this._updateToolbarIssuesCount=updateToolbarIssuesCount;this._issuesTree=new TreeOutline.TreeOutlineInShadow();this._issuesTree.registerRequiredCSS('issues/issuesTree.css');this._issuesTree.setShowSelectionOnKeyboardFocus(true);this._issuesTree.contentElement.classList.add('issues');this.contentElement.appendChild(this._issuesTree.element);this._noIssuesMessageDiv=document.createElement('div');this._noIssuesMessageDiv.classList.add('issues-pane-no-issues');this._noIssuesMessageDiv.textContent=ls`No issues detected so far`;this.contentElement.appendChild(this._noIssuesMessageDiv);this._issuesManager=IssuesManager.IssuesManager.instance();this._aggregator=new IssueAggregator(this._issuesManager);this._aggregator.addEventListener(Events.AggregatedIssueUpdated,this._issueUpdated,this);this._aggregator.addEventListener(Events.FullUpdateRequired,this._fullUpdate,this);for(const issue of this._aggregator.aggregatedIssues()){this._updateIssueView(issue);}
this._updateCounts();this._reloadInfobar=null;this._infoBarDiv=null;this._showReloadInfobarIfNeeded();}
_createToolbars(){const toolbarContainer=this.contentElement.createChild('div','issues-toolbar-container');new Toolbar.Toolbar('issues-toolbar-left',toolbarContainer);const rightToolbar=new Toolbar.Toolbar('issues-toolbar-right',toolbarContainer);rightToolbar.appendSeparator();const toolbarWarnings=document.createElement('div');toolbarWarnings.classList.add('toolbar-warnings');const breakingChangeIcon=Icon.Icon.create('largeicon-breaking-change');toolbarWarnings.appendChild(breakingChangeIcon);const toolbarIssuesCount=toolbarWarnings.createChild('span','warnings-count-label');const toolbarIssuesItem=new Toolbar.ToolbarItem(toolbarWarnings);rightToolbar.appendToolbarItem(toolbarIssuesItem);const updateToolbarIssuesCount=count=>{toolbarIssuesCount.textContent=`${count}`;if(count===1){toolbarIssuesItem.setTitle(ls`Issues pertaining to ${count} operation detected.`);}else{toolbarIssuesItem.setTitle(ls`Issues pertaining to ${count} operations detected.`);}};return{toolbarContainer,updateToolbarIssuesCount};}
_issueUpdated(event){const issue=(event.data);this._updateIssueView(issue);}
_updateIssueView(issue){const description=issue.getDescription();if(!description){console.warn('Could not find description for issue code:',issue.code());return;}
if(!this._issueViews.has(issue.code())){const view=new IssueView(this,issue,description);this._issueViews.set(issue.code(),view);this._issuesTree.appendChild(view);}
this._issueViews.get(issue.code()).update();this._updateCounts();}
_fullUpdate(){this._hideReloadInfoBar();for(const view of this._issueViews.values()){this._issuesTree.removeChild(view);}
this._issueViews.clear();if(this._aggregator){for(const issue of this._aggregator.aggregatedIssues()){this._updateIssueView(issue);}}
this._updateCounts();}
_updateCounts(){const count=this._issuesManager.numberOfIssues();this._updateToolbarIssuesCount(count);this._showIssuesTreeOrNoIssuesDetectedMessage(count);}
_showIssuesTreeOrNoIssuesDetectedMessage(issuesCount){if(issuesCount>0||this._issuesManager.reloadForAccurateInformationRequired()){this._issuesTree.element.hidden=false;this._noIssuesMessageDiv.style.display='none';}else{this._issuesTree.element.hidden=true;this._noIssuesMessageDiv.style.display='flex';}}
revealByCode(code){const issueView=this._issueViews.get(code);if(issueView){issueView.expand();issueView.reveal();}}
_showReloadInfobarIfNeeded(){if(!this._issuesManager.reloadForAccurateInformationRequired()){return;}
function reload(){const mainTarget=SDKModel.TargetManager.instance().mainTarget();if(mainTarget){const resourceModel=mainTarget.model(ResourceTreeModel.ResourceTreeModel);if(resourceModel){resourceModel.reloadPage();}}}
const infobar=new Infobar.Infobar(Infobar.Type.Warning,ls`Some issues might be missing or incomplete, reload the inspected page to get the full information.`,[{text:ls`Reload page`,highlight:false,delegate:reload,dismiss:true}]);this._reloadInfobar=infobar;this._attachReloadInfoBar(infobar);}
_attachReloadInfoBar(infobar){if(!this._infoBarDiv){this._infoBarDiv=document.createElement('div');this._infoBarDiv.classList.add('flex-none');this.contentElement.insertBefore(this._infoBarDiv,this._issuesToolbarContainer.nextSibling);}
this._infoBarDiv.appendChild(infobar.element);infobar.setParentView(this);this.doResize();}
_hideReloadInfoBar(){if(this._reloadInfobar){this._reloadInfobar.dispose();this._reloadInfobar=null;}}}
var IssuesPane=Object.freeze({__proto__:null,IssuesPaneImpl:IssuesPaneImpl});class IssueRevealer{async reveal(issue){if(!(issue instanceof Issue.Issue)){throw new Error('Internal error: not a issue');}
await ViewManager.ViewManager.instance().showView('issues-pane');const view=ViewManager.ViewManager.instance().view('issues-pane');if(view){const issuesPane=(await view.widget());issuesPane.revealByCode(issue.code());}}}
var IssueRevealer$1=Object.freeze({__proto__:null,IssueRevealer:IssueRevealer});export{IssueAggregator$1 as IssueAggregator,IssueRevealer$1 as IssueRevealer,IssuesPane};