2 * Copyright (C) 2012 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * @extends {WebInspector.DialogDelegate}
34 * @implements {WebInspector.ViewportControl.Provider}
35 * @param {!WebInspector.SelectionDialogContentProvider} delegate
37 WebInspector.FilteredItemSelectionDialog = function(delegate)
39 WebInspector.DialogDelegate.call(this);
41 this.element = createElement("div");
42 this.element.className = "filtered-item-list-dialog";
43 this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
44 this.element.appendChild(WebInspector.View.createStyleElement("sources/filteredItemSelectionDialog.css"));
46 this._promptElement = this.element.createChild("input", "monospace");
47 this._promptElement.addEventListener("input", this._onInput.bind(this), false);
48 this._promptElement.type = "text";
49 this._promptElement.setAttribute("spellcheck", "false");
51 this._filteredItems = [];
52 this._viewportControl = new WebInspector.ViewportControl(this);
53 this._itemElementsContainer = this._viewportControl.element;
54 this._itemElementsContainer.classList.add("container");
55 this._itemElementsContainer.classList.add("monospace");
56 this._itemElementsContainer.addEventListener("click", this._onClick.bind(this), false);
57 this.element.appendChild(this._itemElementsContainer);
59 this._delegate = delegate;
60 this._delegate.setRefreshCallback(this._itemsLoaded.bind(this));
64 WebInspector.FilteredItemSelectionDialog.prototype = {
66 * @param {!Element} element
67 * @param {!Element} relativeToElement
69 position: function(element, relativeToElement)
72 const shadowPadding = 20; // shadow + padding
73 var container = WebInspector.Dialog.modalHostView().element;
74 var preferredWidth = Math.max(relativeToElement.offsetWidth * 2 / 3, 500);
75 var width = Math.min(preferredWidth, container.offsetWidth - 2 * shadowPadding);
76 var preferredHeight = Math.max(relativeToElement.offsetHeight * 2 / 3, 204);
77 var height = Math.min(preferredHeight, container.offsetHeight - 2 * shadowPadding);
79 this.element.style.width = width + "px";
80 var box = relativeToElement.boxInWindow(window).relativeToElement(container);
81 var positionX = box.x + Math.max((box.width - width - 2 * shadowPadding) / 2, shadow);
82 positionX = Math.max(shadow, Math.min(container.offsetWidth - width - 2 * shadowPadding, positionX));
83 var positionY = box.y + Math.max((box.height - height - 2 * shadowPadding) / 2, shadow);
84 positionY = Math.max(shadow, Math.min(container.offsetHeight - height - 2 * shadowPadding, positionY));
85 element.positionAt(positionX, positionY, container);
86 this._dialogHeight = height;
88 this._updateShowMatchingItems();
89 this._viewportControl.refresh();
94 WebInspector.setCurrentFocusElement(this._promptElement);
95 if (this._filteredItems.length && this._viewportControl.lastVisibleIndex() === -1)
96 this._viewportControl.refresh();
103 this._isHiding = true;
104 this._delegate.dispose();
105 if (this._filterTimer)
106 clearTimeout(this._filterTimer);
109 renderAsTwoRows: function()
111 this._renderAsTwoRows = true;
116 if (!this._delegate.itemCount())
118 var selectedIndex = this._shouldShowMatchingItems() && this._selectedIndexInFiltered < this._filteredItems.length ? this._filteredItems[this._selectedIndexInFiltered] : null;
119 this._delegate.selectItem(selectedIndex, this._promptElement.value.trim());
122 _itemsLoaded: function()
125 if (this._loadTimeout)
127 this._loadTimeout = setTimeout(this._updateAfterItemsLoaded.bind(this), 0);
130 _updateAfterItemsLoaded: function()
132 delete this._loadTimeout;
137 * @param {number} index
140 _createItemElement: function(index)
142 var itemElement = createElement("div");
143 itemElement.className = "filtered-item-list-dialog-item " + (this._renderAsTwoRows ? "two-rows" : "one-row");
144 itemElement._titleElement = itemElement.createChild("div", "filtered-item-list-dialog-title");
145 itemElement._subtitleElement = itemElement.createChild("div", "filtered-item-list-dialog-subtitle");
146 itemElement._subtitleElement.textContent = "\u200B";
147 itemElement._index = index;
148 this._delegate.renderItem(index, this._promptElement.value.trim(), itemElement._titleElement, itemElement._subtitleElement);
153 * @param {string} query
155 setQuery: function(query)
157 this._promptElement.value = query;
158 this._scheduleFilter();
161 _filterItems: function()
163 delete this._filterTimer;
164 if (this._scoringTimer) {
165 clearTimeout(this._scoringTimer);
166 delete this._scoringTimer;
169 var query = this._delegate.rewriteQuery(this._promptElement.value.trim());
171 var queryLength = query.length;
172 var filterRegex = query ? WebInspector.FilePathScoreFunction.filterRegex(query) : null;
174 var oldSelectedAbsoluteIndex = this._selectedIndexInFiltered ? this._filteredItems[this._selectedIndexInFiltered] : null;
175 var filteredItems = [];
176 this._selectedIndexInFiltered = 0;
180 var bestItemsToCollect = 100;
181 var minBestScore = 0;
182 var overflowItems = [];
184 scoreItems.call(this, 0);
191 function compareIntegers(a, b)
197 * @param {number} fromIndex
198 * @this {WebInspector.FilteredItemSelectionDialog}
200 function scoreItems(fromIndex)
202 var maxWorkItems = 1000;
204 for (var i = fromIndex; i < this._delegate.itemCount() && workDone < maxWorkItems; ++i) {
205 // Filter out non-matching items quickly.
206 if (filterRegex && !filterRegex.test(this._delegate.itemKeyAt(i)))
210 var score = this._delegate.itemScoreAt(i, query);
214 // Find its index in the scores array (earlier elements have bigger scores).
215 if (score > minBestScore || bestScores.length < bestItemsToCollect) {
216 var index = insertionIndexForObjectInListSortedByFunction(score, bestScores, compareIntegers, true);
217 bestScores.splice(index, 0, score);
218 bestItems.splice(index, 0, i);
219 if (bestScores.length > bestItemsToCollect) {
220 // Best list is too large -> drop last elements.
221 overflowItems.push(bestItems.peekLast());
222 bestScores.length = bestItemsToCollect;
223 bestItems.length = bestItemsToCollect;
225 minBestScore = bestScores.peekLast();
227 filteredItems.push(i);
230 // Process everything in chunks.
231 if (i < this._delegate.itemCount()) {
232 this._scoringTimer = setTimeout(scoreItems.bind(this, i), 0);
235 delete this._scoringTimer;
237 this._filteredItems = bestItems.concat(overflowItems).concat(filteredItems);
238 for (var i = 0; i < this._filteredItems.length; ++i) {
239 if (this._filteredItems[i] === oldSelectedAbsoluteIndex) {
240 this._selectedIndexInFiltered = i;
244 this._viewportControl.invalidate();
246 this._selectedIndexInFiltered = 0;
247 this._updateSelection(this._selectedIndexInFiltered, false);
254 _shouldShowMatchingItems: function()
256 return this._delegate.shouldShowMatchingItems(this._promptElement.value);
259 _onInput: function(event)
261 this._updateShowMatchingItems();
262 this._scheduleFilter();
265 _updateShowMatchingItems: function()
267 var shouldShowMatchingItems = this._shouldShowMatchingItems();
268 this._itemElementsContainer.classList.toggle("hidden", !shouldShowMatchingItems);
269 this.element.style.height = shouldShowMatchingItems ? this._dialogHeight + "px" : "auto";
275 _rowsPerViewport: function()
277 return Math.floor(this._viewportControl.element.clientHeight / this._rowHeight);
280 _onKeyDown: function(event)
282 var newSelectedIndex = this._selectedIndexInFiltered;
284 switch (event.keyCode) {
285 case WebInspector.KeyboardShortcut.Keys.Down.code:
286 if (++newSelectedIndex >= this._filteredItems.length)
287 newSelectedIndex = this._filteredItems.length - 1;
288 this._updateSelection(newSelectedIndex, true);
291 case WebInspector.KeyboardShortcut.Keys.Up.code:
292 if (--newSelectedIndex < 0)
293 newSelectedIndex = 0;
294 this._updateSelection(newSelectedIndex, false);
297 case WebInspector.KeyboardShortcut.Keys.PageDown.code:
298 newSelectedIndex = Math.min(newSelectedIndex + this._rowsPerViewport(), this._filteredItems.length - 1);
299 this._updateSelection(newSelectedIndex, true);
302 case WebInspector.KeyboardShortcut.Keys.PageUp.code:
303 newSelectedIndex = Math.max(newSelectedIndex - this._rowsPerViewport(), 0);
304 this._updateSelection(newSelectedIndex, false);
311 _scheduleFilter: function()
313 if (this._filterTimer)
315 this._filterTimer = setTimeout(this._filterItems.bind(this), 0);
319 * @param {number} index
320 * @param {boolean} makeLast
322 _updateSelection: function(index, makeLast)
324 if (!this._filteredItems.length)
326 var element = this._viewportControl.renderedElementAt(this._selectedIndexInFiltered);
328 element.classList.remove("selected");
329 this._viewportControl.scrollItemIntoView(index, makeLast);
330 this._selectedIndexInFiltered = index;
331 element = this._viewportControl.renderedElementAt(index);
333 element.classList.add("selected");
336 _onClick: function(event)
338 var itemElement = event.target.enclosingNodeOrSelfWithClass("filtered-item-list-dialog-item");
341 this._delegate.selectItem(itemElement._index, this._promptElement.value.trim());
342 WebInspector.Dialog.hide();
348 itemCount: function()
350 return this._filteredItems.length;
354 * @param {number} index
357 fastHeight: function(index)
359 if (!this._rowHeight) {
360 var delegateIndex = this._filteredItems[index];
361 var element = this._createItemElement(delegateIndex);
362 this._rowHeight = WebInspector.measurePreferredSize(element, this._viewportControl.contentElement()).height;
364 return this._rowHeight;
368 * @param {number} index
369 * @return {!WebInspector.ViewportElement}
371 itemElement: function(index)
373 var delegateIndex = this._filteredItems[index];
374 var element = this._createItemElement(delegateIndex);
375 if (index === this._selectedIndexInFiltered)
376 element.classList.add("selected");
377 return new WebInspector.StaticViewportElement(element);
383 minimumRowHeight: function()
385 return this.fastHeight(0);
388 __proto__: WebInspector.DialogDelegate.prototype
394 WebInspector.SelectionDialogContentProvider = function()
398 WebInspector.SelectionDialogContentProvider.prototype = {
400 * @param {function():void} refreshCallback
402 setRefreshCallback: function(refreshCallback)
404 this._refreshCallback = refreshCallback;
408 * @param {string} query
411 shouldShowMatchingItems: function(query)
419 itemCount: function()
425 * @param {number} itemIndex
428 itemKeyAt: function(itemIndex)
434 * @param {number} itemIndex
435 * @param {string} query
438 itemScoreAt: function(itemIndex, query)
444 * @param {number} itemIndex
445 * @param {string} query
446 * @param {!Element} titleElement
447 * @param {!Element} subtitleElement
449 renderItem: function(itemIndex, query, titleElement, subtitleElement)
454 * @param {!Element} element
455 * @param {string} query
458 highlightRanges: function(element, query)
464 * @param {string} text
465 * @param {string} query
466 * @return {?Array.<!WebInspector.SourceRange>}
468 function rangesForMatch(text, query)
470 var sm = new difflib.SequenceMatcher(query, text);
471 var opcodes = sm.get_opcodes();
474 for (var i = 0; i < opcodes.length; ++i) {
475 var opcode = opcodes[i];
476 if (opcode[0] === "equal")
477 ranges.push(new WebInspector.SourceRange(opcode[3], opcode[4] - opcode[3]));
478 else if (opcode[0] !== "insert")
484 var text = element.textContent;
485 var ranges = rangesForMatch(text, query);
487 ranges = rangesForMatch(text.toUpperCase(), query.toUpperCase());
489 WebInspector.highlightRangesWithStyleClass(element, ranges, "highlight");
496 * @param {?number} itemIndex
497 * @param {string} promptValue
499 selectItem: function(itemIndex, promptValue)
505 this._refreshCallback();
509 * @param {string} query
512 rewriteQuery: function(query)
524 * @extends {WebInspector.SelectionDialogContentProvider}
525 * @param {!WebInspector.UISourceCode} uiSourceCode
526 * @param {function(number, number)} selectItemCallback
528 WebInspector.JavaScriptOutlineDialog = function(uiSourceCode, selectItemCallback)
530 WebInspector.SelectionDialogContentProvider.call(this);
532 this._functionItems = [];
533 this._selectItemCallback = selectItemCallback;
534 this._outlineWorker = Runtime.startWorker("script_formatter_worker");
535 this._outlineWorker.onmessage = this._didBuildOutlineChunk.bind(this);
536 this._outlineWorker.postMessage({ method: "javaScriptOutline", params: { content: uiSourceCode.workingCopy() } });
540 * @param {!WebInspector.View} view
541 * @param {!WebInspector.UISourceCode} uiSourceCode
542 * @param {function(number, number)} selectItemCallback
544 WebInspector.JavaScriptOutlineDialog.show = function(view, uiSourceCode, selectItemCallback)
546 if (WebInspector.Dialog.currentInstance())
548 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.JavaScriptOutlineDialog(uiSourceCode, selectItemCallback));
549 WebInspector.Dialog.show(view.element, filteredItemSelectionDialog);
552 WebInspector.JavaScriptOutlineDialog.prototype = {
554 * @param {!MessageEvent} event
556 _didBuildOutlineChunk: function(event)
558 var data = /** @type {!WebInspector.JavaScriptOutlineDialog.MessageEventData} */ (event.data);
559 var chunk = data.chunk;
560 for (var i = 0; i < chunk.length; ++i)
561 this._functionItems.push(chunk[i]);
563 if (data.total === data.index + 1)
572 itemCount: function()
574 return this._functionItems.length;
578 * @param {number} itemIndex
581 itemKeyAt: function(itemIndex)
583 return this._functionItems[itemIndex].name;
587 * @param {number} itemIndex
588 * @param {string} query
591 itemScoreAt: function(itemIndex, query)
593 var item = this._functionItems[itemIndex];
598 * @param {number} itemIndex
599 * @param {string} query
600 * @param {!Element} titleElement
601 * @param {!Element} subtitleElement
603 renderItem: function(itemIndex, query, titleElement, subtitleElement)
605 var item = this._functionItems[itemIndex];
606 titleElement.textContent = item.name + (item.arguments ? item.arguments : "");
607 this.highlightRanges(titleElement, query);
608 subtitleElement.textContent = ":" + (item.line + 1);
612 * @param {?number} itemIndex
613 * @param {string} promptValue
615 selectItem: function(itemIndex, promptValue)
617 if (itemIndex === null)
619 var lineNumber = this._functionItems[itemIndex].line;
620 if (!isNaN(lineNumber) && lineNumber >= 0)
621 this._selectItemCallback(lineNumber, this._functionItems[itemIndex].column);
626 if (this._outlineWorker) {
627 this._outlineWorker.terminate();
628 delete this._outlineWorker;
632 __proto__: WebInspector.SelectionDialogContentProvider.prototype
637 * @extends {WebInspector.SelectionDialogContentProvider}
638 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
640 WebInspector.SelectUISourceCodeDialog = function(defaultScores)
642 WebInspector.SelectionDialogContentProvider.call(this);
645 this._defaultScores = defaultScores;
646 this._scorer = new WebInspector.FilePathScoreFunction("");
647 WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
648 WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
651 WebInspector.SelectUISourceCodeDialog.prototype = {
652 _projectRemoved: function(event)
654 var project = /** @type {!WebInspector.Project} */ (event.data);
655 this._populate(project);
660 * @param {!WebInspector.Project=} skipProject
662 _populate: function(skipProject)
664 /** @type {!Array.<!WebInspector.UISourceCode>} */
665 this._uiSourceCodes = [];
666 var projects = WebInspector.workspace.projects().filter(this.filterProject.bind(this));
667 for (var i = 0; i < projects.length; ++i) {
668 if (skipProject && projects[i] === skipProject)
670 this._uiSourceCodes = this._uiSourceCodes.concat(projects[i].uiSourceCodes());
675 * @param {?WebInspector.UISourceCode} uiSourceCode
676 * @param {number=} lineNumber
677 * @param {number=} columnNumber
679 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
681 // Overridden by subclasses
685 * @param {!WebInspector.Project} project
688 filterProject: function(project)
691 // Overridden by subclasses
697 itemCount: function()
699 return this._uiSourceCodes.length;
703 * @param {number} itemIndex
706 itemKeyAt: function(itemIndex)
708 return this._uiSourceCodes[itemIndex].fullDisplayName();
712 * @param {number} itemIndex
713 * @param {string} query
716 itemScoreAt: function(itemIndex, query)
718 var uiSourceCode = this._uiSourceCodes[itemIndex];
719 var score = this._defaultScores ? (this._defaultScores.get(uiSourceCode) || 0) : 0;
720 if (!query || query.length < 2)
723 if (this._query !== query) {
725 this._scorer = new WebInspector.FilePathScoreFunction(query);
728 var path = uiSourceCode.fullDisplayName();
729 return score + 10 * this._scorer.score(path, null);
733 * @param {number} itemIndex
734 * @param {string} query
735 * @param {!Element} titleElement
736 * @param {!Element} subtitleElement
737 * @return {!Array.<!Element>}
739 renderItem: function(itemIndex, query, titleElement, subtitleElement)
741 query = this.rewriteQuery(query);
742 var uiSourceCode = this._uiSourceCodes[itemIndex];
743 titleElement.textContent = uiSourceCode.displayName() + (this._queryLineNumberAndColumnNumber || "");
744 subtitleElement.textContent = uiSourceCode.fullDisplayName().trimEnd(100);
747 var score = new WebInspector.FilePathScoreFunction(query).score(subtitleElement.textContent, indexes);
748 var fileNameIndex = subtitleElement.textContent.lastIndexOf("/");
750 for (var i = 0; i < indexes.length; ++i)
751 ranges.push({offset: indexes[i], length: 1});
752 if (indexes[0] > fileNameIndex) {
753 for (var i = 0; i < ranges.length; ++i)
754 ranges[i].offset -= fileNameIndex + 1;
755 return WebInspector.highlightRangesWithStyleClass(titleElement, ranges, "highlight");
757 return WebInspector.highlightRangesWithStyleClass(subtitleElement, ranges, "highlight");
762 * @param {?number} itemIndex
763 * @param {string} promptValue
765 selectItem: function(itemIndex, promptValue)
767 var parsedExpression = promptValue.trim().match(/^([^:]*)(:\d+)?(:\d+)?$/);
768 if (!parsedExpression)
773 if (parsedExpression[2])
774 lineNumber = parseInt(parsedExpression[2].substr(1), 10) - 1;
775 if (parsedExpression[3])
776 columnNumber = parseInt(parsedExpression[3].substr(1), 10) - 1;
777 var uiSourceCode = itemIndex !== null ? this._uiSourceCodes[itemIndex] : null;
778 this.uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber);
782 * @param {string} query
785 rewriteQuery: function(query)
789 query = query.trim();
790 var lineNumberMatch = query.match(/^([^:]+)((?::[^:]*){0,2})$/);
791 this._queryLineNumberAndColumnNumber = lineNumberMatch ? lineNumberMatch[2] : "";
792 return lineNumberMatch ? lineNumberMatch[1] : query;
796 * @param {!WebInspector.Event} event
798 _uiSourceCodeAdded: function(event)
800 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
801 if (!this.filterProject(uiSourceCode.project()))
803 this._uiSourceCodes.push(uiSourceCode)
809 WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
810 WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
813 __proto__: WebInspector.SelectionDialogContentProvider.prototype
818 * @extends {WebInspector.SelectUISourceCodeDialog}
819 * @param {!WebInspector.SourcesView} sourcesView
820 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
822 WebInspector.OpenResourceDialog = function(sourcesView, defaultScores)
824 WebInspector.SelectUISourceCodeDialog.call(this, defaultScores);
825 this._sourcesView = sourcesView;
828 WebInspector.OpenResourceDialog.prototype = {
831 * @param {?WebInspector.UISourceCode} uiSourceCode
832 * @param {number=} lineNumber
833 * @param {number=} columnNumber
835 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
838 uiSourceCode = this._sourcesView.currentUISourceCode();
841 this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
845 * @param {string} query
848 shouldShowMatchingItems: function(query)
850 return !query.startsWith(":");
854 * @param {!WebInspector.Project} project
857 filterProject: function(project)
859 return !project.isServiceProject();
862 __proto__: WebInspector.SelectUISourceCodeDialog.prototype
866 * @param {!WebInspector.SourcesView} sourcesView
867 * @param {!Element} relativeToElement
868 * @param {string=} query
869 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
871 WebInspector.OpenResourceDialog.show = function(sourcesView, relativeToElement, query, defaultScores)
873 if (WebInspector.Dialog.currentInstance())
876 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.OpenResourceDialog(sourcesView, defaultScores));
877 filteredItemSelectionDialog.renderAsTwoRows();
878 WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
880 filteredItemSelectionDialog.setQuery(query);
885 * @extends {WebInspector.SelectUISourceCodeDialog}
886 * @param {!Array.<string>} types
887 * @param {function(!WebInspector.UISourceCode)} callback
889 WebInspector.SelectUISourceCodeForProjectTypesDialog = function(types, callback)
892 WebInspector.SelectUISourceCodeDialog.call(this);
893 this._callback = callback;
896 WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype = {
898 * @param {!WebInspector.UISourceCode} uiSourceCode
899 * @param {number=} lineNumber
900 * @param {number=} columnNumber
902 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
904 this._callback(uiSourceCode);
908 * @param {!WebInspector.Project} project
911 filterProject: function(project)
913 return this._types.indexOf(project.type()) !== -1;
916 __proto__: WebInspector.SelectUISourceCodeDialog.prototype
920 * @param {string} name
921 * @param {!Array.<string>} types
922 * @param {function(!WebInspector.UISourceCode)} callback
923 * @param {!Element} relativeToElement
925 WebInspector.SelectUISourceCodeForProjectTypesDialog.show = function(name, types, callback, relativeToElement)
927 if (WebInspector.Dialog.currentInstance())
930 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types, callback));
931 filteredItemSelectionDialog.setQuery(name);
932 filteredItemSelectionDialog.renderAsTwoRows();
933 WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
937 * @typedef {{index: number, total: number, chunk: !Array.<!{selectorText: string, lineNumber: number, columnNumber: number}>}}
939 WebInspector.JavaScriptOutlineDialog.MessageEventData;