diff options
author | Shin'ya Ueoka <ueokande@i-beam.org> | 2018-05-01 15:51:40 +0900 |
---|---|---|
committer | Shin'ya Ueoka <ueokande@i-beam.org> | 2018-05-01 15:51:40 +0900 |
commit | 9da2f5fd786ff7ef64eca0a86efb1c0b9a164244 (patch) | |
tree | b888349817d0016dc1499932671bbe6cd95efdaa /src/content/components | |
parent | f9889b7f2b634bfe5a540633d8952f4a6f900658 (diff) | |
parent | 89d6afecfd257ff4fc62748f771abf37ef3a2852 (diff) |
Merge remote-tracking branch 'origin/master' into patch-1
Diffstat (limited to 'src/content/components')
-rw-r--r-- | src/content/components/common/follow.js | 28 | ||||
-rw-r--r-- | src/content/components/common/input.js | 6 | ||||
-rw-r--r-- | src/content/components/common/keymapper.js | 3 | ||||
-rw-r--r-- | src/content/components/top-content/find.js | 13 | ||||
-rw-r--r-- | src/content/components/top-content/follow-controller.js | 23 |
5 files changed, 48 insertions, 25 deletions
diff --git a/src/content/components/common/follow.js b/src/content/components/common/follow.js index 7a35105..2a55ea3 100644 --- a/src/content/components/common/follow.js +++ b/src/content/components/common/follow.js @@ -4,7 +4,8 @@ import * as dom from 'shared/utils/dom'; const TARGET_SELECTOR = [ 'a', 'button', 'input', 'textarea', 'area', - '[contenteditable=true]', '[contenteditable=""]', '[tabindex]' + '[contenteditable=true]', '[contenteditable=""]', '[tabindex]', + '[role="button"]' ].join(','); @@ -29,11 +30,27 @@ const inViewport = (win, element, viewSize, framePosition) => { return true; }; +const isAriaHiddenOrAriaDisabled = (win, element) => { + if (!element || win.document.documentElement === element) { + return false; + } + for (let attr of ['aria-hidden', 'aria-disabled']) { + if (element.hasAttribute(attr)) { + let hidden = element.getAttribute(attr).toLowerCase(); + if (hidden === '' || hidden === 'true') { + return true; + } + } + } + return isAriaHiddenOrAriaDisabled(win, element.parentNode); +}; + export default class Follow { constructor(win, store) { this.win = win; this.store = store; this.newTab = false; + this.background = false; this.hints = {}; this.targets = []; @@ -47,6 +64,7 @@ export default class Follow { this.win.parent.postMessage(JSON.stringify({ type: messages.FOLLOW_KEY_PRESS, key: key.key, + ctrlKey: key.ctrlKey, }), '*'); return true; } @@ -68,6 +86,7 @@ export default class Follow { type: messages.OPEN_URL, url: element.href, newTab: true, + background: this.background, }); } @@ -79,12 +98,13 @@ export default class Follow { }), '*'); } - createHints(keysArray, newTab) { + createHints(keysArray, newTab, background) { if (keysArray.length !== this.targets.length) { throw new Error('illegal hint count'); } this.newTab = newTab; + this.background = background; this.hints = {}; for (let i = 0; i < keysArray.length; ++i) { let keys = keysArray[i]; @@ -150,7 +170,8 @@ export default class Follow { case messages.FOLLOW_REQUEST_COUNT_TARGETS: return this.countHints(sender, message.viewSize, message.framePosition); case messages.FOLLOW_CREATE_HINTS: - return this.createHints(message.keysArray, message.newTab); + return this.createHints( + message.keysArray, message.newTab, message.background); case messages.FOLLOW_SHOW_HINTS: return this.showHints(message.keys); case messages.FOLLOW_ACTIVATE: @@ -170,6 +191,7 @@ export default class Follow { style.visibility !== 'hidden' && element.type !== 'hidden' && element.offsetHeight > 0 && + !isAriaHiddenOrAriaDisabled(win, element) && inViewport(win, element, viewSize, framePosition); }); return filtered; diff --git a/src/content/components/common/input.js b/src/content/components/common/input.js index 22b0a91..eefaf10 100644 --- a/src/content/components/common/input.js +++ b/src/content/components/common/input.js @@ -1,6 +1,10 @@ import * as dom from 'shared/utils/dom'; import * as keys from 'shared/utils/keys'; +const cancelKey = (e) => { + return e.key === 'Escape' || e.key === '[' && e.ctrlKey; +}; + export default class InputComponent { constructor(target) { this.pressed = {}; @@ -37,7 +41,7 @@ export default class InputComponent { capture(e) { if (this.fromInput(e)) { - if (e.key === 'Escape' && e.target.blur) { + if (cancelKey(e) && e.target.blur) { e.target.blur(); } return; diff --git a/src/content/components/common/keymapper.js b/src/content/components/common/keymapper.js index fb8fabe..d9d1b2f 100644 --- a/src/content/components/common/keymapper.js +++ b/src/content/components/common/keymapper.js @@ -47,7 +47,8 @@ export default class KeymapperComponent { return true; } let operation = keymaps.get(matched[0]); - this.store.dispatch(operationActions.exec(operation)); + this.store.dispatch(operationActions.exec( + operation, key.repeat, state.setting)); this.store.dispatch(inputActions.clearKeys()); return true; } diff --git a/src/content/components/top-content/find.js b/src/content/components/top-content/find.js index bccf040..4d46d79 100644 --- a/src/content/components/top-content/find.js +++ b/src/content/components/top-content/find.js @@ -1,6 +1,5 @@ import * as findActions from 'content/actions/find'; import messages from 'shared/messages'; -import * as consoleFrames from '../../console-frames'; export default class FindComponent { constructor(win, store) { @@ -32,23 +31,11 @@ export default class FindComponent { next() { let state = this.store.getState().find; - - if (!state.found) { - return consoleFrames.postError( - window.document, - 'Pattern not found: ' + state.keyword); - } return this.store.dispatch(findActions.next(state.keyword, false)); } prev() { let state = this.store.getState().find; - - if (!state.found) { - return consoleFrames.postError( - window.document, - 'Pattern not found: ' + state.keyword); - } return this.store.dispatch(findActions.prev(state.keyword, false)); } } diff --git a/src/content/components/top-content/follow-controller.js b/src/content/components/top-content/follow-controller.js index d373177..7f36604 100644 --- a/src/content/components/top-content/follow-controller.js +++ b/src/content/components/top-content/follow-controller.js @@ -1,8 +1,7 @@ import * as followControllerActions from 'content/actions/follow-controller'; import messages from 'shared/messages'; import HintKeyProducer from 'content/hint-key-producer'; - -const DEFAULT_HINT_CHARSET = 'abcdefghijklmnopqrstuvwxyz'; +import * as properties from 'shared/settings/properties'; const broadcastMessage = (win, message) => { let json = JSON.stringify(message); @@ -29,11 +28,11 @@ export default class FollowController { switch (message.type) { case messages.FOLLOW_START: return this.store.dispatch( - followControllerActions.enable(message.newTab)); + followControllerActions.enable(message.newTab, message.background)); case messages.FOLLOW_RESPONSE_COUNT_TARGETS: return this.create(message.count, sender); case messages.FOLLOW_KEY_PRESS: - return this.keyPress(message.key); + return this.keyPress(message.key, message.ctrlKey); } } @@ -70,7 +69,11 @@ export default class FollowController { }); } - keyPress(key) { + keyPress(key, ctrlKey) { + if (key === '[' && ctrlKey) { + this.store.dispatch(followControllerActions.disable()); + return true; + } switch (key) { case 'Enter': this.activate(); @@ -84,7 +87,7 @@ export default class FollowController { this.store.dispatch(followControllerActions.backspace()); break; default: - if (DEFAULT_HINT_CHARSET.includes(key)) { + if (this.hintchars().includes(key)) { this.store.dispatch(followControllerActions.keyPress(key)); } break; @@ -93,7 +96,7 @@ export default class FollowController { } count() { - this.producer = new HintKeyProducer(DEFAULT_HINT_CHARSET); + this.producer = new HintKeyProducer(this.hintchars()); let doc = this.win.document; let viewWidth = this.win.innerWidth || doc.documentElement.clientWidth; let viewHeight = this.win.innerHeight || doc.documentElement.clientHeight; @@ -126,6 +129,7 @@ export default class FollowController { type: messages.FOLLOW_CREATE_HINTS, keysArray: produced, newTab: this.state.newTab, + background: this.state.background, }), '*'); } @@ -135,4 +139,9 @@ export default class FollowController { type: messages.FOLLOW_REMOVE_HINTS, }); } + + hintchars() { + return this.store.getState().setting.properties.hintchars || + properties.defaults.hintchars; + } } |