Heello Keyboard Shortcuts

jkでタイムラインをスクロール

Dovrai installare un'estensione come Tampermonkey, Greasemonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Violentmonkey per installare questo script.

Dovrai installare un'estensione come Tampermonkey o Userscripts per installare questo script.

Dovrai installare un'estensione come ad esempio Tampermonkey per installare questo script.

Dovrai installare un gestore di script utente per installare questo script.

(Ho già un gestore di script utente, lasciamelo installare!)

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione come ad esempio Stylus per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

Dovrai installare un'estensione per la gestione degli stili utente per installare questo stile.

(Ho già un gestore di stile utente, lasciamelo installare!)

// ==UserScript==
// @name          Heello Keyboard Shortcuts 
// @namespace     http://userstyles.org
// @description   jkでタイムラインをスクロール
// @author        kawarin
// @match         http://heello.com/*
// @match         https://heello.com/*
// @version       0.7
// ==/UserScript==

// Navigation
// 
// j: Next Ping 
// k: Previous Ping 
// gg: Scroll to top
// shift+g: Scroll to bottom
//
// Actions
//
// e: Echo 



/****************************************************************
 * http://www.openjs.com/scripts/events/keyboard_shortcuts/
 * Version : 2.01.B
 * By Binny V A
 * License : BSD
 */
