mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 881219 - When filtering sources, hiding items in the sources list is redundant, r=rcampbell
This commit is contained in:
parent
fb5ea90063
commit
c73f2421f0
@ -42,7 +42,6 @@ SourcesView.prototype = Heritage.extend(WidgetMethods, {
|
||||
});
|
||||
|
||||
this.emptyText = L10N.getStr("noSourcesText");
|
||||
this.unavailableText = L10N.getStr("noMatchingSourcesText");
|
||||
this._blackBoxCheckboxTooltip = L10N.getStr("blackBoxCheckboxTooltip");
|
||||
|
||||
this._commandset = document.getElementById("debuggerCommands");
|
||||
|
@ -343,7 +343,6 @@ ChromeGlobalsView.prototype = Heritage.extend(WidgetMethods, {
|
||||
|
||||
this.widget = document.getElementById("chrome-globals");
|
||||
this.emptyText = L10N.getStr("noGlobalsText");
|
||||
this.unavailableText = L10N.getStr("noMatchingGlobalsText");
|
||||
|
||||
this.widget.addEventListener("select", this._onSelect, false);
|
||||
this.widget.addEventListener("click", this._onClick, false);
|
||||
@ -921,68 +920,7 @@ FilterView.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Performs a file search if necessary.
|
||||
*
|
||||
* @param string aFile
|
||||
* The source location to search for.
|
||||
*/
|
||||
_performFileSearch: function(aFile) {
|
||||
// Don't search for files if the input hasn't changed.
|
||||
if (this._prevSearchedFile == aFile) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is the target container to be currently filtered. Clicking on a
|
||||
// container generally means it should become a target.
|
||||
let view = this._target;
|
||||
|
||||
// If we're not searching for a file anymore, unhide all the items.
|
||||
if (!aFile) {
|
||||
for (let item in view) {
|
||||
item.target.hidden = false;
|
||||
}
|
||||
view.refresh();
|
||||
}
|
||||
// If the searched file string is valid, hide non-matched items.
|
||||
else {
|
||||
let found = false;
|
||||
let lowerCaseFile = aFile.toLowerCase();
|
||||
|
||||
for (let item in view) {
|
||||
let element = item.target;
|
||||
let lowerCaseLabel = item.label.toLowerCase();
|
||||
|
||||
// Search is not case sensitive, and is tied to the label not the value.
|
||||
if (lowerCaseLabel.match(lowerCaseFile)) {
|
||||
element.hidden = false;
|
||||
|
||||
// Automatically select the first match.
|
||||
if (!found) {
|
||||
found = true;
|
||||
view.selectedItem = item;
|
||||
}
|
||||
}
|
||||
// Item not matched, hide the corresponding node.
|
||||
else {
|
||||
element.hidden = true;
|
||||
}
|
||||
}
|
||||
// If no matches were found, display the appropriate info.
|
||||
if (!found) {
|
||||
view.setUnavailable();
|
||||
}
|
||||
}
|
||||
// Synchronize with the view's filtered sources container.
|
||||
DebuggerView.FilteredSources.syncFileSearch();
|
||||
|
||||
// Hide all the groups with no visible children.
|
||||
view.widget.hideEmptyGroups();
|
||||
|
||||
// Ensure the currently selected item is visible.
|
||||
view.widget.ensureSelectionIsVisible({ withGroup: true });
|
||||
|
||||
// Remember the previously searched file to avoid redundant filtering.
|
||||
this._prevSearchedFile = aFile;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1026,9 +964,6 @@ FilterView.prototype = {
|
||||
if (this._prevSearchedLine && !aToken) {
|
||||
this._target.refresh();
|
||||
}
|
||||
|
||||
// Remember the previously searched token to avoid redundant filtering.
|
||||
this._prevSearchedToken = aToken;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1344,41 +1279,86 @@ FilteredSourcesView.prototype = Heritage.extend(ResultsPanelContainer.prototype,
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the list of sources displayed in this container.
|
||||
* Schedules searching for a source.
|
||||
*
|
||||
* @param string aToken
|
||||
* The function to search for.
|
||||
* @param number aWait
|
||||
* The amount of milliseconds to wait until draining.
|
||||
*/
|
||||
syncFileSearch: function() {
|
||||
this.empty();
|
||||
scheduleSearch: function(aToken, aWait) {
|
||||
// The amount of time to wait for the requests to settle.
|
||||
let maxDelay = FILE_SEARCH_ACTION_MAX_DELAY;
|
||||
let delay = aWait === undefined ? maxDelay / aToken.length : aWait;
|
||||
|
||||
// If there's no currently searched file, or there are no matches found,
|
||||
// hide the popup and avoid creating the view again.
|
||||
if (!DebuggerView.Filtering.searchedFile ||
|
||||
!DebuggerView.Sources.visibleItems.length) {
|
||||
this.hidden = true;
|
||||
// Allow requests to settle down first.
|
||||
setNamedTimeout("sources-search", delay, () => this._doSearch(aToken));
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds file matches in all the displayed sources.
|
||||
*
|
||||
* @param string aToken
|
||||
* The string to search for.
|
||||
*/
|
||||
_doSearch: function(aToken, aStore = []) {
|
||||
// Don't continue filtering if the searched token is an empty string.
|
||||
// In contrast with function searching, in this case we don't want to
|
||||
// show a list of all the files when no search token was supplied.
|
||||
if (!aToken) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the currently visible items in the sources container.
|
||||
let visibleItems = DebuggerView.Sources.visibleItems;
|
||||
let displayedItems = visibleItems.slice(0, RESULTS_PANEL_MAX_RESULTS);
|
||||
for (let item of DebuggerView.Sources.items) {
|
||||
let lowerCaseLabel = item.label.toLowerCase();
|
||||
let lowerCaseToken = aToken.toLowerCase();
|
||||
if (lowerCaseLabel.match(lowerCaseToken)) {
|
||||
aStore.push(item);
|
||||
}
|
||||
|
||||
// Append a location item item to this container.
|
||||
for (let item of displayedItems) {
|
||||
// Once the maximum allowed number of results is reached, proceed
|
||||
// with building the UI immediately.
|
||||
if (aStore.length >= RESULTS_PANEL_MAX_RESULTS) {
|
||||
this._syncView(aStore);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't reach the maximum allowed number of results, but that's ok,
|
||||
// continue building the UI.
|
||||
this._syncView(aStore);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the list of sources displayed in this container.
|
||||
*
|
||||
* @param array aSearchResults
|
||||
* The results array, containing search details for each source.
|
||||
*/
|
||||
_syncView: function(aSearchResults) {
|
||||
// If there are no matches found, keep the popup hidden and avoid
|
||||
// creating the view.
|
||||
if (!aSearchResults.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let item of aSearchResults) {
|
||||
// Append a location item to this container for each match.
|
||||
let trimmedLabel = SourceUtils.trimUrlLength(item.label);
|
||||
let trimmedValue = SourceUtils.trimUrlLength(item.value, 0, "start");
|
||||
let locationItem = this.push([trimmedLabel, trimmedValue], {
|
||||
|
||||
this.push([trimmedLabel, trimmedValue], {
|
||||
index: -1, /* specifies on which position should the item be appended */
|
||||
relaxed: true, /* this container should allow dupes & degenerates */
|
||||
attachment: {
|
||||
fullLabel: item.label,
|
||||
fullValue: item.value
|
||||
url: item.value
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Select the first entry in this container.
|
||||
this.selectedIndex = 0;
|
||||
|
||||
// Only display the results panel if there's at least one entry available.
|
||||
this.hidden = this.itemCount == 0;
|
||||
this.hidden = false;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1400,7 +1380,16 @@ FilteredSourcesView.prototype = Heritage.extend(ResultsPanelContainer.prototype,
|
||||
*/
|
||||
_onSelect: function({ detail: locationItem }) {
|
||||
if (locationItem) {
|
||||
DebuggerView.setEditorLocation(locationItem.attachment.fullValue, 0);
|
||||
let targetUrl = locationItem.attachment.url;
|
||||
let currentLine = DebuggerView.editor.getCaretPosition().line + 1;
|
||||
|
||||
// If the same file is selected, don't change the source editor's
|
||||
// carent or debug locations.
|
||||
if (DebuggerView.Sources.selectedValue == targetUrl) {
|
||||
DebuggerView.setEditorLocation(targetUrl, currentLine, { noDebug: true });
|
||||
} else {
|
||||
DebuggerView.setEditorLocation(targetUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -1447,6 +1436,7 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
||||
* The amount of milliseconds to wait until draining.
|
||||
*/
|
||||
scheduleSearch: function(aToken, aWait) {
|
||||
// The amount of time to wait for the requests to settle.
|
||||
let maxDelay = FUNCTION_SEARCH_ACTION_MAX_DELAY;
|
||||
let delay = aWait === undefined ? maxDelay / aToken.length : aWait;
|
||||
|
||||
@ -1468,8 +1458,7 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
||||
* @param array aSources
|
||||
* An array of [url, text] tuples for each source.
|
||||
*/
|
||||
_doSearch: function(aToken, aSources) {
|
||||
// Get the currently searched token from the filtering input.
|
||||
_doSearch: function(aToken, aSources, aStore = []) {
|
||||
// Continue parsing even if the searched token is an empty string, to
|
||||
// cache the syntax tree nodes generated by the reflection API.
|
||||
|
||||
@ -1486,16 +1475,13 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
||||
aSources.splice(1);
|
||||
}
|
||||
|
||||
// Prepare the results array, containing search details for each source.
|
||||
let searchResults = [];
|
||||
|
||||
for (let [location, contents] of aSources) {
|
||||
let parserMethods = DebuggerController.Parser.get(location, contents);
|
||||
let sourceResults = parserMethods.getNamedFunctionDefinitions(aToken);
|
||||
|
||||
for (let scriptResult of sourceResults) {
|
||||
for (let parseResult of scriptResult.parseResults) {
|
||||
searchResults.push({
|
||||
aStore.push({
|
||||
sourceUrl: scriptResult.sourceUrl,
|
||||
scriptOffset: scriptResult.scriptOffset,
|
||||
functionName: parseResult.functionName,
|
||||
@ -1507,16 +1493,17 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
||||
|
||||
// Once the maximum allowed number of results is reached, proceed
|
||||
// with building the UI immediately.
|
||||
if (searchResults.length >= RESULTS_PANEL_MAX_RESULTS) {
|
||||
this._syncFunctionSearch(searchResults);
|
||||
if (aStore.length >= RESULTS_PANEL_MAX_RESULTS) {
|
||||
this._syncView(aStore);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Couldn't reach the maximum allowed number of results, but that's ok,
|
||||
// continue building the UI.
|
||||
this._syncFunctionSearch(searchResults);
|
||||
this._syncView(aStore);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -1525,13 +1512,10 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
||||
* @param array aSearchResults
|
||||
* The results array, containing search details for each source.
|
||||
*/
|
||||
_syncFunctionSearch: function(aSearchResults) {
|
||||
this.empty();
|
||||
|
||||
// Show the popup even if the search token is an empty string. If there are
|
||||
// no matches found, hide the popup and avoid creating the view again.
|
||||
_syncView: function(aSearchResults) {
|
||||
// If there are no matches found, keep the popup hidden and avoid
|
||||
// creating the view.
|
||||
if (!aSearchResults.length) {
|
||||
this.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1561,7 +1545,7 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
||||
item.actualLocation = item.functionLocation;
|
||||
}
|
||||
|
||||
// Append a function item to this container.
|
||||
// Append a function item to this container for each match.
|
||||
let trimmedLabel = SourceUtils.trimUrlLength(item.displayedName + "()");
|
||||
let trimmedValue = SourceUtils.trimUrlLength(item.sourceUrl, 0, "start");
|
||||
let description = (item.inferredChain || []).join(".");
|
||||
@ -1575,9 +1559,7 @@ FilteredFunctionsView.prototype = Heritage.extend(ResultsPanelContainer.prototyp
|
||||
|
||||
// Select the first entry in this container.
|
||||
this.selectedIndex = 0;
|
||||
|
||||
// Only display the results panel if there's at least one entry available.
|
||||
this.hidden = this.itemCount == 0;
|
||||
this.hidden = false;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -18,6 +18,7 @@ const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_X = 7; // px
|
||||
const BREAKPOINT_CONDITIONAL_POPUP_OFFSET_Y = -3; // px
|
||||
const RESULTS_PANEL_POPUP_POSITION = "before_end";
|
||||
const RESULTS_PANEL_MAX_RESULTS = 10;
|
||||
const FILE_SEARCH_ACTION_MAX_DELAY = 300; // ms
|
||||
const GLOBAL_SEARCH_EXPAND_MAX_RESULTS = 50;
|
||||
const GLOBAL_SEARCH_LINE_MAX_LENGTH = 300; // chars
|
||||
const GLOBAL_SEARCH_ACTION_MAX_DELAY = 1500; // ms
|
||||
|
@ -766,27 +766,12 @@ this.WidgetMethods = {
|
||||
this._stagedItems.length = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Does not remove any item in this container. Instead, it overrides the
|
||||
* current label to signal that it is unavailable and removes the tooltip.
|
||||
*/
|
||||
setUnavailable: function() {
|
||||
this._widget.setAttribute("notice", this.unavailableText);
|
||||
this._widget.setAttribute("label", this.unavailableText);
|
||||
this._widget.removeAttribute("tooltiptext");
|
||||
},
|
||||
|
||||
/**
|
||||
* The label string automatically added to this container when there are
|
||||
* no child nodes present.
|
||||
*/
|
||||
emptyText: "",
|
||||
|
||||
/**
|
||||
* The label string added to this container when it is marked as unavailable.
|
||||
*/
|
||||
unavailableText: "",
|
||||
|
||||
/**
|
||||
* Toggles all the items in this container hidden or visible.
|
||||
*
|
||||
|
@ -57,10 +57,6 @@ stepOutTooltip=Step Out (%S)
|
||||
# when there are no chrome globals available.
|
||||
noGlobalsText=No globals
|
||||
|
||||
# LOCALIZATION NOTE (noMatchingGlobalsText): The text to display in the
|
||||
# menulist when there are no matching chrome globals after filtering.
|
||||
noMatchingGlobalsText=No matching globals
|
||||
|
||||
# LOCALIZATION NOTE (noSourcesText): The text to display in the sources menu
|
||||
# when there are no scripts.
|
||||
noSourcesText=This page has no sources.
|
||||
@ -70,10 +66,6 @@ noSourcesText=This page has no sources.
|
||||
# source.
|
||||
blackBoxCheckboxTooltip=Toggle black boxing
|
||||
|
||||
# LOCALIZATION NOTE (noMatchingSourcesText): The text to display in the
|
||||
# sources menu when there are no matching scripts after filtering.
|
||||
noMatchingSourcesText=No matching sources.
|
||||
|
||||
# LOCALIZATION NOTE (noMatchingStringsText): The text to display in the
|
||||
# global search results when there are no matching strings after filtering.
|
||||
noMatchingStringsText=No matches found
|
||||
|
Loading…
Reference in New Issue
Block a user