/*!
 * @license
 * Copyright 2021 The Go Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style
 * license that can be found in the LICENSE file.
 */const o={PLAY_HREF:".js-exampleHref",PLAY_CONTAINER:".js-exampleContainer",EXAMPLE_INPUT:".Documentation-exampleCode",EXAMPLE_OUTPUT:".Documentation-exampleOutput",EXAMPLE_ERROR:".Documentation-exampleError",PLAY_BUTTON:".Documentation-examplePlayButton",SHARE_BUTTON:".Documentation-exampleShareButton",FORMAT_BUTTON:".Documentation-exampleFormatButton",RUN_BUTTON:".Documentation-exampleRunButton"};class u{constructor(t){this.exampleEl=t;var e,r,n,l;this.exampleEl=t,this.anchorEl=t.querySelector("a"),this.errorEl=t.querySelector(o.EXAMPLE_ERROR),this.playButtonEl=t.querySelector(o.PLAY_BUTTON),this.shareButtonEl=t.querySelector(o.SHARE_BUTTON),this.formatButtonEl=t.querySelector(o.FORMAT_BUTTON),this.runButtonEl=t.querySelector(o.RUN_BUTTON),this.inputEl=this.makeTextArea(t.querySelector(o.EXAMPLE_INPUT)),this.outputEl=t.querySelector(o.EXAMPLE_OUTPUT),(e=this.playButtonEl)==null||e.addEventListener("click",()=>this.handleShareButtonClick()),(r=this.shareButtonEl)==null||r.addEventListener("click",()=>this.handleShareButtonClick()),(n=this.formatButtonEl)==null||n.addEventListener("click",()=>this.handleFormatButtonClick()),(l=this.runButtonEl)==null||l.addEventListener("click",()=>this.handleRunButtonClick()),!!this.inputEl&&(this.resize(),this.inputEl.addEventListener("keyup",()=>this.resize()),this.inputEl.addEventListener("keydown",s=>this.onKeydown(s)))}makeTextArea(t){var r,n;const e=document.createElement("textarea");return e.classList.add("Documentation-exampleCode","code"),e.spellcheck=!1,e.value=(r=t==null?void 0:t.textContent)!=null?r:"",(n=t==null?void 0:t.parentElement)==null||n.replaceChild(e,t),e}getAnchorHash(){var t;return(t=this.anchorEl)==null?void 0:t.hash}expand(){this.exampleEl.open=!0}resize(){var t;if((t=this.inputEl)==null?void 0:t.value){const e=(this.inputEl.value.match(/\n/g)||[]).length;this.inputEl.style.height=`${(20+e*20+12+2)/16}rem`}}onKeydown(t){t.key==="Tab"&&(document.execCommand("insertText",!1,"	"),t.preventDefault())}setInputText(t){this.inputEl&&(this.inputEl.value=t)}setOutputText(t){this.outputEl&&(this.outputEl.textContent=t)}setErrorText(t){this.errorEl&&(this.errorEl.textContent=t),this.setOutputText("An error has occurred\u2026")}handleShareButtonClick(){var e;const t="https://play.golang.org/p/";this.setOutputText("Waiting for remote server\u2026"),fetch("/play/share",{method:"POST",body:(e=this.inputEl)==null?void 0:e.value}).then(r=>r.text()).then(r=>{const n=t+r;this.setOutputText(`<a href="${n}">${n}</a>`),window.open(n)}).catch(r=>{this.setErrorText(r)})}handleFormatButtonClick(){var e,r;this.setOutputText("Waiting for remote server\u2026");const t=new FormData;t.append("body",(r=(e=this.inputEl)==null?void 0:e.value)!=null?r:""),fetch("/play/fmt",{method:"POST",body:t}).then(n=>n.json()).then(({Body:n,Error:l})=>{this.setOutputText(l||"Done."),n&&(this.setInputText(n),this.resize())}).catch(n=>{this.setErrorText(n)})}handleRunButtonClick(){var t;this.setOutputText("Waiting for remote server\u2026"),fetch("/play/compile",{method:"POST",body:JSON.stringify({body:(t=this.inputEl)==null?void 0:t.value,version:2})}).then(e=>e.json()).then(async({Events:e,Errors:r})=>{this.setOutputText(r||"");for(const n of e||[])this.setOutputText(n.Message),await new Promise(l=>setTimeout(l,n.Delay/1e6))}).catch(e=>{this.setErrorText(e)})}}const i=location.hash.match(/^#(example-.*)$/);if(i){const a=document.getElementById(i[1]);a&&(a.open=!0)}const h=[...document.querySelectorAll(o.PLAY_HREF)],c=a=>h.find(t=>t.hash===a.getAnchorHash());for(const a of document.querySelectorAll(o.PLAY_CONTAINER)){const t=new u(a),e=c(t);e?e.addEventListener("click",()=>{t.expand()}):console.warn("example href not found")}export{u as PlaygroundExampleController};
//# sourceMappingURL=playground.js.map