shortcut = {
    'all_shortcuts':{},//All the shortcuts are stored in this array
    'add': function(shortcut_combination,callback,opt) {
        //Provide a set of default options
        var default_options = {
            'type':'keydown',
            'propagate':false,
            'disable_in_input':true,
            'target':document,
            'keycode':false
        }
        if(!opt) opt = default_options;
        else {
            for(var dfo in default_options) {
                if(typeof opt[dfo] == 'undefined') opt[dfo] = default_options[dfo];
            }
        }

        var ele = opt.target;
        if(typeof opt.target == 'string') ele = document.getElementById(opt.target);
        var ths = this;
        shortcut_combination = shortcut_combination.toLowerCase();

        //The function to be called at keypress
        var func = function(e) {
            e = e || window.event;

            if(opt['disable_in_input']) { //Don't enable shortcut keys in Input, Textarea fields
                var element;
                if(e.target) element=e.target;
                else if(e.srcElement) element=e.srcElement;
                if(element.nodeType==3) element=element.parentNode;

                if(element.tagName == 'INPUT' || element.tagName == 'TEXTAREA') return;
            }

            //Find Which key is pressed
            if (e.keyCode) code = e.keyCode;
            else if (e.which) code = e.which;
            var character = String.fromCharCode(code).toLowerCase();

            if(code == 188) character=","; //If the user presses , when the type is onkeydown
            if(code == 190) character="."; //If the user presses , when the type is onkeydown

            var keys = shortcut_combination.split("+");
            //Key Pressed - counts the number of valid keypresses - if it is same as the number of keys, the shortcut function is invoked
            var kp = 0;

            //Work around for stupid Shift key bug created by using lowercase - as a result the shift+num combination was broken
            var shift_nums = {
                "`":"~",
                "1":"!",
                "2":"@",
                "3":"#",
                "4":"$",
                "5":"%",
                "6":"^",
                "7":"&",
                "8":"*",
                "9":"(",
                "0":")",
                "-":"_",
                "=":"+",
                ";":":",
                "'":"\"",
                ",":"<",
                ".":">",
                "/":"?",
                "\\":"|"
            }
            //Special Keys - and their codes
            var special_keys = {
                'esc':27,
                'escape':27,
                'tab':9,
                'space':32,
                'return':13,
                'enter':13,
                'backspace':8,

                'scrolllock':145,
                'scroll_lock':145,
                'scroll':145,
                'capslock':20,
                'caps_lock':20,
                'caps':20,
                'numlock':144,
                'num_lock':144,
                'num':144,

                'pause':19,
                'break':19,

                'insert':45,
                'home':36,
                'delete':46,
                'end':35,

                'pageup':33,
                'page_up':33,
                'pu':33,

                'pagedown':34,
                'page_down':34,
                'pd':34,

                'left':37,
                'up':38,
                'right':39,
                'down':40,

                'f1':112,
                'f2':113,
                'f3':114,
                'f4':115,
                'f5':116,
                'f6':117,
                'f7':118,
                'f8':119,
                'f9':120,
                'f10':121,
                'f11':122,
                'f12':123
            }

            var modifiers = { 
                shift: { wanted:false, pressed:false},
                ctrl : { wanted:false, pressed:false},
                alt  : { wanted:false, pressed:false},
                meta : { wanted:false, pressed:false}    //Meta is Mac specific
            };

            if(e.ctrlKey)    modifiers.ctrl.pressed = true;
            if(e.shiftKey)    modifiers.shift.pressed = true;
            if(e.altKey)    modifiers.alt.pressed = true;
            if(e.metaKey)   modifiers.meta.pressed = true;

            for(var i=0; k=keys[i],i<keys.length; i++) {
                //Modifiers
                if(k == 'ctrl' || k == 'control') {
                    kp++;
                    modifiers.ctrl.wanted = true;

                } else if(k == 'shift') {
                    kp++;
                    modifiers.shift.wanted = true;

                } else if(k == 'alt') {
                    kp++;
                    modifiers.alt.wanted = true;
                } else if(k == 'meta') {
                    kp++;
                    modifiers.meta.wanted = true;
                } else if(k.length > 1) { //If it is a special key
                    if(special_keys[k] == code) kp++;

                } else if(opt['keycode']) {
                    if(opt['keycode'] == code) kp++;

                } else { //The special keys did not match
                    if(character == k) kp++;
                    else {
                        if(shift_nums[character] && e.shiftKey) { //Stupid Shift key bug created by using lowercase
                            character = shift_nums[character]; 
                            if(character == k) kp++;
                        }
                    }
                }
            }

            if(kp == keys.length && 
                    modifiers.ctrl.pressed == modifiers.ctrl.wanted &&
                    modifiers.shift.pressed == modifiers.shift.wanted &&
                    modifiers.alt.pressed == modifiers.alt.wanted &&
                    modifiers.meta.pressed == modifiers.meta.wanted) {
                        callback(e);

                        if(!opt['propagate']) { //Stop the event
                            //e.cancelBubble is supported by IE - this will kill the bubbling process.
                            e.cancelBubble = true;
                            e.returnValue = false;

                            //e.stopPropagation works in Firefox.
                            if (e.stopPropagation) {
                                e.stopPropagation();
                                e.preventDefault();
                            }
                            return false;
                        }
                    }
        }
        this.all_shortcuts[shortcut_combination] = {
            'callback':func, 
            'target':ele, 
            'event': opt['type']
        };
        //Attach the function with the event
        if(ele.addEventListener) ele.addEventListener(opt['type'], func, false);
        else if(ele.attachEvent) ele.attachEvent('on'+opt['type'], func);
        else ele['on'+opt['type']] = func;
    },

    //Remove the shortcut - just specify the shortcut and I will remove the binding
    'remove':function(shortcut_combination) {
        shortcut_combination = shortcut_combination.toLowerCase();
        var binding = this.all_shortcuts[shortcut_combination];
        delete(this.all_shortcuts[shortcut_combination])
            if(!binding) return;
        var type = binding['event'];
        var ele = binding['target'];
        var callback = binding['callback'];

        if(ele.detachEvent) ele.detachEvent('on'+type, callback);
        else if(ele.removeEventListener) ele.removeEventListener(type, callback, false);
        else ele['on'+type] = false;
    }
};

/**********************************************************/
/*           End of "shorcut.js"                          */
/**********************************************************/


// Add class name
function add_class_name(obj,add_classes){
    var tmp_hash = new Array();
    var new_class_names = new Array();
    var class_names = obj.className.split(" ").concat(add_classes.split(" "));
    for(var i in class_names){if(class_names[i] != ""){tmp_hash[class_names[i]] = 0;}}
    for(var key in tmp_hash){new_class_names.push(key);}
    obj.className = new_class_names.join(" ");
}

