@yuebai008/cli
Version:
Command line interface for rapid qg-minigame development
1 lines • 11 kB
JavaScript
import*as Host from"../../core/host/host.js";import*as i18n from"../../core/i18n/i18n.js";import*as IconButton from"../../ui/components/icon_button/icon_button.js";import*as ARIAUtils from"./ARIAUtils.js";import{GlassPane}from"./GlassPane.js";import{Icon}from"./Icon.js";import*as ThemeSupport from"./theme_support/theme_support.js";import{createTextChild,ElementFocusRestorer}from"./UIUtils.js";import softContextMenuStyles from"./softContextMenu.css.legacy.js";import{InspectorView}from"./InspectorView.js";import{Tooltip}from"./Tooltip.js";const UIStrings={checked:"checked",unchecked:"unchecked",sSS:"{PH1}, {PH2}, {PH3}",sS:"{PH1}, {PH2}"},str_=i18n.i18n.registerUIStrings("ui/legacy/SoftContextMenu.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_);export class SoftContextMenu{items;itemSelectedCallback;parentMenu;highlightedMenuItemElement;detailsForElementMap;document;glassPane;contextMenuElement;focusRestorer;hideOnUserMouseDownUnlessInMenu;activeSubMenuElement;subMenu;onMenuClosed;focusOnTheFirstItem=!0;constructor(e,t,n,s){this.items=e,this.itemSelectedCallback=t,this.parentMenu=n,this.highlightedMenuItemElement=null,this.detailsForElementMap=new WeakMap,this.onMenuClosed=s}show(e,t){if(this.items.length){this.document=e,this.glassPane=new GlassPane,this.glassPane.setPointerEventsBehavior(this.parentMenu?"PierceGlassPane":"BlockedByGlassPane"),this.glassPane.registerRequiredCSS(softContextMenuStyles),this.glassPane.setContentAnchorBox(t),this.glassPane.setSizeBehavior("MeasureContent"),this.glassPane.setMarginBehavior("NoMargin"),this.glassPane.setAnchorBehavior(this.parentMenu?"PreferRight":"PreferBottom"),this.contextMenuElement=this.glassPane.contentElement.createChild("div","soft-context-menu"),this.contextMenuElement.tabIndex=-1,ARIAUtils.markAsMenu(this.contextMenuElement),this.contextMenuElement.addEventListener("mouseup",(e=>e.consume()),!1),this.contextMenuElement.addEventListener("keydown",this.menuKeyDown.bind(this),!1);for(let e=0;e<this.items.length;++e)this.contextMenuElement.appendChild(this.createMenuItem(this.items[e]));if(this.glassPane.show(e),this.focusRestorer=new ElementFocusRestorer(this.contextMenuElement),!this.parentMenu){this.hideOnUserMouseDownUnlessInMenu=e=>{let t=this.subMenu;for(;t;){if(t.contextMenuElement===e.composedPath()[0])return;t=t.subMenu}this.discard(),e.consume(!0)},this.document.body.addEventListener("mousedown",this.hideOnUserMouseDownUnlessInMenu,!1);const e=InspectorView.maybeGetInspectorViewInstance()?.element;if(e){let t=!1;const n=new ResizeObserver((()=>{if(t)return n.disconnect(),void this.discard();t=!0}));n.observe(e)}if(this.contextMenuElement.children&&this.focusOnTheFirstItem){const e=this.contextMenuElement.children[0];this.highlightMenuItem(e,!1)}}}}setContextMenuElementLabel(e){this.contextMenuElement&&ARIAUtils.setLabel(this.contextMenuElement,e)}discard(){this.subMenu&&this.subMenu.discard(),this.focusRestorer&&this.focusRestorer.restore(),this.glassPane&&(this.glassPane.hide(),delete this.glassPane,this.hideOnUserMouseDownUnlessInMenu&&(this.document&&this.document.body.removeEventListener("mousedown",this.hideOnUserMouseDownUnlessInMenu,!1),delete this.hideOnUserMouseDownUnlessInMenu)),this.parentMenu&&(delete this.parentMenu.subMenu,this.parentMenu.activeSubMenuElement&&(ARIAUtils.setExpanded(this.parentMenu.activeSubMenuElement,!1),delete this.parentMenu.activeSubMenuElement)),this.onMenuClosed?.()}createMenuItem(e){if("separator"===e.type)return this.createSeparator();if("subMenu"===e.type)return this.createSubMenu(e);const t=document.createElement("div");t.classList.add("soft-context-menu-item"),t.tabIndex=-1,ARIAUtils.markAsMenuItem(t);const n=new IconButton.Icon.Icon;n.data={iconName:"checkmark",color:"var(--icon-default)",width:"14px",height:"14px"},n.classList.add("checkmark"),n.style.minWidth="14px",n.style.minHeight="14px",t.appendChild(n),e.checked||(n.style.opacity="0"),e.tooltip&&Tooltip.install(t,e.tooltip);const s={actionId:void 0,isSeparator:void 0,customElement:void 0,subItems:void 0,subMenuTimer:void 0};if(e.element&&!e.label){if(t.createChild("div","soft-context-menu-custom-item").appendChild(e.element),e.element?.classList.contains("location-menu")){const n=e.element.ariaLabel||"";e.element.ariaLabel="",ARIAUtils.setLabel(t,n)}return s.customElement=e.element,this.detailsForElementMap.set(t,s),t}e.enabled||t.classList.add("soft-context-menu-disabled"),createTextChild(t,e.label||""),e.element&&t.appendChild(e.element),t.createChild("span","soft-context-menu-shortcut").textContent=e.shortcut||"",t.addEventListener("mousedown",this.menuItemMouseDown.bind(this),!1),t.addEventListener("mouseup",this.menuItemMouseUp.bind(this),!1),t.addEventListener("mouseover",this.menuItemMouseOver.bind(this),!1),t.addEventListener("mouseleave",this.menuItemMouseLeave.bind(this),!1),s.actionId=e.id;let i=e.label||"";if("checkbox"===e.type){const t=e.checked?i18nString(UIStrings.checked):i18nString(UIStrings.unchecked);i=e.shortcut?i18nString(UIStrings.sSS,{PH1:String(e.label),PH2:e.shortcut,PH3:t}):i18nString(UIStrings.sS,{PH1:String(e.label),PH2:t})}else e.shortcut&&(i=i18nString(UIStrings.sS,{PH1:String(e.label),PH2:e.shortcut}));return ARIAUtils.setLabel(t,i),this.detailsForElementMap.set(t,s),t}createSubMenu(e){const t=document.createElement("div");t.classList.add("soft-context-menu-item"),t.tabIndex=-1,ARIAUtils.markAsMenuItemSubMenu(t),this.detailsForElementMap.set(t,{subItems:e.subItems,actionId:void 0,isSeparator:void 0,customElement:void 0,subMenuTimer:void 0});const n=new IconButton.Icon.Icon;if(n.data={iconName:"checkmark",color:"var(--icon-default)",width:"14px",height:"14px"},n.classList.add("checkmark","soft-context-menu-item-checkmark"),t.appendChild(n),n.style.minWidth="14px",n.style.opacity="0",createTextChild(t,e.label||""),ARIAUtils.setExpanded(t,!1),Host.Platform.isMac()&&!ThemeSupport.ThemeSupport.instance().hasTheme()){const e=t.createChild("span","soft-context-menu-item-submenu-arrow");ARIAUtils.markAsHidden(e),e.textContent="▶"}else{const e=Icon.create("triangle-right","soft-context-menu-item-submenu-arrow");t.appendChild(e)}return t.addEventListener("mousedown",this.menuItemMouseDown.bind(this),!1),t.addEventListener("mouseup",this.menuItemMouseUp.bind(this),!1),t.addEventListener("mouseover",this.menuItemMouseOver.bind(this),!1),t.addEventListener("mouseleave",this.menuItemMouseLeave.bind(this),!1),t}createSeparator(){const e=document.createElement("div");return e.classList.add("soft-context-menu-separator"),this.detailsForElementMap.set(e,{subItems:void 0,actionId:void 0,isSeparator:!0,customElement:void 0,subMenuTimer:void 0}),e.createChild("div","separator-line"),e}menuItemMouseDown(e){e.consume(!0)}menuItemMouseUp(e){this.triggerAction(e.target,e),e.consume()}root(){let e=this;for(;e.parentMenu;)e=e.parentMenu;return e}triggerAction(e,t){const n=this.detailsForElementMap.get(e);if(n&&!n.subItems)return this.root().discard(),t.consume(!0),void(void 0!==n.actionId&&(this.itemSelectedCallback(n.actionId),delete n.actionId));this.showSubMenu(e),t.consume()}showSubMenu(e){const t=this.detailsForElementMap.get(e);if(!t)return;if(t.subMenuTimer&&(window.clearTimeout(t.subMenuTimer),delete t.subMenuTimer),this.subMenu||!this.document)return;if(this.activeSubMenuElement=e,ARIAUtils.setExpanded(e,!0),!t.subItems)return;this.subMenu=new SoftContextMenu(t.subItems,this.itemSelectedCallback,this);const n=e.boxInWindow();n.y-=5,n.x+=3,n.width-=6,n.height+=10,this.subMenu.show(this.document,n)}menuItemMouseOver(e){this.highlightMenuItem(e.target,!0)}menuItemMouseLeave(e){if(!this.subMenu||!e.relatedTarget)return void this.highlightMenuItem(null,!0);e.relatedTarget===this.contextMenuElement&&this.highlightMenuItem(null,!0)}highlightMenuItem(e,t){if(this.highlightedMenuItemElement!==e){if(this.subMenu&&this.subMenu.discard(),this.highlightedMenuItemElement){const e=this.detailsForElementMap.get(this.highlightedMenuItemElement);this.highlightedMenuItemElement.classList.remove("force-white-icons"),this.highlightedMenuItemElement.classList.remove("soft-context-menu-item-mouse-over"),e&&e.subItems&&e.subMenuTimer&&(window.clearTimeout(e.subMenuTimer),delete e.subMenuTimer)}if(this.highlightedMenuItemElement=e,this.highlightedMenuItemElement){this.highlightedMenuItemElement.classList.add("force-white-icons"),this.highlightedMenuItemElement.classList.add("soft-context-menu-item-mouse-over");const e=this.detailsForElementMap.get(this.highlightedMenuItemElement);e&&e.customElement&&!e.customElement.classList.contains("location-menu")?e.customElement.focus():this.highlightedMenuItemElement.focus(),t&&e&&e.subItems&&!e.subMenuTimer&&(e.subMenuTimer=window.setTimeout(this.showSubMenu.bind(this,this.highlightedMenuItemElement),150))}this.contextMenuElement&&ARIAUtils.setActiveDescendant(this.contextMenuElement,e)}}highlightPrevious(){let e=this.highlightedMenuItemElement?this.highlightedMenuItemElement.previousSibling:this.contextMenuElement?this.contextMenuElement.lastChild:null,t=e?this.detailsForElementMap.get(e):void 0;for(;e&&t&&(t.isSeparator||e.classList.contains("soft-context-menu-disabled"));)e=e.previousSibling,t=e?this.detailsForElementMap.get(e):void 0;e&&this.highlightMenuItem(e,!1)}highlightNext(){let e=this.highlightedMenuItemElement?this.highlightedMenuItemElement.nextSibling:this.contextMenuElement?this.contextMenuElement.firstChild:null,t=e?this.detailsForElementMap.get(e):void 0;for(;e&&(t&&t.isSeparator||e.classList.contains("soft-context-menu-disabled"));)e=e.nextSibling,t=e?this.detailsForElementMap.get(e):void 0;e&&this.highlightMenuItem(e,!1)}menuKeyDown(e){const t=e;function n(){if(!this.highlightedMenuItemElement)return;const e=this.detailsForElementMap.get(this.highlightedMenuItemElement);e&&!e.customElement&&(this.triggerAction(this.highlightedMenuItemElement,t),e.subItems&&this.subMenu&&this.subMenu.highlightNext(),t.consume(!0))}switch(t.key){case"ArrowUp":this.highlightPrevious(),t.consume(!0);break;case"ArrowDown":this.highlightNext(),t.consume(!0);break;case"ArrowLeft":this.parentMenu&&(this.highlightMenuItem(null,!1),this.discard()),t.consume(!0);break;case"ArrowRight":{if(!this.highlightedMenuItemElement)break;const e=this.detailsForElementMap.get(this.highlightedMenuItemElement);e&&e.subItems&&(this.showSubMenu(this.highlightedMenuItemElement),this.subMenu&&this.subMenu.highlightNext()),e?.customElement?.classList.contains("location-menu")&&(e.customElement.dispatchEvent(new KeyboardEvent("keydown",{key:"ArrowRight"})),this.highlightMenuItem(null,!0)),t.consume(!0);break}case"Escape":this.discard(),t.consume(!0);break;case"Enter":if("Enter"!==t.key)return;n.call(this);break;case" ":n.call(this);break;default:t.consume(!0)}}markAsMenuItemCheckBox(){if(this.contextMenuElement)for(const e of this.contextMenuElement.children)"soft-context-menu-separator"!==e.className&&ARIAUtils.markAsMenuItemCheckBox(e)}setFocusOnTheFirstItem(e){this.focusOnTheFirstItem=e}}