mirror of
https://github.com/pcottle/learnGitBranching.git
synced 2025-06-29 17:27:22 +02:00
terminal much better
This commit is contained in:
parent
eed87168ed
commit
8bd5fb3196
7 changed files with 78 additions and 58 deletions
|
@ -14484,7 +14484,6 @@ var VisBranch = VisBase.extend({
|
||||||
branch.obj.get('visBranch')
|
branch.obj.get('visBranch')
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
console.log('getting text size', textNode, 'width', textNode.clientWidth);
|
|
||||||
|
|
||||||
return firefoxFix({
|
return firefoxFix({
|
||||||
w: maxWidth,
|
w: maxWidth,
|
||||||
|
@ -15067,13 +15066,15 @@ var MultiView = Backbone.View.extend({
|
||||||
this.navEvents = _.clone(Backbone.Events);
|
this.navEvents = _.clone(Backbone.Events);
|
||||||
this.navEvents.on('negative', this.getNegFunc(), this);
|
this.navEvents.on('negative', this.getNegFunc(), this);
|
||||||
this.navEvents.on('positive', this.getPosFunc(), this);
|
this.navEvents.on('positive', this.getPosFunc(), this);
|
||||||
|
this.navEvents.on('quit', this.finish, this);
|
||||||
|
|
||||||
this.keyboardListener = new KeyboardListener({
|
this.keyboardListener = new KeyboardListener({
|
||||||
events: this.navEvents,
|
events: this.navEvents,
|
||||||
aliasMap: {
|
aliasMap: {
|
||||||
left: 'negative',
|
left: 'negative',
|
||||||
right: 'positive',
|
right: 'positive',
|
||||||
enter: 'positive'
|
enter: 'positive',
|
||||||
|
esc: 'quit'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -16056,7 +16057,7 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
this.index = -1;
|
this.index = -1;
|
||||||
this.commandSpan = this.$('#prompt span.command')[0];
|
this.commandParagraph = this.$('#prompt p.command')[0];
|
||||||
this.commandCursor = this.$('#prompt span.cursor')[0];
|
this.commandCursor = this.$('#prompt span.cursor')[0];
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
||||||
|
@ -16093,16 +16094,11 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeyDown: function(e) {
|
onKeyDown: function(e) {
|
||||||
console.log('on keydown');
|
|
||||||
console.log(e);
|
|
||||||
|
|
||||||
var el = e.srcElement;
|
var el = e.srcElement;
|
||||||
this.updatePrompt(el);
|
this.updatePrompt(el);
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeyUp: function(e) {
|
onKeyUp: function(e) {
|
||||||
console.log('on key up');
|
|
||||||
console.log(e);
|
|
||||||
this.onKeyDown(e);
|
this.onKeyDown(e);
|
||||||
|
|
||||||
// we need to capture some of these events.
|
// we need to capture some of these events.
|
||||||
|
@ -16145,7 +16141,7 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
// well...
|
// well...
|
||||||
var text = $('#commandTextField').val();
|
var text = $('#commandTextField').val();
|
||||||
var val = this.badHtmlEncode(text);
|
var val = this.badHtmlEncode(text);
|
||||||
this.commandSpan.innerHTML = val;
|
this.commandParagraph.innerHTML = val;
|
||||||
|
|
||||||
// now mutate the cursor...
|
// now mutate the cursor...
|
||||||
this.cursorUpdate(text.length, el.selectionStart, el.selectionEnd);
|
this.cursorUpdate(text.length, el.selectionStart, el.selectionEnd);
|
||||||
|
@ -16155,24 +16151,31 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
|
|
||||||
cursorUpdate: function(commandLength, selectionStart, selectionEnd) {
|
cursorUpdate: function(commandLength, selectionStart, selectionEnd) {
|
||||||
if (selectionStart === undefined || selectionEnd === undefined) {
|
if (selectionStart === undefined || selectionEnd === undefined) {
|
||||||
selectionStart = 0;
|
selectionStart = commandLength - 1;
|
||||||
selectionEnd = 1;
|
selectionEnd = commandLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10px for monospaced font at "1" zoom
|
// 10px for monospaced font at "1" zoom
|
||||||
var zoom = require('../util/zoomLevel').detectZoom();
|
var zoom = require('../util/zoomLevel').detectZoom();
|
||||||
var widthPerChar = 10 * zoom;
|
var widthPerChar = 10 * zoom;
|
||||||
|
var heightPerRow = 22 * zoom;
|
||||||
|
|
||||||
var numCharsSelected = Math.max(1, selectionEnd - selectionStart);
|
var widthOfParagraph = $(this.commandParagraph).width();
|
||||||
var width = String(numCharsSelected * widthPerChar) + 'px';
|
var numCharsPerLine = widthOfParagraph / widthPerChar;
|
||||||
|
|
||||||
|
var numCharsSelected = Math.min(Math.max(1, selectionEnd - selectionStart), numCharsPerLine);
|
||||||
|
var widthOfSelection = String(numCharsSelected * widthPerChar) + 'px';
|
||||||
|
|
||||||
// now for positioning
|
// now for positioning
|
||||||
var numLeft = (selectionStart !== undefined) ? Math.max(commandLength - selectionStart, 0) : 0;
|
var leftOffset = String(widthPerChar * (selectionStart % numCharsPerLine)) + 'px';
|
||||||
var left = String(-numLeft * widthPerChar) + 'px';
|
var topOffset = String(Math.floor(selectionStart / numCharsPerLine) * heightPerRow) + 'px';
|
||||||
|
console.log('height per row', heightPerRow, 'selection start', selectionStart, 'num chars perline', numCharsPerLine);
|
||||||
|
|
||||||
// one reflow? :D
|
// one reflow? :D
|
||||||
$(this.commandCursor).css({
|
$(this.commandCursor).css({
|
||||||
width: width,
|
width: widthOfSelection,
|
||||||
left: left
|
left: leftOffset,
|
||||||
|
top: topOffset
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -20715,7 +20718,7 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
this.index = -1;
|
this.index = -1;
|
||||||
this.commandSpan = this.$('#prompt span.command')[0];
|
this.commandParagraph = this.$('#prompt p.command')[0];
|
||||||
this.commandCursor = this.$('#prompt span.cursor')[0];
|
this.commandCursor = this.$('#prompt span.cursor')[0];
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
||||||
|
@ -20752,16 +20755,11 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeyDown: function(e) {
|
onKeyDown: function(e) {
|
||||||
console.log('on keydown');
|
|
||||||
console.log(e);
|
|
||||||
|
|
||||||
var el = e.srcElement;
|
var el = e.srcElement;
|
||||||
this.updatePrompt(el);
|
this.updatePrompt(el);
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeyUp: function(e) {
|
onKeyUp: function(e) {
|
||||||
console.log('on key up');
|
|
||||||
console.log(e);
|
|
||||||
this.onKeyDown(e);
|
this.onKeyDown(e);
|
||||||
|
|
||||||
// we need to capture some of these events.
|
// we need to capture some of these events.
|
||||||
|
@ -20804,7 +20802,7 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
// well...
|
// well...
|
||||||
var text = $('#commandTextField').val();
|
var text = $('#commandTextField').val();
|
||||||
var val = this.badHtmlEncode(text);
|
var val = this.badHtmlEncode(text);
|
||||||
this.commandSpan.innerHTML = val;
|
this.commandParagraph.innerHTML = val;
|
||||||
|
|
||||||
// now mutate the cursor...
|
// now mutate the cursor...
|
||||||
this.cursorUpdate(text.length, el.selectionStart, el.selectionEnd);
|
this.cursorUpdate(text.length, el.selectionStart, el.selectionEnd);
|
||||||
|
@ -20814,24 +20812,31 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
|
|
||||||
cursorUpdate: function(commandLength, selectionStart, selectionEnd) {
|
cursorUpdate: function(commandLength, selectionStart, selectionEnd) {
|
||||||
if (selectionStart === undefined || selectionEnd === undefined) {
|
if (selectionStart === undefined || selectionEnd === undefined) {
|
||||||
selectionStart = 0;
|
selectionStart = commandLength - 1;
|
||||||
selectionEnd = 1;
|
selectionEnd = commandLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10px for monospaced font at "1" zoom
|
// 10px for monospaced font at "1" zoom
|
||||||
var zoom = require('../util/zoomLevel').detectZoom();
|
var zoom = require('../util/zoomLevel').detectZoom();
|
||||||
var widthPerChar = 10 * zoom;
|
var widthPerChar = 10 * zoom;
|
||||||
|
var heightPerRow = 22 * zoom;
|
||||||
|
|
||||||
var numCharsSelected = Math.max(1, selectionEnd - selectionStart);
|
var widthOfParagraph = $(this.commandParagraph).width();
|
||||||
var width = String(numCharsSelected * widthPerChar) + 'px';
|
var numCharsPerLine = widthOfParagraph / widthPerChar;
|
||||||
|
|
||||||
|
var numCharsSelected = Math.min(Math.max(1, selectionEnd - selectionStart), numCharsPerLine);
|
||||||
|
var widthOfSelection = String(numCharsSelected * widthPerChar) + 'px';
|
||||||
|
|
||||||
// now for positioning
|
// now for positioning
|
||||||
var numLeft = (selectionStart !== undefined) ? Math.max(commandLength - selectionStart, 0) : 0;
|
var leftOffset = String(widthPerChar * (selectionStart % numCharsPerLine)) + 'px';
|
||||||
var left = String(-numLeft * widthPerChar) + 'px';
|
var topOffset = String(Math.floor(selectionStart / numCharsPerLine) * heightPerRow) + 'px';
|
||||||
|
console.log('height per row', heightPerRow, 'selection start', selectionStart, 'num chars perline', numCharsPerLine);
|
||||||
|
|
||||||
// one reflow? :D
|
// one reflow? :D
|
||||||
$(this.commandCursor).css({
|
$(this.commandCursor).css({
|
||||||
width: width,
|
width: widthOfSelection,
|
||||||
left: left
|
left: leftOffset,
|
||||||
|
top: topOffset
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -22171,13 +22176,15 @@ var MultiView = Backbone.View.extend({
|
||||||
this.navEvents = _.clone(Backbone.Events);
|
this.navEvents = _.clone(Backbone.Events);
|
||||||
this.navEvents.on('negative', this.getNegFunc(), this);
|
this.navEvents.on('negative', this.getNegFunc(), this);
|
||||||
this.navEvents.on('positive', this.getPosFunc(), this);
|
this.navEvents.on('positive', this.getPosFunc(), this);
|
||||||
|
this.navEvents.on('quit', this.finish, this);
|
||||||
|
|
||||||
this.keyboardListener = new KeyboardListener({
|
this.keyboardListener = new KeyboardListener({
|
||||||
events: this.navEvents,
|
events: this.navEvents,
|
||||||
aliasMap: {
|
aliasMap: {
|
||||||
left: 'negative',
|
left: 'negative',
|
||||||
right: 'positive',
|
right: 'positive',
|
||||||
enter: 'positive'
|
enter: 'positive',
|
||||||
|
esc: 'quit'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -23895,7 +23902,6 @@ var VisBranch = VisBase.extend({
|
||||||
branch.obj.get('visBranch')
|
branch.obj.get('visBranch')
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
console.log('getting text size', textNode, 'width', textNode.clientWidth);
|
|
||||||
|
|
||||||
return firefoxFix({
|
return firefoxFix({
|
||||||
w: maxWidth,
|
w: maxWidth,
|
||||||
|
|
|
@ -40,10 +40,10 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="commandLineBar" class="box vertical flex0">
|
<div id="commandLineBar" class="box vertical flex0">
|
||||||
<div id="prompt" class="box horizontal">
|
<div id="prompt" class="">
|
||||||
<span class="promptSign box">$</span>
|
<span class="promptSign box">$</span>
|
||||||
<span class="command box"></span>
|
|
||||||
<span class="cursor box"> </span>
|
<span class="cursor box"> </span>
|
||||||
|
<p class="command"></p>
|
||||||
</div>
|
</div>
|
||||||
<textarea id="commandTextField"></textarea>
|
<textarea id="commandTextField"></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -37,7 +37,7 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
this.index = -1;
|
this.index = -1;
|
||||||
this.commandSpan = this.$('#prompt span.command')[0];
|
this.commandParagraph = this.$('#prompt p.command')[0];
|
||||||
this.commandCursor = this.$('#prompt span.cursor')[0];
|
this.commandCursor = this.$('#prompt span.cursor')[0];
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
||||||
|
@ -74,16 +74,11 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeyDown: function(e) {
|
onKeyDown: function(e) {
|
||||||
console.log('on keydown');
|
|
||||||
console.log(e);
|
|
||||||
|
|
||||||
var el = e.srcElement;
|
var el = e.srcElement;
|
||||||
this.updatePrompt(el);
|
this.updatePrompt(el);
|
||||||
},
|
},
|
||||||
|
|
||||||
onKeyUp: function(e) {
|
onKeyUp: function(e) {
|
||||||
console.log('on key up');
|
|
||||||
console.log(e);
|
|
||||||
this.onKeyDown(e);
|
this.onKeyDown(e);
|
||||||
|
|
||||||
// we need to capture some of these events.
|
// we need to capture some of these events.
|
||||||
|
@ -126,7 +121,7 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
// well...
|
// well...
|
||||||
var text = $('#commandTextField').val();
|
var text = $('#commandTextField').val();
|
||||||
var val = this.badHtmlEncode(text);
|
var val = this.badHtmlEncode(text);
|
||||||
this.commandSpan.innerHTML = val;
|
this.commandParagraph.innerHTML = val;
|
||||||
|
|
||||||
// now mutate the cursor...
|
// now mutate the cursor...
|
||||||
this.cursorUpdate(text.length, el.selectionStart, el.selectionEnd);
|
this.cursorUpdate(text.length, el.selectionStart, el.selectionEnd);
|
||||||
|
@ -136,24 +131,31 @@ var CommandPromptView = Backbone.View.extend({
|
||||||
|
|
||||||
cursorUpdate: function(commandLength, selectionStart, selectionEnd) {
|
cursorUpdate: function(commandLength, selectionStart, selectionEnd) {
|
||||||
if (selectionStart === undefined || selectionEnd === undefined) {
|
if (selectionStart === undefined || selectionEnd === undefined) {
|
||||||
selectionStart = 0;
|
selectionStart = commandLength - 1;
|
||||||
selectionEnd = 1;
|
selectionEnd = commandLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 10px for monospaced font at "1" zoom
|
// 10px for monospaced font at "1" zoom
|
||||||
var zoom = require('../util/zoomLevel').detectZoom();
|
var zoom = require('../util/zoomLevel').detectZoom();
|
||||||
var widthPerChar = 10 * zoom;
|
var widthPerChar = 10 * zoom;
|
||||||
|
var heightPerRow = 22 * zoom;
|
||||||
|
|
||||||
var numCharsSelected = Math.max(1, selectionEnd - selectionStart);
|
var widthOfParagraph = $(this.commandParagraph).width();
|
||||||
var width = String(numCharsSelected * widthPerChar) + 'px';
|
var numCharsPerLine = widthOfParagraph / widthPerChar;
|
||||||
|
|
||||||
|
var numCharsSelected = Math.min(Math.max(1, selectionEnd - selectionStart), numCharsPerLine);
|
||||||
|
var widthOfSelection = String(numCharsSelected * widthPerChar) + 'px';
|
||||||
|
|
||||||
// now for positioning
|
// now for positioning
|
||||||
var numLeft = (selectionStart !== undefined) ? Math.max(commandLength - selectionStart, 0) : 0;
|
var leftOffset = String(widthPerChar * (selectionStart % numCharsPerLine)) + 'px';
|
||||||
var left = String(-numLeft * widthPerChar) + 'px';
|
var topOffset = String(Math.floor(selectionStart / numCharsPerLine) * heightPerRow) + 'px';
|
||||||
|
console.log('height per row', heightPerRow, 'selection start', selectionStart, 'num chars perline', numCharsPerLine);
|
||||||
|
|
||||||
// one reflow? :D
|
// one reflow? :D
|
||||||
$(this.commandCursor).css({
|
$(this.commandCursor).css({
|
||||||
width: width,
|
width: widthOfSelection,
|
||||||
left: left
|
left: leftOffset,
|
||||||
|
top: topOffset
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -52,13 +52,15 @@ var MultiView = Backbone.View.extend({
|
||||||
this.navEvents = _.clone(Backbone.Events);
|
this.navEvents = _.clone(Backbone.Events);
|
||||||
this.navEvents.on('negative', this.getNegFunc(), this);
|
this.navEvents.on('negative', this.getNegFunc(), this);
|
||||||
this.navEvents.on('positive', this.getPosFunc(), this);
|
this.navEvents.on('positive', this.getPosFunc(), this);
|
||||||
|
this.navEvents.on('quit', this.finish, this);
|
||||||
|
|
||||||
this.keyboardListener = new KeyboardListener({
|
this.keyboardListener = new KeyboardListener({
|
||||||
events: this.navEvents,
|
events: this.navEvents,
|
||||||
aliasMap: {
|
aliasMap: {
|
||||||
left: 'negative',
|
left: 'negative',
|
||||||
right: 'positive',
|
right: 'positive',
|
||||||
enter: 'positive'
|
enter: 'positive',
|
||||||
|
esc: 'quit'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,6 @@ var VisBranch = VisBase.extend({
|
||||||
branch.obj.get('visBranch')
|
branch.obj.get('visBranch')
|
||||||
));
|
));
|
||||||
});
|
});
|
||||||
console.log('getting text size', textNode, 'width', textNode.clientWidth);
|
|
||||||
|
|
||||||
return firefoxFix({
|
return firefoxFix({
|
||||||
w: maxWidth,
|
w: maxWidth,
|
||||||
|
|
|
@ -6,6 +6,7 @@ body {
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
|
@ -27,9 +28,9 @@ p {
|
||||||
html,
|
html,
|
||||||
body,
|
body,
|
||||||
.box {
|
.box {
|
||||||
display: -webkit-box;
|
|
||||||
display: -moz-box;
|
|
||||||
display: box;
|
display: box;
|
||||||
|
display: -moz-box;
|
||||||
|
display: -webkit-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
body,
|
body,
|
||||||
|
@ -425,6 +426,11 @@ p.commandLine span.prompt {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#commandLineBar p.command {
|
||||||
|
margin: 0;
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
#commandLineBar #commandTextField {
|
#commandLineBar #commandTextField {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -1000px;
|
top: -1000px;
|
||||||
|
@ -443,18 +449,21 @@ p.commandLine span.prompt {
|
||||||
|
|
||||||
#prompt {
|
#prompt {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
position: relative;
|
||||||
|
min-height: 22px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#prompt span {
|
#prompt span {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
border: 0px;
|
border: 0px;
|
||||||
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
#prompt span.cursor {
|
#prompt span.cursor {
|
||||||
background: #DDD;
|
background: #DDD;
|
||||||
position: relative;
|
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
margin-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#prompt span.cursor.shown {
|
#prompt span.cursor.shown {
|
||||||
|
|
6
todo.txt
6
todo.txt
|
@ -4,6 +4,8 @@ Big Things
|
||||||
* basically just an extension of level (or sandbox), that has commands like
|
* basically just an extension of level (or sandbox), that has commands like
|
||||||
```save tree beginning``` or ```save tree goal``` and then a final
|
```save tree beginning``` or ```save tree goal``` and then a final
|
||||||
dialog typing area thingy
|
dialog typing area thingy
|
||||||
|
[ ] warning for window size
|
||||||
|
|
||||||
|
|
||||||
Medium things:
|
Medium things:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -13,7 +15,6 @@ Cases to handle / things to edit
|
||||||
|
|
||||||
Small things to implement:
|
Small things to implement:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
[ ] esc on multiview quits absolutely
|
|
||||||
|
|
||||||
Minor Bugs to fix:
|
Minor Bugs to fix:
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
@ -29,12 +30,13 @@ Ideas for cleaning
|
||||||
/*************************************
|
/*************************************
|
||||||
** Publish Things **
|
** Publish Things **
|
||||||
************************************/
|
************************************/
|
||||||
- cross browser support... firefox only LULZ. should be just css right?
|
|
||||||
- fix terminal input field in general
|
- fix terminal input field in general
|
||||||
|
|
||||||
Done things:
|
Done things:
|
||||||
(I only started this on Dec 17th 2012 to get a better sense of what was done)
|
(I only started this on Dec 17th 2012 to get a better sense of what was done)
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
[x] esc on multiview quits absolutely
|
||||||
|
[x] cross browser support... firefox only LULZ. should be just css right? WRONG
|
||||||
[x] keyboard navigation for level selector
|
[x] keyboard navigation for level selector
|
||||||
[x] optional multiview on start
|
[x] optional multiview on start
|
||||||
[x] local storage for solved map
|
[x] local storage for solved map
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue