commit 82ef981d0a1b1ccdc5ea3fab707d7001b3853e67
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2016-02-21T19:08:07Z |
| subject | SmartInput for back quoted text |
commit 82ef981d0a1b1ccdc5ea3fab707d7001b3853e67
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2016-02-21T19:08:07Z
SmartInput for back quoted text
---
botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js | 38 +++--
botanjs/src/Astro/Blog/AstroEdit/SmartInput.css | 12 ++
botanjs/src/Astro/Blog/AstroEdit/SmartInput.js | 165 +++++++++++++++++++++
.../Blog/AstroEdit/Visualizer/Snippet/Code.css | 12 ++
.../Blog/AstroEdit/Visualizer/Snippet/Code.js | 40 +++--
.../Blog/AstroEdit/Visualizer/Snippet/Image.js | 4 +-
.../Blog/AstroEdit/Visualizer/Snippet/Link.js | 6 +-
.../src/Astro/Blog/AstroEdit/Visualizer/_this.js | 32 ++--
botanjs/src/Astro/Blog/AstroEdit/_this.js | 8 +-
botanjs/src/Astro/Blog/Components/Entry/Blog.css | 6 +
botanjs/src/Astro/Blog/Components/Section.css | 4 +-
botanjs/src/Astro/Blog/Layout/Login.js | 11 +-
botanjs/src/Astro/Build/Page/Index.css | 5 +-
.../src/externs/Astro.Blog.AstroEdit.Visualizer.js | 4 +
14 files changed, 297 insertions(+), 50 deletions(-)
diff --git a/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js
index ebf699b..62dd35d 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/SiteLibrary.js
@@ -223,10 +223,11 @@
// General file, list view
/** @param {_AstJson_.AJaxGetFiles} */
- , buildGeneralCanvas = function (e)
+ , buildGeneralCanvas = function ( e )
{
+ if( !e ) return;
var f = e.files, dateStamp;
- resetCanvas("canvasGeneral");
+ resetCanvas( "canvasGeneral" );
for(var i in f)
{
@@ -527,9 +528,13 @@
, requestInsert = function(confirmed)
{
- if(confirmed)
+ if( confirmed )
{
- var selectedAlbum = IDOMElement(IDOMElement(this.albumList).first(1, function(elem) { return elem.hasAttribute("selected"); })).getDAttribute("id");
+ var selectedAlbum = IDOMElement(
+ IDOMElement( this.albumList ).first( 1, function(elem) {
+ return elem.hasAttribute("selected");
+ } ) ).getDAttribute( "id" );
+
postData(
processorSet
, { "group": "insert", "id": selectedAlbum , "files": this.collection.join(",") }
@@ -541,17 +546,17 @@
, delCollection = function (confirmed)
{
var album_id = IDOMElement(this).getDAttribute("id");
- if(confirmed)
+ if( confirmed )
{
- postData(processorGet, { group: "get", aid: album_id }, getFilestoDelete.bind(this), loadFailed);
+ postData( processorGet, { group: "get", aid: album_id }, getFilestoDelete.bind( this ), loadFailed );
}
else
{
- postData(processorSet, { group: "remove", id: album_id }, refreshCanvas, loadFailed);
+ postData( processorSet, { group: "remove", id: album_id }, refreshCanvas, loadFailed );
}
}
- , getFilestoDelete = function (e)
+ , getFilestoDelete = function ( e )
{
var l = Object.keys(e.files).length
, fc = 0
@@ -646,20 +651,29 @@
, f = e.files, first;
// button mime/type ( counts )
- for(var i in f)
+ for( var i in f )
{
- var elem = Dand.wrap("span", null, "asl_menuItem", (i + "(" + f[i] + ")"), new DataKey("name", i));
+ var elem = Dand.wrap(
+ "span", null, "asl_menuItem"
+ , i + "(" + f[i] + ")"
+ , new DataKey( "name", i ) );
view_index[view_index.length] = [i, elem];
menuBar.appendChild(elem);
IDOMElement(elem).addEventListener(new EventKey("Click", switchView.bind(IDOMElement(elem))));
- if(!first) first = [i, elem];
+ if( !first ) first = [ i, elem ];
+ }
+
+ if( !first )
+ {
+ debug.Info( "No files" );
+ return;
}
// begin load index
- refreshCanvas(first[0]);
+ refreshCanvas( first[0] );
// Set style
first[1].setAttribute("current", 1);
}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/SmartInput.css b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.css
new file mode 100644
index 0000000..6497d7c
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.css
@@ -0,0 +1,12 @@
+.smartbar-candidates {
+ padding: 0.5em;
+ background-color: rgba( 0, 0, 0, 0.2 );
+}
+
+.smartbar-candidates .cn {
+ padding: 0.2em 0.5em;
+}
+
+.smartbar-candidates .cn:hover {
+ background-color: rgba( 0, 0, 0, 0.2 );
+}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/SmartInput.js b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.js
new file mode 100644
index 0000000..bd1946d
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/SmartInput.js
@@ -0,0 +1,165 @@
+(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 GetCandidates = function()
+ {
+ var c = [];
+ var Cands = {
+ "facts": "T"
+ , "text": "T"
+ };
+
+ for( var i in Cands )
+ {
+ c.push( Dand.wrapc( "cn", i ) );
+ }
+
+ return c;
+ };
+
+ /** @param {Astro.Blog.AstroEdit.Visualizer} */
+ var SmartInput = function ( visualizer )
+ {
+ var SBarPresent = false;
+ var insert = function() { return Dand.textNode( "" ); };
+
+ 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;
+
+ switch( e.keyCode )
+ {
+ case 192: // `
+ // Closing the quote, that means this is a block-quoted text
+ e.preventDefault();
+
+ // Hitting ` twice escapes the ` character itself
+ var v = sender.value.substr( 1 );
+ if( v == "" ) insert = function() { return Dand.textNode( "`" ); };
+
+ // 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();
+
+ // Check if matched an action first
+ if( false )
+ {
+ }
+ 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;
+ }
+ };
+
+ var TestEmpty = function( sender, e )
+ {
+ if( sender.value == "" )
+ {
+ sender.BindingBox.close();
+ }
+ };
+
+ var ClosePanel = function( confirmed )
+ {
+ 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";
+
+ 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() );
+
+ 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", function( e ) { HandleInput( Command, e ); } );
+ DCommand.addEventListener( "KeyUp", function( e ) { TestEmpty( Command, e ); } );
+ };
+
+ var BackQuoteBinding = function ( e )
+ {
+ e = e || window.event;
+ if ( e.keyCode ) code = e.keyCode;
+ else if ( e.which ) code = e.which;
+
+ if( !SBarPresent && code == 192 )
+ {
+ e.preventDefault();
+ ShowSmartBar();
+ }
+ };
+
+ IDOMObject( document ).addEventListener( "KeyDown", BackQuoteBinding, false );
+ };
+
+ ns[ NS_EXPORT ]( EX_CLASS, "SmartInput", SmartInput );
+})();
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.css b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.css
new file mode 100644
index 0000000..bb52996
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.css
@@ -0,0 +1,12 @@
+.v_boundary[data-inline="on"][data-type="Code"] {
+ display: inline-block;
+ background-color: #EEE;
+}
+
+.v_box[data-inline="on"] .v_description {
+ display: none;
+}
+
+.v_box[data-inline="on"] {
+ min-height: 0;
+}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js
index 564ef6d..6271c37 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Code.js
@@ -14,6 +14,7 @@
var MessageBox = __import( "Components.MessageBox" );
var escapeStr = ns[ NS_INVOKE ]( "escapeStr" );
+ var compileProp = ns[ NS_INVOKE ]( "compileProp" );
var code = function ( insertSnippet, snippetWrap, createContext, override )
{
@@ -34,7 +35,7 @@
, "JavaScript" , "js"
, "SQL" , "sql"
)
-
+
// Private methods
, compileListItems = function ()
{
@@ -55,7 +56,8 @@
{
// Input fields
var v_snippetInput = Dand.wrap( "textarea", null, "v_snippet_input" )
- , v_codelang = Dand.wrap( "select", null, "v_select flsf", compileListItems() );
+ , v_codelang = Dand.wrap( "select", null, "v_select flsf", compileListItems() )
+ , input_inline = Dand.wrapna('input', new IKey("type", "checkbox") );
if ( this._stage )
{
@@ -69,8 +71,9 @@
}
}
}
-
+
v_snippetInput.value = this._content || "";
+ input_inline.checked = ( this._inline == "on" );
}
else
{
@@ -87,29 +90,31 @@
, [
Dand.wrapc( "v_instruction", v_codelang )
, v_snippetInput
+ , Dand.wrape([ input_inline, Dand.textNode( "Inline" ) ])
]
)
, "OK", "Cancel"
// Switcher
- , visualizer.bind({ code:v_snippetInput, lang: v_codelang, stage: this._stage })
+ , visualizer.bind({ code:v_snippetInput, inline: input_inline, lang: v_codelang, stage: this._stage })
).show();
}
-
-
+
, visualizer = function ( submitted, override )
{
- var lang, code
+ var lang, code, inline
, stage = this.stage;
if ( override )
{
lang = override.lang;
code = override.value;
+ inline = override.inline;
}
else
{
lang = this.lang[this.pSnippeCodeChoice = this.lang.selectedIndex].value;
code = this.code.value;
+ inline = this.inline.checked ? "on" : "";
}
var langName;
@@ -124,7 +129,7 @@
if ( submitted && code )
{
- if (!stage)
+ if ( !stage )
{
// Visualize component
temp = Dand.wrapc(
@@ -136,8 +141,10 @@
, [
new DataKey( "value", code )
, new DataKey( "lang", lang )
+ , new DataKey( "inline", inline )
]
);
+
insertSnippet( j = snippetWrap( "Code", temp ), Boolean( override ) );
}
else
@@ -146,9 +153,10 @@
[
new DataKey( "value", code )
, new DataKey( "lang", lang )
+ , new DataKey( "inline", inline )
]
);
-
+
temp = stage.firstChild;
temp.removeChild( temp.firstChild );
stage.firstChild.appendChild( Dand.textNode( code ) );
@@ -160,9 +168,12 @@
temp = stage;
}
-
- i = { _lang: lang, _content: code, _stage: temp };
-
+
+ i = { _inline: inline, _lang: lang, _content: code, _stage: temp };
+
+ // Set the inline style
+ IDOMElement( j ).setAttribute( new DataKey( "inline", inline ) );
+
// Set context menu
createContext( i, j, handler );
}
@@ -185,10 +196,11 @@
{
// [code lang=\"" + lang + "\"]" + code + "[/code]"
var element = IDOMElement( stage )
- , lang = element.getDAttribute( "lang" );
+ , props= [ "lang", "inline" ];
return "[code"
- + (lang ? (" lang=\"" + lang + "\"") : "") + "]"
+ + compileProp( element, props )
+ + "]"
+ escapeStr( element.getDAttribute( "value" ) )
+ "[/code]"
;
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js
index e387932..7f72294 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Image.js
@@ -31,11 +31,11 @@
, input_preferred = Dand.wrapna('input', new IKey("type", "checkbox"))
;
- if (this._stage)
+ if ( this._stage )
{
input_url.value = this._url;
input_a.value = this._href;
- input_preferred.checked = (this._preferred == "on");
+ input_preferred.checked = ( this._preferred == "on" );
}
// Popup MessageBox
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js
index 67039c3..3fe3c5b 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/Snippet/Link.js
@@ -37,8 +37,7 @@
, input_text
, Dand.wrapc("v_instruction flsf", "Link to:")
, input_a
- ]
- )
+ ])
, "OK", "Cancel", visualizer.bind({text:input_text, href:input_a, stage: this._stage})).show();
}
@@ -100,8 +99,7 @@
// Set context menu
createContext(i, j, handler);
}
- }
- ;
+ };
if (override)
{
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js
index b4fcced..9b7c23e 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Visualizer/_this.js
@@ -165,6 +165,7 @@
var _resSelection = function ()
{
+ contentDiv.focus();
if ( selRange )
{
if ( window.getSelection )
@@ -186,17 +187,18 @@
{
if( !Dand.id( "v_linebreak" ) )
{
- insertSnippet( lastLine, true );
+ insertElement( lastLine, true );
}
else
{
- insertSnippet( contentDiv.removeChild( lastLine ), true );
+ insertElement( contentDiv.removeChild( lastLine ), true );
}
};
- var insertAtCaret = function( element )
+ var insertAtCaret = function( element, newLine )
{
var sel, range;
+ if( newLine == undefined ) newLine = true;
sel = window.getSelection();
if ( sel.getRangeAt && sel.rangeCount )
@@ -212,10 +214,11 @@
}
e_document.updateContent();
- ensureLastLinebreak();
+
+ if( newLine ) ensureLastLinebreak();
};
- var insertSnippet = function( element, override )
+ var insertElement = function( element, override )
{
if ( override )
{
@@ -223,7 +226,6 @@
return;
}
- contentDiv.focus();
_resSelection();
insertAtCaret( element );
};
@@ -283,7 +285,7 @@
if ( _module )
{
// Visualize snippet
- new ( _module )( insertSnippet, snippetWrap, createSnippetMenu, temp );
+ new ( _module )( insertElement, snippetWrap, createSnippetMenu, temp );
}
else
{
@@ -293,7 +295,7 @@
token.setAttribute( "class", token.getAttribute( "class" ) + " flsf" );
snippetQueue( type ).push([ token, temp ]);
- insertSnippet( token, true );
+ insertElement( token, true );
}
};
@@ -397,7 +399,7 @@
snippetControls.appendChild( temp );
snippetControls.appendChild( Dand.textNode( "\t" ) );
- temp.onclick = new ( _module )( insertSnippet, snippetWrap, createSnippetMenu );
+ temp.onclick = new ( _module )( insertElement, snippetWrap, createSnippetMenu );
var queue = snippetQueue( mod_name, _module.alias );
for( var i in queue )
@@ -479,6 +481,18 @@
this.saveSelection = _savSelection;
this.restoreSelection = _resSelection;
+ this.insertAtCaret = insertAtCaret;
+
+ this.insertSnippet = function( type, options )
+ {
+ var _module = loadedModule[ type ];
+
+ new ( _module )(
+ // Disables the override
+ function( e ) { insertElement( e ); }
+ , snippetWrap, createSnippetMenu, options
+ );
+ };
article.invoke(this);
diff --git a/botanjs/src/Astro/Blog/AstroEdit/_this.js b/botanjs/src/Astro/Blog/AstroEdit/_this.js
index 6fe4e24..91e4ff1 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/_this.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/_this.js
@@ -24,6 +24,9 @@
/** @type {Astro.Blog.AstroEdit.SiteLibrary} */
var SiteLibrary = __import( "Astro.Blog.AstroEdit.SiteLibrary" );
+ // calls the smart bar
+ var SmartInput = __import( "Astro.Blog.AstroEdit.SmartInput" );
+
var wh, ww, cw, html, article;
var init = function ()
@@ -56,12 +59,15 @@
// Article modules
new Draft( article, a_conf.paths.get_drafts );
- new Visualizer(
+
+ var Vis = new Visualizer(
article
, Dand.id( "ae_visual_snippets" )
, Config.get( "ServiceUri" )
);
+ new SmartInput( Vis );
+
// Independent modules
new Uploader( a_conf.paths.set_file );
new SiteLibrary(
diff --git a/botanjs/src/Astro/Blog/Components/Entry/Blog.css b/botanjs/src/Astro/Blog/Components/Entry/Blog.css
index aad0417..2eb560c 100644
--- a/botanjs/src/Astro/Blog/Components/Entry/Blog.css
+++ b/botanjs/src/Astro/Blog/Components/Entry/Blog.css
@@ -2,6 +2,12 @@
max-width: 100%;
}
+.inline-code {
+ font-family: monospace;
+ background-color: #EEE;
+ padding: 0.2em 0.5em;
+}
+
.b_entry {
background-color: #FAFAFA;
/* box-shadow: 0 0 8px -2px black; */
diff --git a/botanjs/src/Astro/Blog/Components/Section.css b/botanjs/src/Astro/Blog/Components/Section.css
index 12fab2f..b6c0018 100644
--- a/botanjs/src/Astro/Blog/Components/Section.css
+++ b/botanjs/src/Astro/Blog/Components/Section.css
@@ -11,7 +11,7 @@
opacity: 0.5;
}
-.section-buttons > a:hover, .section-buttons > a[active]:hover {
+.section-buttons > a:hover, .section-buttons > a[data-active="1"]:hover {
opacity: 0.8;
text-decoration: none;
}
@@ -50,7 +50,7 @@
.section-buttons > a > span {
padding: 0.75em 0.5em;
}
-.section-buttons > a[active] {
+.section-buttons > a[data-active="1"] {
opacity: 1;
}
.section-buttons > a > .count {
diff --git a/botanjs/src/Astro/Blog/Layout/Login.js b/botanjs/src/Astro/Blog/Layout/Login.js
index 1cf1d8b..133b775 100644
--- a/botanjs/src/Astro/Blog/Layout/Login.js
+++ b/botanjs/src/Astro/Blog/Layout/Login.js
@@ -26,11 +26,12 @@
var init = function ()
{
+ var username;
var form = Dand.wrapne('form'
, [
// Basic login and password fields
, Dand.wrapc("flsf", "Name:")
- , Dand.wrapna('input', [ field_username, new IKey("type", "text") ] )
+ , username = Dand.wrapna('input', [ field_username, new IKey("type", "text") ] )
, Dand.wrapc("flsf", "Password:")
, Dand.wrapna('input', [ field_password, new IKey("type", "password") ] )
@@ -42,13 +43,13 @@
new IKey('action', formAction)
, new IKey('method', 'POST')
]
- )
- ;
-
+ );
var mbox = new MessageBox( "Blog.Astro", form, "Login", false, submitForm.bind( form ) ).show();
- // Handle enter button
+ username.focus();
+
+ // Handle enter button
mbox.onkeyup = function( _e )
{
if ( submitForm.bind( form )( _e.which == 13 ) )
diff --git a/botanjs/src/Astro/Build/Page/Index.css b/botanjs/src/Astro/Build/Page/Index.css
index a448192..6e7945f 100644
--- a/botanjs/src/Astro/Build/Page/Index.css
+++ b/botanjs/src/Astro/Build/Page/Index.css
@@ -1,7 +1,10 @@
.site-news { font-family: monospace; }
.site-news > span { display: block; }
-.rbuilds > a { display: block; }
+.rbuilds > a {
+ display: block;
+ font-family: monospace;
+}
.rbuilds > a > span {
padding: 0 0.5em;
}
diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js
index 4cf2549..e36379c 100644
--- a/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js
+++ b/botanjs/src/externs/Astro.Blog.AstroEdit.Visualizer.js
@@ -9,4 +9,8 @@ Astro.Blog.AstroEdit.Visualizer.visualizeData;
/** @type {Function} */
Astro.Blog.AstroEdit.Visualizer.saveSelection;
/** @type {Function} */
+Astro.Blog.AstroEdit.Visualizer.insertAtCaret;
+/** @type {Function} */
+Astro.Blog.AstroEdit.Visualizer.insertSnippet;
+/** @type {Function} */
Astro.Blog.AstroEdit.Visualizer.restoreSelection;