commit 1d812de551ae9652c967a857c54c79d3cb41db36
| author | 斟酌 鵬兄 <tgckpg@gmail.com> |
| date | 2015-09-22T11:31:53Z |
| subject | Generalize tags to flags |
commit 1d812de551ae9652c967a857c54c79d3cb41db36
Author: 斟酌 鵬兄 <tgckpg@gmail.com>
Date: 2015-09-22T11:31:53Z
Generalize tags to flags
---
botanjs/src/Astro/Blog/AstroEdit/Article.js | 98 ++++++++--
.../src/Astro/Blog/AstroEdit/{Tag.css => Flag.css} | 12 +-
botanjs/src/Astro/Blog/AstroEdit/Flag.js | 187 +++++++++++++++++++
botanjs/src/Astro/Blog/AstroEdit/Tag.js | 197 ---------------------
botanjs/src/Astro/Blog/AstroEdit/_this.css | 6 +
botanjs/src/Astro/Blog/AstroEdit/_this.js | 13 +-
.../src/externs/Astro.Blog.AstroEdit.IPlugin.js | 8 +
botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js | 6 -
botanjs/src/externs/_AstConf_.AstroEdit.js | 16 +-
botanjs/src/externs/_AstJson_.AJaxGetArticle.js | 2 +
10 files changed, 315 insertions(+), 230 deletions(-)
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Article.js b/botanjs/src/Astro/Blog/AstroEdit/Article.js
index cfe7210..5cfde04 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Article.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/Article.js
@@ -20,11 +20,11 @@
/** @type {Astro.Blog.Components.Bubble} */
var Bubble = __import( "Astro.Blog.Components.Bubble" );
- var opostData = __import( "System.Net.postData" );
+ var opostData = __import( "System.Net.postData" );
var prettyDate = __import( "Astro.utils.Date.pretty" );
var Visualizer = ns[ NS_INVOKE ]( "Visualizer" );
- var Tag = ns[ NS_INVOKE ]( "Tag" );
+ var Flag = ns[ NS_INVOKE ]( "Flag" );
// Editor Override
@@ -34,7 +34,43 @@
opostData( processor, data, success, failed );
};
- var Article = function( processorSet )
+ // Wrappers for every plugins
+ var PluginBundles = function( article, plugins )
+ {
+ this.plugins = plugins;
+ for( var i in this.plugins )
+ {
+ /* @type {Astro.Blog.AstroEdit.IPlugins} */
+ var g = this.plugins[i];
+ g.bindArticle = article;
+ }
+ };
+
+ PluginBundles.prototype.setForView = function( pluginId, data )
+ {
+ for( var i in this.plugins )
+ {
+ var p = this.plugins[i];
+ if( p.id == pluginId )
+ {
+ p.setForView( data );
+ }
+ }
+ };
+
+ PluginBundles.prototype.getSetData = function( pluginId, data )
+ {
+ for( var i in this.plugins )
+ {
+ var p = this.plugins[i];
+ if( p.id == pluginId )
+ {
+ p.getSetData( data );
+ }
+ }
+ };
+
+ var Article = function( processorSet, plugins )
{
var pBubble = new Bubble();
@@ -44,7 +80,6 @@
var _content = "";
//// Classes & obj
- var _ae_tag = null;
var _visualizer = null;
var timestamp = new Date();
@@ -58,6 +93,7 @@
, date_created: timestamp
, archived: false
, tags: null
+ , section: null
, draft: true
, article_id: false
};
@@ -78,7 +114,7 @@
var a_conf = Config.get( "AstroEdit" );
var base_path = Config.get( "BasePath" );
- ///// preview fields
+ /*{{{ preview fields */
var ae_p_fields = {
mtime: set_field_name( Dand.wrap( "input" ), "date_modified" )
, ptime: set_field_name( Dand.wrap( "input" ), "date_published" )
@@ -94,8 +130,42 @@
var temp;
for ( var i in ae_p_fields ) ae_preview.appendChild( ae_p_fields[i] );
- //// End preview fields
+ /* End preview fields }}}*/
+ /*{{{ Button sections */
+ var ae_stitles = Dand.glass( "ae_stitle", true );
+ var ae_panel_section = Dand.glass( "ae_panel_section", true );
+
+ var l = ae_stitles.length;
+ for( var i = 0; i < l; i ++ )
+ {
+ var t = ae_stitles[i];
+ var p = ae_panel_section[i];
+ t.addEventListener( "Click", function( e )
+ {
+ var p = this.p;
+ if( this.t.expanded = !this.t.expanded )
+ {
+ p.style.height = "auto";
+ Cycle.next(
+ function(){
+ p.style.height = this.h + "px";
+ }.bind({ h: p.element.clientHeight })
+ );
+ p.style.height = 0;
+ }
+ else
+ {
+ p.style.height = 0;
+ }
+ }.bind({ t: t, p: p }) );
+ }
+
+ ae_stitles[0].element.click();
+ /* End Button sections }}}*/
+
+ // Install plugins
+ plugins = new PluginBundles( this, plugins );
var enableSaveFunction = function ()
{
@@ -253,8 +323,8 @@
ae_publish.innerHTML = ArticleModel.draft ? "Publish" : "Done edit";
ae_backup.innerHTML = ( ArticleModel.draft ? "Save" : "Backup" ) + "(Ctrl + s)";
-
- _ae_tag && _ae_tag.setTags( ArticleModel.tags );
+ plugins.setForView( "tags", ArticleModel.tags );
+ plugins.setForView( "section", ArticleModel.section );
}
, deleteDraft = function ( confirmed )
@@ -311,10 +381,12 @@
article_id: __article_id ? __article_id : ""
, title: _title
, content: _content
- , tags: _ae_tag.getTags()
, draft: 1
};
+ plugins.getSetData( "tags", _data );
+ plugins.getSetData( "section", _data );
+
postData( processorSet, _data, saveSuccess, serverFailed );
}
};
@@ -345,7 +417,7 @@
? ArticleModel.date_published
: Math.floor( 0.001*( new Date().getTime() ) )
;
- ae_p_fields.tags.value = _ae_tag.getTags();
+ ae_p_fields.tags.value = _ae_tag.getFlags();
ae_preview.submit();
};
@@ -358,10 +430,10 @@
_visualizer = _class;
_visualizer.setContentDiv( ae_content );
}
- if ( _class instanceof Tag )
+ if ( _class instanceof Flag )
{
_ae_tag = _class;
- ArticleModel && ArticleModel.tags && ( _ae_tag ).setTags( ArticleModel.tags );
+ ArticleModel && ArticleModel.tags && ( _ae_tag ).setFlags( ArticleModel.tags );
}
};
@@ -389,7 +461,7 @@
_data.title = _title;
_data.content = _content;
- _data.tags = _ae_tag.getTags();
+ _data.tags = _ae_tag.getFlags();
postData( processorSet, _data, publishSuccess.bind({ contentUpdate: true }), serverFailed );
}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Tag.css b/botanjs/src/Astro/Blog/AstroEdit/Flag.css
similarity index 63%
rename from botanjs/src/Astro/Blog/AstroEdit/Tag.css
rename to botanjs/src/Astro/Blog/AstroEdit/Flag.css
index 10b6b7b..5968bfd 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/Tag.css
+++ b/botanjs/src/Astro/Blog/AstroEdit/Flag.css
@@ -1,27 +1,27 @@
-.tag_active {
+.flag_active {
color: white;
opacity: 1 !important;
}
-.ae_tag_delete {
+.ae_flag_delete {
color: white;
padding: 0 0.5em 0 0;
}
-.ae_tag_delete:hover {
+.ae_flag_delete:hover {
color: red;
}
-.ae_tag_add {
+.ae_flag_add {
color: white;
cursor: default;
font-weight: 200;
}
-.ae_tag_add:hover {
+.ae_flag_add:hover {
color: dodgerblue;
}
-#ae_tags > span {
+.ae_flags > span {
float: left;
}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Flag.js b/botanjs/src/Astro/Blog/AstroEdit/Flag.js
new file mode 100644
index 0000000..63081ee
--- /dev/null
+++ b/botanjs/src/Astro/Blog/AstroEdit/Flag.js
@@ -0,0 +1,187 @@
+(function(){
+ var ns = __namespace( "Astro.Blog.AstroEdit" );
+
+ /** @type {System.Debug} */
+ var debug = __import( "System.Debug" );
+ /** @type {Components.MessageBox} */
+ var MessageBox = __import( "Components.MessageBox" );
+ /** @type {Dandelion} */
+ var Dand = __import( "Dandelion" );
+ /** @type {Dandelion.IDOMElement} */
+ var IDOMElement = __import( "Dandelion.IDOMElement" );
+ /** @type {Astro.Blog.Config} */
+ var Config = __import( "Astro.Blog.Config" );
+
+ var postData = __import( "System.Net.postData" );
+
+ /* @type {AstroEdit.IPlugins} */
+ var Flag = function ( id, target, flagConf )
+ {
+ this.id = id;
+ var stage = Dand.id( target );
+ var ae_addFlag = Dand.glass( "ae_flag_add" , true, stage )[0];
+ var ae_flags = Dand.glass( "ae_flags" , false, stage )[0];
+
+ // Store flags for future use
+ var flags = {};
+
+ ////// Handlers
+ ae_addFlag.addEventListener(
+ "Click", function ( e )
+ {
+ e.stopPropagation();
+ // Input fields
+ var ae_flagInput;
+
+ // Popup MessageBox
+ new MessageBox(
+ "Add new flag(s)"
+ , Dand.wrape([
+ Dand.wrapc(
+ "v_instruction flsf"
+ , "Flags are separated by \\n. (existing flags will be ignored.)"
+ )
+ , ae_flagInput = Dand.wrap( "textarea", null, "v_snippet_input" )
+ ])
+ , "OK", "Cancel"
+ , parseFlags.bind( ae_flagInput )
+ ).show();
+ }
+ );
+
+ var deleteFlag = function (e)
+ {
+ var p = { flag: this.nodeValue, sflage: this.parentNode };
+ postData( flagConf.URICount, p, confirmDelete.bind( p ), serverFailed );
+ e.stopPropagation();
+ };
+
+ var confirmDelete = function (obj)
+ {
+ new MessageBox(
+ "Delete Flag"
+ , [
+ Dand.wrapc("ae_blockswitch",
+ [
+ Dand.textNode( "Are you sure you want to delete " )
+ , Dand.wrap( "span", null, "flag_active", Dand.textNode( this.flag ) )
+ , Dand.textNode( " ?." )
+ ]
+ )
+ , obj.count > 0
+ ? Dand.wrape([
+ Dand.textNode( "This will affect " )
+ , Dand.wrap(
+ "span", null, "ae_affected_count", Dand.textNode( obj.count )
+ )
+ , Dand.textNode(" article(s).")
+ ])
+ : null
+ ]
+ , "Delete", "No"
+ , doDelete.bind(this)
+ ).show();
+ };
+
+ var doDelete = function( confirmed )
+ {
+ if ( confirmed )
+ {
+ postData(
+ flagConf.URISet
+ , { flag: this.flag, del: 1 }
+ , deleteSuccess.bind( this )
+ , serverFailed
+ );
+ }
+ };
+
+ var deleteSuccess = function(obj)
+ {
+ // Remove element
+ this.sflage.parentNode.removeChild(this.sflage);
+ // Delete reference
+ delete flags[this.flag];
+ };
+
+ var parseFlags = function ()
+ {
+ // Filter invalid flags
+ var nflags = this.value.trim().match(/[^\n]+/g), d, e;
+ for (var i in nflags)
+ {
+ if(!flags[(i = nflags[i]).toLowerCase()])
+ {
+ flags[i] = Dand.wrap("span", null, "flag_active",
+ [d = Dand.wrap("span", null, "ae_flag_delete", "\u00D7"), e = Dand.textNode(i)]
+ );
+ // Seperator
+ ae_flags.appendChild(Dand.textNode(" "));
+ ae_flags.appendChild(flags[i]);
+
+ flags[i].onclick = function() { toggleFlag(this) }.bind(flags[i]);
+ d.onclick = deleteFlag.bind(e);
+
+ }
+ else
+ {
+ debug.Info("Flag exist: " + i);
+ // Hightlight these flags
+ flags[i.toLowerCase()].className = "flag_active";
+ }
+ }
+
+ };
+
+ var toggleFlag = function (flag)
+ {
+ var isEnabled = flag.className == "flag_active" ? true : false;
+ flag.className = isEnabled ? "ae_disabled" : "flag_active";
+ };
+
+ var serverFailed = function (obj) { };
+
+ var cflag, ae_children = ae_flags.childNodes;
+ for (var i in ae_children)
+ {
+ if((cflag = ae_children[i]).nodeType == 1)
+ {
+ flags[cflag.lastChild.nodeValue.toLowerCase()] = cflag;
+ IDOMElement( cflag ).addEventListener( "Click", function() { toggleFlag( this ); }.bind( cflag ) );
+ // Bind the last child (x button) to firstChild (textNode: flagname)
+ IDOMElement( cflag.firstChild ).addEventListener( "Click", deleteFlag.bind( cflag.lastChild ) );
+ }
+ }
+
+ this.getSetData = function ( data )
+ {
+ // Compile flag list
+ var tlist = [];
+
+ // Return names
+ for (var i in flags)
+ {
+ if(flags[i].className == "flag_active")
+ tlist[tlist.length] = flags[i].lastChild.nodeValue;
+ }
+
+ data[ this.id ] = tlist.join("\n");
+ }
+
+ this.setForView = function ( flagList )
+ {
+ // Disable all flags first
+ for ( var i in flags ) flags[i].className = "ae_disabled";
+
+ // Set flags from flagList
+ for ( i in flagList )
+ if ( flagList[i] ) flags[flagList[i].toLowerCase()].className = "flag_active";
+ }
+ }
+
+ Flag.prototype.getSetData = function () { };
+ Flag.prototype.setForView = function ( flagList ) { };
+
+ ns[ NS_EXPORT ]( EX_CLASS, "Flag", Flag );
+
+})();
diff --git a/botanjs/src/Astro/Blog/AstroEdit/Tag.js b/botanjs/src/Astro/Blog/AstroEdit/Tag.js
deleted file mode 100644
index 028da5b..0000000
--- a/botanjs/src/Astro/Blog/AstroEdit/Tag.js
+++ /dev/null
@@ -1,197 +0,0 @@
-(function(){
- var ns = __namespace( "Astro.Blog.AstroEdit" );
-
- /** @type {System.Debug} */
- var debug = __import( "System.Debug" );
- /** @type {Components.MessageBox} */
- var MessageBox = __import( "Components.MessageBox" );
- /** @type {Dandelion} */
- var Dand = __import( "Dandelion" );
- /** @type {Dandelion.IDOMElement} */
- var IDOMElement = __import( "Dandelion.IDOMElement" );
- /** @type {Astro.Blog.Config} */
- var Config = __import( "Astro.Blog.Config" );
-
- var postData = __import( "System.Net.postData" );
-
- /** @param {Astro.Blog.AstroEdit.Article} */
- var Tag = function ( ae_article, tagCountUri )
- {
- var Article = ns[ NS_INVOKE ]( "Article" );
-
- if ( !( ae_article instanceof Article ) )
- return false;
-
- /** @type {_AstConf_.AstroEdit} */
- var a_conf = Config.get( "AstroEdit" );
-
- var ae_document = ae_article;
-
- var ae_addTag = Dand.id( "ae_addTags" );
- var ae_tags = Dand.id( "ae_tags" );
-
- // Store tags for future use
- var tags = {};
-
- ////// Handlers
- ae_addTag.onclick = function ()
- {
-
- // Input fields
- var ae_tagInput;
-
- // Popup MessageBox
- new MessageBox(
- "Add new tag(s)"
- , Dand.wrape([
- Dand.wrapc(
- "v_instruction flsf"
- , "Tags are separated by \\n. (existing tags will be ignored.)"
- )
- , ae_tagInput = Dand.wrap( "textarea", null, "v_snippet_input" )
- ])
- , "OK", "Cancel"
- , parseTags.bind( ae_tagInput )
- ).show();
- };
-
- var deleteTag = function (e)
- {
- var p = { tag: this.nodeValue, stage: this.parentNode };
- postData( tagCountUri, p, confirmDelete.bind( p ), serverFailed );
- e.stopPropagation();
- };
-
- var confirmDelete = function (obj)
- {
- new MessageBox(
- "Delete Tag"
- , [
- Dand.wrapc("ae_blockswitch",
- [
- Dand.textNode( "Are you sure you want to delete " )
- , Dand.wrap( "span", null, "tag_active", Dand.textNode( this.tag ) )
- , Dand.textNode( " ?." )
- ]
- )
- , obj.count > 0
- ? Dand.wrape([
- Dand.textNode( "This will affect " )
- , Dand.wrap(
- "span", null, "ae_affected_count", Dand.textNode( obj.count )
- )
- , Dand.textNode(" article(s).")
- ])
- : null
- ]
- , "Delete", "No"
- , doDelete.bind(this)
- ).show();
- };
-
- var doDelete = function( confirmed )
- {
- if ( confirmed )
- {
- postData(
- a_conf.paths.set_tag
- , { tag: this.tag, del: 1 }
- , deleteSuccess.bind( this )
- , serverFailed
- );
- }
- };
-
- var deleteSuccess = function(obj)
- {
- // Remove element
- this.stage.parentNode.removeChild(this.stage);
- // Delete reference
- delete tags[this.tag];
- };
-
- var parseTags = function ()
- {
- // Filter invalid tags
- var ntags = this.value.trim().match(/[^\n]+/g), d, e;
- for (var i in ntags)
- {
- if(!tags[(i = ntags[i]).toLowerCase()])
- {
- tags[i] = Dand.wrap("span", null, "tag_active",
- [d = Dand.wrap("span", null, "ae_tag_delete", "\u00D7"), e = Dand.textNode(i)]
- );
- // Seperator
- ae_tags.appendChild(Dand.textNode(" "));
- ae_tags.appendChild(tags[i]);
-
- tags[i].onclick = function() { toggleTag(this) }.bind(tags[i]);
- d.onclick = deleteTag.bind(e);
-
- }
- else
- {
- debug.Info("Tag exist: " + i);
- // Hightlight these tags
- tags[i.toLowerCase()].className = "tag_active";
- }
- }
-
- };
-
- var toggleTag = function (tag)
- {
- var isEnabled = tag.className == "tag_active" ? true : false;
- tag.className = isEnabled ? "ae_disabled" : "tag_active";
- };
-
- var serverFailed = function (obj) { };
-
-
-
- var ctag, ae_children = ae_tags.childNodes;
- for (var i in ae_children)
- {
- if((ctag = ae_children[i]).nodeType == 1)
- {
- tags[ctag.lastChild.nodeValue.toLowerCase()] = ctag;
- IDOMElement( ctag ).addEventListener( "Click", function() { toggleTag( this ); }.bind( ctag ) );
- // Bind the last child (x button) to firstChild (textNode: tagname)
- IDOMElement( ctag.firstChild ).addEventListener( "Click", deleteTag.bind( ctag.lastChild ) );
- }
- }
-
- this.getTags = function ()
- {
- // Compile tag list
- var tlist = [];
-
- // Return names
- for (var i in tags)
- {
- if(tags[i].className == "tag_active")
- tlist[tlist.length] = tags[i].lastChild.nodeValue;
- }
-
- return tlist.join("\n");
- }
-
- this.setTags = function (tagList)
- {
- // Disable all tags first
- for (var i in tags) tags[i].className = "ae_disabled";
-
- // Set tags from tagList
- for (i in tagList)
- if (tagList[i]) tags[tagList[i].toLowerCase()].className = "tag_active";
- }
-
- ae_document.invoke(this);
- }
-
- Tag.prototype.getTags = function () { };
- Tag.prototype.setTags = function (tagList) { };
-
- ns[ NS_EXPORT ]( EX_CLASS, "Tag", Tag );
-
-})();
diff --git a/botanjs/src/Astro/Blog/AstroEdit/_this.css b/botanjs/src/Astro/Blog/AstroEdit/_this.css
index e312862..a948732 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/_this.css
+++ b/botanjs/src/Astro/Blog/AstroEdit/_this.css
@@ -1,6 +1,8 @@
.ae_panel_section {
padding: 0 1em;
color: white;
+ height: 0;
+ overflow: hidden;;
}
.ae_section_prop {
@@ -116,6 +118,10 @@
font-size: 2em;
}
+.ae_stitle:hover {
+ background-color: rgba( 0, 0, 0, 0.2 );
+}
+
.ae_stitle {
font-size: 1.5em;
}
diff --git a/botanjs/src/Astro/Blog/AstroEdit/_this.js b/botanjs/src/Astro/Blog/AstroEdit/_this.js
index 9e173e9..e013993 100644
--- a/botanjs/src/Astro/Blog/AstroEdit/_this.js
+++ b/botanjs/src/Astro/Blog/AstroEdit/_this.js
@@ -13,8 +13,8 @@
var Article = __import( "Astro.Blog.AstroEdit.Article" );
/** @type {Astro.Blog.AstroEdit.Draft} */
var Draft = __import( "Astro.Blog.AstroEdit.Draft" );
- /** @type {Astro.Blog.AstroEdit.Tag} */
- var Tag = __import( "Astro.Blog.AstroEdit.Tag" );
+ /** @type {Astro.Blog.AstroEdit.Flag} */
+ var Flag = __import( "Astro.Blog.AstroEdit.Flag" );
/** @type {Astro.Blog.AstroEdit.Visualizer} */
var Visualizer = __import( "Astro.Blog.AstroEdit.Visualizer" );
/** @type {Astro.Blog.AstroEdit.Uploader} */
@@ -44,11 +44,16 @@
}
);
- article = new Article( a_conf.paths.set_article );
+ article = new Article(
+ a_conf.paths.set_article
+ , [
+ new Flag( "tags", "ae_tags", a_conf.paths.tags )
+ , new Flag( "section", "ae_secs", a_conf.paths.sections )
+ ]
+ );
// Article modules
new Draft( article, a_conf.paths.get_drafts );
- new Tag( article, a_conf.paths.tag_count );
new Visualizer(
article
, Dand.id( "ae_visual_snippets" )
diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.IPlugin.js b/botanjs/src/externs/Astro.Blog.AstroEdit.IPlugin.js
new file mode 100644
index 0000000..78a1000
--- /dev/null
+++ b/botanjs/src/externs/Astro.Blog.AstroEdit.IPlugin.js
@@ -0,0 +1,8 @@
+/** @constructor Plugin Interface */
+Astro.Blog.AstroEdit.IPlugin = function(){};
+/** @type {String} */
+Astro.Blog.AstroEdit.IPlugin.id;
+/** @type {Function} */
+Astro.Blog.AstroEdit.IPlugin.setFromData;
+/** @type {Function} */
+Astro.Blog.AstroEdit.IPlugin.getSetData;
diff --git a/botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js b/botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js
deleted file mode 100644
index a3c6b92..0000000
--- a/botanjs/src/externs/Astro.Blog.AstroEdit.Tag.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/** @constructor */
-Astro.Blog.AstroEdit.Tag = function(){};
-/** @type {Function} */
-Astro.Blog.AstroEdit.Tag.getTags;
-/** @type {Function} */
-Astro.Blog.AstroEdit.Tag.setTags;
diff --git a/botanjs/src/externs/_AstConf_.AstroEdit.js b/botanjs/src/externs/_AstConf_.AstroEdit.js
index 0ef0cc9..ac4fddb 100644
--- a/botanjs/src/externs/_AstConf_.AstroEdit.js
+++ b/botanjs/src/externs/_AstConf_.AstroEdit.js
@@ -14,7 +14,15 @@ _AstConf_.AstroEdit.paths = {};
_AstConf_.AstroEdit.paths.get_files;
/** @type {string} */
_AstConf_.AstroEdit.paths.set_file;
- /** @type {string} */
- _AstConf_.AstroEdit.paths.tag_count;
- /** @type {string} */
- _AstConf_.AstroEdit.paths.set_tag;
+
+ /** @type {object} */
+ _AstConf_.AstroEdit.tags;
+ /** @type {object} */
+ _AstConf_.AstroEdit.sections;
+
+/** @type {object} */
+_AstConf_.AstroEdit.flags = {};
+/** @type {string} */
+_AstConf_.AstroEdit.flags.URICount;
+/** @type {string} */
+_AstConf_.AstroEdit.flags.URISet;
diff --git a/botanjs/src/externs/_AstJson_.AJaxGetArticle.js b/botanjs/src/externs/_AstJson_.AJaxGetArticle.js
index 71eebd7..9a528da 100644
--- a/botanjs/src/externs/_AstJson_.AJaxGetArticle.js
+++ b/botanjs/src/externs/_AstJson_.AJaxGetArticle.js
@@ -27,6 +27,8 @@ _AstJson_.AJaxGetArticle.entry;
_AstJson_.AJaxGetArticle.entry.date_published;
/** @type {Array} */
_AstJson_.AJaxGetArticle.entry.tags;
+ /** @type {Array} */
+ _AstJson_.AJaxGetArticle.entry.section;
/** @type {String} */
_AstJson_.AJaxGetArticle.entry.text;
/** @type {String} */