import*as Common from'../common/common.js';import*as SDK from'../sdk/sdk.js';export class RemoteObjectPreviewFormatter{static _objectPropertyComparator(a,b){return sortValue(a)-sortValue(b);function sortValue(property){const internalName=_internalName;if(property.name===internalName.PromiseStatus){return 1;}else if(property.name===internalName.PromiseValue){return 2;}else if(property.name===internalName.GeneratorStatus||property.name===internalName.PrimitiveValue){return 3;}
else if(property.type!=='function'&&!property.name.startsWith('#')){return 4;}
return 5;}}
appendObjectPreview(parentElement,preview,isEntry){const description=preview.description;const subTypesWithoutValuePreview=new Set(['null','regexp','error','internal#entry']);if(preview.type!=='object'||subTypesWithoutValuePreview.has(preview.subtype)||isEntry){parentElement.appendChild(this.renderPropertyPreview(preview.type,preview.subtype,description));return;}
const isArrayOrTypedArray=preview.subtype==='array'||preview.subtype==='typedarray';if(description){let text;if(isArrayOrTypedArray){const arrayLength=SDK.RemoteObject.RemoteObject.arrayLength(preview);const arrayLengthText=arrayLength>1?('('+arrayLength+')'):'';const arrayName=SDK.RemoteObject.RemoteObject.arrayNameFromDescription(description);text=arrayName==='Array'?arrayLengthText:(arrayName+arrayLengthText);}else{const hideDescription=description==='Object';text=hideDescription?'':description;}
if(text.length>0){parentElement.createChild('span','object-description').textContent=text+'\xA0';}}
const propertiesElement=parentElement.createChild('span','object-properties-preview');propertiesElement.createTextChild(isArrayOrTypedArray?'[':'{');if(preview.entries){this._appendEntriesPreview(propertiesElement,preview);}else if(isArrayOrTypedArray){this._appendArrayPropertiesPreview(propertiesElement,preview);}else{this._appendObjectPropertiesPreview(propertiesElement,preview);}
if(preview.overflow){const ellipsisText=propertiesElement.textContent.length>1?',\xA0\u2026':'\u2026';propertiesElement.createChild('span').textContent=ellipsisText;}
propertiesElement.createTextChild(isArrayOrTypedArray?']':'}');}
_abbreviateFullQualifiedClassName(description){const abbreviatedDescription=description.split('.');for(let i=0;i<abbreviatedDescription.length-1;++i){abbreviatedDescription[i]=abbreviatedDescription[i].trimMiddle(3);}
return abbreviatedDescription.join('.');}
_appendObjectPropertiesPreview(parentElement,preview){const internalName=_internalName;const properties=preview.properties.filter(p=>p.type!=='accessor').sort(RemoteObjectPreviewFormatter._objectPropertyComparator);for(let i=0;i<properties.length;++i){if(i>0){parentElement.createTextChild(', ');}
const property=properties[i];const name=property.name;if(preview.subtype==='promise'&&name===internalName.PromiseStatus){parentElement.appendChild(this._renderDisplayName('<'+property.value+'>'));const nextProperty=i+1<properties.length?properties[i+1]:null;if(nextProperty&&nextProperty.name===internalName.PromiseValue){if(property.value!=='pending'){parentElement.createTextChild(': ');parentElement.appendChild(this._renderPropertyPreviewOrAccessor([nextProperty]));}
i++;}}else if(preview.subtype==='generator'&&name===internalName.GeneratorStatus){parentElement.appendChild(this._renderDisplayName('<'+property.value+'>'));}else if(name===internalName.PrimitiveValue){parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));}else{parentElement.appendChild(this._renderDisplayName(name));parentElement.createTextChild(': ');parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));}}}
_appendArrayPropertiesPreview(parentElement,preview){const arrayLength=SDK.RemoteObject.RemoteObject.arrayLength(preview);const indexProperties=preview.properties.filter(p=>toArrayIndex(p.name)!==-1).sort(arrayEntryComparator);const otherProperties=preview.properties.filter(p=>toArrayIndex(p.name)===-1).sort(RemoteObjectPreviewFormatter._objectPropertyComparator);function arrayEntryComparator(a,b){return toArrayIndex(a.name)-toArrayIndex(b.name);}
function toArrayIndex(name){const index=name>>>0;if(String(index)===name&&index<arrayLength){return index;}
return-1;}
const canShowGaps=!preview.overflow;let lastNonEmptyArrayIndex=-1;let elementsAdded=false;for(let i=0;i<indexProperties.length;++i){if(elementsAdded){parentElement.createTextChild(', ');}
const property=indexProperties[i];const index=toArrayIndex(property.name);if(canShowGaps&&index-lastNonEmptyArrayIndex>1){appendUndefined(index);parentElement.createTextChild(', ');}
if(!canShowGaps&&i!==index){parentElement.appendChild(this._renderDisplayName(property.name));parentElement.createTextChild(': ');}
parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));lastNonEmptyArrayIndex=index;elementsAdded=true;}
if(canShowGaps&&arrayLength-lastNonEmptyArrayIndex>1){if(elementsAdded){parentElement.createTextChild(', ');}
appendUndefined(arrayLength);}
for(let i=0;i<otherProperties.length;++i){if(elementsAdded){parentElement.createTextChild(', ');}
const property=otherProperties[i];parentElement.appendChild(this._renderDisplayName(property.name));parentElement.createTextChild(': ');parentElement.appendChild(this._renderPropertyPreviewOrAccessor([property]));elementsAdded=true;}
function appendUndefined(index){const span=parentElement.createChild('span','object-value-undefined');const count=index-lastNonEmptyArrayIndex-1;span.textContent=count!==1?Common.UIString.UIString('empty × %d',count):Common.UIString.UIString('empty');elementsAdded=true;}}
_appendEntriesPreview(parentElement,preview){for(let i=0;i<preview.entries.length;++i){if(i>0){parentElement.createTextChild(', ');}
const entry=preview.entries[i];if(entry.key){this.appendObjectPreview(parentElement,entry.key,true);parentElement.createTextChild(' => ');}
this.appendObjectPreview(parentElement,entry.value,true);}}
_renderDisplayName(name){const result=createElementWithClass('span','name');const needsQuotes=/^\s|\s$|^$|\n/.test(name);result.textContent=needsQuotes?'"'+name.replace(/\n/g,'\u21B5')+'"':name;return result;}
_renderPropertyPreviewOrAccessor(propertyPath){const property=propertyPath.peekLast();return this.renderPropertyPreview(property.type,(property.subtype),property.value);}
renderPropertyPreview(type,subtype,description){const span=createElementWithClass('span','object-value-'+(subtype||type));description=description||'';if(type==='accessor'){span.textContent='(...)';span.title=Common.UIString.UIString('The property is computed with a getter');return span;}
if(type==='function'){span.textContent='\u0192';return span;}
if(type==='object'&&subtype==='node'&&description){createSpansForNodeTitle(span,description);return span;}
if(type==='string'){span.createTextChildren('"',description.replace(/\n/g,'\u21B5'),'"');return span;}
if(type==='object'&&!subtype){let preview=this._abbreviateFullQualifiedClassName(description);if(preview==='Object'){preview='{\u2026}';}
span.textContent=preview;span.title=description;return span;}
span.textContent=description;return span;}}
const _internalName={GeneratorStatus:'[[GeneratorStatus]]',PrimitiveValue:'[[PrimitiveValue]]',PromiseStatus:'[[PromiseStatus]]',PromiseValue:'[[PromiseValue]]'};export const createSpansForNodeTitle=function(container,nodeTitle){const match=nodeTitle.match(/([^#.]+)(#[^.]+)?(\..*)?/);container.createChild('span','webkit-html-tag-name').textContent=match[1];if(match[2]){container.createChild('span','webkit-html-attribute-value').textContent=match[2];}
if(match[3]){container.createChild('span','webkit-html-attribute-name').textContent=match[3];}};