diff options
Diffstat (limited to 'src/content/presenters/FollowPresenter.ts')
-rw-r--r-- | src/content/presenters/FollowPresenter.ts | 83 |
1 files changed, 49 insertions, 34 deletions
diff --git a/src/content/presenters/FollowPresenter.ts b/src/content/presenters/FollowPresenter.ts index fef8140..8aef819 100644 --- a/src/content/presenters/FollowPresenter.ts +++ b/src/content/presenters/FollowPresenter.ts @@ -1,11 +1,18 @@ -import Hint, { InputHint, LinkHint } from './Hint'; -import * as doms from '../../shared/utils/dom'; +import Hint, { InputHint, LinkHint } from "./Hint"; +import * as doms from "../../shared/utils/dom"; const TARGET_SELECTOR = [ - 'a', 'button', 'input', 'textarea', 'area', - '[contenteditable=true]', '[contenteditable=""]', '[tabindex]', - '[role="button"]', 'summary' -].join(','); + "a", + "button", + "input", + "textarea", + "area", + "[contenteditable=true]", + '[contenteditable=""]', + "[tabindex]", + '[role="button"]', + "summary", +].join(","); interface Size { width: number; @@ -21,11 +28,9 @@ const inViewport = ( win: Window, element: Element, viewSize: Size, - framePosition: Point, + framePosition: Point ): boolean => { - const { - top, left, bottom, right - } = doms.viewportRect(element); + const { top, left, bottom, right } = doms.viewportRect(element); const doc = win.document; const frameWidth = doc.documentElement.clientWidth; const frameHeight = doc.documentElement.clientHeight; @@ -34,9 +39,12 @@ const inViewport = ( // out of frame return false; } - if (right + framePosition.x < 0 || bottom + framePosition.y < 0 || - left + framePosition.x > viewSize.width || - top + framePosition.y > viewSize.height) { + if ( + right + framePosition.x < 0 || + bottom + framePosition.y < 0 || + left + framePosition.x > viewSize.width || + top + framePosition.y > viewSize.height + ) { // out of viewport return false; } @@ -47,11 +55,11 @@ const isAriaHiddenOrAriaDisabled = (win: Window, element: Element): boolean => { if (!element || win.document.documentElement === element) { return false; } - for (const attr of ['aria-hidden', 'aria-disabled']) { + for (const attr of ["aria-hidden", "aria-disabled"]) { const value = element.getAttribute(attr); if (value !== null) { const hidden = value.toLowerCase(); - if (hidden === '' || hidden === 'true') { + if (hidden === "" || hidden === "true") { return true; } } @@ -88,8 +96,10 @@ export class FollowPresenterImpl implements FollowPresenter { const min = Math.min(targets.length, tags.length); for (let i = 0; i < min; ++i) { const target = targets[i]; - if (target instanceof HTMLAnchorElement || - target instanceof HTMLAreaElement) { + if ( + target instanceof HTMLAnchorElement || + target instanceof HTMLAreaElement + ) { this.hints.push(new LinkHint(target, tags[i])); } else { this.hints.push(new InputHint(target, tags[i])); @@ -98,35 +108,40 @@ export class FollowPresenterImpl implements FollowPresenter { } filterHints(prefix: string): void { - const shown = this.hints.filter(h => h.getTag().startsWith(prefix)); - const hidden = this.hints.filter(h => !h.getTag().startsWith(prefix)); + const shown = this.hints.filter((h) => h.getTag().startsWith(prefix)); + const hidden = this.hints.filter((h) => !h.getTag().startsWith(prefix)); - shown.forEach(h => h.show()); - hidden.forEach(h => h.hide()); + shown.forEach((h) => h.show()); + hidden.forEach((h) => h.hide()); } clearHints(): void { - this.hints.forEach(h => h.remove()); + this.hints.forEach((h) => h.remove()); this.hints = []; } getHint(tag: string): Hint | undefined { - return this.hints.find(h => h.getTag() === tag); + return this.hints.find((h) => h.getTag() === tag); } private getTargets(viewSize: Size, framePosition: Point): HTMLElement[] { const all = window.document.querySelectorAll(TARGET_SELECTOR); - const filtered = Array.prototype.filter.call(all, (element: HTMLElement) => { - const style = window.getComputedStyle(element); - - // AREA's 'display' in Browser style is 'none' - return (element.tagName === 'AREA' || style.display !== 'none') && - style.visibility !== 'hidden' && - (element as HTMLInputElement).type !== 'hidden' && - element.offsetHeight > 0 && - !isAriaHiddenOrAriaDisabled(window, element) && - inViewport(window, element, viewSize, framePosition); - }); + const filtered = Array.prototype.filter.call( + all, + (element: HTMLElement) => { + const style = window.getComputedStyle(element); + + // AREA's 'display' in Browser style is 'none' + return ( + (element.tagName === "AREA" || style.display !== "none") && + style.visibility !== "hidden" && + (element as HTMLInputElement).type !== "hidden" && + element.offsetHeight > 0 && + !isAriaHiddenOrAriaDisabled(window, element) && + inViewport(window, element, viewSize, framePosition) + ); + } + ); return filtered; } } |