Checkbox should wrapped with labels

This commit is contained in:
2016-02-22 07:53:59 +08:00
parent e2cda7ca2c
commit 7be076461a
9 changed files with 133 additions and 104 deletions
@@ -0,0 +1,307 @@
(function(){
var ns = __namespace( "Astro.Blog.AstroEdit" );
/** @type {Dandelion} */
var Dand = __import( "Dandelion" );
/** @type {Dandelion.IDOMElement} */
var IDOMElement = __import( "Dandelion.IDOMElement" );
/** @type {Dandelion.IDOMObject} */
var IDOMObject = __import( "Dandelion.IDOMObject" );
/** @type {System.Cycle} */
var Cycle = __import( "System.Cycle" );
/** @type {System.Debug} */
var debug = __import( "System.Debug" );
/** @type {System.utils} */
var utils = __import( "System.utils" );
/** @type {System.utils.Perf} */
var Perf = __import( "System.utils.Perf" );
/** @type {System.utils.DataKey} */
var DataKey = __import( "System.utils.DataKey" );
/** @type {System.utils.EventKey} */
var EventKey = __import( "System.utils.EventKey" );
/** @type {System.utils.IKey} */
var IKey = __import( "System.utils.IKey" );
/** @type {Components.MessageBox} */
var MessageBox = __import( "Components.MessageBox" );
/** @type {Astro.Blog.Config} */
var Config = __import( "Astro.Blog.Config" );
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 );
};
};
/** @param {Astro.Blog.AstroEdit.Visualizer} */
var SmartInput = function ( visualizer, CandidatesOvd )
{
var SBarPresent = false;
var insert = function() { return Dand.textNode( "" ); };
var __cands = [];
var CandidateCycle = -1;
var KeywordTyped = 0;
var shiftTabbed = false;
var Cands = CandidatesOvd || {
"Article Reference": { module: "ArticleReference", desc: "Article reference link" }
, "facts": { module: "Facts", desc: "Facts, a fact bubble popup when mouseover" }
, "footnote": { module: "Footnote", desc: "Footnote, a footnote displayed at the end of article" }
, "h1": { module: "Heading", options: 1, desc: "Heading, size 1" }
, "h2": { module: "Heading", options: 2, desc: "Heading, size 2" }
, "h3": { module: "Heading", options: 3, desc: "Heading, size 3" }
, "h4": { module: "Heading", options: 4, desc: "Heading, size 4" }
, "h5": { module: "Heading", options: 5, desc: "Heading, size 5" }
};
var GetCandidates = function()
{
if( __cands.length ) return __cands;
for( var i in Cands )
{
/** @param {Astro.Blog.AstroEdit.SmartInput.Definition} */
var c = Cands[i];
__cands.push( Dand.wrapc( "cn", [ i, Dand.wrapc( "desc", c.desc ) ], new DataKey( "key", 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 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 HandleInput = function( sender, e )
{
// Don't handle if holding shift or ctrl key
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 )
{
case 192: // `
// Closing the quote, that means this is a block-quoted text
e.preventDefault();
insert = undefined;
// Hitting ` twice escapes the ` character itself
var v = sender.value.substr( 1 );
if( v == "" ) insert = function() { return Dand.textNode( "`" ); };
sender.BindingBox.close( true );
// Insert the code snippet with inline flag
visualizer.insertSnippet( "code", { "inline": "on", "lang": "plain", "value": v } );
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( selected )
{
insert = undefined;
sender.BindingBox.close();
}
else
{
// Insert this text directly
var v = Dand.textNode( sender.value.substr( 1 ) );
insert = function() { return v; };
sender.BindingBox.close( true );
}
break;
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.getDAttribute( "key" );
sender.value = "`" + CyclingKeyword;
sender.setSelectionRange( KeywordTyped, sender.value.length );
break;
default:
FilteredCandidates();
CandidateCycle = -1;
}
};
var TestEmpty = function( sender, e )
{
if( sender.value == "" )
{
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 = IDOMElement( c[i] );
var t = Cand.getDAttribute( "key" );
Cand.style.display = t.match( new RegExp( "^" + keyword, "i" ) ) ? "" : "none";
// Highlight the exact match
if( t.match( new RegExp( "^" + keyword + "$", "i" ) ) )
{
Cand.setAttribute( new DataKey( "selected", 1 ) );
}
}
}
};
var ClosePanel = function( confirmed )
{
ResetCandidates();
Cycle.next( function() { SBarPresent = false; } );
visualizer.restoreSelection();
if( !confirmed ) return;
if( insert != undefined )
visualizer.insertAtCaret( insert() );
};
var ShowSmartBar = function()
{
if( SBarPresent ) return;
visualizer.saveSelection();
SBarPresent = true;
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, "compx smartbar-candidates", GetCandidates() );
Command.selectionStart = Command.selectionEnd = 1;
Command.BindingBox = new MessageBox(
title
, Dand.wrape([ Command, Candidates ])
, "Back", false
, ClosePanel
);
Command.BindingBox.show();
Command.focus();
var DCommand = IDOMElement( Command );
DCommand.addEventListener( "KeyDown", KeyHandler( Command, HandleInput ) );
DCommand.addEventListener( "KeyUp", KeyHandler( Command, TestEmpty ) );
};
var BackQuoteBinding = function ( sender, e )
{
if( !SBarPresent && code == 192 )
{
e.preventDefault();
ShowSmartBar();
}
};
IDOMObject( document ).addEventListener( "KeyDown", KeyHandler( document, BackQuoteBinding ), false );
};
ns[ NS_EXPORT ]( EX_CLASS, "SmartInput", SmartInput );
})();