import"./NodeText.js";import*as LitHtml from"../third_party/lit-html/lit-html.js";import{crumbsToRender,NodeSelectedEvent}from"./ElementsBreadcrumbsUtils.js";export class ElementsBreadcrumbs extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.resizeObserver=new ResizeObserver((()=>this.checkForOverflowOnResize())),this.crumbsData=[],this.selectedDOMNode=null,this.overflowing=!1,this.userScrollPosition="start",this.isObservingResize=!1,this.userHasManuallyScrolled=!1}set data(e){this.selectedDOMNode=e.selectedNode,this.crumbsData=e.crumbs,this.userHasManuallyScrolled=!1,this.update()}disconnectedCallback(){this.isObservingResize=!1,this.resizeObserver.disconnect()}onCrumbClick(e){return t=>{t.preventDefault(),this.dispatchEvent(new NodeSelectedEvent(e))}}checkForOverflowOnResize(){const e=this.shadow.querySelector(".crumbs"),t=this.shadow.querySelector(".crumbs-scroll-container");if(!e||!t)return;const r=e.clientWidth,o=t.clientWidth;o>=r&&!1===this.overflowing?(this.overflowing=!0,this.userScrollPosition="start",this.render()):o<r&&!0===this.overflowing&&(this.overflowing=!1,this.userScrollPosition="start",this.render())}update(){this.render(),this.engageResizeObserver(),this.ensureSelectedNodeIsVisible()}onCrumbMouseMove(e){return()=>e.highlightNode()}onCrumbMouseLeave(e){return()=>e.clearHighlight()}onCrumbFocus(e){return()=>e.highlightNode()}onCrumbBlur(e){return()=>e.clearHighlight()}engageResizeObserver(){if(!this.resizeObserver||!0===this.isObservingResize)return;const e=this.shadow.querySelector(".crumbs");e&&(this.resizeObserver.observe(e),this.isObservingResize=!0)}checkForOverflow(){if(this.overflowing)return;const e=this.shadow.querySelector(".crumbs-scroll-container"),t=this.shadow.querySelector(".crumbs-window");if(!e||!t)return;const r=t.clientWidth-20;e.clientWidth<r||(this.overflowing=!0,this.render())}onCrumbsWindowScroll(e){if(!e.target)return;const t=e.target;this.updateScrollState(t)}updateScrollState(e){const t=e.scrollWidth-e.clientWidth,r=e.scrollLeft;this.userScrollPosition=r<10?"start":r>=t-10?"end":"middle",this.render()}onOverflowClick(e){return()=>{this.userHasManuallyScrolled=!0;const t=this.shadow.querySelector(".crumbs-window");if(!t)return;const r=t.clientWidth/2,o="left"===e?Math.max(Math.floor(t.scrollLeft-r),0):t.scrollLeft+r;t.scrollTo({behavior:"smooth",left:o})}}renderOverflowButton(e,t){const r=LitHtml.Directives.classMap({overflow:!0,[e]:!0,hidden:!1===this.overflowing});return LitHtml.html`
      <button
        class=${r}
        @click=${this.onOverflowClick(e)}
        ?disabled=${t}
        aria-label="Scroll ${e}"
      >&hellip;</button>
      `}render(){const e=crumbsToRender(this.crumbsData,this.selectedDOMNode);LitHtml.render(LitHtml.html`
      <style>
        :host {
          --node-text-label-color: var(--color-syntax-2);
          --node-text-class-color: var(--color-syntax-4);
          --node-text-id-color: var(--color-syntax-4);
          --node-text-multiple-descriptors-id: var(--color-syntax-7);
        }

        .crumbs {
          display: inline-flex;
          align-items: stretch;
          width: 100%;
          overflow: hidden;
          pointer-events: auto;
          cursor: default;
          white-space: nowrap;
          position: relative;
          background: var(--color-background);
        }

        .crumbs-window {
          flex-grow: 2;
          overflow: hidden;
        }

        .crumbs-scroll-container {
          display: inline-flex;
          margin: 0;
          padding: 0;
        }

        .crumb {
          display: block;
          padding: 0 7px;
          line-height: 23px;
          white-space: nowrap;
        }

        .overflow {
          padding: 0 7px;
          font-weight: bold;
          display: block;
          border: none;
          flex-grow: 0;
          flex-shrink: 0;
          text-align: center;
          background-color: var(--color-background-elevation-1);
          color: var(--color-text-secondary);
        }

        .overflow.hidden {
          display: none;
        }

        .overflow:disabled {
          opacity: 50%;
        }

        .overflow:focus {
          outline: var(--color-primary) auto 1px;
        }

        .overflow:not(:disabled):hover {
          background-color: var(--color-background-elevation-2);
          color: var(--color-text-primary);
          cursor: pointer;
        }

        .crumb-link {
          text-decoration: none;
          color: inherit;
        }

        .crumb:hover {
          background: var(--color-background-elevation-2);
        }

        .crumb.selected {
          background: var(--color-background-elevation-1);
        }

        .crumb:focus {
          outline: var(--color-primary) auto 1px;
        }
      </style>

      <nav class="crumbs">
        ${this.renderOverflowButton("left","start"===this.userScrollPosition)}

        <div class="crumbs-window" @scroll=${this.onCrumbsWindowScroll}>
          <ul class="crumbs-scroll-container">
            ${e.map((e=>{const t={crumb:!0,selected:e.selected};return LitHtml.html`
                <li class=${LitHtml.Directives.classMap(t)}
                  data-node-id=${e.node.id}
                  data-crumb="true"
                >
                  <a href="#"
                    draggable=false
                    class="crumb-link"
                    @click=${this.onCrumbClick(e.node)}
                    @mousemove=${this.onCrumbMouseMove(e.node)}
                    @mouseleave=${this.onCrumbMouseLeave(e.node)}
                    @focus=${this.onCrumbFocus(e.node)}
                    @blur=${this.onCrumbBlur(e.node)}
                  ><devtools-node-text data-node-title=${e.title.main} .data=${{nodeTitle:e.title.main,nodeId:e.title.extras.id,nodeClasses:e.title.extras.classes}}></devtools-node-text></a>
                </li>`}))}
          </ul>
        </div>
        ${this.renderOverflowButton("right","end"===this.userScrollPosition)}
      </nav>
    `,this.shadow,{eventContext:this}),this.checkForOverflow()}ensureSelectedNodeIsVisible(){if(!this.selectedDOMNode||!this.shadow||!this.overflowing||this.userHasManuallyScrolled)return;const e=this.selectedDOMNode.id,t=this.shadow.querySelector(`.crumb[data-node-id="${e}"]`);t&&t.scrollIntoView({behavior:"smooth"})}}customElements.get("devtools-elements-breadcrumbs")||customElements.define("devtools-elements-breadcrumbs",ElementsBreadcrumbs);