Like SystemiConnectFri 15 Oct 2021, 04:50
Auto Save MessagesLGforumFri 26 Feb 2021, 13:31
New tutorial questionTheCrowMon 15 Feb 2021, 08:12
Support iOS Emojis (and other platforms)LGforumSun 14 Feb 2021, 01:25
LGforum (2806)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
Mr.Easybb (1587)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
Bloodbath (745)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
Rukiafan (533)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
Dom (513)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
puppycheese (446)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
pedro (330)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
Neymar (301)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
Hitsu (281)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 
Flora (275)
Javascript Shortcuts (Combinator) Vote_lcapJavascript Shortcuts (Combinator) Voting_barJavascript Shortcuts (Combinator) Vote_rcap 


Javascript Shortcuts (Combinator)

Mr.EasybbMr.Easybb
Status : Love this site, that's why I'm back each day again... lol Samantha's co-owner now. Well deserved!

Posts : 1587
Join date : 2013-01-04
Mon 07 Sep 2015, 23:46
Hello Everyone, I figured I'd post this here before I release the official Github page for Combinator. I'll have you guys do some initial testing if you want. Combinator is a small Javascript library for Keyboard shortcuts, i.e. ( [ic]ctrl+c[/ic], [ic]ctrl+j[/ic], [ic]ctrl+shift+d[/ic]) anything that you want and you can tell the page to do what you want instead. There are a few libraries out there already but I figured I'd post mine since mine is more user friend in the sense and does have some advantages compared to others like Mousetrap.

Combinator is very easy to use and comes with a wrapped up keyCodes object for your using without Combinator initialised. I'll explain that below after Combinator.

So first why the name Combinator? Well shortcuts are a combination of keys pressed, and well this is like the terminator of shortcuts thus Combinator was born Smile



So include this Javascript file.

