aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.eslintrc1
-rw-r--r--src/content/components/common/follow.js31
-rw-r--r--src/content/components/top-content/follow-controller.js18
-rw-r--r--test/content/components/common/follow.test.js5
4 files changed, 42 insertions, 13 deletions
diff --git a/.eslintrc b/.eslintrc
index d244c8f..5636171 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -29,6 +29,7 @@
"id-length": "off",
"indent": ["error", 2],
"jsx-quotes": ["error", "prefer-single"],
+ "max-params": ["error", 5],
"max-statements": ["error", 15],
"multiline-ternary": "off",
"newline-after-var": "off",
diff --git a/src/content/components/common/follow.js b/src/content/components/common/follow.js
index a5fbab4..92d8822 100644
--- a/src/content/components/common/follow.js
+++ b/src/content/components/common/follow.js
@@ -6,16 +6,25 @@ const TARGET_SELECTOR = [
'[contenteditable=true]', '[contenteditable=""]'
].join(',');
-const inWindow = (win, element) => {
+const inViewport = (win, element, viewSize, framePosition) => {
let {
top, left, bottom, right
} = element.getBoundingClientRect();
let doc = win.doc;
- return (
- top >= 0 && left >= 0 &&
- bottom <= (win.innerHeight || doc.documentElement.clientHeight) &&
- right <= (win.innerWidth || doc.documentElement.clientWidth)
- );
+ let frameWidth = win.innerWidth || doc.documentElement.clientWidth;
+ let frameHeight = win.innerHeight || doc.documentElement.clientHeight;
+
+ if (right < 0 || bottom < 0 || top > frameHeight || left > frameWidth) {
+ // out of frame
+ return false;
+ }
+ if (right + framePosition.x < 0 || bottom + framePosition.y < 0 ||
+ left + framePosition.x > viewSize.width ||
+ top + framePosition.y > viewSize.height) {
+ // out of viewport
+ return false;
+ }
+ return true;
};
export default class Follow {
@@ -60,8 +69,8 @@ export default class Follow {
});
}
- countHints(sender) {
- this.targets = Follow.getTargetElements(this.win);
+ countHints(sender, viewSize, framePosition) {
+ this.targets = Follow.getTargetElements(this.win, viewSize, framePosition);
sender.postMessage(JSON.stringify({
type: messages.FOLLOW_RESPONSE_COUNT_TARGETS,
count: this.targets.length,
@@ -133,7 +142,7 @@ export default class Follow {
onMessage(message, sender) {
switch (message.type) {
case messages.FOLLOW_REQUEST_COUNT_TARGETS:
- return this.countHints(sender);
+ return this.countHints(sender, message.viewSize, message.framePosition);
case messages.FOLLOW_CREATE_HINTS:
return this.createHints(message.keysArray, message.newTab);
case messages.FOLLOW_SHOW_HINTS:
@@ -145,7 +154,7 @@ export default class Follow {
}
}
- static getTargetElements(win) {
+ static getTargetElements(win, viewSize, framePosition) {
let all = win.document.querySelectorAll(TARGET_SELECTOR);
let filtered = Array.prototype.filter.call(all, (element) => {
let style = win.getComputedStyle(element);
@@ -153,7 +162,7 @@ export default class Follow {
style.visibility !== 'hidden' &&
element.type !== 'hidden' &&
element.offsetHeight > 0 &&
- inWindow(win, element);
+ inViewport(win, element, viewSize, framePosition);
});
return filtered;
}
diff --git a/src/content/components/top-content/follow-controller.js b/src/content/components/top-content/follow-controller.js
index 0474690..29f40b3 100644
--- a/src/content/components/top-content/follow-controller.js
+++ b/src/content/components/top-content/follow-controller.js
@@ -87,8 +87,24 @@ export default class FollowController {
count() {
this.producer = new HintKeyProducer(DEFAULT_HINT_CHARSET);
- broadcastMessage(this.win, {
+ let doc = this.win.document;
+ let viewWidth = this.win.innerWidth || doc.documentElement.clientWidth;
+ let viewHeight = this.win.innerHeight || doc.documentElement.clientHeight;
+ let frameElements = this.win.document.querySelectorAll('frame,iframe');
+
+ this.win.postMessage(JSON.stringify({
type: messages.FOLLOW_REQUEST_COUNT_TARGETS,
+ viewSize: { width: viewWidth, height: viewHeight },
+ framePosition: { x: 0, y: 0 },
+ }), '*');
+ frameElements.forEach((element) => {
+ let { left: frameX, top: frameY } = element.getBoundingClientRect();
+ let message = JSON.stringify({
+ type: messages.FOLLOW_REQUEST_COUNT_TARGETS,
+ viewSize: { width: viewWidth, height: viewHeight },
+ framePosition: { x: frameX, y: frameY },
+ });
+ element.contentWindow.postMessage(message, '*');
});
}
diff --git a/test/content/components/common/follow.test.js b/test/content/components/common/follow.test.js
index 97bd1d2..1fc935e 100644
--- a/test/content/components/common/follow.test.js
+++ b/test/content/components/common/follow.test.js
@@ -8,7 +8,10 @@ describe('FollowComponent', () => {
});
it('returns visible links', () => {
- let targets = FollowComponent.getTargetElements(window);
+ let targets = FollowComponent.getTargetElements(
+ window,
+ { width: window.innerWidth, height: window.innerHeight },
+ { x: 0, y: 0 });
expect(targets).to.have.lengthOf(3);
let ids = Array.prototype.map.call(targets, (e) => e.id);