import*as Common from"../common/common.js";import*as i18n from"../i18n/i18n.js";import*as ObjectUI from"../object_ui/object_ui.js";import*as SDK from"../sdk/sdk.js";import*as TextEditor from"../text_editor/text_editor.js";import*as TextUtils from"../text_utils/text_utils.js";import*as UI from"../ui/ui.js";const UIStrings={removeExpression:"Remove expression",removeAllExpressions:"Remove all expressions",removeExpressionS:"Remove expression: {PH1}",removeBlankExpression:"Remove blank expression",liveExpressionEditor:"Live expression editor",expression:"Expression",evaluateAllowingSideEffects:"Evaluate, allowing side effects",notAvailable:"not available"},str_=i18n.i18n.registerUIStrings("console/ConsolePinPane.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_),elementToConsolePin=new WeakMap;export class ConsolePinPane extends UI.ThrottledWidget.ThrottledWidget{constructor(e){super(!0,250),this._liveExpressionButton=e,this.registerRequiredCSS("console/consolePinPane.css",{enableLegacyPatching:!0}),this.registerRequiredCSS("object_ui/objectValue.css",{enableLegacyPatching:!0}),this.contentElement.classList.add("console-pins","monospace"),this.contentElement.addEventListener("contextmenu",this._contextMenuEventFired.bind(this),!1),this._pins=new Set,this._pinsSetting=Common.Settings.Settings.instance().createLocalSetting("consolePins",[]);for(const t of this._pinsSetting.get())this.addPin(t)}willHide(){for(const e of this._pins)e.setHovered(!1)}_savePins(){const e=Array.from(this._pins).map((e=>e.expression()));this._pinsSetting.set(e)}_contextMenuEventFired(e){const t=new UI.ContextMenu.ContextMenu(e),i=UI.UIUtils.deepElementFromEvent(e);if(i){const e=i.enclosingNodeOrSelfWithClass("console-pin");if(e){const i=elementToConsolePin.get(e);i&&(t.editSection().appendItem(i18nString(UIStrings.removeExpression),this._removePin.bind(this,i)),i.appendToContextMenu(t))}}t.editSection().appendItem(i18nString(UIStrings.removeAllExpressions),this._removeAllPins.bind(this)),t.show()}_removeAllPins(){for(const e of this._pins)this._removePin(e)}_removePin(e){e.element().remove();const t=this._focusedPinAfterDeletion(e);this._pins.delete(e),this._savePins(),t?t.focus():this._liveExpressionButton.focus()}addPin(e,t){const i=new ConsolePin(e,this);this.contentElement.appendChild(i.element()),this._pins.add(i),this._savePins(),t&&i.focus(),this.update()}_focusedPinAfterDeletion(e){const t=Array.from(this._pins);for(let i=0;i<t.length;i++)if(t[i]===e)return 1===t.length?null:i===t.length-1?t[i-1]:t[i+1];return null}async doUpdate(){if(!this._pins.size||!this.isShowing())return;this.isShowing()&&this.update();const e=Array.from(this._pins,(e=>e.updatePreview()));await Promise.all(e),this._updatedForTest()}_updatedForTest(){}}export class ConsolePin extends Common.ObjectWrapper.ObjectWrapper{constructor(e,t){super();const i=document.createElement("div",{is:"dt-close-button"});i.gray=!0,i.classList.add("close-button"),i.setTabbable(!0),e.length?i.setAccessibleName(i18nString(UIStrings.removeExpressionS,{PH1:e})):i.setAccessibleName(i18nString(UIStrings.removeBlankExpression)),self.onInvokeElement(i,(e=>{t._removePin(this),e.consume(!0)}));const s=UI.Fragment.Fragment.build`
  <div class='console-pin'>
  ${i}
  <div class='console-pin-name' $='name'></div>
  <div class='console-pin-preview' $='preview'></div>
  </div>`;this._pinElement=s.element(),this._pinPreview=s.$("preview");const n=s.$("name");UI.Tooltip.Tooltip.install(n,e),elementToConsolePin.set(this._pinElement,this),this._lastResult=null,this._lastExecutionContext=null,this._editor=null,this._committedExpression=e,this._hovered=!1,this._lastNode=null,this._pinPreview.addEventListener("mouseenter",this.setHovered.bind(this,!0),!1),this._pinPreview.addEventListener("mouseleave",this.setHovered.bind(this,!1),!1),this._pinPreview.addEventListener("click",(e=>{this._lastNode&&(Common.Revealer.reveal(this._lastNode),e.consume())}),!1);const o=s=>(this._editor=s.createEditor({devtoolsAccessibleName:i18nString(UIStrings.liveExpressionEditor),lineNumbers:!1,lineWrapping:!0,mimeType:"javascript",autoHeight:!0,placeholder:i18nString(UIStrings.expression),bracketMatchingSetting:void 0,lineWiseCopyCut:void 0,maxHighlightLength:void 0,padBottom:void 0,inputStyle:void 0}),this._editor.configureAutocomplete(ObjectUI.JavaScriptAutocomplete.JavaScriptAutocompleteConfig.createConfigForEditor(this._editor)),this._editor.widget().show(n),this._editor.widget().element.classList.add("console-pin-editor"),this._editor.widget().element.tabIndex=-1,this._editor.setText(e),this._editor.widget().element.addEventListener("keydown",(e=>{this._editor&&("Tab"!==e.key||this._editor.text()?e.keyCode===UI.KeyboardShortcut.Keys.Esc.code&&this._editor.setText(this._committedExpression):e.consume())}),!0),this._editor.widget().element.addEventListener("focusout",(e=>{if(!this._editor)return;const s=this._editor.text(),n=s.trim();s.length!==n.length&&this._editor.setText(n),this._committedExpression=n,t._savePins(),this._committedExpression.length?i.setAccessibleName(i18nString(UIStrings.removeExpressionS,{PH1:this._committedExpression})):i.setAccessibleName(i18nString(UIStrings.removeBlankExpression)),this._editor.setSelection(TextUtils.TextRange.TextRange.createFromLocation(1/0,1/0))})),this._editor),r=TextEditor.CodeMirrorTextEditor.CodeMirrorTextEditorFactory.instance();this._editorPromise=Promise.resolve().then((()=>o(r)))}setHovered(e){this._hovered!==e&&(this._hovered=e,!e&&this._lastNode&&SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight())}expression(){return this._committedExpression}element(){return this._pinElement}async focus(){const e=await this._editorPromise;e.widget().focus(),e.setSelection(TextUtils.TextRange.TextRange.createFromLocation(1/0,1/0))}appendToContextMenu(e){this._lastResult&&!("error"in this._lastResult)&&this._lastResult.object&&(e.appendApplicableItems(this._lastResult.object),this._lastResult=null)}async updatePreview(){if(!this._editor)return;const e=this._editor.textWithCurrentSuggestion().trim(),t=this._pinElement.hasFocus(),i=t&&e!==this._committedExpression,s=i?250:void 0,n=UI.Context.Context.instance().flavor(SDK.RuntimeModel.ExecutionContext),{preview:o,result:r}=await ObjectUI.JavaScriptREPL.JavaScriptREPL.evaluateAndBuildPreview(e,i,s,!t,"console");this._lastResult&&this._lastExecutionContext&&this._lastExecutionContext.runtimeModel.releaseEvaluationResult(this._lastResult),this._lastResult=r||null,this._lastExecutionContext=n||null;const l=o.deepTextContent();if(!l||l!==this._pinPreview.deepTextContent()){if(this._pinPreview.removeChildren(),r&&SDK.RuntimeModel.RuntimeModel.isSideEffectFailure(r)){const e=this._pinPreview.createChild("span","object-value-calculate-value-button");e.textContent="(\u2026)",UI.Tooltip.Tooltip.install(e,i18nString(UIStrings.evaluateAllowingSideEffects))}else l?this._pinPreview.appendChild(o):t||UI.UIUtils.createTextChild(this._pinPreview,i18nString(UIStrings.notAvailable));UI.Tooltip.Tooltip.install(this._pinPreview,l)}let a=null;r&&!("error"in r)&&"object"===r.object.type&&"node"===r.object.subtype&&(a=r.object),this._hovered&&(a?SDK.OverlayModel.OverlayModel.highlightObjectAsDOMNode(a):this._lastNode&&SDK.OverlayModel.OverlayModel.hideDOMNodeHighlight()),this._lastNode=a||null;const d=r&&!("error"in r)&&r.exceptionDetails&&!SDK.RuntimeModel.RuntimeModel.isSideEffectFailure(r);this._pinElement.classList.toggle("error-level",Boolean(d))}}