summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--readme.md2
-rw-r--r--source/background.ts4
-rw-r--r--source/content.ts1
-rw-r--r--source/features/exclude-filter-shortcut.tsx169
4 files changed, 4 insertions, 172 deletions
diff --git a/readme.md b/readme.md
index a3be74ad..1c142a20 100644
--- a/readme.md
+++ b/readme.md
@@ -120,7 +120,6 @@ GitHub Enterprise is also supported. More info in the options.
- [Quickly visit a repository's default branch and latest version tag.](https://user-images.githubusercontent.com/1402241/38107328-ccb3fb46-33bb-11e8-9654-23a6410943cc.png)
- [Open multiple issues at once in your repos.](https://user-images.githubusercontent.com/1402241/38084752-4820b0d8-3378-11e8-868c-a1582b16f915.gif)
- [Swap branches in the branch compare view.](https://user-images.githubusercontent.com/857700/42854438-821096f2-8a01-11e8-8752-76f7563b5e18.png)
-- [Exclude PR/issue filters from their list](https://user-images.githubusercontent.com/1402241/48470535-493cfb00-e824-11e8-863a-964f52b62553.png) with <kbd>alt/option</kbd>-<kbd>click</kbd>.
- [Insert collapsible content when writing comments (via `<summary>`).](https://user-images.githubusercontent.com/1402241/53678019-0c721280-3cf4-11e9-9c24-4d11a697f67c.png)
### More info at a glance
@@ -208,6 +207,7 @@ And [many more…](source/content.css)
- [Implemented by GitHub](https://user-images.githubusercontent.com/36004334/52573199-ea365480-2e19-11e9-8ebf-3ea6a7a640f8.png): [Access the `Labels` `Milestones` navigation from individual milestone pages.](https://cloud.githubusercontent.com/assets/170270/25217211/37b67aea-25d0-11e7-8482-bead2b04ee74.png)
- [Implemented by GitHub](https://github.blog/changelog/2019-02-13-comment-author-label/): [The comments of who opened an issue/PR are marked with `Original Poster` label.](https://cloud.githubusercontent.com/assets/4331946/25075520/d62fbbd0-2316-11e7-921f-ab736dc3522e.png)
- [Implemented by GitHub](https://github.blog/changelog/2019-02-14-prompt-to-clean-up-merged-forks): [Quickly delete a forked repo after its pull request has been merged.](https://cloud.githubusercontent.com/assets/170270/13520281/b2c9335c-e211-11e5-9e36-b0f325166356.png)
+- [Implemented by GitHub](https://github.blog/changelog/2019-03-05-exclude-labels-from-search/): [Exclude PR/issue filters from their list](https://user-images.githubusercontent.com/1402241/48470535-493cfb00-e824-11e8-863a-964f52b62553.png) with <kbd>alt/option</kbd>-<kbd>click</kbd>.
## Customization
diff --git a/source/background.ts b/source/background.ts
index 575ad538..2a23ee51 100644
--- a/source/background.ts
+++ b/source/background.ts
@@ -22,7 +22,9 @@ new OptionsSync().define({
.replace(/^add-/, '') // #1719
.replace('milestone-navigation', '') // #1767
.replace('op-labels', '') // #1776
- .replace('delete-fork-link', ''); // #1791
+ .replace('delete-fork-link', '') // #1791
+ .replace('exclude-filter-shortcut', '') // #1831
+ ; // eslint-disable-line semi-style
},
OptionsSync.migrations.removeUnused
]
diff --git a/source/content.ts b/source/content.ts
index 2cf6bcb0..7e11fea0 100644
--- a/source/content.ts
+++ b/source/content.ts
@@ -63,7 +63,6 @@ import './features/comments-time-machine-links';
import './features/jump-to-bottom-link';
import './features/filter-comments-by-you';
import './features/hide-issue-list-autocomplete';
-import './features/exclude-filter-shortcut';
import './features/show-recently-pushed-branches-on-more-pages';
import './features/create-release-shortcut';
import './features/patch-diff-links';
diff --git a/source/features/exclude-filter-shortcut.tsx b/source/features/exclude-filter-shortcut.tsx
deleted file mode 100644
index b84b8378..00000000
--- a/source/features/exclude-filter-shortcut.tsx
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
-Exclude PR/issue filters from their list with <kbd>alt</kbd> <kbd>click</kbd>.
-https://user-images.githubusercontent.com/1402241/48470535-493cfb00-e824-11e8-863a-964f52b62553.png
-*/
-
-import React from 'dom-chef';
-import select from 'select-dom';
-import delegate from 'delegate';
-import * as icons from '../libs/icons';
-import features from '../libs/features';
-
-const getFilterName = item => {
- return item
- .closest('details')
- .querySelector('summary')
- .textContent
- .trim()
- .replace(/s$/, '') // 'Assignees' -> 'Assignee'; 'Milestones -> Milestone'
- .toLowerCase();
-};
-
-const getItemName = item => {
- const itemText = select('.name', item) || select('.select-menu-item-text', item);
- const text = itemText.firstChild.textContent.trim();
- return text.includes(' ') ? `"${text}"` : text;
-};
-
-const getLastQuery = item => {
- return new URLSearchParams(item.search)
- .get('q')
-
- // Get the last query
- .split(' ')
- .pop();
-};
-
-const getItemQuery = item => {
- const filter = getFilterName(item);
- if (filter === 'sort') {
- return;
- }
-
- if (filter === 'review') {
- // Review filters have the review query set even if they’re selected
- return getLastQuery(item);
- }
-
- if (filter === 'project') {
- // Project filters don’t have the project query set if they’re selected
- // and the query cannot be determined via getFilterName/getItemName
- const query = getLastQuery(item);
- if (query.startsWith('project:')) {
- return query;
- }
-
- return; // Not supported
- }
-
- const name = getItemName(item);
- if (name) {
- return `${filter}:${name}`;
- }
- // "No label/milestone/etc" filters won't have a name here and can't be excluded
-};
-
-const buildSearch = item => {
- const itemQuery = getItemQuery(item);
- if (!itemQuery) {
- return false;
- }
-
- const search = new URLSearchParams(location.search);
- const currentQuery = (search.get('q') || '').trim();
- const negatedQuery = `-${itemQuery}`;
- if (currentQuery.includes(negatedQuery)) {
- // If -label:bug is there, drop it (to match the regular click behavior)
- search.set('q', currentQuery.replace(negatedQuery, ' ').replace(/ {2,}/, ' ').trim());
- } else if (currentQuery.includes(itemQuery)) {
- // If label:bug is there, replace it with -label:bug
- search.set('q', currentQuery.replace(itemQuery, negatedQuery));
- } else {
- // If label:bug isn't there, add -label:bug
- search.set('q', `${currentQuery} ${negatedQuery}`);
- }
-
- return search;
-};
-
-const visitNegatedQuery = event => {
- if (!event.altKey) {
- return;
- }
-
- // Avoid the default (downloading the link)
- // even if the link isn't supported
- // because we never want to download pages
- event.preventDefault();
- const item = event.delegateTarget;
- const search = buildSearch(item);
- if (search) {
- item.search = search;
- }
-
- item.click();
-};
-
-const getIcon = isNegated => {
- return <span class="select-menu-item-icon">{isNegated ? icons.x() : icons.check()}</span>;
-};
-
-const updateFilterIcons = () => {
- const search = new URLSearchParams(location.search);
- const queries = (search.get('q') || '')
- .trim()
- .match(/(".*?"|[^"\s]+)+(?=\s*|\s*$)/g) || []; // Split by query, exclude spaces in quotes https://stackoverflow.com/a/16261693/288906
-
- const links = new Map();
- for (const link of select.all('.table-list-filters .select-menu-item:not(.rgh-exclude-filter-icon)')) {
- link.classList.add('rgh-exclude-filter-icon');
-
- const filter = getItemQuery(link);
- if (filter) {
- links.set(filter, link);
- }
- }
-
- if (links.size === 0) {
- return;
- }
-
- for (const query of queries) {
- const isNegated = query[0] === '-';
- const plainQuery = query.replace(/^-/, '');
- const link = links.get(plainQuery);
- if (!link) {
- continue;
- }
-
- const icon = link.querySelector('.octicon-check');
- if (!icon) {
- link.prepend(getIcon(isNegated));
- } else if (isNegated) {
- icon.replaceWith(getIcon(isNegated));
- }
-
- link.setAttribute('aria-checked', 'true'); // Necessary for Assignees, but also the correct thing to do
- }
-};
-
-function init() {
- delegate('.table-list-filters', 'a.select-menu-item', 'click', visitNegatedQuery, false);
-
- updateFilterIcons();
-
- // Some filters are loaded on demand
- const observer = new MutationObserver(updateFilterIcons);
- for (const dropdown of select.all('.table-list-filters details-menu')) {
- observer.observe(dropdown, {childList: true});
- }
-}
-
-features.add({
- id: 'exclude-filter-shortcut',
- include: [
- features.isIssueList
- ],
- load: features.onAjaxedPages,
- init
-});