forked from Botanical/BotanJS
		
	Generalize tags to flags
This commit is contained in:
		@@ -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 );
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										187
									
								
								botanjs/src/Astro/Blog/AstroEdit/Flag.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										187
									
								
								botanjs/src/Astro/Blog/AstroEdit/Flag.js
									
									
									
									
									
										Normal file
									
								
							@@ -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 );
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
@@ -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 );
 | 
			
		||||
 | 
			
		||||
})();
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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" )
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										8
									
								
								botanjs/src/externs/Astro.Blog.AstroEdit.IPlugin.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								botanjs/src/externs/Astro.Blog.AstroEdit.IPlugin.js
									
									
									
									
									
										Normal file
									
								
							@@ -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;
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
/** @constructor */
 | 
			
		||||
Astro.Blog.AstroEdit.Tag = function(){};
 | 
			
		||||
/** @type {Function} */
 | 
			
		||||
Astro.Blog.AstroEdit.Tag.getTags;
 | 
			
		||||
/** @type {Function} */
 | 
			
		||||
Astro.Blog.AstroEdit.Tag.setTags;
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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} */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user