Permalink
Browse files

Use default keyboard handling for browser in places

Rather than overriding and trying to interpret every key pressed, let
the default behavior happen if a specific keybinding hasn't been
registered over the top.

This enables a /ton/
  * Weird keyboards
  * Cross browser input (for unregistered keys)
  * Paste without flash! (no copy yet)

This works by attaching a hidden field when the input goes. If the
editor doesn't recognize the keys pressed as a registered binding, the
default behavior is executed upon this hidden field and its results
inserted into the editor. It is then cleared out.
  • Loading branch information...
1 parent e353cd9 commit ac98afa01a7b2eebf778ad862c6df8fc2fc44135 @rhburrows committed Jun 23, 2011
Showing with 30 additions and 61 deletions.
  1. +1 −1 example/editor.html
  2. +11 −5 src/core.js
  3. +3 −45 src/defaults.js
  4. +15 −1 src/input.js
  5. +0 −9 test/coreTest.js
View
2 example/editor.html
@@ -3,7 +3,7 @@
<title>Test</title>
</head>
<body>
- <textarea id="editor" cols="80" rows="92"></textarea>
+ <textarea id="editor" cols="80" rows="50"></textarea>
<script type="text/javascript" src="../lib/jquery-1.6.1.min.js"></script>
<script type="text/javascript" src="../src/core.js"></script>
<script type="text/javascript" src="../src/editor.js"></script>
View
16 src/core.js
@@ -28,12 +28,13 @@
var inputManager = new $.fn.s2e.config.InputManager();
textarea.css({
- position: 'absolute',
- left: '-' + (2*width) + 'px',
- top: '-' + (2*height) + 'px'
+ position: 'absolute',
+ left: '-' + (2*width) + 'px',
+ top: '-' + (2*height) + 'px'
});
textarea.val(options.initialText);
textarea.after(display.canvas);
+ textarea.after(inputManager.characterReader);
inputManager.bindKeys($.fn.s2e.config.keybindings);
@@ -48,7 +49,7 @@
display.paint(editor);
$(display).bind('s2e:click', function(ev) {
- textarea.focus();
+ $(inputManager.characterReader).focus();
editor.movePointTo(ev.position);
});
@@ -57,7 +58,12 @@
textarea.trigger(extendEvent(e, editor, display));
});
- textarea.keydown(inputManager.handler(editor));
+ $(inputManager.characterReader).keydown(inputManager.handler(editor));
+ $(inputManager.characterReader).css({
+ position: 'absolute',
+ left: '-300px',
+ top: '-300px'
+ });
return editor;
});
View
48 src/defaults.js
@@ -1,8 +1,4 @@
(function($){
- function insertF(c) {
- return function(e, ev){ e.insertChar(c); };
- }
-
var defaultKeys = {
'<LEFT>' : function(editor) {
editor.pointBackward();
@@ -28,18 +24,9 @@
editor.insertChar('\t');
},
- '<SPACE>' : insertF(' '),
- '<ENTER>' : insertF('\n'),
- 'S-1' : insertF('!'),
- 'S-2' : insertF('@'),
- 'S-3' : insertF('#'),
- 'S-4' : insertF('$'),
- 'S-5' : insertF('%'),
- 'S-6' : insertF('^'),
- 'S-7' : insertF('&'),
- 'S-8' : insertF('*'),
- 'S-9' : insertF('('),
- 'S-0' : insertF(')'),
+ '<ENTER>' : function(editor) {
+ editor.insertChar('\n');
+ },
'C-f' : function(editor) {
editor.pointForward();
@@ -66,34 +53,5 @@
}
};
- // some keys on my keyboard don't match js defaults
- // Bind these by hand because javascript thinks they are extended characters
- var extra = {
- '\\187' : ['=', '+'],
- '\\188' : [',', '<'],
- '\\190' : ['.', '>'],
- '\\191' : ['/', '?'],
- '\\219' : ['[', '{'],
- '\\220' : ['\\', '|'],
- '\\221' : [']', '}'],
- '\\222' : ['\'', '"']
- };
- $.each(extra, function(code, values) {
- defaultKeys[code] = function(e){ e.insertChar(values[0]); };
- defaultKeys['S-'+code] = function(e){ e.insertChar(values[1]); };
- });
-
- // Uppercase and lowercase letters
- for (var j=65; j<91; j++) {
- var c = String.fromCharCode(j);
- defaultKeys[c] = insertF(c.toLowerCase());
- defaultKeys['S-' + c] = insertF(c);
- }
- // 0-9
- for (var n=48; n<58; n++) {
- var num = String.fromCharCode(n);
- defaultKeys['\\' + n] = insertF(num);
- }
-
$.fn.s2e.config.keybindings = defaultKeys;
})(jQuery);
View
16 src/input.js
@@ -1,5 +1,7 @@
(function($){
function InputManager() {
+ this.characterReader = document.createElement('input');
+ $(this.characterReader).attr('type', 'text');
this.bindings = {};
}
@@ -60,6 +62,7 @@
handler : function(editor) {
var bindings = this.bindings;
+ var characterReader = this.characterReader;
return function(e) {
var keyString;
if (typeof SPECIAL_KEY_STRINGS[e.which] !== 'undefined') {
@@ -81,12 +84,23 @@
if (typeof bindings[keyString + modifiers] !== "undefined") {
e.preventDefault();
+ e.stopPropagation();
return bindings[keyString + modifiers](editor, e);
} else if (typeof bindings["\\" + e.which + modifiers] !== "undefined") {
e.preventDefault();
+ e.stopPropagation();
return bindings["\\" + e.which + modifiers](editor, e);
} else {
- e.preventDefault();
+ setTimeout(function(){
+ var s = $(characterReader).val();
+ if (s.length == 1) {
+ editor.insertChar(c);
+ } else if (s.length > 1) {
+ editor.insertString(s);
+ }
+ $(characterReader).val('');
+ }, 5);
+ e.stopPropagation();
return true;
}
};
View
9 test/coreTest.js
@@ -15,15 +15,6 @@ test("textarea-editor link", function(){
"It keeps the backing textarea synced to the canvas");
});
-test("click", function(){
- equals($('#editor:focus').size(), 0,
- "The textarea should not be focused to start");
-
- $("canvas").click();
- equals($('#editor:focus').size(), 1,
- "The textarea should be focused after clicking on the canvas");
-});
-
test("s2e:click is sent to the textarea", function(){
textarea.bind('s2e:click', function(e){
equals(e.editor, editor, "It provides access to the editor");

0 comments on commit ac98afa

Please sign in to comment.