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._viewportControl.element.classList.add("fill");
58 this._itemElementsContainer = this._viewportControl.element;
59 this._itemElementsContainer.classList.add("container");
60 this._itemElementsContainer.classList.add("monospace");
61 this._itemElementsContainer.addEventListener("click", this._onClick.bind(this), false);
62 this.element.appendChild(this._itemElementsContainer);
64 this._delegate = delegate;
65 this._delegate.setRefreshCallback(this._itemsLoaded.bind(this));
69 WebInspector.FilteredItemSelectionDialog.prototype = {
71 * @param {!Element} element
72 * @param {!Element} relativeToElement
74 position: function(element, relativeToElement)
77 const shadowPadding = 20; // shadow + padding
78 var container = WebInspector.Dialog.modalHostView().element;
79 var preferredWidth = Math.max(relativeToElement.offsetWidth * 2 / 3, 500);
80 var width = Math.min(preferredWidth, container.offsetWidth - 2 * shadowPadding);
81 var preferredHeight = Math.max(relativeToElement.offsetHeight * 2 / 3, 204);
82 var height = Math.min(preferredHeight, container.offsetHeight - 2 * shadowPadding);
84 this.element.style.width = width + "px";
85 var box = relativeToElement.boxInWindow(window).relativeToElement(container);
86 var positionX = box.x + Math.max((box.width - width - 2 * shadowPadding) / 2, shadow);
87 positionX = Math.max(shadow, Math.min(container.offsetWidth - width - 2 * shadowPadding, positionX));
88 var positionY = box.y + Math.max((box.height - height - 2 * shadowPadding) / 2, shadow);
89 positionY = Math.max(shadow, Math.min(container.offsetHeight - height - 2 * shadowPadding, positionY));
90 element.positionAt(positionX, positionY, container);
91 this._dialogHeight = height;
93 this._updateShowMatchingItems();
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 var element = this._viewportControl.renderedElementAt(this._selectedIndexInFiltered);
330 element.classList.remove("selected");
331 this._viewportControl.scrollItemIntoView(index, makeLast);
332 this._selectedIndexInFiltered = index;
333 element = this._viewportControl.renderedElementAt(index);
335 element.classList.add("selected");
338 _onClick: function(event)
340 var itemElement = event.target.enclosingNodeOrSelfWithClass("filtered-item-list-dialog-item");
343 this._delegate.selectItem(itemElement._index, this._promptElement.value.trim());
344 WebInspector.Dialog.hide();
350 itemCount: function()
352 return this._filteredItems.length;
356 * @param {number} index
359 fastHeight: function(index)
361 if (!this._rowHeight) {
362 var delegateIndex = this._filteredItems[index];
363 var element = this._createItemElement(delegateIndex);
364 this._rowHeight = element.measurePreferredSize(this._viewportControl.contentElement()).height;
366 return this._rowHeight;
370 * @param {number} index
371 * @return {!WebInspector.ViewportElement}
373 itemElement: function(index)
375 var delegateIndex = this._filteredItems[index];
376 var element = this._createItemElement(delegateIndex);
377 if (index === this._selectedIndexInFiltered)
378 element.classList.add("selected");
379 return new WebInspector.StaticViewportElement(element);
385 minimumRowHeight: function()
387 return this.fastHeight(0);
390 __proto__: WebInspector.DialogDelegate.prototype
396 WebInspector.SelectionDialogContentProvider = function()
400 WebInspector.SelectionDialogContentProvider.prototype = {
402 * @param {function():void} refreshCallback
404 setRefreshCallback: function(refreshCallback)
406 this._refreshCallback = refreshCallback;
410 * @param {string} query
413 shouldShowMatchingItems: function(query)
421 itemCount: function()
427 * @param {number} itemIndex
430 itemKeyAt: function(itemIndex)
436 * @param {number} itemIndex
437 * @param {string} query
440 itemScoreAt: function(itemIndex, query)
446 * @param {number} itemIndex
447 * @param {string} query
448 * @param {!Element} titleElement
449 * @param {!Element} subtitleElement
451 renderItem: function(itemIndex, query, titleElement, subtitleElement)
456 * @param {!Element} element
457 * @param {string} query
460 highlightRanges: function(element, query)
466 * @param {string} text
467 * @param {string} query
468 * @return {?Array.<!WebInspector.SourceRange>}
470 function rangesForMatch(text, query)
472 var sm = new difflib.SequenceMatcher(query, text);
473 var opcodes = sm.get_opcodes();
476 for (var i = 0; i < opcodes.length; ++i) {
477 var opcode = opcodes[i];
478 if (opcode[0] === "equal")
479 ranges.push(new WebInspector.SourceRange(opcode[3], opcode[4] - opcode[3]));
480 else if (opcode[0] !== "insert")
486 var text = element.textContent;
487 var ranges = rangesForMatch(text, query);
489 ranges = rangesForMatch(text.toUpperCase(), query.toUpperCase());
491 WebInspector.highlightRangesWithStyleClass(element, ranges, "highlight");
498 * @param {?number} itemIndex
499 * @param {string} promptValue
501 selectItem: function(itemIndex, promptValue)
507 this._refreshCallback();
511 * @param {string} query
514 rewriteQuery: function(query)
526 * @extends {WebInspector.SelectionDialogContentProvider}
527 * @param {!WebInspector.UISourceCode} uiSourceCode
528 * @param {function(number, number)} selectItemCallback
530 WebInspector.JavaScriptOutlineDialog = function(uiSourceCode, selectItemCallback)
532 WebInspector.SelectionDialogContentProvider.call(this);
534 this._functionItems = [];
535 this._selectItemCallback = selectItemCallback;
536 this._outlineWorker = new Worker("script_formatter_worker/ScriptFormatterWorker.js");
537 this._outlineWorker.onmessage = this._didBuildOutlineChunk.bind(this);
538 this._outlineWorker.postMessage({ method: "javaScriptOutline", params: { content: uiSourceCode.workingCopy() } });
542 * @param {!WebInspector.View} view
543 * @param {!WebInspector.UISourceCode} uiSourceCode
544 * @param {function(number, number)} selectItemCallback
546 WebInspector.JavaScriptOutlineDialog.show = function(view, uiSourceCode, selectItemCallback)
548 if (WebInspector.Dialog.currentInstance())
550 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.JavaScriptOutlineDialog(uiSourceCode, selectItemCallback));
551 WebInspector.Dialog.show(view.element, filteredItemSelectionDialog);
554 WebInspector.JavaScriptOutlineDialog.prototype = {
556 * @param {!MessageEvent} event
558 _didBuildOutlineChunk: function(event)
560 var data = /** @type {!WebInspector.JavaScriptOutlineDialog.MessageEventData} */ (event.data);
561 var chunk = data.chunk;
562 for (var i = 0; i < chunk.length; ++i)
563 this._functionItems.push(chunk[i]);
565 if (data.total === data.index + 1)
574 itemCount: function()
576 return this._functionItems.length;
580 * @param {number} itemIndex
583 itemKeyAt: function(itemIndex)
585 return this._functionItems[itemIndex].name;
589 * @param {number} itemIndex
590 * @param {string} query
593 itemScoreAt: function(itemIndex, query)
595 var item = this._functionItems[itemIndex];
600 * @param {number} itemIndex
601 * @param {string} query
602 * @param {!Element} titleElement
603 * @param {!Element} subtitleElement
605 renderItem: function(itemIndex, query, titleElement, subtitleElement)
607 var item = this._functionItems[itemIndex];
608 titleElement.textContent = item.name + (item.arguments ? item.arguments : "");
609 this.highlightRanges(titleElement, query);
610 subtitleElement.textContent = ":" + (item.line + 1);
614 * @param {?number} itemIndex
615 * @param {string} promptValue
617 selectItem: function(itemIndex, promptValue)
619 if (itemIndex === null)
621 var lineNumber = this._functionItems[itemIndex].line;
622 if (!isNaN(lineNumber) && lineNumber >= 0)
623 this._selectItemCallback(lineNumber, this._functionItems[itemIndex].column);
628 if (this._outlineWorker) {
629 this._outlineWorker.terminate();
630 delete this._outlineWorker;
634 __proto__: WebInspector.SelectionDialogContentProvider.prototype
639 * @extends {WebInspector.SelectionDialogContentProvider}
640 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
642 WebInspector.SelectUISourceCodeDialog = function(defaultScores)
644 WebInspector.SelectionDialogContentProvider.call(this);
647 this._defaultScores = defaultScores;
648 this._scorer = new WebInspector.FilePathScoreFunction("");
649 WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
650 WebInspector.workspace.addEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
653 WebInspector.SelectUISourceCodeDialog.prototype = {
654 _projectRemoved: function(event)
656 var project = /** @type {!WebInspector.Project} */ (event.data);
657 this._populate(project);
662 * @param {!WebInspector.Project=} skipProject
664 _populate: function(skipProject)
666 /** @type {!Array.<!WebInspector.UISourceCode>} */
667 this._uiSourceCodes = [];
668 var projects = WebInspector.workspace.projects().filter(this.filterProject.bind(this));
669 for (var i = 0; i < projects.length; ++i) {
670 if (skipProject && projects[i] === skipProject)
672 this._uiSourceCodes = this._uiSourceCodes.concat(projects[i].uiSourceCodes());
677 * @param {?WebInspector.UISourceCode} uiSourceCode
678 * @param {number=} lineNumber
679 * @param {number=} columnNumber
681 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
683 // Overridden by subclasses
687 * @param {!WebInspector.Project} project
690 filterProject: function(project)
693 // Overridden by subclasses
699 itemCount: function()
701 return this._uiSourceCodes.length;
705 * @param {number} itemIndex
708 itemKeyAt: function(itemIndex)
710 return this._uiSourceCodes[itemIndex].fullDisplayName();
714 * @param {number} itemIndex
715 * @param {string} query
718 itemScoreAt: function(itemIndex, query)
720 var uiSourceCode = this._uiSourceCodes[itemIndex];
721 var score = this._defaultScores ? (this._defaultScores.get(uiSourceCode) || 0) : 0;
722 if (!query || query.length < 2)
725 if (this._query !== query) {
727 this._scorer = new WebInspector.FilePathScoreFunction(query);
730 var path = uiSourceCode.fullDisplayName();
731 return score + 10 * this._scorer.score(path, null);
735 * @param {number} itemIndex
736 * @param {string} query
737 * @param {!Element} titleElement
738 * @param {!Element} subtitleElement
739 * @return {!Array.<!Element>}
741 renderItem: function(itemIndex, query, titleElement, subtitleElement)
743 query = this.rewriteQuery(query);
744 var uiSourceCode = this._uiSourceCodes[itemIndex];
745 titleElement.textContent = uiSourceCode.displayName() + (this._queryLineNumberAndColumnNumber || "");
746 subtitleElement.textContent = uiSourceCode.fullDisplayName().trimEnd(100);
749 var score = new WebInspector.FilePathScoreFunction(query).score(subtitleElement.textContent, indexes);
750 var fileNameIndex = subtitleElement.textContent.lastIndexOf("/");
752 for (var i = 0; i < indexes.length; ++i)
753 ranges.push({offset: indexes[i], length: 1});
754 if (indexes[0] > fileNameIndex) {
755 for (var i = 0; i < ranges.length; ++i)
756 ranges[i].offset -= fileNameIndex + 1;
757 return WebInspector.highlightRangesWithStyleClass(titleElement, ranges, "highlight");
759 return WebInspector.highlightRangesWithStyleClass(subtitleElement, ranges, "highlight");
764 * @param {?number} itemIndex
765 * @param {string} promptValue
767 selectItem: function(itemIndex, promptValue)
769 var parsedExpression = promptValue.trim().match(/^([^:]*)(:\d+)?(:\d+)?$/);
770 if (!parsedExpression)
775 if (parsedExpression[2])
776 lineNumber = parseInt(parsedExpression[2].substr(1), 10) - 1;
777 if (parsedExpression[3])
778 columnNumber = parseInt(parsedExpression[3].substr(1), 10) - 1;
779 var uiSourceCode = itemIndex !== null ? this._uiSourceCodes[itemIndex] : null;
780 this.uiSourceCodeSelected(uiSourceCode, lineNumber, columnNumber);
784 * @param {string} query
787 rewriteQuery: function(query)
791 query = query.trim();
792 var lineNumberMatch = query.match(/^([^:]+)((?::[^:]*){0,2})$/);
793 this._queryLineNumberAndColumnNumber = lineNumberMatch ? lineNumberMatch[2] : "";
794 return lineNumberMatch ? lineNumberMatch[1] : query;
798 * @param {!WebInspector.Event} event
800 _uiSourceCodeAdded: function(event)
802 var uiSourceCode = /** @type {!WebInspector.UISourceCode} */ (event.data);
803 if (!this.filterProject(uiSourceCode.project()))
805 this._uiSourceCodes.push(uiSourceCode)
811 WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.UISourceCodeAdded, this._uiSourceCodeAdded, this);
812 WebInspector.workspace.removeEventListener(WebInspector.Workspace.Events.ProjectRemoved, this._projectRemoved, this);
815 __proto__: WebInspector.SelectionDialogContentProvider.prototype
820 * @extends {WebInspector.SelectUISourceCodeDialog}
821 * @param {!WebInspector.SourcesView} sourcesView
822 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
824 WebInspector.OpenResourceDialog = function(sourcesView, defaultScores)
826 WebInspector.SelectUISourceCodeDialog.call(this, defaultScores);
827 this._sourcesView = sourcesView;
830 WebInspector.OpenResourceDialog.prototype = {
833 * @param {?WebInspector.UISourceCode} uiSourceCode
834 * @param {number=} lineNumber
835 * @param {number=} columnNumber
837 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
840 uiSourceCode = this._sourcesView.currentUISourceCode();
843 this._sourcesView.showSourceLocation(uiSourceCode, lineNumber, columnNumber);
847 * @param {string} query
850 shouldShowMatchingItems: function(query)
852 return !query.startsWith(":");
856 * @param {!WebInspector.Project} project
859 filterProject: function(project)
861 return !project.isServiceProject();
864 __proto__: WebInspector.SelectUISourceCodeDialog.prototype
868 * @param {!WebInspector.SourcesView} sourcesView
869 * @param {!Element} relativeToElement
870 * @param {string=} query
871 * @param {!Map.<!WebInspector.UISourceCode, number>=} defaultScores
873 WebInspector.OpenResourceDialog.show = function(sourcesView, relativeToElement, query, defaultScores)
875 if (WebInspector.Dialog.currentInstance())
878 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.OpenResourceDialog(sourcesView, defaultScores));
879 filteredItemSelectionDialog.renderAsTwoRows();
881 filteredItemSelectionDialog.setQuery(query);
882 WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
887 * @extends {WebInspector.SelectUISourceCodeDialog}
888 * @param {!Array.<string>} types
889 * @param {function(!WebInspector.UISourceCode)} callback
891 WebInspector.SelectUISourceCodeForProjectTypesDialog = function(types, callback)
894 WebInspector.SelectUISourceCodeDialog.call(this);
895 this._callback = callback;
898 WebInspector.SelectUISourceCodeForProjectTypesDialog.prototype = {
900 * @param {!WebInspector.UISourceCode} uiSourceCode
901 * @param {number=} lineNumber
902 * @param {number=} columnNumber
904 uiSourceCodeSelected: function(uiSourceCode, lineNumber, columnNumber)
906 this._callback(uiSourceCode);
910 * @param {!WebInspector.Project} project
913 filterProject: function(project)
915 return this._types.indexOf(project.type()) !== -1;
918 __proto__: WebInspector.SelectUISourceCodeDialog.prototype
922 * @param {string} name
923 * @param {!Array.<string>} types
924 * @param {function(!WebInspector.UISourceCode)} callback
925 * @param {!Element} relativeToElement
927 WebInspector.SelectUISourceCodeForProjectTypesDialog.show = function(name, types, callback, relativeToElement)
929 if (WebInspector.Dialog.currentInstance())
932 var filteredItemSelectionDialog = new WebInspector.FilteredItemSelectionDialog(new WebInspector.SelectUISourceCodeForProjectTypesDialog(types, callback));
933 filteredItemSelectionDialog.setQuery(name);
934 filteredItemSelectionDialog.renderAsTwoRows();
935 WebInspector.Dialog.show(relativeToElement, filteredItemSelectionDialog);
939 * @typedef {{index: number, total: number, chunk: !Array.<!{selectorText: string, lineNumber: number, columnNumber: number}>}}
941 WebInspector.JavaScriptOutlineDialog.MessageEventData;