forked from Botanical/BotanJS
Choice Tabbing
This commit is contained in:
parent
1ab79e1d0d
commit
e2cda7ca2c
@ -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();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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 );
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user