forked from Botanical/BotanJS
Astro Classes
This commit is contained in:
@@ -0,0 +1,453 @@
|
||||
(function(){
|
||||
var ns = __namespace( "Astro.Blog.AstroEdit" );
|
||||
|
||||
/** @type {System.Cycle} */
|
||||
var Cycle = __import( "System.Cycle" );
|
||||
/** @type {System.utils.EventKey} */
|
||||
var EventKey = __import( "System.utils.EventKey" );
|
||||
/** @type {System.Debug} */
|
||||
var debug = __import( "System.Debug" );
|
||||
/** @type {Components.MessageBox} */
|
||||
var MessageBox = __import( "Components.MessageBox" );
|
||||
/** @type {Dandelion} */
|
||||
var Dand = __import( "Dandelion" );
|
||||
/** @type {Dandelion.IDOMObject} */
|
||||
var IDOMObject = __import( "Dandelion.IDOMObject" );
|
||||
/** @type {Dandelion.IDOMElement} */
|
||||
var IDOMElement = __import( "Dandelion.IDOMElement" );
|
||||
/** @type {Astro.Blog.Config} */
|
||||
var Config = __import( "Astro.Blog.Config" );
|
||||
/** @type {Astro.Blog.Components.Bubble} */
|
||||
var Bubble = __import( "Astro.Blog.Components.Bubble" );
|
||||
|
||||
var postData = __import( "System.Net.postData" );
|
||||
var prettyDate = __import( "Astro.utils.Date.pretty" );
|
||||
|
||||
var Visualizer = ns[ NS_INVOKE ]( "Visualizer" );
|
||||
var Tag = ns[ NS_INVOKE ]( "Tag" );
|
||||
|
||||
var Article = function( processorSet )
|
||||
{
|
||||
var pBubble = new Bubble();
|
||||
|
||||
var Draft = ns[ NS_INVOKE ]( "Draft" );
|
||||
|
||||
var _title = "";
|
||||
var _content = "";
|
||||
|
||||
//// Classes & obj
|
||||
var _ae_tag = null;
|
||||
var _visualizer = null;
|
||||
var timestamp = new Date();
|
||||
|
||||
/** @type {_AstJson_.AJaxGetArticle.entry} */
|
||||
var ArticleModel = {
|
||||
title: ""
|
||||
, slug: ""
|
||||
, content: ""
|
||||
, date_modified: timestamp
|
||||
, date_published: timestamp
|
||||
, date_created: timestamp
|
||||
, archived: false
|
||||
, tags: null
|
||||
, draft: true
|
||||
, article_id: false
|
||||
};
|
||||
|
||||
var ae_content = Dand.id( "ae_content" );
|
||||
var ae_title = Dand.id( "ae_title" );
|
||||
|
||||
// Article info
|
||||
var ae_cdate = Dand.id( "ae_cdate" );
|
||||
var ae_mdate = Dand.id( "ae_mdate" );
|
||||
var ae_pdate = Dand.id( "ae_pdate" );
|
||||
var ae_status = Dand.id( "ae_status" );
|
||||
var ae_backup = Dand.id( "ae_backup_btn" );
|
||||
var ae_publish = Dand.id( "ae_publish_btn" );
|
||||
var ae_preview = Dand.id( "ae_preview" );
|
||||
|
||||
/** @type {_AstConf_.AstroEdit} */
|
||||
var a_conf = Config.get( "AstroEdit" );
|
||||
var base_path = Config.get( "BasePath" );
|
||||
|
||||
///// preview fields
|
||||
var ae_p_fields = {
|
||||
mtime: set_field_name( Dand.wrap( "input" ), "date_modified" )
|
||||
, ptime: set_field_name( Dand.wrap( "input" ), "date_published" )
|
||||
, title: set_field_name( Dand.wrap( "input" ), "title" )
|
||||
, content: set_field_name( Dand.wrap( "input" ), "content" )
|
||||
, tags: set_field_name( Dand.wrap( "input" ), "tags" )
|
||||
};
|
||||
|
||||
// Initialize id
|
||||
var __article_id = false;
|
||||
var canSave = false;
|
||||
|
||||
var temp;
|
||||
|
||||
for ( var i in ae_p_fields ) ae_preview.appendChild( ae_p_fields[i] );
|
||||
//// End preview fields
|
||||
|
||||
|
||||
var enableSaveFunction = function ()
|
||||
{
|
||||
ae_backup.className = "ae_iValue ae_dodgerblue flsf";
|
||||
canSave = true;
|
||||
}
|
||||
|
||||
, disableSaveFunction = function ()
|
||||
{
|
||||
ae_backup.className = "ae_iValue ae_disabled flsf";
|
||||
canSave = false;
|
||||
}
|
||||
|
||||
, contentUpdate = function ()
|
||||
{
|
||||
if( !canSave ) enableSaveFunction();
|
||||
// (_visualizer.saveRaw() != _content) ? enableSaveFunction() : disableSaveFunction();
|
||||
}
|
||||
|
||||
//// private methods
|
||||
////// Handlers ///////
|
||||
|
||||
, saveSuccess = function (obj)
|
||||
{
|
||||
disableSaveFunction();
|
||||
ae_mdate.innerHTML = prettyDate( new Date( obj.date_modified ) );
|
||||
|
||||
// Replace state of the content and title
|
||||
ArticleModel.title = _title;
|
||||
ArticleModel.content = _content;
|
||||
ArticleModel.date_modified = obj.date_modified;
|
||||
|
||||
// Set article id if this is a new document
|
||||
if ( obj.article_id )
|
||||
ArticleModel.article_id = __article_id = obj.article_id;
|
||||
|
||||
window.history.replaceState( ArticleModel, "", base_path + "astroedit/" + __article_id + "/" );
|
||||
}
|
||||
|
||||
, publishSuccess = function (obj)
|
||||
{
|
||||
ae_publish.innerHTML = "Done edit";
|
||||
ae_backup.innerHTML = "Backup(Ctrl + s)";
|
||||
|
||||
ArticleModel.date_published = obj.date_published;
|
||||
ae_pdate.innerHTML = prettyDate( new Date( obj.date_published ) );
|
||||
|
||||
this.contentUpdate && saveSuccess(obj);
|
||||
|
||||
new MessageBox("AstroEdit", "You have successfully published your article!", "Stay here", "Exit and goto article", publishAction).show();
|
||||
}
|
||||
|
||||
, publishAction = function (stay)
|
||||
{
|
||||
if (!stay)
|
||||
{
|
||||
window.open( base_path + "article/view/" + ArticleModel.slug + "/") && window.close();
|
||||
}
|
||||
}
|
||||
|
||||
, restoreArticle = function(obj)
|
||||
{
|
||||
debug.Info("[Document] Looking for stored data");
|
||||
if (obj)
|
||||
{
|
||||
debug.Info("[Document] .. data found");
|
||||
// Set stored article id
|
||||
__article_id = obj.article_id;
|
||||
setArticle( obj );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!( ArticleModel && 0 < ArticleModel.article_id ))
|
||||
{
|
||||
debug.Info("[Document] .. data not found");
|
||||
// This is a state of new article
|
||||
var d = Math.floor(new Date().getTime()/1000);
|
||||
__article_id = false;
|
||||
setArticle({
|
||||
title:""
|
||||
, content:""
|
||||
, date_modified: d
|
||||
, date_published: 0
|
||||
, date_created: d
|
||||
, archived: false
|
||||
, tags: null
|
||||
, draft: true
|
||||
, article_id: false
|
||||
});
|
||||
window.history.replaceState( ArticleModel, "", base_path + "astroedit/new/" );
|
||||
}
|
||||
}
|
||||
}
|
||||
/** @param {_AstJson_.AJaxGetArticle} */
|
||||
, showArticle = function( obj )
|
||||
{
|
||||
if ( obj && obj.entry )
|
||||
{
|
||||
debug.Info( "[Document] Article Loaded" );
|
||||
if ( obj.backup )
|
||||
{
|
||||
pBubble.setColor( "royalblue" );
|
||||
pBubble.pop( "Using backup entry" );
|
||||
Cycle.delay( function () { pBubble.blurp() }, 3000 );
|
||||
}
|
||||
setArticle( obj.entry );
|
||||
if ( !obj.entry.article_id )
|
||||
{
|
||||
// sever will not return article_id
|
||||
// since it is an UPDATE
|
||||
// Store the article_id manually
|
||||
obj.entry.article_id = __article_id;
|
||||
}
|
||||
__statePusher( obj.entry, __article_id );
|
||||
}
|
||||
else
|
||||
{
|
||||
debug.Info( "[Document] Article: " + String( __article_id ) + " not found on server." );
|
||||
__article_id = false;
|
||||
}
|
||||
}
|
||||
|
||||
, setArticle = function ( entry )
|
||||
{
|
||||
ArticleModel = entry;
|
||||
ae_title.value = _title = ArticleModel.title;
|
||||
|
||||
_visualizer.visualizeData( _content = ArticleModel.content );
|
||||
|
||||
ae_mdate.innerHTML = prettyDate( new Date( ArticleModel.date_modified ) );
|
||||
ae_cdate.innerHTML = prettyDate( new Date( ArticleModel.date_created ) );
|
||||
|
||||
ae_pdate.innerHTML = ArticleModel.date_published
|
||||
? prettyDate( new Date( ArticleModel.date_published ) )
|
||||
: "Not published."
|
||||
;
|
||||
|
||||
ae_status.innerHTML =
|
||||
( ArticleModel.archived ? "Archived. " : "" )
|
||||
+ ( ArticleModel.draft ? "In draft" : "Published" )
|
||||
;
|
||||
|
||||
ae_publish.innerHTML = ArticleModel.draft ? "Publish" : "Done edit";
|
||||
ae_backup.innerHTML = ( ArticleModel.draft ? "Save" : "Backup" ) + "(Ctrl + s)";
|
||||
|
||||
|
||||
_ae_tag && _ae_tag.setTags( ArticleModel.tags );
|
||||
}
|
||||
|
||||
, deleteDraft = function (confirmed)
|
||||
{
|
||||
if (confirmed)
|
||||
{
|
||||
var _data = {
|
||||
"draft": ArticleModel.draft ? 1 : 0
|
||||
, "article_id": __article_id
|
||||
, "del": 1
|
||||
};
|
||||
|
||||
postData( processorSet, _data, deleteSuccess, serverFailed );
|
||||
}
|
||||
}
|
||||
|
||||
, deleteSuccess = function ()
|
||||
{
|
||||
location.reload(true);
|
||||
}
|
||||
|
||||
, serverFailed = function ( obj )
|
||||
{
|
||||
pBubble.setColor( "red" );
|
||||
pBubble.pop( obj["mesg"] );
|
||||
Cycle.delay( function () { pBubble.blurp() }, 3000 );
|
||||
}
|
||||
|
||||
, contentEmpty = function ()
|
||||
{
|
||||
return !Boolean( ae_content.hasChildNodes() );
|
||||
}
|
||||
;
|
||||
|
||||
// Bind properties
|
||||
|
||||
this.saveOrBackup = function ()
|
||||
{
|
||||
if (canSave)
|
||||
{
|
||||
// Store current content and title
|
||||
_title = ae_title.value.trim();
|
||||
_content = _visualizer.saveRaw();
|
||||
|
||||
/** @type {_AstJson_.AJaxGetArticle.entry} */
|
||||
var _data =
|
||||
{
|
||||
article_id: __article_id ? __article_id : ""
|
||||
, title: _title
|
||||
, content: _content
|
||||
, tags: _ae_tag.getTags()
|
||||
, draft: ArticleModel.draft ? 1 : 0
|
||||
};
|
||||
|
||||
if (ArticleModel.draft == 0)
|
||||
{
|
||||
// This a published article
|
||||
// action is Backup
|
||||
_data.backup = 1;
|
||||
}
|
||||
|
||||
postData( processorSet, _data, saveSuccess, serverFailed);
|
||||
}
|
||||
};
|
||||
|
||||
this.load = function ( aid, statePusher )
|
||||
{
|
||||
if( aid && __article_id != aid )
|
||||
{
|
||||
debug.Info( "[Document] Loading article: " + aid );
|
||||
__statePusher = statePusher;
|
||||
postData(
|
||||
a_conf.paths.get_article
|
||||
, { article_id: __article_id = aid }
|
||||
, showArticle
|
||||
, serverFailed
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
this.getArticleId = function () { return __article_id; }
|
||||
|
||||
this.preview = function ()
|
||||
{
|
||||
ae_p_fields.title.value = ae_title.value;
|
||||
ae_p_fields.content.value = _visualizer.saveRaw();
|
||||
ae_p_fields.mtime.value = ArticleModel.date_modified;
|
||||
ae_p_fields.ptime.value = Number( ArticleModel.date_published )
|
||||
? ArticleModel.date_published
|
||||
: Math.floor( 0.001*( new Date().getTime() ) )
|
||||
;
|
||||
ae_p_fields.tags.value = _ae_tag.getTags();
|
||||
|
||||
ae_preview.submit();
|
||||
};
|
||||
|
||||
this.invoke = function (_class)
|
||||
{
|
||||
if ( _class instanceof Draft ) _ae_draft = _class;
|
||||
if ( _class instanceof Visualizer )
|
||||
{
|
||||
_visualizer = _class;
|
||||
_visualizer.setContentDiv( ae_content );
|
||||
}
|
||||
if ( _class instanceof Tag )
|
||||
{
|
||||
_ae_tag = _class;
|
||||
ArticleModel && ArticleModel.tags && ( _ae_tag ).setTags( ArticleModel.tags );
|
||||
}
|
||||
};
|
||||
|
||||
this.saveAndPublish = function ()
|
||||
{
|
||||
if ( contentEmpty() ) return;
|
||||
|
||||
/** @type {_AstJson_.AJaxGetArticle.entry} */
|
||||
var _data = {
|
||||
article_id: __article_id ? __article_id : ""
|
||||
, draft: 0
|
||||
};
|
||||
|
||||
if ( !ArticleModel.draft )
|
||||
{
|
||||
// This is a published article
|
||||
// Do not backup
|
||||
_data.backup = 0;
|
||||
canSave = true;
|
||||
}
|
||||
|
||||
if ( canSave )
|
||||
{
|
||||
// Store current content and title
|
||||
_title = ae_title.value.trim();
|
||||
_content = _visualizer.saveRaw();
|
||||
|
||||
_data.title = _title;
|
||||
_data.content = _content;
|
||||
_data.tags = _ae_tag.getTags();
|
||||
|
||||
postData( processorSet, _data, publishSuccess.bind({ contentUpdate: true }), serverFailed );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Do not submit uneccessary data!
|
||||
postData( processorSet, _data, publishSuccess, serverFailed );
|
||||
}
|
||||
};
|
||||
|
||||
this.drop = function ()
|
||||
{
|
||||
new MessageBox(
|
||||
"Delete draft"
|
||||
, "Are you sure you want to delete this draft? (Published article will only remove backup draft.)"
|
||||
, "Delete", "No"
|
||||
, deleteDraft
|
||||
).show();
|
||||
};
|
||||
|
||||
this.updateContent = contentUpdate;
|
||||
|
||||
// Setting Ctrl+s functions
|
||||
new IDOMObject(document).addEventListener(
|
||||
new EventKey("KeyDown", function(e)
|
||||
{
|
||||
// key Ctrl(17)
|
||||
if(e.ctrlKey == true && e.which == 83)
|
||||
{
|
||||
// key s (83)
|
||||
this.saveOrBackup();
|
||||
e.preventDefault();
|
||||
}
|
||||
/*
|
||||
else if(e.which == 66)
|
||||
{
|
||||
// key b(66)
|
||||
this.backup.bind(this)();
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
}.bind(this))
|
||||
);
|
||||
|
||||
IDOMElement( ae_backup ).addEventListener( "Click", this.saveOrBackup );
|
||||
|
||||
window.addEventListener(
|
||||
"popstate"
|
||||
, function( event )
|
||||
{
|
||||
debug.Info( "[Document] Pop State fired" );
|
||||
restoreArticle( event.state );
|
||||
}
|
||||
);
|
||||
|
||||
ae_title.oninput = function ()
|
||||
{
|
||||
( ae_title.value != _title ) ? enableSaveFunction() : disableSaveFunction();
|
||||
}
|
||||
|
||||
temp = IDOMElement(ae_content);
|
||||
|
||||
temp.addEventListener( "Input", function() { enableSaveFunction(); } );
|
||||
|
||||
document.body.appendChild( pBubble.init() );
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
var set_field_name = function ( elem, value )
|
||||
{
|
||||
elem.name = value;
|
||||
elem.type = "hidden";
|
||||
return elem;
|
||||
};
|
||||
|
||||
ns[ NS_EXPORT ]( EX_CLASS, "Article", Article );
|
||||
})();
|
||||
Reference in New Issue
Block a user