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 if (!WebInspector.FilteredItemSelectionDialog._stylesLoaded) {
42 WebInspector.View.createStyleElement("filteredItemSelectionDialog.css");
43 WebInspector.FilteredItemSelectionDialog._stylesLoaded = true;
46 this.element = document.createElement("div");
47 this.element.className = "filtered-item-list-dialog";
48 this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
50 this._promptElement = this.element.createChild("input", "monospace");
51 this._promptElement.addEventListener("input", this._onInput.bind(this), false);
52 this._promptElement.type = "text";
53 this._promptElement.setAttribute("spellcheck", "false");
55 this._filteredItems = [];
56 this._viewportControl = new WebInspector.ViewportControl(this);
57 this._itemElementsContainer = this._viewportControl.element;
58 this._itemElementsContainer.classList.add("container");
59 this._itemElementsContainer.classList.add("monospace");
60 this._itemElementsContainer.addEventListener("click", this._onClick.bind(this), false);
61 this.element.appendChild(this._itemElementsContainer);
63 this._delegate = delegate;
64 this._delegate.setRefreshCallback(this._itemsLoaded.bind(this));
68 WebInspector.FilteredItemSelectionDialog.prototype = {
70 * @param {!Element} element
71 * @param {!Element} relativeToElement
73 position: function(element, relativeToElement)
76 const shadowPadding = 20; // shadow + padding
77 var container = WebInspector.Dialog.modalHostView().element;
78 var preferredWidth = Math.max(relativeToElement.offsetWidth * 2 / 3, 500);
79 var width = Math.min(preferredWidth, container.offsetWidth - 2 * shadowPadding);
80 var preferredHeight = Math.max(relativeToElement.offsetHeight * 2 / 3, 204);
81 var height = Math.min(preferredHeight, container.offsetHeight - 2 * shadowPadding);
83 this.element.style.width = width + "px";
84 var box = relativeToElement.boxInWindow(window).relativeToElement(container);
85 var positionX = box.x + Math.max((box.width - width - 2 * shadowPadding) / 2, shadow);
86 positionX = Math.max(shadow, Math.min(container.offsetWidth - width - 2 * shadowPadding, positionX));
87 var positionY = box.y + Math.max((box.height - height - 2 * shadowPadding) / 2, shadow);
88 positionY = Math.max(shadow, Math.min(container.offsetHeight - height - 2 * shadowPadding, positionY));
89 element.positionAt(positionX, positionY, container);
90 this._dialogHeight = height;
92 this._updateShowMatchingItems();
93 this._viewportControl.refresh();
98 WebInspector.setCurrentFocusElement(this._promptElement);
99 if (this._filteredItems.length && this._viewportControl.lastVisibleIndex() === -1)
100 this._viewportControl.refresh();
107 this._isHiding = true;
108 this._delegate.dispose();
109 if (this._filterTimer)
110 clearTimeout(this._filterTimer);
113 renderAsTwoRows: function()
115 this._renderAsTwoRows = true;
120 if (!this._delegate.itemCount())
122 var selectedIndex = this._shouldShowMatchingItems() && this._selectedIndexInFiltered < this._filteredItems.length ? this._filteredItems[this._selectedIndexInFiltered] : null;
123 this._delegate.selectItem(selectedIndex, this._promptElement.value.trim());
126 _itemsLoaded: function()
129 if (this._loadTimeout)
131 this._loadTimeout = setTimeout(this._updateAfterItemsLoaded.bind(this), 0);
134 _updateAfterItemsLoaded: function()
136 delete this._loadTimeout;
141 * @param {number} index
144 _createItemElement: function(index)
146 var itemElement = document.createElement("div");
147 itemElement.className = "filtered-item-list-dialog-item " + (this._renderAsTwoRows ? "two-rows" : "one-row");
148 itemElement._titleElement = itemElement.createChild("div", "filtered-item-list-dialog-title");
149 itemElement._subtitleElement = itemElement.createChild("div", "filtered-item-list-dialog-subtitle");
150 itemElement._subtitleElement.textContent = "\u200B";
151 itemElement._index = index;
152 this._delegate.renderItem(index, this._promptElement.value.trim(), itemElement._titleElement, itemElement._subtitleElement);
157 * @param {string} query
159 setQuery: function(query)
161 this._promptElement.value = query;
162 this._scheduleFilter();
165 _filterItems: function()
167 delete this._filterTimer;
168 if (this._scoringTimer) {
169 clearTimeout(this._scoringTimer);
170 delete this._scoringTimer;
173 var query = this._delegate.rewriteQuery(this._promptElement.value.trim());
175 var queryLength = query.length;
176 var filterRegex = query ? WebInspector.FilePathScoreFunction.filterRegex(query) : null;
178 var oldSelectedAbsoluteIndex = this._selectedIndexInFiltered ? this._filteredItems[this._selectedIndexInFiltered] : null;
179 var filteredItems = [];
180 this._selectedIndexInFiltered = 0;
184 var bestItemsToCollect = 100;
185 var minBestScore = 0;
186 var overflowItems = [];
188 scoreItems.call(this, 0);
195 function compareIntegers(a, b)
201 * @param {number} fromIndex
202 * @this {WebInspector.FilteredItemSelectionDialog}
204 function scoreItems(fromIndex)
206 var maxWorkItems = 1000;
208 for (var i = fromIndex; i < this._delegate.itemCount() && workDone < maxWorkItems; ++i) {
209 // Filter out non-matching items quickly.
210 if (filterRegex && !filterRegex.test(this._delegate.itemKeyAt(i)))
214 var score = this._delegate.itemScoreAt(i, query);
218 // Find its index in the scores array (earlier elements have bigger scores).
219 if (score > minBestScore || bestScores.length < bestItemsToCollect) {
220 var index = insertionIndexForObjectInListSortedByFunction(score, bestScores, compareIntegers, true);
221 bestScores.splice(index, 0, score);
222 bestItems.splice(index, 0, i);
223 if (bestScores.length > bestItemsToCollect) {
224 // Best list is too large -> drop last elements.
225 overflowItems.push(bestItems.peekLast());
226 bestScores.length = bestItemsToCollect;
227 bestItems.length = bestItemsToCollect;
229 minBestScore = bestScores.peekLast();
231 filteredItems.push(i);
234 // Process everything in chunks.
235 if (i < this._delegate.itemCount()) {
236 this._scoringTimer = setTimeout(scoreItems.bind(this, i), 0);
239 delete this._scoringTimer;
241 this._filteredItems = bestItems.concat(overflowItems).concat(filteredItems);
242 for (var i = 0; i < this._filteredItems.length; ++i) {
243 if (this._filteredItems[i] === oldSelectedAbsoluteIndex) {
244 this._selectedIndexInFiltered = i;
248 this._viewportControl.invalidate();
250 this._selectedIndexInFiltered = 0;
251 this._updateSelection(this._selectedIndexInFiltered, false);
258 _shouldShowMatchingItems: function()
260 return this._delegate.shouldShowMatchingItems(this._promptElement.value);
263 _onInput: function(event)
265 this._updateShowMatchingItems();
266 this._scheduleFilter();
269 _updateShowMatchingItems: function()
271 var shouldShowMatchingItems = this._shouldShowMatchingItems();
272 this._itemElementsContainer.classList.toggle("hidden", !shouldShowMatchingItems);
273 this.element.style.height = shouldShowMatchingItems ? this._dialogHeight + "px" : "auto";
279 _rowsPerViewport: function()
281 return Math.floor(this._viewportControl.element.clientHeight / this._rowHeight);
284 _onKeyDown: function(event)
286 var newSelectedIndex = this._selectedIndexInFiltered;
288 switch (event.keyCode) {
289 case WebInspector.KeyboardShortcut.Keys.Down.code:
290 if (++newSelectedIndex >= this._filteredItems.length)
291 newSelectedIndex = this._filteredItems.length - 1;
292 this._updateSelection(newSelectedIndex, true);
295 case WebInspector.KeyboardShortcut.Keys.Up.code:
296 if (--newSelectedIndex < 0)
297 newSelectedIndex = 0;
298 this._updateSelection(newSelectedIndex, false);
301 case WebInspector.KeyboardShortcut.Keys.PageDown.code:
302 newSelectedIndex = Math.min(newSelectedIndex + this._rowsPerViewport(), this._filteredItems.length - 1);
303 this._updateSelection(newSelectedIndex, true);
306 case WebInspector.KeyboardShortcut.Keys.PageUp.code:
307 newSelectedIndex = Math.max(newSelectedIndex - this._rowsPerViewport(), 0);
308 this._updateSelection(newSelectedIndex, false);
315 _scheduleFilter: function()
317 if (this._filterTimer)
319 this._filterTimer = setTimeout(this._filterItems.bind(this), 0);
323 * @param {number} index
324 * @param {boolean} makeLast
326 _updateSelection: function(index, makeLast)
328 if (!this._filteredItems.length)
330 var element = this._viewportControl.renderedElementAt(this._selectedIndexInFiltered);
332 element.classList.remove("selected");
333 this._viewportControl.scrollItemIntoView(index, makeLast);
334 this._selectedIndexInFiltered = index;
335 element = this._viewportControl.renderedElementAt(index);
337 element.classList.add("selected");
340 _onClick: function(event)
342 var itemElement = event.target.enclosingNodeOrSelfWithClass("filtered-item-list-dialog-item");
345 this._delegate.selectItem(itemElement._index, this._promptElement.value.trim());
346 WebInspector.Dialog.hide();
352 itemCount: function()
354 return this._filteredItems.length;
358 * @param {number} index
361 fastHeight: function(index)
363 if (!this._rowHeight) {
364 var delegateIndex = this._filteredItems[index];
365 var element = this._createItemElement(delegateIndex);
366 this._rowHeight = element.measurePreferredSize(this._viewportControl.contentElement()).height;
368 return this._rowHeight;
372 * @param {number} index
373 * @return {!WebInspector.ViewportElement}
375 itemElement: function(index)
377 var delegateIndex = this._filteredItems[index];
378 var element = this._createItemElement(delegateIndex);
379 if (index === this._selectedIndexInFiltered)
380 element.classList.add("selected");
381 return new WebInspector.StaticViewportElement(element);
387 minimumRowHeight: function()
389 return this.fastHeight(0);
392 __proto__: WebInspector.DialogDelegate.prototype
398 WebInspector.SelectionDialogContentProvider = function()
402 WebInspector.SelectionDialogContentProvider.prototype = {
404 * @param {function():void} refreshCallback
406 setRefreshCallback: function(refreshCallback)
408 this._refreshCallback = refreshCallback;
412 * @param {string} query
415 shouldShowMatchingItems: function(query)
423 itemCount: function()
429 * @param {number} itemIndex
432 itemKeyAt: function(itemIndex)
438 * @param {number} itemIndex
439 * @param {string} query
442 itemScoreAt: function(itemIndex, query)
448 * @param {number} itemIndex
449 * @param {string} query
450 * @param {!Element} titleElement
451 * @param {!Element} subtitleElement
453 renderItem: function(itemIndex, query, titleElement, subtitleElement)
458 * @param {!Element} element
459 * @param {string} query
462 highlightRanges: function(element, query)
468 * @param {string} text
469 * @param {string} query
470 * @return {?Array.<!WebInspector.SourceRange>}
472 function rangesForMatch(text, query)
474 var sm = new difflib.SequenceMatcher(query, text);
475 var opcodes = sm.get_opcodes();
478 for (var i = 0; i < opcodes.length; ++i) {
479 var opcode = opcodes[i];
480 if (opcode[0] === "equal")
481 ranges.push(new WebInspector.SourceRange(opcode[3], opcode[4] - opcode[3]));
482 else if (opcode[0] !== "insert")
488 var text = element.textContent;
489 var ranges = rangesForMatch(text, query);
491 ranges = rangesForMatch(text.toUpperCase(), query.toUpperCase());
493 WebInspector.highlightRangesWithStyleClass(element, ranges, "highlight");
500 * @param {?number} itemIndex
501 * @param {string} promptValue
503 selectItem: function(itemIndex, promptValue)
509 this._refreshCallback();
513 * @param {string} query
516 rewriteQuery: function(query)
528 * @extends {WebInspector.SelectionDialogContentProvider}
529 * @param {!WebInspector.UISourceCode} uiSourceCode
530 * @param {function(number, number)} selectItemCallback
532 WebInspector.JavaScriptOutlineDialog = function(uiSourceCode, selectItemCallback)
534 WebInspector.SelectionDialogContentProvider.call(this);
536 this._functionItems = [];
537 this._selectItemCallback = selectItemCallback;
538 this._outlineWorker = Runtime.startWorker("script_formatter_worker");
539 this._outlineWorker.onmessage = this._didBuildOutlineChunk.bind(this);
540 this._outlineWorker.postMessage({ method: "javaScriptOutline", params: { content: uiSourceCode.workingCopy() } });
544 * @param {!WebInspector.View} view
545 * @param {!WebInspector.UISourceCode} uiSourceCode
546 * @param {function(number, number)} selectItemCallback
548 WebInspector.JavaScriptOutlineDialog.show = function(view, uiSourceCode, selectItemCallback)
550 if (WebInspector.Dialog.currentInstance())
552 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.JavaScriptOutlineDialog(uiSourceCode, selectItemCallback));
553 WebInspector.Dialog.show(view.element, filteredItemSelectionDialog);
556 WebInspector.JavaScriptOutlineDialog.prototype = {
558 * @param {!MessageEvent} event
560 _didBuildOutlineChunk: function(event)
562 var data = /** @type {!WebInspector.JavaScriptOutlineDialog.MessageEventData} */ (event.data);
563 var chunk = data.chunk;
564 for (var i = 0; i < chunk.length; ++i)
565 this._functionItems.push(chunk[i]);
567 if (data.total === data.index + 1)
576 itemCount: function()
578 return this._functionItems.length;
582 * @param {number} itemIndex
585 itemKeyAt: function(itemIndex)
587 return this._functionItems[itemIndex].name;
591 * @param {number} itemIndex
592 * @param {string} query
595 itemScoreAt: function(itemIndex, query)
597 var item = this._functionItems[itemIndex];
602 * @param {number} itemIndex
603 * @param {string} query
604 * @param {!Element} titleElement
605 * @param {!Element} subtitleElement
607 renderItem: function(itemIndex, query, titleElement, subtitleElement)
609 var item = this._functionItems[itemIndex];
610 titleElement.textContent = item.name + (item.arguments ? item.arguments : "");
611 this.highlightRanges(titleElement, query);
612 subtitleElement.textContent = ":" + (item.line + 1);
616 * @param {?number} itemIndex
617 * @param {string} promptValue
619 selectItem: function(itemIndex, promptValue)
621 if (itemIndex === null)
623 var lineNumber = this._functionItems[itemIndex].line;
624 if (!isNaN(lineNumber) && lineNumber >= 0)
625 this._selectItemCallback(lineNumber, this._functionItems[itemIndex].column);
630 if (this._outlineWorker) {
631 this._outlineWorker.terminate();
632 delete this._outlineWorker;
636 __proto__: WebInspector.SelectionDialogContentProvider.prototype
641 * @extends {WebInspector.SelectionDialogContentProvider}
642 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
644 WebInspector.SelectUISourceCodeDialog = function(defaultScores)
646 WebInspector.SelectionDialogContentProvider.call(this);
649 this._defaultScores = defaultScores;
650 this._scorer = new WebInspector.FilePathScoreFunction("");
651 WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
652 WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
655 WebInspector.SelectUISourceCodeDialog.prototype = {
656 _projectRemoved: function(event)
658 var project = /** @type {!WebInspector.Project} */ (event.data);
659 this._populate(project);
664 * @param {!WebInspector.Project=} skipProject
666 _populate: function(skipProject)
668 /** @type {!Array.<!WebInspector.UISourceCode>} */
669 this._uiSourceCodes = [];
670 var projects = WebInspector.workspace.projects().filter(this.filterProject.bind(this));
671 for (var i = 0; i < projects.length; ++i) {
672 if (skipProject && projects[i] === skipProject)
674 this._uiSourceCodes = this._uiSourceCodes.concat(projects[i].uiSourceCodes());
679 * @param {?WebInspector.UISourceCode} uiSourceCode
680 * @param {number=} lineNumber
681 * @param {number=} columnNumber
683 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
685 // Overridden by subclasses
689 * @param {!WebInspector.Project} project
692 filterProject: function(project)
695 // Overridden by subclasses
701 itemCount: function()
703 return this._uiSourceCodes.length;
707 * @param {number} itemIndex
710 itemKeyAt: function(itemIndex)
712 return this._uiSourceCodes[itemIndex].fullDisplayName();
716 * @param {number} itemIndex
717 * @param {string} query
720 itemScoreAt: function(itemIndex, query)
722 var uiSourceCode = this._uiSourceCodes[itemIndex];
723 var score = this._defaultScores ? (this._defaultScores.get(uiSourceCode) || 0) : 0;
724 if (!query || query.length < 2)
727 if (this._query !== query) {
729 this._scorer = new WebInspector.FilePathScoreFunction(query);
732 var path = uiSourceCode.fullDisplayName();
733 return score + 10 * this._scorer.score(path, null);
737 * @param {number} itemIndex
738 * @param {string} query
739 * @param {!Element} titleElement
740 * @param {!Element} subtitleElement
741 * @return {!Array.<!Element>}
743 renderItem: function(itemIndex, query, titleElement, subtitleElement)
745 query = this.rewriteQuery(query);
746 var uiSourceCode = this._uiSourceCodes[itemIndex];
747 titleElement.textContent = uiSourceCode.displayName() + (this._queryLineNumberAndColumnNumber || "");
748 subtitleElement.textContent = uiSourceCode.fullDisplayName().trimEnd(100);
751 var score = new WebInspector.FilePathScoreFunction(query).score(subtitleElement.textContent, indexes);
752 var fileNameIndex = subtitleElement.textContent.lastIndexOf("/");
754 for (var i = 0; i < indexes.length; ++i)
755 ranges.push({offset: indexes[i], length: 1});
756 if (indexes[0] > fileNameIndex) {
757 for (var i = 0; i < ranges.length; ++i)
758 ranges[i].offset -= fileNameIndex + 1;
759 return WebInspector.highlightRangesWithStyleClass(titleElement, ranges, "highlight");
761 return WebInspector.highlightRangesWithStyleClass(subtitleElement, ranges, "highlight");
766 * @param {?number} itemIndex
767 * @param {string} promptValue
769 selectItem: function(itemIndex, promptValue)
771 var parsedExpression = promptValue.trim().match(/^([^:]*)(:\d+)?(:\d+)?$/);
772 if (!parsedExpression)
777 if (parsedExpression[2])
778 lineNumber = parseInt(parsedExpression[2].substr(1), 10) - 1;
779 if (parsedExpression[3])
780 columnNumber = parseInt(parsedExpression[3].substr(1), 10) - 1;
781 var uiSourceCode = itemIndex !== null ? this._uiSourceCodes[itemIndex] : null;
782 this.uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber);
786 * @param {string} query
789 rewriteQuery: function(query)
793 query = query.trim();
794 var lineNumberMatch = query.match(/^([^:]+)((?::[^:]*){0,2})$/);
795 this._queryLineNumberAndColumnNumber = lineNumberMatch ? lineNumberMatch[2] : "";
796 return lineNumberMatch ? lineNumberMatch[1] : query;
800 * @param {!WebInspector.Event} event
802 _uiSourceCodeAdded: function(event)
804 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
805 if (!this.filterProject(uiSourceCode.project()))
807 this._uiSourceCodes.push(uiSourceCode)
813 WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
814 WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
817 __proto__: WebInspector.SelectionDialogContentProvider.prototype
822 * @extends {WebInspector.SelectUISourceCodeDialog}
823 * @param {!WebInspector.SourcesView} sourcesView
824 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
826 WebInspector.OpenResourceDialog = function(sourcesView, defaultScores)
828 WebInspector.SelectUISourceCodeDialog.call(this, defaultScores);
829 this._sourcesView = sourcesView;
832 WebInspector.OpenResourceDialog.prototype = {
835 * @param {?WebInspector.UISourceCode} uiSourceCode
836 * @param {number=} lineNumber
837 * @param {number=} columnNumber
839 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
842 uiSourceCode = this._sourcesView.currentUISourceCode();
845 this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
849 * @param {string} query
852 shouldShowMatchingItems: function(query)
854 return !query.startsWith(":");
858 * @param {!WebInspector.Project} project
861 filterProject: function(project)
863 return !project.isServiceProject();
866 __proto__: WebInspector.SelectUISourceCodeDialog.prototype
870 * @param {!WebInspector.SourcesView} sourcesView
871 * @param {!Element} relativeToElement
872 * @param {string=} query
873 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
875 WebInspector.OpenResourceDialog.show = function(sourcesView, relativeToElement, query, defaultScores)
877 if (WebInspector.Dialog.currentInstance())
880 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.OpenResourceDialog(sourcesView, defaultScores));
881 filteredItemSelectionDialog.renderAsTwoRows();
882 WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
884 filteredItemSelectionDialog.setQuery(query);
889 * @extends {WebInspector.SelectUISourceCodeDialog}
890 * @param {!Array.<string>} types
891 * @param {function(!WebInspector.UISourceCode)} callback
893 WebInspector.SelectUISourceCodeForProjectTypesDialog = function(types, callback)
896 WebInspector.SelectUISourceCodeDialog.call(this);
897 this._callback = callback;
900 WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype = {
902 * @param {!WebInspector.UISourceCode} uiSourceCode
903 * @param {number=} lineNumber
904 * @param {number=} columnNumber
906 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
908 this._callback(uiSourceCode);
912 * @param {!WebInspector.Project} project
915 filterProject: function(project)
917 return this._types.indexOf(project.type()) !== -1;
920 __proto__: WebInspector.SelectUISourceCodeDialog.prototype
924 * @param {string} name
925 * @param {!Array.<string>} types
926 * @param {function(!WebInspector.UISourceCode)} callback
927 * @param {!Element} relativeToElement
929 WebInspector.SelectUISourceCodeForProjectTypesDialog.show = function(name, types, callback, relativeToElement)
931 if (WebInspector.Dialog.currentInstance())
934 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types, callback));
935 filteredItemSelectionDialog.setQuery(name);
936 filteredItemSelectionDialog.renderAsTwoRows();
937 WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
941 * @typedef {{index: number, total: number, chunk: !Array.<!{selectorText: string, lineNumber: number, columnNumber: number}>}}
943 WebInspector.JavaScriptOutlineDialog.MessageEventData;