diff --git a/src/content/components/top-content/index.js b/src/content/components/top-content/index.js index c318901..c4a8461 100644 --- a/src/content/components/top-content/index.js +++ b/src/content/components/top-content/index.js @@ -1,7 +1,9 @@ import CommonComponent from '../common'; import FollowController from './follow-controller'; import * as consoleFrames from '../../console-frames'; +import * as addonActions from '../../actions/addon'; import messages from 'shared/messages'; +import * as re from 'shared/utils/re'; export default class TopContent { @@ -11,17 +13,39 @@ export default class TopContent { new CommonComponent(win, store), new FollowController(win, store), ]; + this.store = store; + this.prevBlacklist = undefined; // TODO make component - consoleFrames.initialize(window.document); + consoleFrames.initialize(this.win.document); messages.onMessage(this.onMessage.bind(this)); } update() { + let blacklist = this.store.getState().setting.blacklist; + if (JSON.stringify(this.prevBlacklist) !== JSON.stringify(blacklist)) { + this.disableIfBlack(blacklist); + this.prevBlacklist = blacklist; + } + this.children.forEach(c => c.update()); } + disableIfBlack(blacklist) { + let loc = this.win.location; + let partial = loc.host + loc.pathname; + let matched = blacklist + .map((item) => { + let pattern = item.includes('/') ? item : item + '/*'; + return re.fromWildcard(pattern); + }) + .some(regex => regex.test(partial)); + if (matched) { + this.store.dispatch(addonActions.disable()); + } + } + onMessage(message) { switch (message.type) { case messages.CONSOLE_HIDE_COMMAND: diff --git a/src/shared/utils/re.js b/src/shared/utils/re.js new file mode 100644 index 0000000..7db9091 --- /dev/null +++ b/src/shared/utils/re.js @@ -0,0 +1,6 @@ +const fromWildcard = (pattern) => { + let regexStr = '^' + pattern.replace(/\*/g, '.*') + '$'; + return new RegExp(regexStr); +}; + +export { fromWildcard }; diff --git a/src/shared/validators/setting.js b/src/shared/validators/setting.js index 5039ec2..949ab29 100644 --- a/src/shared/validators/setting.js +++ b/src/shared/validators/setting.js @@ -1,6 +1,6 @@ import operations from 'shared/operations'; -const VALID_TOP_KEYS = ['keymaps', 'search']; +const VALID_TOP_KEYS = ['keymaps', 'search', 'blacklist']; const VALID_OPERATION_VALUES = Object.keys(operations).map((key) => { return operations[key]; }); diff --git a/test/shared/util/re.test.js b/test/shared/util/re.test.js new file mode 100644 index 0000000..9ed6521 --- /dev/null +++ b/test/shared/util/re.test.js @@ -0,0 +1,20 @@ +import { expect } from 'chai'; +import * as re from 'shared/utils/re'; + +describe("re util", () => { + it('matches by pattern', () => { + let regex = re.fromWildcard('*.example.com/*'); + expect('foo.example.com/bar').to.match(regex); + expect('foo.example.com').not.to.match(regex); + expect('example.com/bar').not.to.match(regex); + + regex = re.fromWildcard('example.com/*') + expect('example.com/foo').to.match(regex); + expect('example.com/').to.match(regex); + + regex = re.fromWildcard('example.com/*bar') + expect('example.com/foobar').to.match(regex); + expect('example.com/bar').to.match(regex); + expect('example.com/foobarfoo').not.to.match(regex); + }) +});