commit e2cda7ca2c5ac82c951cfa40d1693b3910be70ac
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2016-02-21T21:53:32Z |
| subject | Choice Tabbing |
commit e2cda7ca2c5ac82c951cfa40d1693b3910be70ac
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2016-02-21T21:53:32Z
Choice Tabbing
---
botanjs/src/Astro/Blog/AstroEdit/Article.js | 5 +-
botanjs/src/Astro/Blog/AstroEdit/SmartInput.css | 4 +
botanjs/src/Astro/Blog/AstroEdit/SmartInput.js | 171 ++++++++++++++++++++---
botanjs/src/Astro/Blog/Components/Entry/Blog.css | 2 +
4 files changed, 159 insertions(+), 23 deletions(-)
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Article.js b/botanjs/src/Astro/Blog/AstroEdit/Article.js
index 6aea58a..b2676bd 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Article.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Article.js
@@ -246,7 +246,10 @@
{
if ( !stay )
{
- window.open( base_path + "article/view/" + ArticleModel.slug + "/") && window.close();
+ var op = window.open( base_path + "article/view/" + ArticleModel.slug + "/" );
+ Cycle.next( function() {
+ if( op ) window.close();
+ });
}
}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/SmartInput.css b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.css
index 6497d7c..0951ceb 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/SmartInput.css
+++ b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.css
@@ -10,3 +10,7 @@
.smartbar-candidates .cn:hover {
background-color: rgba( 0, 0, 0, 0.2 );
}
+
+.smartbar-candidates .cn[data-selected="1"] {
+ background-color: orangered;
+}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/SmartInput.js b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.js
index bd1946d..4c0dc08 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/SmartInput.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.js
@@ -26,22 +26,89 @@
/** @type {Astro.Blog.Config} */
var Config = __import( "Astro.Blog.Config" );
+ var __cands = [];
var GetCandidates = function()
{
- var c = [];
+ if( __cands.length ) return __cands;
+
var Cands = {
- "facts": "T"
+ "Article Reference": "Ref"
+ , "facts": "T"
, "text": "T"
+ , "h1": "h1"
+ , "h2": "h2"
+ , "h3": "h3"
+ , "h4": "h4"
+ , "h5": "h5"
};
for( var i in Cands )
{
- c.push( Dand.wrapc( "cn", i ) );
+ __cands.push( Dand.wrapc( "cn", i, new DataKey( "key", Cands[i] ) ) );
+ }
+
+ return __cands;
+ };
+
+ var ResetCandidates = function()
+ {
+ var Cands = GetCandidates();
+ for( var i in Cands )
+ {
+ var c = IDOMElement( Cands[i] );
+ c.setAttribute( new DataKey( "selected", 0 ) );
+ }
+ };
+
+ var FilteredCandidates = function()
+ {
+ var Cands = GetCandidates();
+ var selected = [];
+ for( var i in Cands )
+ {
+ var c = IDOMElement( Cands[i] );
+ c.setAttribute( new DataKey( "selected", 0 ) );
+
+ if( c.style.display != "none" )
+ {
+ selected.push( c );
+ }
}
- return c;
+ return selected;
};
+ var SelectedCandidate = function()
+ {
+ var Cands = GetCandidates();
+ for( var i in Cands )
+ {
+ var c = IDOMElement( Cands[i] );
+ if( c.getDAttribute( "selected" ) == "1" )
+ {
+ return c;
+ }
+ }
+
+ return null;
+ };
+
+ var KeyHandler = function( sender, handler )
+ {
+ return function( e )
+ {
+ e = e || window.event;
+ if ( e.keyCode ) code = e.keyCode;
+ else if ( e.which ) code = e.which;
+
+ handler( sender, e );
+ };
+ };
+
+ var CandidateCycle = -1;
+ var KeywordTyped = 0;
+ var shiftTabbed = false;
+
/** @param {Astro.Blog.AstroEdit.Visualizer} */
var SmartInput = function ( visualizer )
{
@@ -50,12 +117,14 @@
var HandleInput = function( sender, e )
{
- e = e || window.event;
- if ( e.keyCode ) code = e.keyCode;
- else if ( e.which ) code = e.which;
-
// Don't handle if holding shift or ctrl key
- if( e.shiftKey || e.ctrlKey ) return;
+ if( e.shiftKey || e.ctrlKey )
+ {
+ // Except the Shift + Tab, we need to cycle this
+ shiftTabbed = e.shiftKey && e.keyCode == 9;
+
+ if( !shiftTabbed ) return;
+ }
switch( e.keyCode )
{
@@ -67,18 +136,21 @@
var v = sender.value.substr( 1 );
if( v == "" ) insert = function() { return Dand.textNode( "`" ); };
+ insert = undefined;
+ sender.BindingBox.close( true );
+
// Insert the code snippet with inline flag
visualizer.insertSnippet( "code", { "inline": "on", "lang": "plain", "value": v } );
-
- sender.BindingBox.close( true );
break;
case 13: // Enter
// Not closing the quote, either a direct text or the first matched action
e.preventDefault();
+ var selected = SelectedCandidate();
// Check if matched an action first
- if( false )
+ if( selected )
{
+
}
else
{
@@ -91,6 +163,36 @@
case 27: // Esc
sender.BindingBox.close();
break;
+ case 9: // Tab
+ // Hitting tab will cycle around the candidates
+ e.preventDefault();
+
+ var c = FilteredCandidates();
+ var l = c.length;
+ if( !l ) break;
+
+ CandidateCycle += e.shiftKey ? -1 : 1;
+
+ if( CandidateCycle == l )
+ {
+ CandidateCycle = 0;
+ }
+ else if( CandidateCycle == -1 )
+ {
+ CandidateCycle = c.length - 1;
+ }
+
+ var ThisCandidate = c[ CandidateCycle ];
+ ThisCandidate.setAttribute( new DataKey( "selected", 1 ) );
+
+ var CyclingKeyword = ThisCandidate.element.textContent;
+
+ sender.value = "`" + CyclingKeyword;
+ sender.setSelectionRange( KeywordTyped, sender.value.length );
+ break;
+ default:
+ FilteredCandidates();
+ CandidateCycle = -1;
}
};
@@ -100,10 +202,39 @@
{
sender.BindingBox.close();
}
+
+ // Search exact matched Candidates
+ switch( e.keyCode )
+ {
+ case 9: // Tab, do nothing
+ break;
+ case 16: // Shift, check if shiftTabbed
+ if( shiftTabbed )
+ {
+ shiftTabbed = false;
+ break;
+ }
+ default:
+ if( CandidateCycle == -1 )
+ {
+ KeywordTyped = sender.value.length;
+ }
+
+ var c = GetCandidates();
+ var keyword = sender.value.substr( 1 );
+ for( var i in c )
+ {
+ var Cand = c[i];
+ var t = Cand.textContent;
+ Cand.style.display = t.match( new RegExp( "^" + keyword, "i" ) ) ? "" : "none";
+ }
+ }
};
var ClosePanel = function( confirmed )
{
+ ResetCandidates();
+
Cycle.next( function() { SBarPresent = false; } );
visualizer.restoreSelection();
@@ -120,13 +251,13 @@
SBarPresent = true;
- var title = "Quick Access";
+ var title = "Quick Access ( Prototype )";
var Command = Dand.wrap(
"input", null, "v_snippet_input_single"
, null, IKey.quickDef( "type", "text", "placeholder", "Command", "value", "`" )
);
- var Candidates = Dand.wrap( "div", null, "smartbar-candidates", GetCandidates() );
+ var Candidates = Dand.wrap( "div", null, "compx smartbar-candidates", GetCandidates() );
Command.selectionStart = Command.selectionEnd = 1;
@@ -141,16 +272,12 @@
Command.focus();
var DCommand = IDOMElement( Command );
- DCommand.addEventListener( "KeyDown", function( e ) { HandleInput( Command, e ); } );
- DCommand.addEventListener( "KeyUp", function( e ) { TestEmpty( Command, e ); } );
+ DCommand.addEventListener( "KeyDown", KeyHandler( Command, HandleInput ) );
+ DCommand.addEventListener( "KeyUp", KeyHandler( Command, TestEmpty ) );
};
- var BackQuoteBinding = function ( e )
+ var BackQuoteBinding = function ( sender, e )
{
- e = e || window.event;
- if ( e.keyCode ) code = e.keyCode;
- else if ( e.which ) code = e.which;
-
if( !SBarPresent && code == 192 )
{
e.preventDefault();
@@ -158,7 +285,7 @@
}
};
- IDOMObject( document ).addEventListener( "KeyDown", BackQuoteBinding, false );
+ IDOMObject( document ).addEventListener( "KeyDown", KeyHandler( document, BackQuoteBinding ), false );
};
ns[ NS_EXPORT ]( EX_CLASS, "SmartInput", SmartInput );
diff --git a/botanjs/src/Astro/Blog/Components/Entry/Blog.css b/botanjs/src/Astro/Blog/Components/Entry/Blog.css
index 2eb560c..8e63474 100644
--- a/botanjs/src/Astro/Blog/Components/Entry/Blog.css
+++ b/botanjs/src/Astro/Blog/Components/Entry/Blog.css
@@ -4,6 +4,8 @@
.inline-code {
font-family: monospace;
+ font-size: 1.12em;
+
background-color: #EEE;
padding: 0.2em 0.5em;
}