From 4b35a6c5563ca7a0d050c049280aafeb097060c0 Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 27 Mar 2016 13:21:52 -0700 Subject: [PATCH] Popup stub now working. --- ext/client.css | 27 ++++++++++++++++ ext/client.js | 63 +++++++++++++++++++++++++++++++++++++ ext/manifest.json | 3 +- ext/{content.js => util.js} | 55 ++++++++++++++++++++++---------- 4 files changed, 130 insertions(+), 18 deletions(-) create mode 100644 ext/client.css create mode 100644 ext/client.js rename ext/{content.js => util.js} (50%) diff --git a/ext/client.css b/ext/client.css new file mode 100644 index 00000000..913624d7 --- /dev/null +++ b/ext/client.css @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2016 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +.yomichan-popup { + background-color: #fff; + border: 1px solid #999; + box-shadow: 0 0 10px rgba(0, 0, 0, .5); + padding: 10px; + pointer-events: none; + position: fixed; + width: auto; +} diff --git a/ext/client.js b/ext/client.js new file mode 100644 index 00000000..535d3748 --- /dev/null +++ b/ext/client.js @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2016 Alex Yatskov + * Author: Alex Yatskov + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +class Client { + constructor() { + $('body').append('
'); + + this.popup = $('.yomichan-popup'); + this.popupOffset = 10; + + window.addEventListener('mousemove', whenEnabled(this.onMouseMove.bind(this))); + } + + onMouseMove(e) { + const range = getRangeAtCursor(e, 10); + if (range === null) { + this.hidePopup(); + return; + } + + const rect = getRangePaddedRect(range); + if (e.clientX < rect.left || e.clientX > rect.right) { + this.hidePopup(); + return; + } + + this.showPopup(range); + } + + showPopup(range) { + const selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); + + const pos = getPopupPositionForRange(this.popup, range, this.popupOffset); + this.popup.css({left: pos.x, top: pos.y, visibility: 'visible'}); + } + + hidePopup() { + const selection = window.getSelection(); + selection.removeAllRanges(); + + this.popup.css({visibility: 'hidden'}); + } +} + +window.yomiClient = new Client(); diff --git a/ext/manifest.json b/ext/manifest.json index a225faeb..9b244b16 100644 --- a/ext/manifest.json +++ b/ext/manifest.json @@ -9,6 +9,7 @@ "content_scripts": [{ "matches": ["*://*/*"], - "js": ["content.js", "api.js"] + "js": ["lib/jquery-2.2.2.min.js", "api.js", "util.js", "client.js"], + "css": ["client.css"] }] } diff --git a/ext/content.js b/ext/util.js similarity index 50% rename from ext/content.js rename to ext/util.js index 72e45337..e90904f1 100644 --- a/ext/content.js +++ b/ext/util.js @@ -30,30 +30,51 @@ function getRangeAtCursor(e, lookAhead) { const offset = range.startOffset; const length = Math.min(node.length - offset, lookAhead); + if (length === 0) { + return null; + } range.setEnd(node, offset + length); return range; } +function getRangePaddedRect(range) { + const node = range.startContainer; + const startOffset = range.startOffset; + const endOffset = range.endOffset; -function onMouseDown(e) { - // e.preventDefault(); + range.setStart(node, Math.max(0, startOffset - 1)); + range.setEnd(node, Math.min(node.length, endOffset + 1)); + const rect = range.getBoundingClientRect(); + range.setStart(node, startOffset); + range.setEnd(node, endOffset); - const range = getRangeAtCursor(e, 20); - if (range === null) { - return; - } - - const selection = window.getSelection(); - selection.removeAllRanges(); - selection.addRange(range); - - findTerm(range.toString(), response => { - console.log(response); - }); + return rect; } +function getPopupPositionForRange(popup, range, offset) { + const rangeRect = range.getBoundingClientRect(); + const popupRect = popup.get(0).getBoundingClientRect(); -(() => { - window.addEventListener('mousedown', onMouseDown, false); -})(); + let posX = rangeRect.left; + if (posX + popupRect.width >= window.innerWidth) { + posX = window.innerWidth - popupRect.width; + } + + let posY = rangeRect.bottom + offset; + if (posY + popupRect.height >= window.innerHeight) { + posY = rangeRect.top - popupRect.height - offset; + } + + return {x: posX, y: posY}; +} + +function whenEnabled(callback) { + return (...args) => { + getState((state) => { + if (state === 'enabled') { + callback(...args); + } + }); + }; +}