Code:
[panda=js]
!function(){"use strict";function e(e,t,n){"addEventListener"in document?e.addEventListener(t,n):"attachEvent"in document?e.attachEvent("on"+t,n):e["on"+t]=n}function t(e,t,n){"addEventListener"in document?e.removeEventListener(t,n):"detachEvent"in document?e.attachEvent("on"+t,n):e["on"+t]=null}function n(e,n,r){r||(r=document);var i=this;addListener(r,"keydown",function a(o){i.waiting?keyCodes.literal[e.toUpperCase()]===o.which&&(n.call(i,o),i.waiting=!1,t(this,"keydown",a)):t(r,"keydown",a)})}function r(e){for(var t in y.cmd)e.call(y.cmd,t)}function i(t){t||(t=document),e(t,"keydown",function(e){var t,i,a,o,c;if(t="which"in e?e.which:e.keyCode,e.ctrlKey&&-1===p.indexOf("ctrl")&&p.push("ctrl"),e.altKey&&-1===p.indexOf("alt")&&p.push("alt"),e.shiftKey&&-1===p.indexOf("shift")&&p.push("shift"),p.length>0&&(g=!0,r(function(e){this[e].hasOwnProperty("waiting")&&delete this[e].waiting})),i=keyCodes.numerical[t],-1===p.indexOf(i)&&p.push(i),a=p.join("+").toLowerCase(),y.cmd.hasOwnProperty(a)){if(o=y.cmd[a],e.preventDefault(),e.stopPropagation(),!o.repeat&&o.executed||o.once&&o.called)return!1;if(o.repeat||(m=o),!o.input)for(c=e.target;c!=document.body;){if(!o.input&&("input"===c.tagName.toLowerCase()||"textarea"===c.tagName.toLowerCase()))return!1;if(!o.input&&c.hasAttribute("contenteditable")&&c.getAttribute("contenteditable")===!0)return!1;c=c.parentNode}if(null!==o.ignoreClass){var s=o.ignoreClass.replace(/\s+/g,"|");if(s=new RegExp(s,"gi"),s.test(this.className))return!1}o.waiting=!0,o.exec.call(e,n.bind(o)),o.executed=!0,o.called=!0,p=[],a=""}}),e(t,"keyup",function(e){var t,n,r="which"in e?e.which:e.keyCode;return n=p.join("+").toLowerCase(),17===r||18===r?(e.preventDefault(),g=!1,p=[],!1):(t=p.indexOf(keyCodes.numerical[r]),t>-1&&p.splice(t,1),null!==m&&(m.executed=!1),void 0)})}function a(e){return e=e.toLowerCase(),y.cmd.hasOwnProperty(e)?y.cmd[e]:null}function o(e){return e=e.toLowerCase(),y.cmd.hasOwnProperty(e)?(delete y.cmd[e],!0):!1}function c(e,t){var n={};if("string"!=typeof e)return new Error("The first argument for register must be a string combinator.");if(e=e.toLowerCase(),/Mac|iPod|iPhone|iPad/.test(navigator.platform)&&e.replace("ctrl","meta"),w.indexOf(e)>-1==!0)return new Error(e+" cannot be used, this is a system specific combinator");if(y.cmd.hasOwnProperty(e))return new Error(e+" already exists. Please release this combinator before overwriting.");if(e.split("+").length>4)return new Error(e+" is too long, the system can only handle four consecutive keys pressed.");for(var r in f)t.hasOwnProperty(r)&&"executed"!==r&&"called"!==r&&"waiting"!==r?n[r]=t[r]:n[r]=f[r];y.cmd[e]=n}function s(e){if(e=e.toLowerCase(),y.cmd.hasOwnProperty(e)){var t=y.cmd[e];t.waiting=!0,t.exec.call(t,n.bind(t))}}function d(n,r){return r||(r=document),h=!0,e(r,"keydown",function i(e){if(h){var r="which"in e?e.which:e.keyCode,a=keyCodes.numerical[r];n.call(this,a,e)}else t(this,"keydown",i)}),{stop:l}}function l(){h=!1}function u(e){return e=e.toLowerCase(),y.cmd.hasOwnProperty(e)?(y.cmd[e].executed=!1,y.cmd[e].called=!1,!0):!1}var w=["ctrl+n","ctrl+shift+n","ctrl+t","ctrl+shift+t","ctrl+w","ctrl+shift+w"],f={title:null,exec:function(){},repeat:!0,input:!0,once:!1,executed:!1,called:!1,ignoreClass:null},h=!1,p=[],m=null,g=!1;window.keyCodes={},window.keyCodes.numerical={8:"backspace",9:"tab",13:"enter",16:"shift",17:"ctrl",18:"alt",19:"pause/break",20:"caps lock",27:"escapse",33:"page up",34:"page down",35:"end",36:"home",37:"left arrow",38:"up arrow",39:"right arrow",40:"down arrow",45:"insert",46:"delete",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",65:"A",66:"B",67:"C",68:"D",69:"E",70:"F",71:"G",72:"H",73:"I",74:"J",75:"K",76:"L",77:"M",78:"N",79:"O",80:"P",81:"Q",82:"R",83:"S",84:"T",85:"U",86:"V",87:"W",88:"X",89:"Y",90:"Z",91:"left window",106:"multiply",107:"add",109:"subtract",110:"decimal point",111:"divide",186:"semi-colon",187:"equal sign",188:"comma",189:"dash",190:"period",191:"forward slash",192:"grave accent",219:"open bracket",220:"back slash",221:"close bracket",222:"single quote"},window.keyCodes.literal={backspace:8,tab:9,enter:13,shift:16,ctrl:17,alt:18,"pause/break":19,"caps lock":20,escape:27,"page up":33,"page down":34,end:35,home:36,"left arrow":37,"up arrow":38,"right arrow":39,"down arrow":40,insert:45,"delete":46,0:48,1:49,2:50,3:51,4:52,5:53,6:54,7:55,8:56,9:57,A:65,B:66,C:67,D:68,E:69,F:70,G:71,H:72,I:73,J:74,K:75,L:76,M:77,N:78,O:79,P:80,Q:81,R:82,S:83,T:84,U:85,V:86,W:87,X:88,Y:89,Z:90,"left window":91,multiply:106,add:107,subtract:109,"decimal point":110,divide:111,"semi-colon":186,"equal sign":187,comma:188,dash:189,period:190,"forward slash":191,"grave accent":192,"open bracket":219,"back slash":220,"close bracket":221,"single quote":222};var y={fetch:a,register:c,listen:i,release:o,reset:u,trigger:s,record:d,cmd:{}};window.combinator=y}();

Mark it all pages, or you can add it directly to the head of your document by editing the head template.



So basically you're done, but how do we listen to shortcuts or anything like that? Well there are eight properties to the combinator object, and below is the explanation to each.





[ic]combinator.register(shortcut,properties);[/ic]

The register property is a function to add new shortcuts, I prefer you to use this method but you can write out the list of them yourself using the [ic]combinator.cmd[/ic] property. So let's take a look at how to use the register property.

Code:
[panda=js]
combinator.register("ctrl+b",{
    title: null,
    exec:function() {
        console.log("hello");
    },
    input: true,
    repeat:true,
    once:false,
    ignoreClass: null
});

So the above is a simple register example. Some notes to understand, most of what you see is the default value except for the exec property. So if you want your command to work inside inputs (inputs, textareas, contenteditable elements) then you don't need to add it. Basically if the default is true for you, you don't need to add it at all. So let's go over each of these properties separately.

[ic] title [/ic] is the name of the command

[ic] exec [/ic] is the function to execute when the command is entered. It has one argument which is a sequence to listen for after. See example below to understand. The [ic]this[/ic] inside the scope of exec is the [ic]event[/ic] property of keydown.

[ic] input [/ic] default is true, meaning the commands will work inside any input element, textarea, or contenteditable element.

[ic] repeat [/ic] default is true, repeat means if we hold down the command it will repeat itself, if we want it to execute once instead of repeat set this to false. Though remember the user just has to lift their finger from the key and press it again and it'll work.

[ic] once [/ic] default is false, once is basically what it says. The command will only fire once no matter how many times the user presses it the command. You can reset this later if you want.

[ic] ignoreClass [/ic] default is null, if you want an element such as a textarea that you don't want the commands to work in then create a class such as "ignore-halt" and add it to the textarea, this is good because if you only want one textarea to not work and other inputs to work then this is how it is done.




[ic]combinator.listen(location);[/ic]

listen makes the location we set, default argument is document, listen for the commands. Later this will be useful when combinator allows for multiple instances of combinator. If you want the entire document to listen then just leave the argument alone.



[ic]combinator.fetch(shortcut);[/ic]

fetch gets the object we want from our [ic]combinator.cmd[/ic] object, this is just useful so we don't have to write [ic]combinator.cmd["ctrl+b"][/ic] especially since I made cases all lower case and if you think that your command is actually [ic]ctrl+B[/ic] it will actually be [ic]ctrl+b[/ic]



[ic]combinator.release(shortcut);[/ic]

Release, this is a special function since we don't allow you to overwrite combinators you must first release the original from the object. This is incase you forget that you already defined the combinator.

Returns true if the object is released.

[ic]combinator.trigger(shortcut);[/ic]

trigger makes it so you can trigger the [ic]exec[/ic] function that you defined without having to press the commands.

[ic]combinator.record(callback,location);[/ic]

record the event on keydown happening in a specific location, default location is document again. This is great to use if you want to just listen to what keys were pressed. Example later on. Save this in a variable because it returns a function to stop listening.

[ic]combinator.cmd[/ic]

The cmd object is all the commands you've entered in.



Examples:

Code:
[panda=js]
    combinator.register("ctrl+b",{
        title:"my new ctrl+b",
        exec:function(sequence) {
            sequence("a",function(e){
                console.log("A was pressed");
            },document);
        }
    });

This combinator will work as follows. So first we press [ic]ctrl+b[/ic] now we wait and if we press [ic]a[/ic] the message that is logged will be "A was pressed".

Remember that if a new combinator is started that the old sequence that was waiting will be destroyed.


Code:
[panda=js]
  var recorder =  combinator.record(function(literal, e){
        console.log(literal + " is " + e.which + " in a numerical key");
        recorder.stop();
    },document.body);

What this does is if we press "enter" it will log "Enter is 13 in a numerical key". Then the recorder will stop.


A complex example:

Code:
[panda=js]
    combinator.register("ctrl+b",{
        title:"my new ctrl+b",
        exec:function(sequence) {
            sequence("a",function(e){
                combinator.reset("ctrl+b");
            });
        },
        once:true
    });

This will actually be a combinator that runs only once, until we press "a" then it will reset the combinator and we can start over again.



If you'd like any more examples please give me an idea and I'll write an example for you.
Mr.EasybbMr.Easybb
Status : Love this site, that's why I'm back each day again... lol Samantha's co-owner now. Well deserved!

Posts : 1587
Join date : 2013-01-04
Tue 08 Sep 2015, 00:34
I forgot about the keyCodes object that is wrapped inside Combinator. It's very easy to use if you don't want to use the entirety of Combinator.

Code:
[panda=js]document.addEventListener("keydown",function(e){
  if( keyCodes.literal.enter === e.which)
      console.log("true");
  if( keyCodes.numerical[e.which] === "enter")
      console.log("true");
});

Or if you want to know the key code of a button use

Code:
[panda=js]console.log(keyCodes.numerical[13]);
//logs enter
Mr.EasybbMr.Easybb
Status : Love this site, that's why I'm back each day again... lol Samantha's co-owner now. Well deserved!

Posts : 1587
Join date : 2013-01-04
Tue 08 Sep 2015, 23:56
I real usage for AvacWeb would be

Code:
[panda=js]combinator.register("ctrl+shift+c",{
    title:"Insert CSS BBCode",
    exec:function(){
        avac_editor.insert('[code][panda=css]','[/code]');
    },
    repeat:false
});

combinator.listen(avac_editor.box);
LGforumLGforum
Status : Working to restore AWC!

Posts : 2806
Join date : 2011-10-05
Age : 30
Location : UK
Mon 14 Sep 2015, 16:09
I love this! I haven't really seen this type of thing before but I think it would work great with the Avacweb editor. Smile
I might just have to have a more thorough look at this, can you link me to the Github page for it when you release it.
Mr.EasybbMr.Easybb
Status : Love this site, that's why I'm back each day again... lol Samantha's co-owner now. Well deserved!

Posts : 1587
Join date : 2013-01-04
Tue 15 Sep 2015, 00:55
I surely will, it's on there right now but the Wiki isn't complete. Plus I am releasing two versions, a debugging version and a regular version. Both will also have a minified version. There is something I forgot to mention which some key combinators will not work because they are OS / Browser specific and this is because of Chrome4 and other browsers decided to do the same.

Code:
[panda=js]["ctrl+n", "ctrl+shift+n", "ctrl+t", "ctrl+shift+t", "ctrl+w", "ctrl+shift+w"];

Those are the keys that are not able to be over written.

You can view the github here, I'm not positive it is done yet, I know it doesn't have updated minified version nor debugging versions yet.

https://github.com/chrisbaldwinj/combinator
avatarcinder75
Status : No status yet...

Posts : 23
Join date : 2014-08-20
Sat 17 Oct 2015, 06:43
Mr.EasyBB we need your Easysupport Addon PLZZZZZZZZZZZZZ :C hahaha
Andrei34Andrei34
Status : yyy

Posts : 12
Join date : 2015-09-04
Sat 17 Oct 2015, 11:00
Looks interesting. I would like to use this but I'm not very good at javascript. Is it possible that when somebody press Ctrl+V, in place of seeing the source code of the webpage, an alert box to be opened? If yes, how can I do that?
Mr.EasybbMr.Easybb
Status : Love this site, that's why I'm back each day again... lol Samantha's co-owner now. Well deserved!

Posts : 1587
Join date : 2013-01-04
Sat 17 Oct 2015, 18:08
@Andrei34 ctrl+v is paste you can override that. You can't however override the few I posted above that's os specifics now. And @cinder I'm not sure of I have that source but I'll look into it. Please if you all have suggestions for me post them on the thread of my announcement of me being the new administration / manager here ok. It's easier for me to sort through it all.

So now I'm on the computer I'll show you a ctrl+v method

Code:
[panda=js]combinator.register("ctrl+v",{
    title:"Paste Rejection!",
    exec:function(){
        alert("HEY DON't PRESS THAT COMBINATOR AGAIN!");
    },
    repeat:false
});
Mr.EasybbMr.Easybb
Status : Love this site, that's why I'm back each day again... lol Samantha's co-owner now. Well deserved!

Posts : 1587
Join date : 2013-01-04
Sat 17 Oct 2015, 19:14
@Cinder just wrote a new algorithm for easySupport making the program a lot smaller!!
avatarcinder75
Status : No status yet...

Posts : 23
Join date : 2014-08-20
Sun 18 Oct 2015, 09:09
:O thats awesome thanks a lot THANKSSSSSS! Razz
Andrei34Andrei34
Status : yyy

Posts : 12
Join date : 2015-09-04
Sun 18 Oct 2015, 15:44
@Mr.EasyBB, I was refering at Ctrl+U Smile Anyway, thank ypu, I will test the code later.
Mr.EasybbMr.Easybb
Status : Love this site, that's why I'm back each day again... lol Samantha's co-owner now. Well deserved!

Posts : 1587
Join date : 2013-01-04
Mon 19 Oct 2015, 04:32
As long as it's not in the not allowed list it'll overwrite the default action.
Sponsored content