Choice Tabbing

This commit is contained in:
斟酌 鵬兄 2016-02-22 05:53:32 +08:00
parent 1ab79e1d0d
commit e2cda7ca2c
4 changed files with 159 additions and 23 deletions

View File

@ -246,7 +246,10 @@
{ {
if ( !stay ) 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();
});
} }
} }

View File

@ -10,3 +10,7 @@
.smartbar-candidates .cn:hover { .smartbar-candidates .cn:hover {
background-color: rgba( 0, 0, 0, 0.2 ); background-color: rgba( 0, 0, 0, 0.2 );
} }
.smartbar-candidates .cn[data-selected="1"] {
background-color: orangered;
}

View File

@ -26,22 +26,89 @@
/** @type {Astro.Blog.Config} */ /** @type {Astro.Blog.Config} */
var Config = __import( "Astro.Blog.Config" ); var Config = __import( "Astro.Blog.Config" );
var __cands = [];
var GetCandidates = function() var GetCandidates = function()
{ {
var c = []; if( __cands.length ) return __cands;
var Cands = { var Cands = {
"facts": "T" "Article Reference": "Ref"
, "facts": "T"
, "text": "T" , "text": "T"
, "h1": "h1"
, "h2": "h2"
, "h3": "h3"
, "h4": "h4"
, "h5": "h5"
}; };
for( var i in Cands ) for( var i in Cands )
{ {
c.push( Dand.wrapc( "cn", i ) ); __cands.push( Dand.wrapc( "cn", i, new DataKey( "key", Cands[i] ) ) );
} }
return c; 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 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} */ /** @param {Astro.Blog.AstroEdit.Visualizer} */
var SmartInput = function ( visualizer ) var SmartInput = function ( visualizer )
{ {
@ -50,12 +117,14 @@
var HandleInput = function( sender, e ) 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 // 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 ) switch( e.keyCode )
{ {
@ -67,18 +136,21 @@
var v = sender.value.substr( 1 ); var v = sender.value.substr( 1 );
if( v == "" ) insert = function() { return Dand.textNode( "`" ); }; if( v == "" ) insert = function() { return Dand.textNode( "`" ); };
insert = undefined;
sender.BindingBox.close( true );
// Insert the code snippet with inline flag // Insert the code snippet with inline flag
visualizer.insertSnippet( "code", { "inline": "on", "lang": "plain", "value": v } ); visualizer.insertSnippet( "code", { "inline": "on", "lang": "plain", "value": v } );
sender.BindingBox.close( true );
break; break;
case 13: // Enter case 13: // Enter
// Not closing the quote, either a direct text or the first matched action // Not closing the quote, either a direct text or the first matched action
e.preventDefault(); e.preventDefault();
var selected = SelectedCandidate();
// Check if matched an action first // Check if matched an action first
if( false ) if( selected )
{ {
} }
else else
{ {
@ -91,6 +163,36 @@
case 27: // Esc case 27: // Esc
sender.BindingBox.close(); sender.BindingBox.close();
break; 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(); 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 ) var ClosePanel = function( confirmed )
{ {
ResetCandidates();
Cycle.next( function() { SBarPresent = false; } ); Cycle.next( function() { SBarPresent = false; } );
visualizer.restoreSelection(); visualizer.restoreSelection();
@ -120,13 +251,13 @@
SBarPresent = true; SBarPresent = true;
var title = "Quick Access"; var title = "Quick Access ( Prototype )";
var Command = Dand.wrap( var Command = Dand.wrap(
"input", null, "v_snippet_input_single" "input", null, "v_snippet_input_single"
, null, IKey.quickDef( "type", "text", "placeholder", "Command", "value", "`" ) , 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; Command.selectionStart = Command.selectionEnd = 1;
@ -141,16 +272,12 @@
Command.focus(); Command.focus();
var DCommand = IDOMElement( Command ); var DCommand = IDOMElement( Command );
DCommand.addEventListener( "KeyDown", function( e ) { HandleInput( Command, e ); } ); DCommand.addEventListener( "KeyDown", KeyHandler( Command, HandleInput ) );
DCommand.addEventListener( "KeyUp", function( e ) { TestEmpty( Command, e ); } ); 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 ) if( !SBarPresent && code == 192 )
{ {
e.preventDefault(); 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 ); ns[ NS_EXPORT ]( EX_CLASS, "SmartInput", SmartInput );

View File

@ -4,6 +4,8 @@
.inline-code { .inline-code {
font-family: monospace; font-family: monospace;
font-size: 1.12em;
background-color: #EEE; background-color: #EEE;
padding: 0.2em 0.5em; padding: 0.2em 0.5em;
} }