Search.SearchView=class extends UI.VBox{constructor(){super(true);this.setMinimumSize(0,40);this.registerRequiredCSS('search/searchView.css');this._focusOnShow=false;this._isIndexing=false;this._searchId=1;this._searchMatchesCount=0;this._searchResultsCount=0;this._nonEmptySearchResultsCount=0;this._searchingView=null;this._notFoundView=null;this._searchConfig=null;this._pendingSearchConfig=null;this._searchResultsPane=null;this._progressIndicator=null;this._visiblePane=null;this.contentElement.classList.add('search-view');this._searchPanelElement=this.contentElement.createChild('div','search-drawer-header');this._searchPanelElement.addEventListener('keydown',this._onKeyDown.bind(this),false);this._searchPanelElement.addEventListener('input',this._onInput.bind(this),false);this._searchResultsElement=this.contentElement.createChild('div');this._searchResultsElement.className='search-results';this._search=UI.HistoryInput.create();this._searchPanelElement.appendChild(this._search);this._search.placeholder=Common.UIString('Search all sources (use "file:" to filter by path)\u200e');this._search.setAttribute('type','text');this._search.classList.add('search-config-search');this._search.setAttribute('results','0');this._search.setAttribute('size',42);const searchIcon=UI.Icon.create('mediumicon-search','search-icon');this._searchPanelElement.appendChild(searchIcon);this._searchInputClearElement=UI.Icon.create('mediumicon-gray-cross-hover','search-cancel-button');this._searchInputClearElement.classList.add('hidden');this._searchInputClearElement.addEventListener('click',this._onSearchInputClear.bind(this),false);const cancelButtonContainer=this._searchPanelElement.createChild('div','search-cancel-button-container');cancelButtonContainer.appendChild(this._searchInputClearElement);const toolbar=new UI.Toolbar('search-toolbar',this._searchPanelElement);this._ignoreCaseCheckbox=new UI.ToolbarCheckbox(Common.UIString('Ignore case'));toolbar.appendToolbarItem(this._ignoreCaseCheckbox);this._regexCheckbox=new UI.ToolbarCheckbox(Common.UIString('Regular expression'));toolbar.appendToolbarItem(this._regexCheckbox);toolbar.appendToolbarItem(new UI.ToolbarSeparator(true));this._scopeMenu=new UI.ToolbarComboBox(()=>{});toolbar.appendToolbarItem(this._scopeMenu);const searchStatusBarElement=this.contentElement.createChild('div','search-toolbar-summary');this._searchMessageElement=searchStatusBarElement.createChild('div','search-message');this._searchProgressPlaceholderElement=searchStatusBarElement.createChild('div','flex-centered');this._searchResultsMessageElement=searchStatusBarElement.createChild('div','search-message');this._advancedSearchConfig=Common.settings.createLocalSetting('advancedSearchConfig',new Search.SearchConfig(null,'',true,false).toPlainObject());this._searchScopes=new Map();this._defaultScope=Search.SearchView._readScopesExtenstions(this._scopeMenu,this._searchScopes);this._load();this._searchScope=null;}
|
static openSearch(searchScopeType,query){UI.viewManager.showView('search.search');const searchView=(self.runtime.sharedInstance(Search.SearchView));searchView._toggle(searchScopeType,query);}
|
static _readScopesExtenstions(combobox,scopesMap){let defaultScope=null;for(const extension of self.runtime.extensions(Search.SearchScope)){const id=extension.descriptor().id;const title=extension.title();scopesMap.set(id,extension);combobox.addOption(combobox.createOption(title,title,id));if(!defaultScope)
|
defaultScope=extension;}
|
return defaultScope;}
|
_buildSearchConfig(){return new Search.SearchConfig(this._scopeMenu.selectedOption().value,this._search.value,this._ignoreCaseCheckbox.checked(),this._regexCheckbox.checked());}
|
async _toggle(searchScopeType,queryCandidate){if(queryCandidate)
|
this._search.value=queryCandidate;this._selectScope(searchScopeType);if(this.isShowing())
|
this.focus();else
|
this._focusOnShow=true;await this._initScope(this._scopeMenu.selectedOption().value);this._startIndexing();}
|
async _initScope(scopeType){const extension=scopeType?this._searchScopes.get(scopeType):this._defaultScope;this._searchScope=await extension.instance();}
|
wasShown(){if(this._focusOnShow){this.focus();this._focusOnShow=false;}}
|
_onIndexingFinished(){const finished=!this._progressIndicator.isCanceled();this._progressIndicator.done();this._progressIndicator=null;this._isIndexing=false;this._indexingFinished(finished);if(!finished)
|
this._pendingSearchConfig=null;if(!this._pendingSearchConfig)
|
return;const searchConfig=this._pendingSearchConfig;this._pendingSearchConfig=null;this._innerStartSearch(searchConfig);}
|
_startIndexing(){this._isIndexing=true;if(this._progressIndicator)
|
this._progressIndicator.done();this._progressIndicator=new UI.ProgressIndicator();this._searchMessageElement.textContent=Common.UIString('Indexing\u2026');this._progressIndicator.show(this._searchProgressPlaceholderElement);this._searchScope.performIndexing(new Common.ProgressProxy(this._progressIndicator,this._onIndexingFinished.bind(this)));}
|
_onSearchInputClear(){this._search.value='';this.focus();this._searchInputClearElement.classList.add('hidden');}
|
_onSearchResult(searchId,searchResult){if(searchId!==this._searchId||!this._progressIndicator)
|
return;if(this._progressIndicator&&this._progressIndicator.isCanceled()){this._onIndexingFinished();return;}
|
this._addSearchResult(searchResult);if(!searchResult.matchesCount())
|
return;if(!this._searchResultsPane){this._searchResultsPane=new Search.SearchResultsPane((this._searchConfig));this._showPane(this._searchResultsPane);}
|
this._searchResultsPane.addSearchResult(searchResult);}
|
_onSearchFinished(searchId,finished){if(searchId!==this._searchId||!this._progressIndicator)
|
return;if(!this._searchResultsPane)
|
this._nothingFound();this._searchFinished(finished);this._searchConfig=null;}
|
async _startSearch(searchConfig){this._resetSearch();++this._searchId;await this._initScope(searchConfig.scopeType());if(!this._isIndexing)
|
this._startIndexing();this._pendingSearchConfig=searchConfig;}
|
_innerStartSearch(searchConfig){this._searchConfig=searchConfig;if(this._progressIndicator)
|
this._progressIndicator.done();this._progressIndicator=new UI.ProgressIndicator();this._searchStarted(this._progressIndicator);this._searchScope.performSearch(searchConfig,this._progressIndicator,this._onSearchResult.bind(this,this._searchId),this._onSearchFinished.bind(this,this._searchId));}
|
_resetSearch(){this._stopSearch();this._showPane(null);this._searchResultsPane=null;}
|
_stopSearch(){if(this._progressIndicator&&!this._isIndexing)
|
this._progressIndicator.cancel();if(this._searchScope)
|
this._searchScope.stopSearch();this._searchConfig=null;}
|
_searchStarted(progressIndicator){this._resetCounters();if(!this._searchingView)
|
this._searchingView=new UI.EmptyWidget(Common.UIString('Searching\u2026'));this._showPane(this._searchingView);this._searchMessageElement.textContent=Common.UIString('Searching\u2026');progressIndicator.show(this._searchProgressPlaceholderElement);this._updateSearchResultsMessage();}
|
_indexingFinished(finished){this._searchMessageElement.textContent=finished?'':Common.UIString('Indexing interrupted.');}
|
_updateSearchResultsMessage(){if(this._searchMatchesCount&&this._searchResultsCount){if(this._searchMatchesCount===1&&this._nonEmptySearchResultsCount===1){this._searchResultsMessageElement.textContent=Common.UIString('Found 1 matching line in 1 file.');}else if(this._searchMatchesCount>1&&this._nonEmptySearchResultsCount===1){this._searchResultsMessageElement.textContent=Common.UIString('Found %d matching lines in 1 file.',this._searchMatchesCount);}else{this._searchResultsMessageElement.textContent=Common.UIString('Found %d matching lines in %d files.',this._searchMatchesCount,this._nonEmptySearchResultsCount);}}else{this._searchResultsMessageElement.textContent='';}}
|
_showPane(panel){if(this._visiblePane)
|
this._visiblePane.detach();if(panel)
|
panel.show(this._searchResultsElement);this._visiblePane=panel;}
|
_resetCounters(){this._searchMatchesCount=0;this._searchResultsCount=0;this._nonEmptySearchResultsCount=0;}
|
_nothingFound(){if(!this._notFoundView)
|
this._notFoundView=new UI.EmptyWidget(Common.UIString('No matches found.'));this._showPane(this._notFoundView);this._searchResultsMessageElement.textContent=Common.UIString('No matches found.');}
|
_addSearchResult(searchResult){const matchesCount=searchResult.matchesCount();this._searchMatchesCount+=matchesCount;this._searchResultsCount++;if(matchesCount)
|
this._nonEmptySearchResultsCount++;this._updateSearchResultsMessage();}
|
_searchFinished(finished){this._searchMessageElement.textContent=finished?Common.UIString('Search finished.'):Common.UIString('Search interrupted.');}
|
focus(){this._search.focus();this._search.select();}
|
willHide(){this._stopSearch();}
|
_onKeyDown(event){switch(event.keyCode){case UI.KeyboardShortcut.Keys.Enter.code:this._onAction();break;}}
|
_onInput(){const hasText=this._search.value&&this._search.value.length;this._searchInputClearElement.classList.toggle('hidden',!hasText);}
|
_save(){this._advancedSearchConfig.set(this._buildSearchConfig().toPlainObject());}
|
_load(){const searchConfig=Search.SearchConfig.fromPlainObject(this._advancedSearchConfig.get());this._search.value=searchConfig.query();this._ignoreCaseCheckbox.setChecked(searchConfig.ignoreCase());this._regexCheckbox.setChecked(searchConfig.isRegex());this._selectScope(searchConfig.scopeType()||this._scopeMenu.options()[0].value);if(this._search.value&&this._search.value.length)
|
this._searchInputClearElement.classList.remove('hidden');}
|
_onAction(){const searchConfig=this._buildSearchConfig();if(!searchConfig.query()||!searchConfig.query().length)
|
return;this._save();this._startSearch(searchConfig);}
|
_selectScope(scopeType){if(!scopeType)
|
return;let scope=this._scopeMenu.options().find(option=>option.value===scopeType);if(!scope){console.warn(`Search scope '${scopeType}' was not found`);scope=this._scopeMenu.options()[0];}
|
this._scopeMenu.select(scope);}};Search.SearchView.ActionDelegate=class{handleAction(context,actionId){this._showSearch();return true;}
|
_showSearch(){const selection=UI.inspectorView.element.window().getSelection();let queryCandidate='';if(selection.rangeCount)
|
queryCandidate=selection.toString().replace(/\r?\n.*/,'');Search.SearchView.openSearch(null,queryCandidate);}};;Search.SearchConfig=class{constructor(scopeType,query,ignoreCase,isRegex){this._scopeType=scopeType;this._query=query;this._ignoreCase=ignoreCase;this._isRegex=isRegex;this._parse();}
|
static fromPlainObject(object){const scopeType=object.scopeType||null;return new Search.SearchConfig(scopeType,object.query,object.ignoreCase,object.isRegex);}
|
scopeType(){return this._scopeType;}
|
query(){return this._query;}
|
ignoreCase(){return this._ignoreCase;}
|
isRegex(){return this._isRegex;}
|
toPlainObject(){return{scopeType:this.scopeType(),query:this.query(),ignoreCase:this.ignoreCase(),isRegex:this.isRegex()};}
|
_parse(){const quotedPattern=/"([^\\"]|\\.)+"/;const unquotedWordPattern=/(\s*(?!-?f(ile)?:)[^\\ ]|\\.)+/;const unquotedPattern=unquotedWordPattern.source+'(\\s+'+unquotedWordPattern.source+')*';const pattern=['(\\s*'+Search.SearchConfig.FilePatternRegex.source+'\\s*)','('+quotedPattern.source+')','('+unquotedPattern+')',].join('|');const regexp=new RegExp(pattern,'g');const queryParts=this._query.match(regexp)||[];this._fileQueries=[];this._queries=[];for(let i=0;i<queryParts.length;++i){const queryPart=queryParts[i];if(!queryPart)
|
continue;const fileQuery=this._parseFileQuery(queryPart);if(fileQuery){this._fileQueries.push(fileQuery);this._fileRegexQueries=this._fileRegexQueries||[];this._fileRegexQueries.push({regex:new RegExp(fileQuery.text,this.ignoreCase?'i':''),isNegative:fileQuery.isNegative});continue;}
|
if(this._isRegex){this._queries.push(queryPart);continue;}
|
if(queryPart.startsWith('"')){if(!queryPart.endsWith('"'))
|
continue;this._queries.push(this._parseQuotedQuery(queryPart));continue;}
|
this._queries.push(this._parseUnquotedQuery(queryPart));}}
|
filePathMatchesFileQuery(filePath){if(!this._fileRegexQueries)
|
return true;for(let i=0;i<this._fileRegexQueries.length;++i){if(!!filePath.match(this._fileRegexQueries[i].regex)===this._fileRegexQueries[i].isNegative)
|
return false;}
|
return true;}
|
queries(){return this._queries;}
|
_parseUnquotedQuery(query){return query.replace(/\\(.)/g,'$1');}
|
_parseQuotedQuery(query){return query.substring(1,query.length-1).replace(/\\(.)/g,'$1');}
|
_parseFileQuery(query){const match=query.match(Search.SearchConfig.FilePatternRegex);if(!match)
|
return null;const isNegative=!!match[1];query=match[3];let result='';for(let i=0;i<query.length;++i){const char=query[i];if(char==='*'){result+='.*';}else if(char==='\\'){++i;const nextChar=query[i];if(nextChar===' ')
|
result+=' ';}else{if(String.regexSpecialCharacters().indexOf(query.charAt(i))!==-1)
|
result+='\\';result+=query.charAt(i);}}
|
return new Search.SearchConfig.QueryTerm(result,isNegative);}};Search.SearchConfig.FilePatternRegex=/(-)?f(ile)?:((?:[^\\ ]|\\.)+)/;Search.SearchConfig.RegexQuery;Search.SearchConfig.QueryTerm=class{constructor(text,isNegative){this.text=text;this.isNegative=isNegative;}};Search.SearchResult=function(){};Search.SearchResult.prototype={label(){},matchesCount(){},matchLineNumber(index){},matchLineContent(index){},matchRevealable(index){}};Search.SearchScope=function(){};Search.SearchScope.prototype={performSearch(searchConfig,progress,searchResultCallback,searchFinishedCallback){},performIndexing(progress){},stopSearch(){}};;Search.SearchResultsPane=class extends UI.VBox{constructor(searchConfig){super(true);this._searchConfig=searchConfig;this._searchResults=[];this._treeOutline=new UI.TreeOutlineInShadow();this._treeOutline.registerRequiredCSS('search/searchResultsPane.css');this.contentElement.appendChild(this._treeOutline.element);this._matchesExpandedCount=0;}
|
addSearchResult(searchResult){this._searchResults.push(searchResult);this._addTreeElement(searchResult);}
|
_addTreeElement(searchResult){const treeElement=new Search.SearchResultsPane.SearchResultsTreeElement(this._searchConfig,searchResult);this._treeOutline.appendChild(treeElement);if(this._matchesExpandedCount<Search.SearchResultsPane._matchesExpandedByDefault)
|
treeElement.expand();this._matchesExpandedCount+=searchResult.matchesCount();}};Search.SearchResultsPane._matchesExpandedByDefault=20;Search.SearchResultsPane._matchesShownAtOnce=20;Search.SearchResultsPane.SearchResultsTreeElement=class extends UI.TreeElement{constructor(searchConfig,searchResult){super('',true);this._searchConfig=searchConfig;this._searchResult=searchResult;this._initialized=false;this.toggleOnClick=true;this.selectable=false;}
|
onexpand(){if(this._initialized)
|
return;this._updateMatchesUI();this._initialized=true;}
|
_updateMatchesUI(){this.removeChildren();const toIndex=Math.min(this._searchResult.matchesCount(),Search.SearchResultsPane._matchesShownAtOnce);if(toIndex<this._searchResult.matchesCount()){this._appendSearchMatches(0,toIndex-1);this._appendShowMoreMatchesElement(toIndex-1);}else{this._appendSearchMatches(0,toIndex);}}
|
onattach(){this._updateSearchMatches();}
|
_updateSearchMatches(){this.listItemElement.classList.add('search-result');const fileNameSpan=createElement('span');fileNameSpan.className='search-result-file-name';fileNameSpan.textContent=this._searchResult.label();this.listItemElement.appendChild(fileNameSpan);const matchesCountSpan=createElement('span');matchesCountSpan.className='search-result-matches-count';const searchMatchesCount=this._searchResult.matchesCount();if(searchMatchesCount===1)
|
matchesCountSpan.textContent=Common.UIString('(%d match)',searchMatchesCount);else
|
matchesCountSpan.textContent=Common.UIString('(%d matches)',searchMatchesCount);this.listItemElement.appendChild(matchesCountSpan);if(this.expanded)
|
this._updateMatchesUI();}
|
_appendSearchMatches(fromIndex,toIndex){const searchResult=this._searchResult;const queries=this._searchConfig.queries();const regexes=[];for(let i=0;i<queries.length;++i)
|
regexes.push(createSearchRegex(queries[i],!this._searchConfig.ignoreCase(),this._searchConfig.isRegex()));for(let i=fromIndex;i<toIndex;++i){const lineNumber=searchResult.matchLineNumber(i);const lineContent=searchResult.matchLineContent(i);let matchRanges=[];for(let j=0;j<regexes.length;++j)
|
matchRanges=matchRanges.concat(this._regexMatchRanges(lineContent,regexes[j]));const anchor=Components.Linkifier.linkifyRevealable(searchResult.matchRevealable(i),'');const numberString=numberToStringWithSpacesPadding(lineNumber+1,4);const lineNumberSpan=createElement('span');lineNumberSpan.classList.add('search-match-line-number');lineNumberSpan.textContent=numberString;anchor.appendChild(lineNumberSpan);const contentSpan=this._createContentSpan(lineContent,matchRanges);anchor.appendChild(contentSpan);const searchMatchElement=new UI.TreeElement();searchMatchElement.selectable=false;this.appendChild(searchMatchElement);searchMatchElement.listItemElement.className='search-match source-code';searchMatchElement.listItemElement.appendChild(anchor);}}
|
_appendShowMoreMatchesElement(startMatchIndex){const matchesLeftCount=this._searchResult.matchesCount()-startMatchIndex;const showMoreMatchesText=Common.UIString('Show all matches (%d more).',matchesLeftCount);const showMoreMatchesTreeElement=new UI.TreeElement(showMoreMatchesText);this.appendChild(showMoreMatchesTreeElement);showMoreMatchesTreeElement.listItemElement.classList.add('show-more-matches');showMoreMatchesTreeElement.onselect=this._showMoreMatchesElementSelected.bind(this,showMoreMatchesTreeElement,startMatchIndex);}
|
_createContentSpan(lineContent,matchRanges){const contentSpan=createElement('span');contentSpan.className='search-match-content';contentSpan.textContent=lineContent;UI.highlightRangesWithStyleClass(contentSpan,matchRanges,'highlighted-match');return contentSpan;}
|
_regexMatchRanges(lineContent,regex){regex.lastIndex=0;let match;const matchRanges=[];while((regex.lastIndex<lineContent.length)&&(match=regex.exec(lineContent)))
|
matchRanges.push(new TextUtils.SourceRange(match.index,match[0].length));return matchRanges;}
|
_showMoreMatchesElementSelected(showMoreMatchesTreeElement,startMatchIndex){this.removeChild(showMoreMatchesTreeElement);this._appendSearchMatches(startMatchIndex,this._searchResult.matchesCount());return false;}};;Runtime.cachedResources["search/searchResultsPane.css"]="/*\n * Copyright 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n padding: 0;\n margin: 0;\n}\n\n.tree-outline {\n padding: 0;\n}\n\n.tree-outline ol {\n padding: 0;\n}\n\n.tree-outline li {\n height: 16px;\n}\n\nli.search-result {\n padding: 2px 0 2px 4px;\n word-wrap: normal;\n white-space: pre;\n cursor: pointer;\n}\n\nli.search-result:hover {\n background-color: rgba(121, 121, 121, 0.1);\n}\n\nli.search-result .search-result-file-name {\n font-weight: bold;\n color: #222;\n white-space: nowrap;\n}\n\nli.search-result .search-result-matches-count {\n margin-left: 5px;\n color: #222;\n}\n\nli.show-more-matches {\n padding: 4px 0;\n color: #222;\n cursor: pointer;\n margin-left: 20px;\n}\n\nli.show-more-matches:hover {\n text-decoration: underline;\n}\n\nli.search-match {\n word-wrap: normal;\n white-space: pre;\n}\n\nli.search-match::before {\n display: none;\n}\n\nli.search-match .search-match-line-number {\n color: rgb(128, 128, 128);\n text-align: right;\n vertical-align: top;\n word-break: normal;\n padding: 2px 4px 2px 6px;\n margin-right: 5px;\n border-right: 1px solid #BBB;\n}\n\nli.search-match:not(:hover) .search-match-line-number {\n background-color: #F0F0F0;\n}\n\nli.search-match:hover {\n background-color: rgba(56, 121, 217, 0.1);\n}\n\nli.search-match .highlighted-match {\n background-color: #F1EA00;\n}\n\n:host-context(.-theme-with-dark-background) li.search-match .highlighted-match {\n background-color: hsl(133, 100%, 30%) !important;\n}\n\n.tree-outline .devtools-link {\n text-decoration: none;\n display: block;\n flex: auto;\n}\n\nli.search-match .search-match-content {\n color: #000;\n}\n\n/*# sourceURL=search/searchResultsPane.css */";Runtime.cachedResources["search/searchView.css"]="/*\n * Copyright 2014 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.search-drawer-header {\n flex: none;\n display: flex;\n border-bottom: 2px solid #e8e8e8;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.search-drawer-header input.search-config-search {\n padding: 0 28px;\n margin: 2px 1px 2px 2px;\n height: 28px;\n border-radius: 2px;\n color: #303030;\n border: none;\n min-width: 95px;\n}\n\n.search-drawer-header input.search-config-search:focus {\n box-shadow: 0 0 0 2px rgba(66, 133, 244, 0.4);\n}\n\n.search-drawer-header .search-icon {\n left: 8px;\n top: 8px;\n position: absolute;\n}\n\n.search-config-search::-webkit-search-cancel-button {\n -webkit-appearance: none;\n}\n\n.search-drawer-header .search-cancel-button-container {\n position: relative;\n}\n\n.search-drawer-header .search-cancel-button {\n position: absolute;\n right: 7px;\n top: 8px;\n}\n\n:host-context(.platform-mac) .search-drawer-header input.search-config-search {\n top: 1px;\n}\n\n.search-toolbar-summary {\n background-color: #eee;\n border-top: 1px solid #ccc;\n padding-left: 5px;\n flex: 0 0 19px;\n display: flex;\n padding-right: 5px;\n}\n\n.search-toolbar-summary .search-message {\n padding-top: 2px;\n padding-left: 1ex;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n}\n\n.search-view .search-results {\n overflow-y: auto;\n display: flex;\n flex: auto;\n}\n\n.search-view .search-results > div {\n flex: auto;\n}\n\n.search-results .empty-view {\n pointer-events: none;\n}\n\n.empty-view {\n font-size: 24px;\n color: rgb(75%, 75%, 75%);\n font-weight: bold;\n padding: 10px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n\n.search-toolbar {\n border-left: 1px solid #dadada;\n padding: 4px 16px 0 8px;\n flex-grow: 1;\n}\n\n/*# sourceURL=search/searchView.css */";
|