UNPKG

@yuebai008/cli

Version:

Command line interface for rapid qg-minigame development

1 lines 12.4 kB
import*as Common from"../../core/common/common.js";import*as i18n from"../../core/i18n/i18n.js";import*as Platform from"../../core/platform/platform.js";import*as ARIAUtils from"./ARIAUtils.js";import{HistoryInput}from"./HistoryInput.js";import{InspectorView}from"./InspectorView.js";import searchableViewStyles from"./searchableView.css.legacy.js";import{Toolbar,ToolbarButton,ToolbarToggle}from"./Toolbar.js";import{Tooltip}from"./Tooltip.js";import{createTextButton}from"./UIUtils.js";import{VBox}from"./Widget.js";const UIStrings={replace:"Replace",findString:"Find",searchPrevious:"Search previous",searchNext:"Search next",matchCase:"Match Case",useRegularExpression:"Use Regular Expression",cancel:"Cancel",replaceAll:"Replace all",dOfD:"{PH1} of {PH2}",matchString:"1 match",dMatches:"{PH1} matches"},str_=i18n.i18n.registerUIStrings("ui/legacy/SearchableView.ts",UIStrings),i18nString=i18n.i18n.getLocalizedString.bind(void 0,str_);export class SearchableView extends VBox{searchProvider;replaceProvider;setting;replaceable;footerElementContainer;footerElement;replaceToggleButton;searchInputElement;matchesElement;searchNavigationPrevElement;searchNavigationNextElement;replaceInputElement;buttonsContainer;caseSensitiveButton;regexButton;secondRowButtons;replaceButtonElement;replaceAllButtonElement;minimalSearchQuerySize;searchIsVisible;currentQuery;valueChangedTimeoutId;constructor(e,t,i){super(!0),this.registerRequiredCSS(searchableViewStyles),searchableViewsByElement.set(this.element,this),this.searchProvider=e,this.replaceProvider=t,this.setting=i?Common.Settings.Settings.instance().createSetting(i,{}):null,this.replaceable=!1,this.contentElement.createChild("slot"),this.footerElementContainer=this.contentElement.createChild("div","search-bar hidden"),this.footerElementContainer.style.order="100",this.footerElement=this.footerElementContainer.createChild("div","toolbar-search");const s=new Toolbar("replace-toggle-toolbar",this.footerElement);this.replaceToggleButton=new ToolbarToggle(i18nString(UIStrings.replace),"replace"),this.replaceToggleButton.addEventListener(ToolbarButton.Events.Click,this.toggleReplace,this),s.appendToolbarItem(this.replaceToggleButton);const r=this.footerElement.createChild("div","toolbar-search-inputs"),n=r.createChild("div","toolbar-search-control");this.searchInputElement=HistoryInput.create(),this.searchInputElement.type="search",this.searchInputElement.classList.add("search-replace","custom-search-input"),this.searchInputElement.id="search-input-field",this.searchInputElement.placeholder=i18nString(UIStrings.findString),n.appendChild(this.searchInputElement),this.matchesElement=n.createChild("label","search-results-matches"),this.matchesElement.setAttribute("for","search-input-field");const a=n.createChild("div","toolbar-search-navigation-controls");this.searchNavigationPrevElement=a.createChild("div","toolbar-search-navigation toolbar-search-navigation-prev"),this.searchNavigationPrevElement.addEventListener("click",this.onPrevButtonSearch.bind(this),!1),Tooltip.install(this.searchNavigationPrevElement,i18nString(UIStrings.searchPrevious)),ARIAUtils.setLabel(this.searchNavigationPrevElement,i18nString(UIStrings.searchPrevious)),this.searchNavigationNextElement=a.createChild("div","toolbar-search-navigation toolbar-search-navigation-next"),this.searchNavigationNextElement.addEventListener("click",this.onNextButtonSearch.bind(this),!1),Tooltip.install(this.searchNavigationNextElement,i18nString(UIStrings.searchNext)),ARIAUtils.setLabel(this.searchNavigationNextElement,i18nString(UIStrings.searchNext)),this.searchInputElement.addEventListener("keydown",this.onSearchKeyDown.bind(this),!0),this.searchInputElement.addEventListener("input",this.onInput.bind(this),!1),this.replaceInputElement=r.createChild("input","search-replace toolbar-replace-control hidden"),this.replaceInputElement.addEventListener("keydown",this.onReplaceKeyDown.bind(this),!0),this.replaceInputElement.placeholder=i18nString(UIStrings.replace),this.buttonsContainer=this.footerElement.createChild("div","toolbar-search-buttons");const o=this.buttonsContainer.createChild("div","first-row-buttons"),h=new Toolbar("toolbar-search-options",o);this.searchProvider.supportsCaseSensitiveSearch()&&(this.caseSensitiveButton=new ToolbarToggle(i18nString(UIStrings.matchCase)),this.caseSensitiveButton.setText("Aa"),this.caseSensitiveButton.addEventListener(ToolbarButton.Events.Click,this.toggleCaseSensitiveSearch,this),h.appendToolbarItem(this.caseSensitiveButton)),this.searchProvider.supportsRegexSearch()&&(this.regexButton=new ToolbarToggle(i18nString(UIStrings.useRegularExpression)),this.regexButton.setText(".*"),this.regexButton.addEventListener(ToolbarButton.Events.Click,this.toggleRegexSearch,this),h.appendToolbarItem(this.regexButton));const c=createTextButton(i18nString(UIStrings.cancel),this.closeSearch.bind(this),"search-action-button");o.appendChild(c),this.secondRowButtons=this.buttonsContainer.createChild("div","second-row-buttons hidden"),this.replaceButtonElement=createTextButton(i18nString(UIStrings.replace),this.replace.bind(this),"search-action-button"),this.replaceButtonElement.disabled=!0,this.secondRowButtons.appendChild(this.replaceButtonElement),this.replaceAllButtonElement=createTextButton(i18nString(UIStrings.replaceAll),this.replaceAll.bind(this),"search-action-button"),this.secondRowButtons.appendChild(this.replaceAllButtonElement),this.replaceAllButtonElement.disabled=!0,this.minimalSearchQuerySize=3,this.loadSetting()}static fromElement(e){let t=null;for(;e&&!t;)t=searchableViewsByElement.get(e)||null,e=e.parentElementOrShadowHost();return t}toggleCaseSensitiveSearch(){this.caseSensitiveButton&&this.caseSensitiveButton.setToggled(!this.caseSensitiveButton.toggled()),this.saveSetting(),this.performSearch(!1,!0)}toggleRegexSearch(){this.regexButton&&this.regexButton.setToggled(!this.regexButton.toggled()),this.saveSetting(),this.performSearch(!1,!0)}toggleReplace(){this.replaceToggleButton.setToggled(!this.replaceToggleButton.toggled()),this.updateSecondRowVisibility()}saveSetting(){if(!this.setting)return;const e=this.setting.get()||{};this.caseSensitiveButton&&(e.caseSensitive=this.caseSensitiveButton.toggled()),this.regexButton&&(e.isRegex=this.regexButton.toggled()),this.setting.set(e)}loadSetting(){const e=this.setting&&this.setting.get()||{};this.searchProvider.supportsCaseSensitiveSearch()&&this.caseSensitiveButton&&this.caseSensitiveButton.setToggled(Boolean(e.caseSensitive)),this.searchProvider.supportsRegexSearch()&&this.regexButton&&this.regexButton.setToggled(Boolean(e.isRegex))}setMinimalSearchQuerySize(e){this.minimalSearchQuerySize=e}setPlaceholder(e,t){this.searchInputElement.placeholder=e,t&&ARIAUtils.setLabel(this.searchInputElement,t)}setReplaceable(e){this.replaceable=e}updateSearchMatchesCount(e){const t=this.searchProvider;t.currentSearchMatches!==e&&(t.currentSearchMatches=e,this.updateSearchMatchesCountAndCurrentMatchIndex(t.currentQuery?e:0,-1))}updateCurrentMatchIndex(e){const t=this.searchProvider;this.updateSearchMatchesCountAndCurrentMatchIndex(t.currentSearchMatches,e)}isSearchVisible(){return Boolean(this.searchIsVisible)}closeSearch(){this.cancelSearch(),this.footerElementContainer.hasFocus()&&this.focus(),this.searchProvider.onSearchClosed?.()}toggleSearchBar(e){this.footerElementContainer.classList.toggle("hidden",!e),this.doResize()}cancelSearch(){this.searchIsVisible&&(this.resetSearch(),delete this.searchIsVisible,this.toggleSearchBar(!1))}resetSearch(){this.clearSearch(),this.updateReplaceVisibility(),this.matchesElement.textContent=""}refreshSearch(){this.searchIsVisible&&(this.resetSearch(),this.performSearch(!1,!1))}handleFindNextShortcut(){return!!this.searchIsVisible&&(this.searchProvider.jumpToNextSearchResult(),!0)}handleFindPreviousShortcut(){return!!this.searchIsVisible&&(this.searchProvider.jumpToPreviousSearchResult(),!0)}handleFindShortcut(){return this.showSearchField(),!0}handleCancelSearchShortcut(){return!!this.searchIsVisible&&(this.closeSearch(),!0)}updateSearchNavigationButtonState(e){this.replaceButtonElement.disabled=!e,this.replaceAllButtonElement.disabled=!e,this.searchNavigationPrevElement.classList.toggle("enabled",e),this.searchNavigationNextElement.classList.toggle("enabled",e)}updateSearchMatchesCountAndCurrentMatchIndex(e,t){this.currentQuery?this.matchesElement.textContent=0===e||t>=0?i18nString(UIStrings.dOfD,{PH1:t+1,PH2:e}):1===e?i18nString(UIStrings.matchString):i18nString(UIStrings.dMatches,{PH1:e}):this.matchesElement.textContent="",this.updateSearchNavigationButtonState(e>0)}showSearchField(){let e;if(this.searchIsVisible&&this.cancelSearch(),!this.searchInputElement.hasFocus()){const t=InspectorView.instance().element.window().getSelection();t&&t.rangeCount&&(e=t.toString().replace(/\r?\n.*/,""))}this.toggleSearchBar(!0),this.updateReplaceVisibility(),e&&(this.searchInputElement.value=e),this.performSearch(!1,!1),this.searchInputElement.focus(),this.searchInputElement.select(),this.searchIsVisible=!0}updateReplaceVisibility(){this.replaceToggleButton.setVisible(this.replaceable),this.replaceable||(this.replaceToggleButton.setToggled(!1),this.updateSecondRowVisibility())}onSearchKeyDown(e){const t=e;if(Platform.KeyboardUtilities.isEscKey(t))return this.closeSearch(),void t.consume(!0);"Enter"===t.key&&(this.currentQuery?this.jumpToNextSearchResult(t.shiftKey):this.performSearch(!0,!0,t.shiftKey))}onReplaceKeyDown(e){"Enter"===e.key&&this.replace()}jumpToNextSearchResult(e){this.currentQuery&&(e?this.searchProvider.jumpToPreviousSearchResult():this.searchProvider.jumpToNextSearchResult())}onNextButtonSearch(e){this.searchNavigationNextElement.classList.contains("enabled")&&(this.jumpToNextSearchResult(),this.searchInputElement.focus())}onPrevButtonSearch(e){this.searchNavigationPrevElement.classList.contains("enabled")&&(this.jumpToNextSearchResult(!0),this.searchInputElement.focus())}clearSearch(){const e=this.searchProvider;delete this.currentQuery,Boolean(e.currentQuery)&&(delete e.currentQuery,this.searchProvider.onSearchCanceled()),this.updateSearchMatchesCountAndCurrentMatchIndex(0,-1)}performSearch(e,t,i){const s=this.searchInputElement.value;if(!s||!e&&s.length<this.minimalSearchQuerySize&&!this.currentQuery)return void this.clearSearch();this.currentQuery=s,this.searchProvider.currentQuery=s;const r=this.currentSearchConfig();this.searchProvider.performSearch(r,t,i)}currentSearchConfig(){const e=this.searchInputElement.value,t=!!this.caseSensitiveButton&&this.caseSensitiveButton.toggled(),i=!!this.regexButton&&this.regexButton.toggled();return new SearchConfig(e,t,i)}updateSecondRowVisibility(){const e=this.replaceToggleButton.toggled();this.footerElementContainer.classList.toggle("replaceable",e),this.secondRowButtons.classList.toggle("hidden",!e),this.replaceInputElement.classList.toggle("hidden",!e),e?this.replaceInputElement.focus():this.searchInputElement.focus(),this.doResize()}replace(){if(!this.replaceProvider)throw new Error("No 'replacable' provided to SearchableView!");const e=this.currentSearchConfig();this.replaceProvider.replaceSelectionWith(e,this.replaceInputElement.value),delete this.currentQuery,this.performSearch(!0,!0)}replaceAll(){if(!this.replaceProvider)throw new Error("No 'replacable' provided to SearchableView!");const e=this.currentSearchConfig();this.replaceProvider.replaceAllWith(e,this.replaceInputElement.value)}onInput(e){if(!Common.Settings.Settings.instance().moduleSetting("searchAsYouType").get())return void this.clearSearch();this.valueChangedTimeoutId&&clearTimeout(this.valueChangedTimeoutId);const t=this.searchInputElement.value.length<3?200:0;this.valueChangedTimeoutId=window.setTimeout(this.onValueChanged.bind(this),t)}onValueChanged(){this.searchIsVisible&&(delete this.valueChangedTimeoutId,this.performSearch(!1,!0))}}export const _symbol=Symbol("searchableView");const searchableViewsByElement=new WeakMap;export class SearchConfig{query;caseSensitive;isRegex;constructor(e,t,i){this.query=e,this.caseSensitive=t,this.isRegex=i}toSearchRegex(e){let t=this.caseSensitive?"":"i";e&&(t+="g");const i=this.isRegex?"/"+this.query+"/":this.query;let s,r=!1;try{/^\/.+\/$/.test(i)&&(s=new RegExp(i.substring(1,i.length-1),t),r=!0)}catch(e){}return s||(s=Platform.StringUtilities.createPlainTextSearchRegex(i,t)),{regex:s,fromQuery:r}}}