// Delete class name 
function delete_class_name(obj,delete_classes){
    var new_class_names = new Array();
    var class_names = obj.className.split(" ");
    var delete_class_names = delete_classes.split(" ");
    for(var i in class_names){
        var flag = true;
        for(var j in delete_class_names){
            if(class_names[i] == delete_class_names[j]){flag = false;break;};
        }
        if(flag){new_class_names.push(class_names[i])}
    }
    obj.className = new_class_names.join(" ");
}
/*
// Send Ping
function shortPing(content) {
    var obj = new XMLHttpRequest();
    obj.open('POST', "https://heello.com/pings.json", true);
    obj.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    obj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    obj.send("text="+encodeURIComponent(content));
}

// Echo
function shortEcho(id) {
    var obj = new XMLHttpRequest();
    obj.open('POST', "https://heello.com/pings/" + id + "/echo", true);
    obj.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    obj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    obj.send('');
}

// Like
function shortLike(id) {
    var obj = new XMLHttpRequest();
    obj.open('POST', "https://heello.com/pings/" + id + "/like.json", true);
    obj.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
    obj.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    obj.send('');
}

// Button
function clickPing(){
    var forms = document.getElementsByTagName('form');
    if (forms[0].getElementsByTagName('textarea')[0].value){
        document.querySelector('div.modal-buttons input[type="button"].grey-button').click();
    }
    if (forms[1]) {
        if (forms[1].getElementsByTagName('textarea')[0].value){
            forms[1].querySelector('input[type="button"].grey-button').click();
        }
    }
    document.activeElement.blur();
}
*/

// Scroll window
function scrollStream(elm) {
    var body = document.body;
    var html = document.documentElement;
    var rect = elm.getBoundingClientRect();
    var pos = {
        "left": rect.left + (body.scrollLeft || html.scrollLeft),
        "top" : rect.top  + (body.scrollTop || html.scrollTop) - (html.clientHeight)/2 + 90 
    }
    window.scrollTo(body.scrollLeft || html.scrollLeft, pos.top);
}

// Initialization
var userprofile = document.querySelector('ul#nav-buttons.nav-pills li.dropdown ul.dropdown-menu li a').href;
var username = userprofile.replace('https://heello.com/', '');

// Background-color of selected Ping 
var sh = document.styleSheets[0];
sh.insertRule("div.hovered-stream-item {background-color: #eff8ff;}", sh.cssRules.length);

var pnt = null;
var cmf = false;
var elements = document.getElementById('timeline');

//var newPing = document.querySelector('span#nav-compose.black-button img');
var click = function(n) {
    var e = document.createEvent('MouseEvents');
    e.initMouseEvent("click",true,true,window,0,0,0,0,0,false,false,false,false,0,null);
    n.dispatchEvent(e);
};

// Keyboard shortcuts

// Navigation
//
// j: Next Ping
shortcut.add('j', function() {
    var hov = elements.querySelector('div.hovered-stream-item');
    if (pnt === null) {
        add_class_name(elements.querySelector('div[data-id]'), 'hovered-stream-item');
        pnt = 0;
    } else if (pnt >= 0 && pnt < elements.querySelectorAll('div[data-id]').length-1) {
        delete_class_name(hov, 'hovered-stream-item');
        add_class_name(elements.querySelectorAll('div[data-id]')[pnt+1], 'hovered-stream-item');
        pnt++;
    }
    var hov2 = elements.querySelector('div.hovered-stream-item');
    if (hov2) {
        scrollStream(hov2);
    }
});

// k: Previous Ping
shortcut.add('k', function() {
    var hov = elements.querySelector('div.hovered-stream-item');
    if (pnt === 0) {
        delete_class_name(hov, 'hovered-stream-item');
        pnt = null;
    } else if (pnt > 0) {
        delete_class_name(hov, 'hovered-stream-item');
        add_class_name(elements.querySelectorAll('div[data-id]')[pnt-1], 'hovered-stream-item');
        pnt--;
    }
    var hov2 = elements.querySelector('div.hovered-stream-item');
    if (hov2) {
        scrollStream(hov2);
    }
});

