forked from Botanical/BotanJS
		
	Added footnote support
This commit is contained in:
		@@ -0,0 +1,37 @@
 | 
			
		||||
(function ()
 | 
			
		||||
{
 | 
			
		||||
	var ns = __namespace( "Astro.Blog.AstroEdit.SmartInput.CandidateAction" );
 | 
			
		||||
 | 
			
		||||
	/** @type {System.utils.IKey} */
 | 
			
		||||
	var IKey                              = __import( "System.utils.IKey" );
 | 
			
		||||
	/** @type {System.utils.DataKey} */
 | 
			
		||||
	var DataKey                           = __import( "System.utils.DataKey" );
 | 
			
		||||
	/** @type {Dandelion.IDOMElement} */
 | 
			
		||||
	var IDOMElement                       = __import( "Dandelion.IDOMElement" );
 | 
			
		||||
	/** @type {Dandelion} */
 | 
			
		||||
	var Dand                              = __import( "Dandelion" );
 | 
			
		||||
 | 
			
		||||
	/** @type {Astro.Blog.AstroEdit.SmartInput.ICandidateAction} */
 | 
			
		||||
	var Footnote = function ( visualizer, key )
 | 
			
		||||
	{
 | 
			
		||||
		this.visualizer = visualizer;
 | 
			
		||||
		this.key = key;
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Footnote.prototype.GetCandidates = function( handler )
 | 
			
		||||
	{
 | 
			
		||||
		handler( false );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Footnote.prototype.Process = function( content )
 | 
			
		||||
	{
 | 
			
		||||
		this.visualizer.insertSnippet( "footnote", { "value": content } );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Footnote.prototype.Retreat = function( sender, e )
 | 
			
		||||
	{
 | 
			
		||||
		return sender.value == "" && e.keyCode == 8; // Backspace
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_CLASS, "Footnote", Footnote );
 | 
			
		||||
})();
 | 
			
		||||
@@ -140,6 +140,7 @@
 | 
			
		||||
		var insert = function() { return Dand.textNode( "" ); };
 | 
			
		||||
 | 
			
		||||
		var ModLevels = [];
 | 
			
		||||
		var BindingBox = null;
 | 
			
		||||
 | 
			
		||||
		ModLevels.Cands = function() { return ModLevels[0][0]; };
 | 
			
		||||
		ModLevels.Action = function() { return ModLevels[0][1]; };
 | 
			
		||||
@@ -232,11 +233,11 @@
 | 
			
		||||
					if( v == "" )
 | 
			
		||||
					{
 | 
			
		||||
						insert = function() { return Dand.textNode( "`" ); };
 | 
			
		||||
						sender.BindingBox.close( true );
 | 
			
		||||
						BindingBox.close( true );
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
					sender.BindingBox.close();
 | 
			
		||||
					BindingBox.close();
 | 
			
		||||
					// Insert the code snippet with inline flag
 | 
			
		||||
					visualizer.insertSnippet( "code", { "inline": "on", "lang": "plain", "value": v } );
 | 
			
		||||
					break;
 | 
			
		||||
@@ -249,7 +250,7 @@
 | 
			
		||||
					if( ModLevels.Cands().Empty && 1 < ModLevels.length )
 | 
			
		||||
					{
 | 
			
		||||
						ModLevels.Action()( sender.value.substr( 1 ) );
 | 
			
		||||
						sender.BindingBox.close();
 | 
			
		||||
						BindingBox.close();
 | 
			
		||||
						break;
 | 
			
		||||
					}
 | 
			
		||||
 | 
			
		||||
@@ -259,19 +260,19 @@
 | 
			
		||||
					{
 | 
			
		||||
						insert = undefined;
 | 
			
		||||
						var close = ModLevels.Action()( selected.getDAttribute( "key" ) );
 | 
			
		||||
						if( close ) sender.BindingBox.close();
 | 
			
		||||
						if( close ) BindingBox.close();
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						// Insert this text directly
 | 
			
		||||
						var v = Dand.textNode( sender.value.substr( 1 ) );
 | 
			
		||||
						insert = function() { return v; };
 | 
			
		||||
						sender.BindingBox.close( true );
 | 
			
		||||
						BindingBox.close( true );
 | 
			
		||||
					}
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case 27: // Esc
 | 
			
		||||
					sender.BindingBox.close();
 | 
			
		||||
					BindingBox.close();
 | 
			
		||||
					break;
 | 
			
		||||
 | 
			
		||||
				case 9: // Tab
 | 
			
		||||
@@ -389,6 +390,7 @@
 | 
			
		||||
				title( true );
 | 
			
		||||
				stage()[0].value = "`";
 | 
			
		||||
				stage()[0].setAttribute( "placeholder", ModLevels.Cands().desc );
 | 
			
		||||
				BindingBox.show();
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
@@ -396,7 +398,7 @@
 | 
			
		||||
		{
 | 
			
		||||
			if( ModLevels.length == 1 )
 | 
			
		||||
			{
 | 
			
		||||
				sender.BindingBox.close();
 | 
			
		||||
				BindingBox.close();
 | 
			
		||||
				destructor.Destruct();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -414,6 +416,7 @@
 | 
			
		||||
 | 
			
		||||
				input.selectionStart = 1;
 | 
			
		||||
				input.selectionEnd = input.value.length;
 | 
			
		||||
				BindingBox.show();
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
@@ -434,7 +437,7 @@
 | 
			
		||||
			MsgBox.show();
 | 
			
		||||
 | 
			
		||||
			var Command = stage()[0];
 | 
			
		||||
			Command.BindingBox = MsgBox;
 | 
			
		||||
			BindingBox = MsgBox;
 | 
			
		||||
 | 
			
		||||
			Command.focus();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,3 @@
 | 
			
		||||
.v_boundary[data-type="Footnote"] {
 | 
			
		||||
	color: #f15a24;
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,97 @@
 | 
			
		||||
(function ()
 | 
			
		||||
{
 | 
			
		||||
	var ns = __namespace( "Astro.Blog.AstroEdit.Visualizer.Snippet" );
 | 
			
		||||
 | 
			
		||||
	/** @type {System.utils.IKey} */
 | 
			
		||||
	var IKey                              = __import( "System.utils.IKey" );
 | 
			
		||||
	/** @type {System.utils.DataKey} */
 | 
			
		||||
	var DataKey                           = __import( "System.utils.DataKey" );
 | 
			
		||||
	/** @type {Dandelion.IDOMElement} */
 | 
			
		||||
	var IDOMElement                       = __import( "Dandelion.IDOMElement" );
 | 
			
		||||
	/** @type {Dandelion} */
 | 
			
		||||
	var Dand                              = __import( "Dandelion" );
 | 
			
		||||
	/** @type {Components.MessageBox} */
 | 
			
		||||
	var MessageBox                        = __import( "Components.MessageBox" );
 | 
			
		||||
 | 
			
		||||
	var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
 | 
			
		||||
 | 
			
		||||
	var footnote = function (insertSnippet, snippetWrap, createContext, override)
 | 
			
		||||
	{
 | 
			
		||||
		var temp, i, j
 | 
			
		||||
		
 | 
			
		||||
		, handler = function ()
 | 
			
		||||
		{
 | 
			
		||||
			// Input fields
 | 
			
		||||
			var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" );
 | 
			
		||||
			
 | 
			
		||||
			if ( this._stage )
 | 
			
		||||
			{
 | 
			
		||||
				v_snippetInput.value = this._mText;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			// Popup MessageBox
 | 
			
		||||
			new MessageBox(
 | 
			
		||||
				"Insert Footnote"
 | 
			
		||||
				, v_snippetInput
 | 
			
		||||
				, "OK", "Cancel"
 | 
			
		||||
				, visualizer.bind({ mText: v_snippetInput, stage: this._stage })
 | 
			
		||||
			).show();
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		, visualizer = function (submitted, override)
 | 
			
		||||
		{
 | 
			
		||||
			
 | 
			
		||||
			var mText, stage = this.stage;
 | 
			
		||||
			
 | 
			
		||||
			mText = override ? override.value : this.mText.value;
 | 
			
		||||
			
 | 
			
		||||
			if (submitted && mText)
 | 
			
		||||
			{
 | 
			
		||||
				if (!stage)
 | 
			
		||||
				{
 | 
			
		||||
					// Visualize component
 | 
			
		||||
					temp = Dand.wrapne( "span", "^", [
 | 
			
		||||
						new DataKey( "value", mText )
 | 
			
		||||
					]);
 | 
			
		||||
 | 
			
		||||
					insertSnippet(
 | 
			
		||||
						j = snippetWrap( "Footnote", temp, false, "span" )
 | 
			
		||||
						, Boolean( override )
 | 
			
		||||
					);
 | 
			
		||||
				}
 | 
			
		||||
				else
 | 
			
		||||
				{
 | 
			
		||||
					IDOMElement( stage ).setAttribute(new DataKey( "value", mText ));
 | 
			
		||||
					temp = stage;
 | 
			
		||||
				}
 | 
			
		||||
				
 | 
			
		||||
				i = { _mText: mText, _stage: temp };
 | 
			
		||||
				
 | 
			
		||||
				// Set context menu
 | 
			
		||||
				createContext( i, j, handler );
 | 
			
		||||
			}
 | 
			
		||||
		};
 | 
			
		||||
		
 | 
			
		||||
		if ( override )
 | 
			
		||||
		{
 | 
			
		||||
			visualizer( true, override );
 | 
			
		||||
			override = false;
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			return handler;
 | 
			
		||||
		}
 | 
			
		||||
		return true;
 | 
			
		||||
	
 | 
			
		||||
	};
 | 
			
		||||
	
 | 
			
		||||
	var compile = function (stage)
 | 
			
		||||
	{
 | 
			
		||||
		// [footnote][/footnote]
 | 
			
		||||
		return "[footnote]" + escapeStr( IDOMElement(stage).getDAttribute("value") ) + "[/footnote]";
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	__static_method( footnote, "compile", compile );
 | 
			
		||||
 | 
			
		||||
	ns[ NS_EXPORT ]( EX_CLASS, "Footnote", footnote );
 | 
			
		||||
})();
 | 
			
		||||
@@ -38,6 +38,7 @@
 | 
			
		||||
		 , "Html"        , "background: coral;"
 | 
			
		||||
		 , "SiteFile"    , "background: royalblue;"
 | 
			
		||||
		 , "Heading"     , ""
 | 
			
		||||
		 , "Footnote"     , ""
 | 
			
		||||
		 , "ArticleLink" , ""
 | 
			
		||||
	);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -51,6 +51,7 @@
 | 
			
		||||
	color: #555;
 | 
			
		||||
    text-align: justify;
 | 
			
		||||
	min-height: 155px;
 | 
			
		||||
	margin-bottom: 3em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.b_bodyWrapper a { color: #f15a24; }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										31
									
								
								botanjs/src/Astro/Blog/Components/Footnote.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								botanjs/src/Astro/Blog/Components/Footnote.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
			
		||||
.footnote {
 | 
			
		||||
	padding-top: 0.25em;
 | 
			
		||||
	position: relative;
 | 
			
		||||
	margin-bottom: 2em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.footnote {
 | 
			
		||||
	color: #555;
 | 
			
		||||
	list-style-type: decimal;
 | 
			
		||||
	list-style-position: inside;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.footnote > li {
 | 
			
		||||
	padding-left: 0.5em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.footnote > li[focused] {
 | 
			
		||||
	background-color: #EE5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.footnote:before {
 | 
			
		||||
	content: "";
 | 
			
		||||
 | 
			
		||||
	position: absolute;
 | 
			
		||||
 | 
			
		||||
	top: 0;
 | 
			
		||||
 | 
			
		||||
	width: 40%;
 | 
			
		||||
 | 
			
		||||
	border-top: 1px black solid;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										46
									
								
								botanjs/src/Astro/Blog/Components/Footnote.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								botanjs/src/Astro/Blog/Components/Footnote.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,46 @@
 | 
			
		||||
(function(){
 | 
			
		||||
	var ns = __namespace( "Astro.Blog.Components.Footnote" );
 | 
			
		||||
	/** @type {Dandelion} */
 | 
			
		||||
	var Dand                             = __import( "Dandelion" );
 | 
			
		||||
	/** @type {Dandelion.IDOMElement} */
 | 
			
		||||
	var IDOMElement                      = __import( "Dandelion.IDOMElement" );
 | 
			
		||||
	/** @type {Astro.Bootstrap} */
 | 
			
		||||
	var Bootstrap                        = __import( "Astro.Bootstrap" );
 | 
			
		||||
	/** @type {Astro.Blog.Config} */
 | 
			
		||||
	var Config                           = __import( "Astro.Blog.Config" );
 | 
			
		||||
	/** @type {Astro.utils.Date} */
 | 
			
		||||
	var XDate                            = __import( "Astro.utils.Date" );
 | 
			
		||||
 | 
			
		||||
	/** @param {Dandelion.IDOMElement} elem */
 | 
			
		||||
	var Footnote = function( elem )
 | 
			
		||||
	{
 | 
			
		||||
		var jumpers = Dand.glass( "ft", true );
 | 
			
		||||
		if( !jumpers.length ) return;
 | 
			
		||||
 | 
			
		||||
		var notes = Dand.glass( "footnote", true )[0];
 | 
			
		||||
 | 
			
		||||
		jumpers.forEach( function( e ) {
 | 
			
		||||
 | 
			
		||||
			var a = e.first( 1 );
 | 
			
		||||
			IDOMElement( a ).addEventListener( "Click", function()
 | 
			
		||||
			{
 | 
			
		||||
				var clicked = a.hash.substr( 1 );
 | 
			
		||||
				notes.foreach( 1, function( e ) {
 | 
			
		||||
					if( e.id == clicked )
 | 
			
		||||
					{
 | 
			
		||||
						e.setAttribute( "focused", 1 );
 | 
			
		||||
					}
 | 
			
		||||
					else
 | 
			
		||||
					{
 | 
			
		||||
						e.removeAttribute( "focused" );
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		} );
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	Bootstrap.regInit(function() {
 | 
			
		||||
		new Footnote();
 | 
			
		||||
	});
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
@@ -36,6 +36,7 @@
 | 
			
		||||
 | 
			
		||||
.section {
 | 
			
		||||
	position: relative;
 | 
			
		||||
	overflow: hidden;
 | 
			
		||||
 | 
			
		||||
	margin: 1em -2em;
 | 
			
		||||
	padding: 2em;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user