Add partial blacklist form
This commit is contained in:
		
							parent
							
								
									7528fe831f
								
							
						
					
					
						commit
						fa6dfb0395
					
				
					 8 changed files with 185 additions and 58 deletions
				
			
		| 
						 | 
				
			
			@ -2,17 +2,17 @@ import './BlacklistForm.scss';
 | 
			
		|||
import AddButton from '../ui/AddButton';
 | 
			
		||||
import DeleteButton from '../ui/DeleteButton';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import { BlacklistJSON } from '../../../shared/settings/Blacklist';
 | 
			
		||||
import Blacklist, { BlacklistItem } from '../../../shared/settings/Blacklist';
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  value: BlacklistJSON;
 | 
			
		||||
  onChange: (value: BlacklistJSON) => void;
 | 
			
		||||
  value: Blacklist;
 | 
			
		||||
  onChange: (value: Blacklist) => void;
 | 
			
		||||
  onBlur: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class BlacklistForm extends React.Component<Props> {
 | 
			
		||||
  public static defaultProps: Props = {
 | 
			
		||||
    value: [],
 | 
			
		||||
    value: new Blacklist([]),
 | 
			
		||||
    onChange: () => {},
 | 
			
		||||
    onBlur: () => {},
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			@ -20,24 +20,22 @@ class BlacklistForm extends React.Component<Props> {
 | 
			
		|||
  render() {
 | 
			
		||||
    return <div className='form-blacklist-form'>
 | 
			
		||||
      {
 | 
			
		||||
        this.props.value
 | 
			
		||||
          .map((item, index) => {
 | 
			
		||||
            if (typeof item !== 'string') {
 | 
			
		||||
              // TODO support partial blacklist;
 | 
			
		||||
              return null;
 | 
			
		||||
            }
 | 
			
		||||
            return <div key={index} className='form-blacklist-form-row'>
 | 
			
		||||
              <input data-index={index} type='text' name='url'
 | 
			
		||||
                className='column-url' value={item}
 | 
			
		||||
                onChange={this.bindValue.bind(this)}
 | 
			
		||||
                onBlur={this.props.onBlur}
 | 
			
		||||
              />
 | 
			
		||||
              <DeleteButton data-index={index} name='delete'
 | 
			
		||||
                onClick={this.bindValue.bind(this)}
 | 
			
		||||
                onBlur={this.props.onBlur}
 | 
			
		||||
              />
 | 
			
		||||
            </div>;
 | 
			
		||||
          })
 | 
			
		||||
        this.props.value.items.map((item, index) => {
 | 
			
		||||
          if (item.partial) {
 | 
			
		||||
            return null;
 | 
			
		||||
          }
 | 
			
		||||
          return <div key={index} className='form-blacklist-form-row'>
 | 
			
		||||
            <input data-index={index} type='text' name='url'
 | 
			
		||||
              className='column-url' value={item.pattern}
 | 
			
		||||
              onChange={this.bindValue.bind(this)}
 | 
			
		||||
              onBlur={this.props.onBlur}
 | 
			
		||||
            />
 | 
			
		||||
            <DeleteButton data-index={index} name='delete'
 | 
			
		||||
              onClick={this.bindValue.bind(this)}
 | 
			
		||||
              onBlur={this.props.onBlur}
 | 
			
		||||
            />
 | 
			
		||||
          </div>;
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
      <AddButton name='add' style={{ float: 'right' }}
 | 
			
		||||
        onClick={this.bindValue.bind(this)} />
 | 
			
		||||
| 
						 | 
				
			
			@ -47,17 +45,17 @@ class BlacklistForm extends React.Component<Props> {
 | 
			
		|||
  bindValue(e: any) {
 | 
			
		||||
    let name = e.target.name;
 | 
			
		||||
    let index = e.target.getAttribute('data-index');
 | 
			
		||||
    let next = this.props.value.slice();
 | 
			
		||||
    let items = this.props.value.items;
 | 
			
		||||
 | 
			
		||||
    if (name === 'url') {
 | 
			
		||||
      next[index] = e.target.value;
 | 
			
		||||
      items[index] = new BlacklistItem(e.target.value, false, []);
 | 
			
		||||
    } else if (name === 'add') {
 | 
			
		||||
      next.push('');
 | 
			
		||||
      items.push(new BlacklistItem('', false, []));
 | 
			
		||||
    } else if (name === 'delete') {
 | 
			
		||||
      next.splice(index, 1);
 | 
			
		||||
      items.splice(index, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.props.onChange(next);
 | 
			
		||||
    this.props.onChange(new Blacklist(items));
 | 
			
		||||
    if (name === 'delete') {
 | 
			
		||||
      this.props.onBlur();
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										28
									
								
								src/settings/components/form/PartialBlacklistForm.scss
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								src/settings/components/form/PartialBlacklistForm.scss
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,28 @@
 | 
			
		|||
.form-partial-blacklist-form {
 | 
			
		||||
  @mixin row-base {
 | 
			
		||||
    display: flex;
 | 
			
		||||
 | 
			
		||||
    .column-url {
 | 
			
		||||
      flex: 5;
 | 
			
		||||
      min-width: 0;
 | 
			
		||||
    }
 | 
			
		||||
    .column-keys {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      min-width: 0;
 | 
			
		||||
    }
 | 
			
		||||
    .column-delete {
 | 
			
		||||
      flex: 1;
 | 
			
		||||
      min-width: 0;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-header {
 | 
			
		||||
    @include row-base;
 | 
			
		||||
 | 
			
		||||
    font-weight: bold;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  &-row {
 | 
			
		||||
    @include row-base;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										79
									
								
								src/settings/components/form/PartialBlacklistForm.tsx
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/settings/components/form/PartialBlacklistForm.tsx
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,79 @@
 | 
			
		|||
import './PartialBlacklistForm.scss';
 | 
			
		||||
import AddButton from '../ui/AddButton';
 | 
			
		||||
import DeleteButton from '../ui/DeleteButton';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import Blacklist, { BlacklistItem } from '../../../shared/settings/Blacklist';
 | 
			
		||||
 | 
			
		||||
interface Props {
 | 
			
		||||
  value: Blacklist;
 | 
			
		||||
  onChange: (value: Blacklist) => void;
 | 
			
		||||
  onBlur: () => void;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class PartialBlacklistForm extends React.Component<Props> {
 | 
			
		||||
  public static defaultProps: Props = {
 | 
			
		||||
    value: new Blacklist([]),
 | 
			
		||||
    onChange: () => {},
 | 
			
		||||
    onBlur: () => {},
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render() {
 | 
			
		||||
    return <div className='form-partial-blacklist-form'>
 | 
			
		||||
      <div className='form-partial-blacklist-form-header'>
 | 
			
		||||
        <div className='column-url'>URL</div>
 | 
			
		||||
        <div className='column-keys'>Keys</div>
 | 
			
		||||
      </div>
 | 
			
		||||
      {
 | 
			
		||||
        this.props.value.items.map((item, index) => {
 | 
			
		||||
          if (!item.partial) {
 | 
			
		||||
            return null;
 | 
			
		||||
          }
 | 
			
		||||
          return <div key={index} className='form-partial-blacklist-form-row'>
 | 
			
		||||
            <input data-index={index} type='text' name='url'
 | 
			
		||||
              className='column-url' value={item.pattern}
 | 
			
		||||
              onChange={this.bindValue.bind(this)}
 | 
			
		||||
              onBlur={this.props.onBlur}
 | 
			
		||||
            />
 | 
			
		||||
            <input data-index={index} type='text' name='keys'
 | 
			
		||||
              className='column-keys' value={item.keys.join(',')}
 | 
			
		||||
              onChange={this.bindValue.bind(this)}
 | 
			
		||||
              onBlur={this.props.onBlur}
 | 
			
		||||
            />
 | 
			
		||||
            <DeleteButton data-index={index} name='delete'
 | 
			
		||||
              onClick={this.bindValue.bind(this)}
 | 
			
		||||
              onBlur={this.props.onBlur}
 | 
			
		||||
            />
 | 
			
		||||
          </div>;
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
      <AddButton name='add' style={{ float: 'right' }}
 | 
			
		||||
        onClick={this.bindValue.bind(this)} />
 | 
			
		||||
    </div>;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bindValue(e: any) {
 | 
			
		||||
    let name = e.target.name;
 | 
			
		||||
    let index = e.target.getAttribute('data-index');
 | 
			
		||||
    let items = this.props.value.items;
 | 
			
		||||
 | 
			
		||||
    if (name === 'url') {
 | 
			
		||||
      let current = items[index];
 | 
			
		||||
      items[index] = new BlacklistItem(e.target.value, true, current.keys);
 | 
			
		||||
    } else if (name === 'keys') {
 | 
			
		||||
      let current = items[index];
 | 
			
		||||
      items[index] = new BlacklistItem(
 | 
			
		||||
        current.pattern, true, e.target.value.split(','));
 | 
			
		||||
    } else if (name === 'add') {
 | 
			
		||||
      items.push(new BlacklistItem('', true, []));
 | 
			
		||||
    } else if (name === 'delete') {
 | 
			
		||||
      items.splice(index, 1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.props.onChange(new Blacklist(items));
 | 
			
		||||
    if (name === 'delete') {
 | 
			
		||||
      this.props.onBlur();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default PartialBlacklistForm;
 | 
			
		||||
| 
						 | 
				
			
			@ -6,6 +6,7 @@ import SearchForm from './form/SearchForm';
 | 
			
		|||
import KeymapsForm from './form/KeymapsForm';
 | 
			
		||||
import BlacklistForm from './form/BlacklistForm';
 | 
			
		||||
import PropertiesForm from './form/PropertiesForm';
 | 
			
		||||
import PartialBlacklistForm from './form/PartialBlacklistForm';
 | 
			
		||||
import * as settingActions from '../../settings/actions/setting';
 | 
			
		||||
import SettingData, {
 | 
			
		||||
  FormKeymaps, FormSearch, FormSettings, JSONTextSettings,
 | 
			
		||||
| 
						 | 
				
			
			@ -53,7 +54,15 @@ class SettingsComponent extends React.Component<Props> {
 | 
			
		|||
      <fieldset>
 | 
			
		||||
        <legend>Blacklist</legend>
 | 
			
		||||
        <BlacklistForm
 | 
			
		||||
          value={form.blacklist.toJSON()}
 | 
			
		||||
          value={form.blacklist}
 | 
			
		||||
          onChange={this.bindBlacklistForm.bind(this)}
 | 
			
		||||
          onBlur={this.save.bind(this)}
 | 
			
		||||
        />
 | 
			
		||||
      </fieldset>
 | 
			
		||||
      <fieldset>
 | 
			
		||||
        <legend>Partial blacklist</legend>
 | 
			
		||||
        <PartialBlacklistForm
 | 
			
		||||
          value={form.blacklist}
 | 
			
		||||
          onChange={this.bindBlacklistForm.bind(this)}
 | 
			
		||||
          onBlur={this.save.bind(this)}
 | 
			
		||||
        />
 | 
			
		||||
| 
						 | 
				
			
			@ -138,11 +147,10 @@ class SettingsComponent extends React.Component<Props> {
 | 
			
		|||
    this.props.dispatch(settingActions.set(data));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bindBlacklistForm(value: any) {
 | 
			
		||||
  bindBlacklistForm(blacklist: Blacklist) {
 | 
			
		||||
    let data = new SettingData({
 | 
			
		||||
      source: this.props.source,
 | 
			
		||||
      form: (this.props.form as FormSettings).buildWithBlacklist(
 | 
			
		||||
        Blacklist.fromJSON(value)),
 | 
			
		||||
      form: (this.props.form as FormSettings).buildWithBlacklist(blacklist),
 | 
			
		||||
    });
 | 
			
		||||
    this.props.dispatch(settingActions.set(data));
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,5 @@
 | 
			
		|||
import Key from './Key';
 | 
			
		||||
 | 
			
		||||
export type BlacklistItemJSON = string | {
 | 
			
		||||
  url: string,
 | 
			
		||||
  keys: string[],
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +33,9 @@ export class BlacklistItem {
 | 
			
		|||
 | 
			
		||||
  public readonly keys: string[];
 | 
			
		||||
 | 
			
		||||
  private constructor(
 | 
			
		||||
  private readonly keyEntities: Key[];
 | 
			
		||||
 | 
			
		||||
  constructor(
 | 
			
		||||
    pattern: string,
 | 
			
		||||
    partial: boolean,
 | 
			
		||||
    keys: string[]
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +44,7 @@ export class BlacklistItem {
 | 
			
		|||
    this.regex = regexFromWildcard(pattern);
 | 
			
		||||
    this.partial = partial;
 | 
			
		||||
    this.keys = keys;
 | 
			
		||||
    this.keyEntities = this.keys.map(Key.fromMapKey);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static fromJSON(raw: any): BlacklistItem {
 | 
			
		||||
| 
						 | 
				
			
			@ -81,17 +86,20 @@ export class BlacklistItem {
 | 
			
		|||
      : this.regex.test(url.host);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  includeKey(url: URL, keys: string): boolean {
 | 
			
		||||
  includeKey(url: URL, key: Key): boolean {
 | 
			
		||||
    if (!this.matches(url)) {
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    return !this.partial || this.keys.includes(keys);
 | 
			
		||||
    if (!this.partial) {
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    return this.keyEntities.some(k => k.equals(key));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default class Blacklist {
 | 
			
		||||
  constructor(
 | 
			
		||||
    private blacklist: BlacklistItem[],
 | 
			
		||||
    public readonly items: BlacklistItem[],
 | 
			
		||||
  ) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -104,14 +112,14 @@ export default class Blacklist {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  toJSON(): BlacklistJSON {
 | 
			
		||||
    return this.blacklist.map(item => item.toJSON());
 | 
			
		||||
    return this.items.map(item => item.toJSON());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  includesEntireBlacklist(url: URL): boolean {
 | 
			
		||||
    return this.blacklist.some(item => !item.partial && item.matches(url));
 | 
			
		||||
    return this.items.some(item => !item.partial && item.matches(url));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  includeKey(url: URL, key: string) {
 | 
			
		||||
    return this.blacklist.some(item => item.includeKey(url, key));
 | 
			
		||||
  includeKey(url: URL, key: Key) {
 | 
			
		||||
    return this.items.some(item => item.includeKey(url, key));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import Key from '../../shared/settings/Key';
 | 
			
		||||
import Key from './Key';
 | 
			
		||||
 | 
			
		||||
export default class KeySequence {
 | 
			
		||||
  constructor(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,13 +2,16 @@ import React from 'react';
 | 
			
		|||
import ReactDOM from 'react-dom';
 | 
			
		||||
import ReactTestRenderer from 'react-test-renderer';
 | 
			
		||||
import ReactTestUtils from 'react-dom/test-utils';
 | 
			
		||||
import BlacklistForm from 'settings/components/form/BlacklistForm'
 | 
			
		||||
import { expect } from 'chai'
 | 
			
		||||
 | 
			
		||||
import BlacklistForm from '../../../../src/settings/components/form/BlacklistForm'
 | 
			
		||||
import Blacklist from '../../../../src/shared/settings/Blacklist';
 | 
			
		||||
 | 
			
		||||
describe("settings/form/BlacklistForm", () => {
 | 
			
		||||
  describe('render', () => {
 | 
			
		||||
    it('renders BlacklistForm', () => {
 | 
			
		||||
      let root = ReactTestRenderer.create(
 | 
			
		||||
        <BlacklistForm value={['*.slack.com', 'www.google.com/maps']} />,
 | 
			
		||||
        <BlacklistForm value={Blacklist.fromJSON(['*.slack.com', 'www.google.com/maps'])} />,
 | 
			
		||||
      ).root;
 | 
			
		||||
 | 
			
		||||
      let children = root.children[0].children;
 | 
			
		||||
| 
						 | 
				
			
			@ -43,10 +46,10 @@ describe("settings/form/BlacklistForm", () => {
 | 
			
		|||
    it('invokes onChange event on edit', (done) => {
 | 
			
		||||
      ReactTestUtils.act(() => {
 | 
			
		||||
        ReactDOM.render(<BlacklistForm
 | 
			
		||||
          value={['*.slack.com', 'www.google.com/maps*']}
 | 
			
		||||
          value={Blacklist.fromJSON(['*.slack.com', 'www.google.com/maps*'])}
 | 
			
		||||
          onChange={value => {
 | 
			
		||||
            expect(value).to.have.lengthOf(2);
 | 
			
		||||
            expect(value).to.have.members(['gitter.im', 'www.google.com/maps*']);
 | 
			
		||||
            let urls = value.items.map(item => item.pattern);
 | 
			
		||||
            expect(urls).to.have.members(['gitter.im', 'www.google.com/maps*']);
 | 
			
		||||
            done();
 | 
			
		||||
          }}
 | 
			
		||||
        />, container)
 | 
			
		||||
| 
						 | 
				
			
			@ -60,10 +63,10 @@ describe("settings/form/BlacklistForm", () => {
 | 
			
		|||
    it('invokes onChange event on delete', (done) => {
 | 
			
		||||
      ReactTestUtils.act(() => {
 | 
			
		||||
        ReactDOM.render(<BlacklistForm
 | 
			
		||||
          value={['*.slack.com', 'www.google.com/maps*']}
 | 
			
		||||
          value={Blacklist.fromJSON(['*.slack.com', 'www.google.com/maps*'])}
 | 
			
		||||
          onChange={value => {
 | 
			
		||||
            expect(value).to.have.lengthOf(1);
 | 
			
		||||
            expect(value).to.have.members(['www.google.com/maps*']);
 | 
			
		||||
            let urls = value.items.map(item => item.pattern);
 | 
			
		||||
            expect(urls).to.have.members(['www.google.com/maps*']);
 | 
			
		||||
            done();
 | 
			
		||||
          }}
 | 
			
		||||
        />, container)
 | 
			
		||||
| 
						 | 
				
			
			@ -76,10 +79,10 @@ describe("settings/form/BlacklistForm", () => {
 | 
			
		|||
    it('invokes onChange event on add', (done) => {
 | 
			
		||||
      ReactTestUtils.act(() => {
 | 
			
		||||
        ReactDOM.render(<BlacklistForm
 | 
			
		||||
          value={['*.slack.com']}
 | 
			
		||||
          value={Blacklist.fromJSON(['*.slack.com'])}
 | 
			
		||||
          onChange={value => {
 | 
			
		||||
            expect(value).to.have.lengthOf(2);
 | 
			
		||||
            expect(value).to.have.members(['*.slack.com', '']);
 | 
			
		||||
            let urls = value.items.map(item => item.pattern);
 | 
			
		||||
            expect(urls).to.have.members(['*.slack.com', '']);
 | 
			
		||||
            done();
 | 
			
		||||
          }}
 | 
			
		||||
        />, container);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
import Blacklist, { BlacklistItem } from '../../../src/shared/settings/Blacklist';
 | 
			
		||||
import { expect } from 'chai';
 | 
			
		||||
import Key from '../../../src/shared/settings/Key';
 | 
			
		||||
 | 
			
		||||
describe('BlacklistItem', () => {
 | 
			
		||||
  describe('#fromJSON', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -82,11 +83,13 @@ describe('BlacklistItem', () => {
 | 
			
		|||
 | 
			
		||||
  describe('#includesPartialKeys', () => {
 | 
			
		||||
    it('matches with partial keys', () => {
 | 
			
		||||
      let item = BlacklistItem.fromJSON({url: 'google.com', keys: ['j', 'k']});
 | 
			
		||||
      let item = BlacklistItem.fromJSON({url: 'google.com', keys: ['j', 'k', '<C-U>']});
 | 
			
		||||
 | 
			
		||||
      expect(item.includeKey(new URL('http://google.com/maps'), 'j')).to.be.true;
 | 
			
		||||
      expect(item.includeKey(new URL('http://google.com/maps'), 'z')).to.be.false;
 | 
			
		||||
      expect(item.includeKey(new URL('http://maps.google.com/'), 'j')).to.be.false;
 | 
			
		||||
      expect(item.includeKey(new URL('http://google.com/maps'), Key.fromMapKey('j'))).to.be.true;
 | 
			
		||||
      expect(item.includeKey(new URL('http://google.com/maps'), Key.fromMapKey('<C-U>'))).to.be.true;
 | 
			
		||||
      expect(item.includeKey(new URL('http://google.com/maps'), Key.fromMapKey('z'))).to.be.false;
 | 
			
		||||
      expect(item.includeKey(new URL('http://google.com/maps'), Key.fromMapKey('u'))).to.be.false;
 | 
			
		||||
      expect(item.includeKey(new URL('http://maps.google.com/'), Key.fromMapKey('j'))).to.be.false;
 | 
			
		||||
    })
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			@ -147,9 +150,9 @@ describe('Blacklist', () => {
 | 
			
		|||
        { url: 'github.com', keys: ['j', 'k'] },
 | 
			
		||||
      ]);
 | 
			
		||||
 | 
			
		||||
      expect(blacklist.includeKey(new URL('https://google.com'), 'j')).to.be.true;
 | 
			
		||||
      expect(blacklist.includeKey(new URL('https://github.com'), 'j')).to.be.true;
 | 
			
		||||
      expect(blacklist.includeKey(new URL('https://github.com'), 'a')).to.be.false;
 | 
			
		||||
      expect(blacklist.includeKey(new URL('https://google.com'), Key.fromMapKey('j'))).to.be.true;
 | 
			
		||||
      expect(blacklist.includeKey(new URL('https://github.com'), Key.fromMapKey('j'))).to.be.true;
 | 
			
		||||
      expect(blacklist.includeKey(new URL('https://github.com'), Key.fromMapKey('a'))).to.be.false;
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Reference in a new issue