// shift+g: scroll to bottom
shortcut.add('shift+g', function() {
    var hov = elements.querySelector('div.hovered-stream-item');
    var pings = elements.querySelectorAll('div[data-id]');
    if (pnt !== null && pnt < pings.length-1) {
        delete_class_name(hov, 'hovered-stream-item');
    }
    pnt = pings.length-1;
    add_class_name(pings[pnt], 'hovered-stream-item');
    scrollStream(pings[pnt]);
});

// Actions
//
// e: Echo
shortcut.add('e', function() {
//    var id;
    var echolink;
    var hov = elements.querySelector('div.hovered-stream-item');
    if (hov) {
        echolink = hov.querySelector('a[href$="echo"]');
//        id = hov.getAttribute('data-id');
    } else {
//        id = elements.querySelector('div[data-id]').getAttribute('data-id');
        echolink = elements.querySelector('div[data-id] a[href$="echo"]');
    }
//    shortEcho(id);
    click(echolink);
});
/*
// c: Repeat
shortcut.add('c', function() {
    var content;
    var hov = elements.querySelector('div.hovered-stream-item');
    if (hov) {
        content = hov.querySelector('div.ping-text').textContent;        
    } else {
        content = elements.querySelector('div.ping-text').textContent;
    }
    shortPing(content);
});
*/
// enter: Open Ping details
shortcut.add('enter', function() {
    window.location.href = elements.querySelector('div.hovered-stream-item h3 small a').href;
});
/*
// n: New Ping
shortcut.add('n', function() {
    click(newPing);
});

// shift + enter: Send Ping
// ctrl + enter : Send Ping
shortcut.add('shift+enter', function() {
    clickPing();
}, { 'disable_in_input': false});

shortcut.add('ctrl+enter', function() {
    clickPing();
}, { 'disable_in_input': false});
*/
// Timelines
//
//   g: Timeline Commands Flag ON
// g g: Scroll to top
shortcut.add('g', function() {
    if (cmf) {
        cmf = false;
        var hov = elements.querySelector('div.hovered-stream-item');
        if (hov) {
            delete_class_name(hov, 'hovered-stream-item');
        }
        pnt = null;
        window.scrollTo(document.body.scrollLeft || document.documentElement.scrollLeft, 0);
    } else {
        cmf = true;
    }
});
/*
// g h: Home
shortcut.add('h', function() {
    if (cmf) {
        cmf = false;
        window.location.href = '/';
    }
});

//   r: Reply
// g r: Replies
shortcut.add('r', function() {
    if (cmf) {
        cmf = false;
        window.location.href = '/replies';
    } else {
        click(elements.querySelector('div.hovered-stream-item span.ping-reply img'));
    }
});

// g l: What's Happening?
shortcut.add('l', function() {
    if (cmf) {
        cmf = false;
        window.location.href = '/live';
    }
});

// g p: Profile
shortcut.add('p', function() {
    if (cmf) {
        cmf = false;
        window.location.href = '/' + username;
    }
});

// g s: Settings
shortcut.add('s', function() {
    if (cmf) {
        cmf = false;
        window.location.href = '/account/settings';
    }
});

//   f: Like      
// g f: Likes
shortcut.add('f', function() {
    if (cmf) {
        cmf = false;
        window.location.href = '/' + username + '/likes';
    } else {
        var hov = elements.querySelector('div.hovered-stream-item');
        if (hov) {
            id = hov.getAttribute('data-id');
            shortLike(id);
        }
    }
});

//
// esc: Close modal windows
shortcut.add('esc', function() {
    cmf = false;
    var closeButtons = document.querySelectorAll("div.modal-title div.modal-title-close");
    for (var i=0; i<closeButtons.length; i++) {
        click(closeButtons[i]);
    }
    document.activeElement.blur();
}, {'disable_in_input': false});
*/