More work into base behaviour

- Selection stage sort-of finished (needs more love)
- Labels are only shown for items visible on screen, the rest are
  ignored.
- Current actions include focus for input, submit for forms and click
  for anchors.
- Using numbers for now, will change to text later.
This commit is contained in:
Felipe Martin 2017-04-01 13:12:40 +02:00
parent 82af7d3812
commit dbd77765a5
1 changed files with 78 additions and 19 deletions

View File

@ -1,9 +1,27 @@
var isVisible = function(node) {
// From: http://stackoverflow.com/questions/123999/how-to-tell-if-a-dom-element-is-visible-in-the-current-viewport/7557433#7557433
var rect = node.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
);
}
class KeyHinter {
constructor() {
this.number = 0;
this.nodes = {};
this.currentSelectionNumber = 0;
this.currentSelection = [];
this.mappings = {}
this.keyCodes = [
48, 49, 50, 51, 52, 53, 54, 55, 56, 57
]
}
// Highlight
@ -14,22 +32,18 @@ class KeyHinter {
this.listenKeybinds()
var _this = this;
document.querySelectorAll('a, form').forEach(function(nodeEl) {
_this.number++;
_this.nodes[_this.number] = nodeEl;
document.querySelectorAll('a, form, input').forEach(function(nodeEl) {
if (isVisible(nodeEl)) {
_this.number++;
_this.nodes[_this.number] = nodeEl;
var el = _this.generateLabelFor(nodeEl);
var el = _this.generateLabelFor(nodeEl);
if (nodeEl.nodeName == 'A') {
el.classList.add('keyhinter-label-anchor');
} else if (nodeEl.nodeName == 'FORM') {
el.classList.add('keyhinter-label-form');
el.textContent = _this.number;
el.setAttribute('data-keyhinter-number', _this.number);
document.body.appendChild(el);
}
el.textContent = _this.number;
el.setAttribute('data-keyhinter-number', _this.number);
document.body.appendChild(el);
})
}
@ -38,19 +52,65 @@ class KeyHinter {
var el = document.createElement('div');
var nodePosition = node.getBoundingClientRect();
el.classList.add('keyhinter-label');
el.style.left = nodePosition.left + 'px';
el.style.top = nodePosition.top + 'px';
if (node.nodeName === 'A') {
el.classList.add('keyhinter-label-anchor');
} else if (node.nodeName === 'FORM') {
el.classList.add('keyhinter-label-form');
} else if (node.nodeName === 'INPUT') {
el.classList.add('keyhinter-label-input');
}
return el;
}
doClick(obj) {
console.log(obj.nodeName)
switch(obj.nodeName) {
case 'INPUT':
obj.focus();
break;
case 'FORM':
obj.submit();
break;
default:
obj.click();
break;
}
}
// Keybinds
listenKeybinds() {
var _this = this;
document.onkeydown = function(event) {
if (event.keyCode == 27) {
console.log('Esc')
if (event.keyCode === 27) { // ESC
event.preventDefault();
_this.destroy();
} else if (_this.keyCodes.indexOf(event.keyCode) !== -1) {
event.preventDefault();
var num = event.keyCode - 48;
_this.currentSelection.push(num);
document.querySelectorAll('[data-keyhinter-number]').forEach(function(item){
item.style.visibility = 'hidden';
})
var query = document.querySelectorAll('[data-keyhinter-number^="' + _this.currentSelection.join('') + '"]')
if (query.length === 1) {
var node = _this.nodes[_this.currentSelection.join('')];
_this.doClick(node);
_this.destroy();
} else {
query.forEach(function(item){
item.style.visibility = 'visible'
})
_this.currentSelectionNumber++;
}
} else {
console.log("Default:" + event.keyCode)
}
}
}
@ -65,18 +125,17 @@ class KeyHinter {
document.body.removeChild(node);
})
this.stopListeningKeybinds();
stage = new KeyHinter()
keyHinter = new KeyHinter()
}
}
var stage = new KeyHinter();
var keyHinter = new KeyHinter();
chrome.runtime.onMessage.addListener(function (msg, sender, sendResponse) {
// If the received message has the expected format...
console.log(msg, sender, sendResponse)
if (msg.action === 'start_keyhinter') {
// Call the specified callback, passing
// the web-page's DOM content as argument
stage.highlight();
keyHinter.highlight();
}
});