XWidget.js 3.0 KB

12345678910111213141516171819202122232425
  1. export default class XWidget extends UI.XElement{constructor(){super();this.style.setProperty('display','flex');this.style.setProperty('flex-direction','column');this.style.setProperty('align-items','stretch');this.style.setProperty('justify-content','flex-start');this.style.setProperty('contain','layout style');this._visible=false;this._shadowRoot;this._defaultFocusedElement=null;this._elementsToRestoreScrollPositionsFor=[];this._onShownCallback;this._onHiddenCallback;this._onResizedCallback;if(!XWidget._observer){XWidget._observer=new ResizeObserver(entries=>{for(const entry of entries){if(entry.target._visible&&entry.target._onResizedCallback){entry.target._onResizedCallback.call(null);}}});}
  2. XWidget._observer.observe(this);this.setElementsToRestoreScrollPositionsFor([this]);}
  3. static focusWidgetForNode(node){node=node&&node.parentNodeOrShadowHost();let widget=null;while(node){if(node instanceof XWidget){if(widget){node._defaultFocusedElement=widget;}
  4. widget=node;}
  5. node=node.parentNodeOrShadowHost();}}
  6. isShowing(){return this._visible;}
  7. registerRequiredCSS(cssFile){UI.appendStyle(this._shadowRoot||this,cssFile);}
  8. setOnShown(callback){this._onShownCallback=callback;}
  9. setOnHidden(callback){this._onHiddenCallback=callback;}
  10. setOnResized(callback){this._onResizedCallback=callback;}
  11. setElementsToRestoreScrollPositionsFor(elements){for(const element of this._elementsToRestoreScrollPositionsFor){element.removeEventListener('scroll',XWidget._storeScrollPosition,{passive:true,capture:false});}
  12. this._elementsToRestoreScrollPositionsFor=elements;for(const element of this._elementsToRestoreScrollPositionsFor){element.addEventListener('scroll',XWidget._storeScrollPosition,{passive:true,capture:false});}}
  13. restoreScrollPositions(){for(const element of this._elementsToRestoreScrollPositionsFor){if(element._scrollTop){element.scrollTop=element._scrollTop;}
  14. if(element._scrollLeft){element.scrollLeft=element._scrollLeft;}}}
  15. static _storeScrollPosition(event){const element=event.currentTarget;element._scrollTop=element.scrollTop;element._scrollLeft=element.scrollLeft;}
  16. setDefaultFocusedElement(element){if(element&&!this.isSelfOrAncestor(element)){throw new Error('Default focus must be descendant');}
  17. this._defaultFocusedElement=element;}
  18. focus(){if(!this._visible){return;}
  19. let element;if(this._defaultFocusedElement&&this.isSelfOrAncestor(this._defaultFocusedElement)){element=this._defaultFocusedElement;}else if(this.tabIndex!==-1){element=this;}else{let child=this.traverseNextNode(this);while(child){if((child instanceof XWidget)&&child._visible){element=child;break;}
  20. child=child.traverseNextNode(this);}}
  21. if(!element||element.hasFocus()){return;}
  22. if(element===this){HTMLElement.prototype.focus.call(this);}else{element.focus();}}
  23. connectedCallback(){this._visible=true;this.restoreScrollPositions();if(this._onShownCallback){this._onShownCallback.call(null);}}
  24. disconnectedCallback(){this._visible=false;if(this._onHiddenCallback){this._onHiddenCallback.call(null);}}}
  25. self.customElements.define('x-widget',XWidget);self.UI=self.UI||{};UI=UI||{};UI.XWidget=XWidget;