Skip to content
This repository was archived by the owner on Sep 6, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
240f3a9
Support multiple file filters with a dropdown menu.
RaymondLim May 12, 2014
0e73ef8
Adding the template for the filter dropdown menu.
RaymondLim May 12, 2014
e6ef41a
Switch to DropdownButton widget for filter picker.
RaymondLim May 14, 2014
0c0c44d
Remove the unneeded template
RaymondLim May 14, 2014
47cacb6
Remove unneeded whitespace.
RaymondLim May 14, 2014
72e2c2d
Visual tweaks. The styling that affects other dropdown menu is the to…
larz0 May 14, 2014
ed0c537
Merge remote-tracking branch 'origin' into rlim/multi-exclusion-set
RaymondLim May 14, 2014
748efac
Merge branch 'rlim/multi-exclusion-set' of https://github.com/adobe/b…
RaymondLim May 14, 2014
4915301
Add no-focus class to the filter picker button and handle focus resto…
RaymondLim May 14, 2014
99f3ede
Fix the vertical scroll bar showing up in CEF 1750 build by reducing …
RaymondLim May 15, 2014
f347c7f
Fixed some issues related to the index of the selected item or items …
RaymondLim May 16, 2014
171d73a
Fix broken integration tests caused by switching to the new filter UI.
RaymondLim May 18, 2014
42930a3
Some more integration tests for file filters UI.
RaymondLim May 19, 2014
aedbcba
Address lots of code review feedback and implement the check mark for…
RaymondLim May 22, 2014
1954e31
Remove ViewUtils that is no longer needed.
RaymondLim May 22, 2014
ff6f068
Missed to include this file in previous commit.
RaymondLim May 22, 2014
5665631
Replace DOM elements for filter list items with a template.
RaymondLim May 23, 2014
ba8bd1b
Making additional changes for second review feedback.
RaymondLim May 23, 2014
1b957c4
Move the triggerHandler call into _renderList instead of calling it d…
RaymondLim May 25, 2014
7d32194
Add JSDoc for listRendered event at the top of DropdownButton module.
RaymondLim May 27, 2014
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions src/htmlContent/edit-filter-dialog.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<div class="file-filter-dialog modal">
<div class="modal-header">
<h1 class="dialog-title">{{Strings.FILE_FILTER_DIALOG}}</h1>
</div>
<div class="modal-body">
<div class="dialog-message">
{{{instruction}}}
<textarea class="exclusions-editor"></textarea>
<input type="text" class="exclusions-name" placeholder="{{Strings.FILTER_NAME_PLACEHOLDER}}">
<div class="exclusions-filecount">{{Strings.FILTER_COUNTING_FILES}}</div>
</div>
</div>
<div class="modal-footer">
<button class="dialog-button btn" data-button-id="cancel">{{Strings.CANCEL}}</button>
<button class="dialog-button btn primary" data-button-id="ok">{{Strings.OK}}</button>
</div>
</div>
4 changes: 4 additions & 0 deletions src/htmlContent/filter-name.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class='filter-trash-icon'>&times;</div><!--
--><span class='recent-filter-name'>{{{filter-name}}}</span><!--
--><span class='recent-filter-patterns'>{{{filter-patterns}}}</span><!--
--><span class='filter-edit-icon'></span>
9 changes: 6 additions & 3 deletions src/nls/root/strings.js
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,14 @@ define({
"ERROR_FETCHING_UPDATE_INFO_MSG" : "There was a problem getting the latest update information from the server. Please make sure you are connected to the internet and try again.",

// File exclusion filters
"NO_FILE_FILTER" : "Exclude files\u2026",
"NEW_FILE_FILTER" : "New Exclusion Set\u2026",
"CLEAR_FILE_FILTER" : "Don't Exclude Files",
"NO_FILE_FILTER" : "No Files Excluded",
"EXCLUDE_FILE_FILTER" : "Exclude {0}",
"EDIT_FILE_FILTER" : "Edit\u2026",
"FILE_FILTER_DIALOG" : "Edit Filter",
"FILE_FILTER_DIALOG" : "Edit Exclusion Set",
"FILE_FILTER_INSTRUCTIONS" : "Exclude files and folders matching any of the following strings / substrings or <a href='{0}' title='{0}'>wildcards</a>. Enter each string on a new line.",
"FILE_FILTER_LIST_PREFIX" : "except",
"FILTER_NAME_PLACEHOLDER" : "Name this exclusion set (optional)",
"FILE_FILTER_CLIPPED_SUFFIX" : "and {0} more",
"FILTER_COUNTING_FILES" : "Counting files\u2026",
"FILTER_FILE_COUNT" : "Allows {0} of {1} files {2}",
Expand Down
400 changes: 313 additions & 87 deletions src/search/FileFilters.js

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/search/FindInFiles.js
Original file line number Diff line number Diff line change
Expand Up @@ -954,10 +954,12 @@ define(function (require, exports, module) {
$(this.modalBar).on("close", this._handleClose.bind(this));

// Custom closing behavior: if in the middle of executing search, blur shouldn't close ModalBar yet. And
// don't close bar when opening Edit Filter dialog either.
// don't close bar when opening Edit Filter dialog or showing the filter dropdown list either.
var self = this;
this.modalBar.isLockedOpen = function () {
return self.getDialogTextField().attr("disabled") || $(".modal.instance .exclusions-editor").length > 0;
return self.getDialogTextField().attr("disabled") ||
$(".modal.instance .exclusions-editor").length > 0 ||
$("ul.dropdown-menu.dropdownbutton-popup").length > 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This selector is very general - it could find some dropdown on the screen that wasn't associated with the file picker. Can we be more specific here?

Also, it would be best to add a specific API to FileFilters that just tells you whether its picker or dialog is open, and encapsulate the knowledge of how to determine that within FileFilters itself, rather than having FindInFiles know the details of how it's implemented.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The additional code here is no longer needed since we've found a solution for clicking outside of the dropdown to keep the Find bar open with focus restored to the Search text field.

};

var $searchField = $("input#find-what"),
Expand Down
71 changes: 61 additions & 10 deletions src/styles/brackets.less
Original file line number Diff line number Diff line change
Expand Up @@ -1199,27 +1199,78 @@ a, img {
}

// File exclusion filter (used only in Find in Files search bar, for now)
.filter-picker {
display: inline-block;
margin-left: 8px;
button {
margin-left: 8px;
}
.filter-trash-icon {
position: absolute;
left: 7px;
width: 16px;
height: 16px;
font-size: 20px;
color: rgba(0, 0, 0, 0.5);
line-height: 15px;
text-align: center;
visibility: hidden;
}

.filter-trash-icon:hover {
color: rgba(0, 0, 0, 1);
}

.filter-edit-icon {
float: right;
width: 13px;
height: 13px;
background-image: url("images/edit-icon.svg");
background-repeat: no-repeat;
opacity: 0.5;
visibility: hidden;
position: relative;
top: 2px;
right: -4px;
}

.filter-edit-icon:hover {
opacity: 1;
}

li:hover .filter-trash-icon,
li:hover .filter-edit-icon {
visibility: visible;
}

.recent-filter-name {
margin-left: 12px;
}

.recent-filter-patterns {
color: @tc-light-weight-quiet-text;
padding-right: 52px;
}

button.file-filter-picker {
margin-left: 10px;
}

// File exclusion filter editor dialog
textarea.exclusions-editor {
input.exclusions-name {
display: block;
width: 100%;
height: 160px;
height: 30px;
box-sizing: border-box; // needed for width: 100% since it has padding
margin-top: 12px;
margin-bottom: 0;
}
textarea.exclusions-editor {
display: block;
width: 100%;
height: 120px;
box-sizing: border-box; // needed for width: 100% since it has padding
margin-top: 5px;
margin-bottom: 0;
.code-font();
}
.exclusions-filecount {
margin: 12px 0 -20px 0;
padding: 4px 6px;
margin: 12px 0 -14px 0;
padding: 4px 8px;
background-color: @tc-highlight;
border-radius: @tc-control-border-radius;
}
Expand Down
30 changes: 28 additions & 2 deletions src/styles/brackets_patterns_override.less
Original file line number Diff line number Diff line change
Expand Up @@ -464,7 +464,7 @@ a:focus {
&.dropdown-menu {
border: none;
border-radius: @tc-control-border-radius;
padding: 0;
padding: 5px 0;
position: absolute;
display: block;
box-shadow: @tc-dropdown-shadow;
Expand All @@ -477,6 +477,7 @@ a:focus {

&.dropdown-menu li a {
padding: 1px 15px 1px 15px;
color: @bc-black;
}

&.dropdown-menu .stylesheet-link {
Expand All @@ -488,8 +489,33 @@ a:focus {
color: @bc-black !important;
}

&.dropdown-menu a {
&::before {
position: absolute;
left: 10px;
text-align: center;
content: "✓";
display: none;
}
/* toggle checkmark visibility */
&.checked::before {
display: inline-block;
}
}

&.dropdown-menu a:hover {
/* toggle checkmark visibility */
&.checked::before {
display: none;
}
}

&.dropdown-menu a:not(.selected):hover {
background: none;
background: none;
}

.divider {
margin: 5px 1px;
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/styles/images/edit-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion src/utils/DropdownEventHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,12 @@ define(function (require, exports, module) {
}
}

this._setSelectedIndex(pos, true);
// If the item to be selected is a divider, then rotate one more.
if ($(this.$items[pos]).hasClass("divider")) {
this._rotateSelection((distance > 0) ? (distance + 1) : (distance - 1));
} else {
this._setSelectedIndex(pos, true);
}
};

/**
Expand Down
62 changes: 55 additions & 7 deletions src/widgets/DropdownButton.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,58 @@ define(function (require, exports, module) {
DropdownButton.prototype._renderList = function () {
var html = "";
this.items.forEach(function (item, i) {
html += "<li><a class='stylesheet-link' data-index='" + i + "'>";
html += this.itemRenderer(item, i);
html += "</a></li>";
if (item === "---") {
html += "<li class='divider'></li>";
} else {
html += "<li><a class='stylesheet-link' data-index='" + i + "'>";
html += this.itemRenderer(item, i);
html += "</a></li>";
}
}.bind(this));
return html;
};

/**
* Refresh the dropdown list by removing and re-creating all list items.
* Call this after deleting/adding any item in the dropdown list.
*/
DropdownButton.prototype.refresh = function () {
if (!this.$dropdown) {
return;
}

// Remove all list items and then re-create them from this.items.
$("li", this.$dropdown).remove();
this.$dropdown.append(this._renderList());

// Also trigger openDropdown handler so that custom event handlers can be
// set up for any custom UI in the list.
$(this).triggerHandler("openDropdown", [this.$dropdown]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a little funny to re-trigger openDropdown here since it gets called on every re-render. Perhaps we should change the name of this event to render and trigger it from _renderList().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will work for all refresh cases if we move this call into _renderList(), but it will not work for the first time we're creating the dropdown list since this.$dropdown is not yet available in _renderList().

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. Then maybe we should just make this a separate refresh event and attach the handler to both events.

};

/**
* Check/Uncheck the list item of the given index.
* @param {number} index The index of the list item to be checked or unchecked
* @param {boolean} checked True if the list item is to be checked, false to get check
* mark removed.
*/
DropdownButton.prototype.setChecked = function (index, checked) {
if (!this.$dropdown) {
return;
}

var listItems = $("li", this.$dropdown),
count = listItems.length;

if (index > -1 && index < count) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the contents of this could just be $("a", listItems[index]).toggleClass("checked", checked); (there's no harm in trying to remove the class if it doesn't have it).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (checked) {
$("a", listItems[index]).addClass("checked");
} else if ($(listItems[index]).hasClass("checked")) {
$("a", listItems[index]).removeClass("checked");
}
}
};

/** Pops open the dropdown if currently closed. Does nothing if items.length == 0 */
DropdownButton.prototype.showDropdown = function () {
// Act like a plain old button if no items to show
Expand Down Expand Up @@ -178,6 +223,8 @@ define(function (require, exports, module) {
$dropdown.focus();

this.$dropdown = $dropdown;

$(this).triggerHandler("openDropdown", [$dropdown]);
};

/**
Expand All @@ -188,12 +235,12 @@ define(function (require, exports, module) {
DropdownButton.prototype._onDropdownClose = function () {
window.document.body.removeEventListener("click", this._onClickOutside, true);
$(PanelManager).off("editorAreaResize", this.closeDropdown);

// Restore focus to old pos, unless "select" handler changed it
if (window.document.activeElement === this.$dropdown[0]) {
this._lastFocus.focus();
}

this._dropdownEventHandler = null;
this.$dropdown = null; // already remvoed from DOM automatically by PopUpManager
};
Expand All @@ -209,8 +256,9 @@ define(function (require, exports, module) {
DropdownButton.prototype._onClickOutside = function (event) {
var $container = $(event.target).closest(".dropdownbutton-popup");

// If click is outside dropdown list, then close dropdown list
if ($container.length === 0 || $container[0] !== this.$dropdown[0]) {
// If click is outside dropdown list or dropdown button, then close dropdown list
if (!$(event.target).hasClass("btn btn-dropdown") &&
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This selector will find any item that has these classes, and there could be another one on the screen. Can we compare the target to the specific DOM elements we care about?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I switched it to compare the event target with this.$button.

($container.length === 0 || $container[0] !== this.$dropdown[0])) {
this.closeDropdown();
}
};
Expand Down
Loading