[pLog-svn] r2763 - in plog/trunk: class/action/admin
class/controller js js/prototype js/ui locale templates/admin
templates/admin/xml
mark at devel.lifetype.net
mark at devel.lifetype.net
Tue Jan 10 10:38:39 GMT 2006
Author: mark
Date: 2006-01-10 10:38:38 +0000 (Tue, 10 Jan 2006)
New Revision: 2763
Added:
plog/trunk/class/action/admin/adminaddarticlecategoryajaxaction.class.php
plog/trunk/class/action/admin/adminsavedraftarticleajaxaction.class.php
plog/trunk/js/prototype/
plog/trunk/js/prototype/prototype.js
Removed:
plog/trunk/class/action/admin/adminxmlsavedraftaction.class.php
Modified:
plog/trunk/class/controller/admincontrollermap.properties.php
plog/trunk/js/ui/plogui.js
plog/trunk/locale/locale_en_UK.php
plog/trunk/locale/locale_zh_TW.php
plog/trunk/templates/admin/header.template
plog/trunk/templates/admin/newpost.template
plog/trunk/templates/admin/xml/response.template
Log:
LifeType, powerd by Ajax now.
I just rewrite/rename the adminxmlsavedraftaction.class.php to admin/adminsavedraftarticleajaxaction.class.php with prototype Ajax library ( http://prototype.conio.net ). And it reduce the complexity of original plogui.js dramatically.
I also add a new feature addArticleCategoryAjax -- admin/adminaddarticlecategoryajaxaction.class.php. It can allow user to add a new article category when he is writing post, he doesn't need to change to addArticleCategory page. (I learned this idea from wordpress 2.0).
And, I also think this skill can used in dynamic content, it is easier than hacking smarty {dynamic} tags.
Discuss: I think the addArticleCategoryAjax for newpost is enough, do you need it available in editpost?
Added: plog/trunk/class/action/admin/adminaddarticlecategoryajaxaction.class.php
===================================================================
--- plog/trunk/class/action/admin/adminaddarticlecategoryajaxaction.class.php 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/class/action/admin/adminaddarticlecategoryajaxaction.class.php 2006-01-10 10:38:38 UTC (rev 2763)
@@ -0,0 +1,98 @@
+<?php
+
+ include_once( PLOG_CLASS_PATH."class/action/admin/adminaction.class.php" );
+ include_once( PLOG_CLASS_PATH."class/dao/articlecategories.class.php" );
+ include_once( PLOG_CLASS_PATH."class/data/textfilter.class.php" );
+ include_once( PLOG_CLASS_PATH."class/view/admin/adminxmlview.class.php" );
+
+ /**
+ * \ingroup Action
+ * @private
+ *
+ * Action that adds a new article category to the database.
+ */
+ class AdminAddArticleCategoryAjaxAction extends AdminAction
+ {
+
+ var $_categoryName;
+ var $_categoryUrl;
+ var $_properties;
+ var $_categoryDescription;
+
+ /**
+ * Constructor. If nothing else, it also has to call the constructor of the parent
+ * class, BlogAction with the same parameters
+ */
+ function AdminAddArticleCategoryAjaxAction( $actionInfo, $request )
+ {
+ $this->AdminAction( $actionInfo, $request );
+ }
+ function validate()
+ {
+ // fetch the data, we already know it's valid and that we can trust it!
+ $this->_categoryName = Textfilter::filterAllHTML($this->_request->getValue( "categoryName" ));
+ $this->_categoryUrl = "";
+ $this->_categoryInMainPage = 1;
+ $this->_categoryDescription = $this->_categoryName;
+ $this->_properties = "";
+
+ // check if there's any file to upload
+ if( empty($this->_categoryName) || $this->_categoryName == "" ) {
+ $this->_view = new AdminXmlView( $this->_blogInfo, "response" );
+ $this->_view->setValue( "method", "addCategoryAjax" );
+ $this->_view->setValue( "success", "0" );
+ $this->_view->setValue( "message", $this->_locale->tr("error_adding_article_category") );
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Carries out the specified action
+ */
+ function perform()
+ {
+ // create the object...
+ $categories = new ArticleCategories();
+ $category = new ArticleCategory( $this->_categoryName,
+ $this->_categoryUrl,
+ $this->_blogInfo->getId(),
+ $this->_categoryInMainPage,
+ $this->_categoryDescription,
+ 0,
+ $this->_properties );
+
+ // fire the pre event...
+ $this->notifyEvent( EVENT_PRE_CATEGORY_ADD, Array( "category" => &$category ));
+
+ $this->_view = new AdminXmlView( $this->_blogInfo, "response" );
+ $this->_view->setValue( "method", "addCategoryAjax" );
+
+ // once we have built the object, we can add it to the database!
+ $catId = $categories->addArticleCategory( $category );
+
+ // once we have built the object, we can add it to the database
+ $this->_view = new AdminXmlView( $this->_blogInfo, "response" );
+ $this->_view->setValue( "method", "addCategoryAjax" );
+ if( $catId )
+ {
+ $this->_view->setValue( "success", "1" );
+ $this->_view->setValue( "message", $this->_locale->pr("category_added_ok", $this->_categoryName) );
+
+ $result = '<id>'.$catId.'</id>';
+ $result .= '<name>'.$this->_categoryName.'</name>';
+ $this->_view->setValue( "result", $result );
+
+ // fire the post event
+ $this->notifyEvent( EVENT_POST_CATEGORY_ADD, Array( "category" => &$category ));
+ }
+ else
+ {
+ $this->_view->setValue( "success", "0" );
+ $this->_view->setValue( "message", $this->_locale->tr("error_adding_article_category") );
+ }
+
+ return true;
+ }
+ }
+?>
\ No newline at end of file
Added: plog/trunk/class/action/admin/adminsavedraftarticleajaxaction.class.php
===================================================================
--- plog/trunk/class/action/admin/adminsavedraftarticleajaxaction.class.php 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/class/action/admin/adminsavedraftarticleajaxaction.class.php 2006-01-10 10:38:38 UTC (rev 2763)
@@ -0,0 +1,140 @@
+<?php
+
+ include_once( PLOG_CLASS_PATH."class/action/admin/adminaction.class.php" );
+ include_once( PLOG_CLASS_PATH."class/view/admin/adminxmlview.class.php" );
+ include_once( PLOG_CLASS_PATH."class/data/timestamp.class.php");
+ include_once( PLOG_CLASS_PATH."class/dao/articles.class.php" );
+
+ /**
+ * \ingroup Action
+ * @private
+ */
+ class AdminSaveDraftArticleAjaxAction extends AdminAction
+ {
+
+ function AdminSaveDraftArticleAjaxAction( $actionInfo, $request )
+ {
+ $this->AdminAction( $actionInfo, $request );
+ }
+
+ function validate()
+ {
+ $this->_postText = $this->_request->getValue( "postText" );
+ $this->_postExtendedText = $this->_request->getValue( "postExtendedText" );
+ $this->_postTopic = $this->_request->getValue( "postTopic" );
+
+ // if there is no text, extended text or topic there is no point in saving anything
+ if( $this->_postText == "" && $this->_postExtendedTExt == "" &&
+ $this->_postTopic == "" ) {
+ // nothing to do yet, so let's quit
+ $this->_view = new AdminXmlView( $this->_blogInfo, "response" );
+ $this->_view->setValue( "method", "saveDraftArticleAjax" );
+ $this->_view->setValue( "success", "0" );
+ $this->_view->setValue( "message", $this->_locale->tr( "error_saving_draft" ) );
+
+ return false;
+ }
+
+ $this->_postCategories = $this->_request->getValue( "postCategories" );
+ $this->_postStatus = $this->_request->getValue( "postStatus" );
+ $this->_postSlug = $this->_request->getValue( "postSlug" );
+ $this->_sendNotification = $this->_request->getValue( "sendNotification" );
+ $this->_sendTrackbacks = $this->_request->getValue( "sendTrackbacks" );
+ $this->_sendPings = $this->_request->getValue( "sendPings" );
+ $this->_postId = $this->_request->getValue( "postId" );
+ $this->_commentsEnabled = $this->_request->getValue( "commentsEnabled" );
+ if( $this->_commentsEnabled != 1 )
+ $this->_commentsEnabled = false;
+ else
+ $this->_commentsEnabled = true;
+
+ // fetch the custom fields
+ $this->_customFields = $this->_request->getValue( "customField" );
+
+ // fetch the timestamp that the post will have
+ if( $this->_config->getValue( "disable_javascript_calendar")) {
+ $this->_postDay = $this->_request->getValue( "postDay" );
+ $this->_postMonth = $this->_request->getValue( "postMonth" );
+ $this->_postHour = $this->_request->getValue( "postHour" );
+ $this->_postMinutes = $this->_request->getValue( "postMinutes" );
+ $this->_postYear = $this->_request->getValue( "postYear" );
+ }
+ else {
+ $postDateTime = $this->_request->getValue( "postDateTime" );
+ $dateTimeParts = explode(" ", $postDateTime);
+ $dateParts = explode("/", $dateTimeParts[0] );
+ $timeParts = explode(":",$dateTimeParts[1] );
+ $this->_postDay = $dateParts[0];
+ $this->_postMonth = $dateParts[1];
+ $this->_postYear = $dateParts[2];
+ $this->_postHour = $timeParts[0];
+ $this->_postMinutes = $timeParts[1];
+ }
+
+ $this->_postTimestamp = new Timestamp();
+ $this->_postTimestamp->setMinutes( $this->_postMinutes );
+ $this->_postTimestamp->setHour( $this->_postHour );
+ $this->_postTimestamp->setDay( $this->_postDay );
+ $this->_postTimestamp->setMonth( $this->_postMonth );
+ $this->_postTimestamp->setYear( $this->_postYear );
+ return true;
+ }
+
+ function perform()
+ {
+ $status = POST_STATUS_DRAFT;
+ $articles = new Articles();
+ $postText = Textfilter::xhtmlize($this->_postText).POST_EXTENDED_TEXT_MODIFIER.Textfilter::xhtmlize($this->_postExtendedText);
+
+ $article = new Article( $this->_postTopic, $postText, $this->_postCategories, $this->_userInfo->getId(),
+ $this->_blogInfo->getId(), $status, 0, Array(), $this->_postSlug );
+ // set also the date before it's too late
+ $article->setDateObject( $this->_postTimestamp );
+ $article->setCommentsEnabled( $this->_commentsEnabled );
+ // prepare the custom fields
+ $fields = Array();
+ if( is_array($this->_customFields)) {
+ foreach( $this->_customFields as $fieldId => $fieldValue ) {
+ // 3 of those parameters are not really need when creating a new object... it's enough that
+ // we know the field definition id.
+ $customField = new CustomFieldValue( $fieldId, $fieldValue, "", -1, "", $artId, $this->_blogInfo->getId(), -1);
+ array_push( $fields, $customField );
+ }
+ $article->setFields( $fields );
+ }
+
+ // in case the post is already in the db
+ if( $this->_postId != "" ) {
+ $article->setId( $this->_postId );
+ $postSavedOk = $articles->updateArticle( $article );
+
+ if( $postSavedOk )
+ $artId = $this->_postId;
+ else
+ $artId = false;
+ }
+ else {
+ $artId = $articles->addArticle( $article );
+ }
+
+ // once we have built the object, we can add it to the database
+ $this->_view = new AdminXmlView( $this->_blogInfo, "response" );
+ $this->_view->setValue( "method", "saveDraftArticleAjax" );
+ if( $artId )
+ {
+ $this->_view->setValue( "success", "1" );
+ $this->_view->setValue( "message", $this->_locale->pr( "draft_saved_ok", $this->_postTopic ) );
+
+ $result = '<id>'.$artId.'</id>';
+ $this->_view->setValue( "result", $result );
+ }
+ else
+ {
+ $this->_view->setValue( "success", "0" );
+ $this->_view->setValue( "message", $this->_locale->tr( "error_saving_draft" ) );
+ }
+
+ return true;
+ }
+ }
+?>
\ No newline at end of file
Deleted: plog/trunk/class/action/admin/adminxmlsavedraftaction.class.php
===================================================================
--- plog/trunk/class/action/admin/adminxmlsavedraftaction.class.php 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/class/action/admin/adminxmlsavedraftaction.class.php 2006-01-10 10:38:38 UTC (rev 2763)
@@ -1,128 +0,0 @@
-<?php
-
- include_once( PLOG_CLASS_PATH."class/action/admin/adminaction.class.php" );
- include_once( PLOG_CLASS_PATH."class/view/admin/adminxmlview.class.php" );
-
- /**
- * \ingroup Action
- * @private
- */
- class AdminXmlSaveDraftAction extends AdminAction
- {
-
- function AdminXmlSaveDraftAction( $actionInfo, $request )
- {
- $this->AdminAction( $actionInfo, $request );
- }
-
- function validate()
- {
- $this->_postText = $this->_request->getValue( "postText" );
- $this->_postExtendedText = $this->_request->getValue( "postExtendedText" );
- $this->_postTopic = $this->_request->getValue( "postTopic" );
-
- // if there is no text, extended text or topic there is no point in saving anything
- if( $this->_postText == "" && $this->_postExtendedTExt == "" &&
- $this->_postTopic == "" ) {
- // nothing to do yet, so let's quit
- $this->_view = new AdminXmlView( $this->_blogInfo, "response" );
- $this->_view->setValue( "method", "saveXmlDraft" );
- $this->_view->setValue( "result", "0" );
-
- return false;
- }
-
- $this->_postCategories = $this->_request->getValue( "postCategories" );
- $this->_postStatus = $this->_request->getValue( "postStatus" );
- $this->_postSlug = $this->_request->getValue( "postSlug" );
- $this->_sendNotification = $this->_request->getValue( "sendNotification" );
- $this->_sendTrackbacks = $this->_request->getValue( "sendTrackbacks" );
- $this->_sendPings = $this->_request->getValue( "sendPings" );
- $this->_postId = $this->_request->getValue( "postId" );
- $this->_commentsEnabled = $this->_request->getValue( "commentsEnabled" );
- if( $this->_commentsEnabled != 1 )
- $this->_commentsEnabled = false;
- else
- $this->_commentsEnabled = true;
-
- // fetch the custom fields
- $this->_customFields = $this->_request->getValue( "customField" );
-
- // fetch the timestamp that the post will have
- if( $this->_config->getValue( "disable_javascript_calendar")) {
- $this->_postDay = $this->_request->getValue( "postDay" );
- $this->_postMonth = $this->_request->getValue( "postMonth" );
- $this->_postHour = $this->_request->getValue( "postHour" );
- $this->_postMinutes = $this->_request->getValue( "postMinutes" );
- $this->_postYear = $this->_request->getValue( "postYear" );
- }
- else {
- $postDateTime = $this->_request->getValue( "postDateTime" );
- $dateTimeParts = explode(" ", $postDateTime);
- $dateParts = explode("/", $dateTimeParts[0] );
- $timeParts = explode(":",$dateTimeParts[1] );
- $this->_postDay = $dateParts[0];
- $this->_postMonth = $dateParts[1];
- $this->_postYear = $dateParts[2];
- $this->_postHour = $timeParts[0];
- $this->_postMinutes = $timeParts[1];
- }
-
- $this->_postTimestamp = new Timestamp();
- $this->_postTimestamp->setMinutes( $this->_postMinutes );
- $this->_postTimestamp->setHour( $this->_postHour );
- $this->_postTimestamp->setDay( $this->_postDay );
- $this->_postTimestamp->setMonth( $this->_postMonth );
- $this->_postTimestamp->setYear( $this->_postYear );
- return true;
- }
-
- function perform()
- {
- $status = POST_STATUS_DRAFT;
- $articles = new Articles();
- $postText = Textfilter::xhtmlize($this->_postText).POST_EXTENDED_TEXT_MODIFIER.Textfilter::xhtmlize($this->_postExtendedText);
-
- $article = new Article( $this->_postTopic, $postText, $this->_postCategories, $this->_userInfo->getId(),
- $this->_blogInfo->getId(), $status, 0, Array(), $this->_postSlug );
- // set also the date before it's too late
- $article->setDateObject( $this->_postTimestamp );
- $article->setCommentsEnabled( $this->_commentsEnabled );
- // prepare the custom fields
- $fields = Array();
- if( is_array($this->_customFields)) {
- foreach( $this->_customFields as $fieldId => $fieldValue ) {
- // 3 of those parameters are not really need when creating a new object... it's enough that
- // we know the field definition id.
- $customField = new CustomFieldValue( $fieldId, $fieldValue, "", -1, "", $artId, $this->_blogInfo->getId(), -1);
- array_push( $fields, $customField );
- }
- $article->setFields( $fields );
- }
-
- // in case the post is already in the db
- if( $this->_postId != "" ) {
- $article->setId( $this->_postId );
- $postSavedOk = $articles->updateArticle( $article );
-
- if( $postSavedOk )
- $artId = $this->_postId;
- else
- $artId = false;
- }
- else {
- $artId = $articles->addArticle( $article );
- }
-
- // once we have built the object, we can add it to the database
- $this->_view = new AdminXmlView( $this->_blogInfo, "response" );
- $this->_view->setValue( "method", "saveXmlDraft" );
- if( $artId )
- $this->_view->setValue( "result", $artId );
- else
- $this->_view->setValue( "result", "0" );
-
- return true;
- }
- }
-?>
\ No newline at end of file
Modified: plog/trunk/class/controller/admincontrollermap.properties.php
===================================================================
--- plog/trunk/class/controller/admincontrollermap.properties.php 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/class/controller/admincontrollermap.properties.php 2006-01-10 10:38:38 UTC (rev 2763)
@@ -26,6 +26,8 @@
$actions["newArticleCategory"] = "AdminNewArticleCategoryAction";
// adds the category to the db
$actions["addArticleCategory"] = "AdminAddArticleCategoryAction";
+ // adds the category to the db through Ajax
+ $actions["addArticleCategoryAjax"] = "AdminAddArticleCategoryAjaxAction";
// shows the settings of the blog
$actions["blogSettings"] = "AdminBlogSettingsAction";
// updates the settings of the blog
@@ -230,7 +232,7 @@
$actions["xmlPing"] = "AdminXmlPingAction";
// the action below is used in cooperation with the XmlHttpRequest object to
// automatically save drafts of posts in the background
- $actions["saveXmlDraft"] = "AdminXmlSaveDraftAction";
+ $actions["saveDraftArticleAjax"] = "AdminSaveDraftArticleAjaxAction";
// remove a trackback
$actions["deleteTrackback"] = "AdminDeleteTrackbackAction";
$actions["deleteTrackbacks"] = "AdminDeleteTrackbackAction";
Added: plog/trunk/js/prototype/prototype.js
===================================================================
--- plog/trunk/js/prototype/prototype.js 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/js/prototype/prototype.js 2006-01-10 10:38:38 UTC (rev 2763)
@@ -0,0 +1,1038 @@
+/* Prototype JavaScript framework, version 1.3.1
+ * (c) 2005 Sam Stephenson <sam at conio.net>
+ *
+ * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
+ * against the source tree, available from the Prototype darcs repository.
+ *
+ * Prototype is freely distributable under the terms of an MIT-style license.
+ *
+ * For details, see the Prototype web site: http://prototype.conio.net/
+ *
+/*--------------------------------------------------------------------------*/
+
+var Prototype = {
+ Version: '1.3.1',
+ emptyFunction: function() {}
+}
+
+var Class = {
+ create: function() {
+ return function() {
+ this.initialize.apply(this, arguments);
+ }
+ }
+}
+
+var Abstract = new Object();
+
+Object.extend = function(destination, source) {
+ for (property in source) {
+ destination[property] = source[property];
+ }
+ return destination;
+}
+
+Object.prototype.extend = function(object) {
+ return Object.extend.apply(this, [this, object]);
+}
+
+Function.prototype.bind = function(object) {
+ var __method = this;
+ return function() {
+ __method.apply(object, arguments);
+ }
+}
+
+Function.prototype.bindAsEventListener = function(object) {
+ var __method = this;
+ return function(event) {
+ __method.call(object, event || window.event);
+ }
+}
+
+Number.prototype.toColorPart = function() {
+ var digits = this.toString(16);
+ if (this < 16) return '0' + digits;
+ return digits;
+}
+
+var Try = {
+ these: function() {
+ var returnValue;
+
+ for (var i = 0; i < arguments.length; i++) {
+ var lambda = arguments[i];
+ try {
+ returnValue = lambda();
+ break;
+ } catch (e) {}
+ }
+
+ return returnValue;
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var PeriodicalExecuter = Class.create();
+PeriodicalExecuter.prototype = {
+ initialize: function(callback, frequency) {
+ this.callback = callback;
+ this.frequency = frequency;
+ this.currentlyExecuting = false;
+
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ if (!this.currentlyExecuting) {
+ try {
+ this.currentlyExecuting = true;
+ this.callback();
+ } finally {
+ this.currentlyExecuting = false;
+ }
+ }
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+function $() {
+ var elements = new Array();
+
+ for (var i = 0; i < arguments.length; i++) {
+ var element = arguments[i];
+ if (typeof element == 'string')
+ element = document.getElementById(element);
+
+ if (arguments.length == 1)
+ return element;
+
+ elements.push(element);
+ }
+
+ return elements;
+}
+
+if (!Array.prototype.push) {
+ Array.prototype.push = function() {
+ var startLength = this.length;
+ for (var i = 0; i < arguments.length; i++)
+ this[startLength + i] = arguments[i];
+ return this.length;
+ }
+}
+
+if (!Function.prototype.apply) {
+ // Based on code from http://www.youngpup.net/
+ Function.prototype.apply = function(object, parameters) {
+ var parameterStrings = new Array();
+ if (!object) object = window;
+ if (!parameters) parameters = new Array();
+
+ for (var i = 0; i < parameters.length; i++)
+ parameterStrings[i] = 'parameters[' + i + ']';
+
+ object.__apply__ = this;
+ var result = eval('object.__apply__(' +
+ parameterStrings.join(', ') + ')');
+ object.__apply__ = null;
+
+ return result;
+ }
+}
+
+String.prototype.extend({
+ stripTags: function() {
+ return this.replace(/<\/?[^>]+>/gi, '');
+ },
+
+ escapeHTML: function() {
+ var div = document.createElement('div');
+ var text = document.createTextNode(this);
+ div.appendChild(text);
+ return div.innerHTML;
+ },
+
+ unescapeHTML: function() {
+ var div = document.createElement('div');
+ div.innerHTML = this.stripTags();
+ return div.childNodes[0].nodeValue;
+ }
+});
+
+var Ajax = {
+ getTransport: function() {
+ return Try.these(
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')},
+ function() {return new XMLHttpRequest()}
+ ) || false;
+ }
+}
+
+Ajax.Base = function() {};
+Ajax.Base.prototype = {
+ setOptions: function(options) {
+ this.options = {
+ method: 'post',
+ asynchronous: true,
+ parameters: ''
+ }.extend(options || {});
+ },
+
+ responseIsSuccess: function() {
+ return this.transport.status == undefined
+ || this.transport.status == 0
+ || (this.transport.status >= 200 && this.transport.status < 300);
+ },
+
+ responseIsFailure: function() {
+ return !this.responseIsSuccess();
+ }
+}
+
+Ajax.Request = Class.create();
+Ajax.Request.Events =
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
+
+Ajax.Request.prototype = (new Ajax.Base()).extend({
+ initialize: function(url, options) {
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+ this.request(url);
+ },
+
+ request: function(url) {
+ var parameters = this.options.parameters || '';
+ if (parameters.length > 0) parameters += '&_=';
+
+ try {
+ if (this.options.method == 'get')
+ url += '?' + parameters;
+
+ this.transport.open(this.options.method, url,
+ this.options.asynchronous);
+
+ if (this.options.asynchronous) {
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
+ setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
+ }
+
+ this.setRequestHeaders();
+
+ var body = this.options.postBody ? this.options.postBody : parameters;
+ this.transport.send(this.options.method == 'post' ? body : null);
+
+ } catch (e) {
+ }
+ },
+
+ setRequestHeaders: function() {
+ var requestHeaders =
+ ['X-Requested-With', 'XMLHttpRequest',
+ 'X-Prototype-Version', Prototype.Version];
+
+ if (this.options.method == 'post') {
+ requestHeaders.push('Content-type',
+ 'application/x-www-form-urlencoded');
+
+ /* Force "Connection: close" for Mozilla browsers to work around
+ * a bug where XMLHttpReqeuest sends an incorrect Content-length
+ * header. See Mozilla Bugzilla #246651.
+ */
+ if (this.transport.overrideMimeType)
+ requestHeaders.push('Connection', 'close');
+ }
+
+ if (this.options.requestHeaders)
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
+
+ for (var i = 0; i < requestHeaders.length; i += 2)
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
+ },
+
+ onStateChange: function() {
+ var readyState = this.transport.readyState;
+ if (readyState != 1)
+ this.respondToReadyState(this.transport.readyState);
+ },
+
+ respondToReadyState: function(readyState) {
+ var event = Ajax.Request.Events[readyState];
+
+ if (event == 'Complete')
+ (this.options['on' + this.transport.status]
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
+ || Prototype.emptyFunction)(this.transport);
+
+ (this.options['on' + event] || Prototype.emptyFunction)(this.transport);
+
+ /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
+ if (event == 'Complete')
+ this.transport.onreadystatechange = Prototype.emptyFunction;
+ }
+});
+
+Ajax.Updater = Class.create();
+Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
+
+Ajax.Updater.prototype.extend(Ajax.Request.prototype).extend({
+ initialize: function(container, url, options) {
+ this.containers = {
+ success: container.success ? $(container.success) : $(container),
+ failure: container.failure ? $(container.failure) :
+ (container.success ? null : $(container))
+ }
+
+ this.transport = Ajax.getTransport();
+ this.setOptions(options);
+
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
+ this.options.onComplete = (function() {
+ this.updateContent();
+ onComplete(this.transport);
+ }).bind(this);
+
+ this.request(url);
+ },
+
+ updateContent: function() {
+ var receiver = this.responseIsSuccess() ?
+ this.containers.success : this.containers.failure;
+
+ var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
+ var response = this.transport.responseText.replace(match, '');
+ var scripts = this.transport.responseText.match(match);
+
+ if (receiver) {
+ if (this.options.insertion) {
+ new this.options.insertion(receiver, response);
+ } else {
+ receiver.innerHTML = response;
+ }
+ }
+
+ if (this.responseIsSuccess()) {
+ if (this.onComplete)
+ setTimeout((function() {this.onComplete(
+ this.transport)}).bind(this), 10);
+ }
+
+ if (this.options.evalScripts && scripts) {
+ match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
+ setTimeout((function() {
+ for (var i = 0; i < scripts.length; i++)
+ eval(scripts[i].match(match)[1]);
+ }).bind(this), 10);
+ }
+ }
+});
+
+Ajax.PeriodicalUpdater = Class.create();
+Ajax.PeriodicalUpdater.prototype = (new Ajax.Base()).extend({
+ initialize: function(container, url, options) {
+ this.setOptions(options);
+ this.onComplete = this.options.onComplete;
+
+ this.frequency = (this.options.frequency || 2);
+ this.decay = 1;
+
+ this.updater = {};
+ this.container = container;
+ this.url = url;
+
+ this.start();
+ },
+
+ start: function() {
+ this.options.onComplete = this.updateComplete.bind(this);
+ this.onTimerEvent();
+ },
+
+ stop: function() {
+ this.updater.onComplete = undefined;
+ clearTimeout(this.timer);
+ (this.onComplete || Ajax.emptyFunction).apply(this, arguments);
+ },
+
+ updateComplete: function(request) {
+ if (this.options.decay) {
+ this.decay = (request.responseText == this.lastText ?
+ this.decay * this.options.decay : 1);
+
+ this.lastText = request.responseText;
+ }
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
+ this.decay * this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
+ }
+});
+
+document.getElementsByClassName = function(className) {
+ var children = document.getElementsByTagName('*') || document.all;
+ var elements = new Array();
+
+ for (var i = 0; i < children.length; i++) {
+ var child = children[i];
+ var classNames = child.className.split(' ');
+ for (var j = 0; j < classNames.length; j++) {
+ if (classNames[j] == className) {
+ elements.push(child);
+ break;
+ }
+ }
+ }
+
+ return elements;
+}
+
+/*--------------------------------------------------------------------------*/
+
+if (!window.Element) {
+ var Element = new Object();
+}
+
+Object.extend(Element, {
+ toggle: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ element.style.display =
+ (element.style.display == 'none' ? '' : 'none');
+ }
+ },
+
+ hide: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ element.style.display = 'none';
+ }
+ },
+
+ show: function() {
+ for (var i = 0; i < arguments.length; i++) {
+ var element = $(arguments[i]);
+ element.style.display = '';
+ }
+ },
+
+ remove: function(element) {
+ element = $(element);
+ element.parentNode.removeChild(element);
+ },
+
+ getHeight: function(element) {
+ element = $(element);
+ return element.offsetHeight;
+ },
+
+ hasClassName: function(element, className) {
+ element = $(element);
+ if (!element)
+ return;
+ var a = element.className.split(' ');
+ for (var i = 0; i < a.length; i++) {
+ if (a[i] == className)
+ return true;
+ }
+ return false;
+ },
+
+ addClassName: function(element, className) {
+ element = $(element);
+ Element.removeClassName(element, className);
+ element.className += ' ' + className;
+ },
+
+ removeClassName: function(element, className) {
+ element = $(element);
+ if (!element)
+ return;
+ var newClassName = '';
+ var a = element.className.split(' ');
+ for (var i = 0; i < a.length; i++) {
+ if (a[i] != className) {
+ if (i > 0)
+ newClassName += ' ';
+ newClassName += a[i];
+ }
+ }
+ element.className = newClassName;
+ },
+
+ // removes whitespace-only text node children
+ cleanWhitespace: function(element) {
+ var element = $(element);
+ for (var i = 0; i < element.childNodes.length; i++) {
+ var node = element.childNodes[i];
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
+ Element.remove(node);
+ }
+ }
+});
+
+var Toggle = new Object();
+Toggle.display = Element.toggle;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.Insertion = function(adjacency) {
+ this.adjacency = adjacency;
+}
+
+Abstract.Insertion.prototype = {
+ initialize: function(element, content) {
+ this.element = $(element);
+ this.content = content;
+
+ if (this.adjacency && this.element.insertAdjacentHTML) {
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
+ } else {
+ this.range = this.element.ownerDocument.createRange();
+ if (this.initializeRange) this.initializeRange();
+ this.fragment = this.range.createContextualFragment(this.content);
+ this.insertContent();
+ }
+ }
+}
+
+var Insertion = new Object();
+
+Insertion.Before = Class.create();
+Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
+ initializeRange: function() {
+ this.range.setStartBefore(this.element);
+ },
+
+ insertContent: function() {
+ this.element.parentNode.insertBefore(this.fragment, this.element);
+ }
+});
+
+Insertion.Top = Class.create();
+Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
+ initializeRange: function() {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(true);
+ },
+
+ insertContent: function() {
+ this.element.insertBefore(this.fragment, this.element.firstChild);
+ }
+});
+
+Insertion.Bottom = Class.create();
+Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
+ initializeRange: function() {
+ this.range.selectNodeContents(this.element);
+ this.range.collapse(this.element);
+ },
+
+ insertContent: function() {
+ this.element.appendChild(this.fragment);
+ }
+});
+
+Insertion.After = Class.create();
+Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
+ initializeRange: function() {
+ this.range.setStartAfter(this.element);
+ },
+
+ insertContent: function() {
+ this.element.parentNode.insertBefore(this.fragment,
+ this.element.nextSibling);
+ }
+});
+
+var Field = {
+ clear: function() {
+ for (var i = 0; i < arguments.length; i++)
+ $(arguments[i]).value = '';
+ },
+
+ focus: function(element) {
+ $(element).focus();
+ },
+
+ present: function() {
+ for (var i = 0; i < arguments.length; i++)
+ if ($(arguments[i]).value == '') return false;
+ return true;
+ },
+
+ select: function(element) {
+ $(element).select();
+ },
+
+ activate: function(element) {
+ $(element).focus();
+ $(element).select();
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var Form = {
+ serialize: function(form) {
+ var elements = Form.getElements($(form));
+ var queryComponents = new Array();
+
+ for (var i = 0; i < elements.length; i++) {
+ var queryComponent = Form.Element.serialize(elements[i]);
+ if (queryComponent)
+ queryComponents.push(queryComponent);
+ }
+
+ return queryComponents.join('&');
+ },
+
+ getElements: function(form) {
+ var form = $(form);
+ var elements = new Array();
+
+ for (tagName in Form.Element.Serializers) {
+ var tagElements = form.getElementsByTagName(tagName);
+ for (var j = 0; j < tagElements.length; j++)
+ elements.push(tagElements[j]);
+ }
+ return elements;
+ },
+
+ getInputs: function(form, typeName, name) {
+ var form = $(form);
+ var inputs = form.getElementsByTagName('input');
+
+ if (!typeName && !name)
+ return inputs;
+
+ var matchingInputs = new Array();
+ for (var i = 0; i < inputs.length; i++) {
+ var input = inputs[i];
+ if ((typeName && input.type != typeName) ||
+ (name && input.name != name))
+ continue;
+ matchingInputs.push(input);
+ }
+
+ return matchingInputs;
+ },
+
+ disable: function(form) {
+ var elements = Form.getElements(form);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element.blur();
+ element.disabled = 'true';
+ }
+ },
+
+ enable: function(form) {
+ var elements = Form.getElements(form);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ element.disabled = '';
+ }
+ },
+
+ focusFirstElement: function(form) {
+ var form = $(form);
+ var elements = Form.getElements(form);
+ for (var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ if (element.type != 'hidden' && !element.disabled) {
+ Field.activate(element);
+ break;
+ }
+ }
+ },
+
+ reset: function(form) {
+ $(form).reset();
+ }
+}
+
+Form.Element = {
+ serialize: function(element) {
+ var element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if (parameter)
+ return encodeURIComponent(parameter[0]) + '=' +
+ encodeURIComponent(parameter[1]);
+ },
+
+ getValue: function(element) {
+ var element = $(element);
+ var method = element.tagName.toLowerCase();
+ var parameter = Form.Element.Serializers[method](element);
+
+ if (parameter)
+ return parameter[1];
+ }
+}
+
+Form.Element.Serializers = {
+ input: function(element) {
+ switch (element.type.toLowerCase()) {
+ case 'submit':
+ case 'hidden':
+ case 'password':
+ case 'text':
+ return Form.Element.Serializers.textarea(element);
+ case 'checkbox':
+ case 'radio':
+ return Form.Element.Serializers.inputSelector(element);
+ }
+ return false;
+ },
+
+ inputSelector: function(element) {
+ if (element.checked)
+ return [element.name, element.value];
+ },
+
+ textarea: function(element) {
+ return [element.name, element.value];
+ },
+
+ select: function(element) {
+ var value = '';
+ if (element.type == 'select-one') {
+ var index = element.selectedIndex;
+ if (index >= 0)
+ value = element.options[index].value || element.options[index].text;
+ } else {
+ value = new Array();
+ for (var i = 0; i < element.length; i++) {
+ var opt = element.options[i];
+ if (opt.selected)
+ value.push(opt.value || opt.text);
+ }
+ }
+ return [element.name, value];
+ }
+}
+
+/*--------------------------------------------------------------------------*/
+
+var $F = Form.Element.getValue;
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.TimedObserver = function() {}
+Abstract.TimedObserver.prototype = {
+ initialize: function(element, frequency, callback) {
+ this.frequency = frequency;
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ this.registerCallback();
+ },
+
+ registerCallback: function() {
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
+ },
+
+ onTimerEvent: function() {
+ var value = this.getValue();
+ if (this.lastValue != value) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ }
+}
+
+Form.Element.Observer = Class.create();
+Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.Observer = Class.create();
+Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+
+/*--------------------------------------------------------------------------*/
+
+Abstract.EventObserver = function() {}
+Abstract.EventObserver.prototype = {
+ initialize: function(element, callback) {
+ this.element = $(element);
+ this.callback = callback;
+
+ this.lastValue = this.getValue();
+ if (this.element.tagName.toLowerCase() == 'form')
+ this.registerFormCallbacks();
+ else
+ this.registerCallback(this.element);
+ },
+
+ onElementEvent: function() {
+ var value = this.getValue();
+ if (this.lastValue != value) {
+ this.callback(this.element, value);
+ this.lastValue = value;
+ }
+ },
+
+ registerFormCallbacks: function() {
+ var elements = Form.getElements(this.element);
+ for (var i = 0; i < elements.length; i++)
+ this.registerCallback(elements[i]);
+ },
+
+ registerCallback: function(element) {
+ if (element.type) {
+ switch (element.type.toLowerCase()) {
+ case 'checkbox':
+ case 'radio':
+ element.target = this;
+ element.prev_onclick = element.onclick || Prototype.emptyFunction;
+ element.onclick = function() {
+ this.prev_onclick();
+ this.target.onElementEvent();
+ }
+ break;
+ case 'password':
+ case 'text':
+ case 'textarea':
+ case 'select-one':
+ case 'select-multiple':
+ element.target = this;
+ element.prev_onchange = element.onchange || Prototype.emptyFunction;
+ element.onchange = function() {
+ this.prev_onchange();
+ this.target.onElementEvent();
+ }
+ break;
+ }
+ }
+ }
+}
+
+Form.Element.EventObserver = Class.create();
+Form.Element.EventObserver.prototype = (new Abstract.EventObserver()).extend({
+ getValue: function() {
+ return Form.Element.getValue(this.element);
+ }
+});
+
+Form.EventObserver = Class.create();
+Form.EventObserver.prototype = (new Abstract.EventObserver()).extend({
+ getValue: function() {
+ return Form.serialize(this.element);
+ }
+});
+
+
+if (!window.Event) {
+ var Event = new Object();
+}
+
+Object.extend(Event, {
+ KEY_BACKSPACE: 8,
+ KEY_TAB: 9,
+ KEY_RETURN: 13,
+ KEY_ESC: 27,
+ KEY_LEFT: 37,
+ KEY_UP: 38,
+ KEY_RIGHT: 39,
+ KEY_DOWN: 40,
+ KEY_DELETE: 46,
+
+ element: function(event) {
+ return event.target || event.srcElement;
+ },
+
+ isLeftClick: function(event) {
+ return (((event.which) && (event.which == 1)) ||
+ ((event.button) && (event.button == 1)));
+ },
+
+ pointerX: function(event) {
+ return event.pageX || (event.clientX +
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
+ },
+
+ pointerY: function(event) {
+ return event.pageY || (event.clientY +
+ (document.documentElement.scrollTop || document.body.scrollTop));
+ },
+
+ stop: function(event) {
+ if (event.preventDefault) {
+ event.preventDefault();
+ event.stopPropagation();
+ } else {
+ event.returnValue = false;
+ }
+ },
+
+ // find the first node with the given tagName, starting from the
+ // node the event was triggered on; traverses the DOM upwards
+ findElement: function(event, tagName) {
+ var element = Event.element(event);
+ while (element.parentNode && (!element.tagName ||
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
+ element = element.parentNode;
+ return element;
+ },
+
+ observers: false,
+
+ _observeAndCache: function(element, name, observer, useCapture) {
+ if (!this.observers) this.observers = [];
+ if (element.addEventListener) {
+ this.observers.push([element, name, observer, useCapture]);
+ element.addEventListener(name, observer, useCapture);
+ } else if (element.attachEvent) {
+ this.observers.push([element, name, observer, useCapture]);
+ element.attachEvent('on' + name, observer);
+ }
+ },
+
+ unloadCache: function() {
+ if (!Event.observers) return;
+ for (var i = 0; i < Event.observers.length; i++) {
+ Event.stopObserving.apply(this, Event.observers[i]);
+ Event.observers[i][0] = null;
+ }
+ Event.observers = false;
+ },
+
+ observe: function(element, name, observer, useCapture) {
+ var element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ ((navigator.appVersion.indexOf('AppleWebKit') > 0)
+ || element.attachEvent))
+ name = 'keydown';
+
+ this._observeAndCache(element, name, observer, useCapture);
+ },
+
+ stopObserving: function(element, name, observer, useCapture) {
+ var element = $(element);
+ useCapture = useCapture || false;
+
+ if (name == 'keypress' &&
+ ((navigator.appVersion.indexOf('AppleWebKit') > 0)
+ || element.detachEvent))
+ name = 'keydown';
+
+ if (element.removeEventListener) {
+ element.removeEventListener(name, observer, useCapture);
+ } else if (element.detachEvent) {
+ element.detachEvent('on' + name, observer);
+ }
+ }
+});
+
+/* prevent memory leaks in IE */
+Event.observe(window, 'unload', Event.unloadCache, false);
+
+var Position = {
+
+ // set to true if needed, warning: firefox performance problems
+ // NOT neeeded for page scrolling, only if draggable contained in
+ // scrollable elements
+ includeScrollOffsets: false,
+
+ // must be called before calling withinIncludingScrolloffset, every time the
+ // page is scrolled
+ prepare: function() {
+ this.deltaX = window.pageXOffset
+ || document.documentElement.scrollLeft
+ || document.body.scrollLeft
+ || 0;
+ this.deltaY = window.pageYOffset
+ || document.documentElement.scrollTop
+ || document.body.scrollTop
+ || 0;
+ },
+
+ realOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.scrollTop || 0;
+ valueL += element.scrollLeft || 0;
+ element = element.parentNode;
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ cumulativeOffset: function(element) {
+ var valueT = 0, valueL = 0;
+ do {
+ valueT += element.offsetTop || 0;
+ valueL += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+ return [valueL, valueT];
+ },
+
+ // caches x/y coordinate pair to use with overlap
+ within: function(element, x, y) {
+ if (this.includeScrollOffsets)
+ return this.withinIncludingScrolloffsets(element, x, y);
+ this.xcomp = x;
+ this.ycomp = y;
+ this.offset = this.cumulativeOffset(element);
+
+ return (y >= this.offset[1] &&
+ y < this.offset[1] + element.offsetHeight &&
+ x >= this.offset[0] &&
+ x < this.offset[0] + element.offsetWidth);
+ },
+
+ withinIncludingScrolloffsets: function(element, x, y) {
+ var offsetcache = this.realOffset(element);
+
+ this.xcomp = x + offsetcache[0] - this.deltaX;
+ this.ycomp = y + offsetcache[1] - this.deltaY;
+ this.offset = this.cumulativeOffset(element);
+
+ return (this.ycomp >= this.offset[1] &&
+ this.ycomp < this.offset[1] + element.offsetHeight &&
+ this.xcomp >= this.offset[0] &&
+ this.xcomp < this.offset[0] + element.offsetWidth);
+ },
+
+ // within must be called directly before
+ overlap: function(mode, element) {
+ if (!mode) return 0;
+ if (mode == 'vertical')
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
+ element.offsetHeight;
+ if (mode == 'horizontal')
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
+ element.offsetWidth;
+ },
+
+ clone: function(source, target) {
+ source = $(source);
+ target = $(target);
+ target.style.position = 'absolute';
+ var offsets = this.cumulativeOffset(source);
+ target.style.top = offsets[1] + 'px';
+ target.style.left = offsets[0] + 'px';
+ target.style.width = source.offsetWidth + 'px';
+ target.style.height = source.offsetHeight + 'px';
+ }
+}
Modified: plog/trunk/js/ui/plogui.js
===================================================================
--- plog/trunk/js/ui/plogui.js 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/js/ui/plogui.js 2006-01-10 10:38:38 UTC (rev 2763)
@@ -1,166 +1,100 @@
/**
- * when adding a new form, checks that there is at least one category selected
+ * this function is the one called when clicking the "save draft and continue" button
*/
-function submitNewPost(form)
+function saveDraftArticleAjax()
{
- if( form.postCategories.selectedIndex == -1 ) {
- // we have no category selected!
- window.alert(msgErrorNoCategorySelected);
+ // if there is no category selected, then we won't save a draft!
+ form = document.getElementById( "newPost" );
+
+ if( form.postTopic.value == '' ) {
+ window.alert( msgErrorPostTopic );
return false;
- }
+ }
+
+ // Can't use form.postText.value, becasue the form.postText.value still "null"
+ if( htmlAreaEnabled ) {
+ postText = tinyMCE.getContent('postText');
+ } else {
+ postText = form.postText.value;
+ }
- return true;
+ if (postText == '') {
+ window.alert( msgErrorPostText );
+ return false;
+ }
+
+ if( !submitNewPost( form ))
+ return false;
+
+ var formData = getPostEditFormElements( "newPost" );
+ var url = plogAdminBaseUrl;
+ var params = 'op=saveDraftArticleAjax&'+formData;
+ var myAjax = new Ajax.Request(
+ url,
+ {method: 'post', parameters: params, onComplete: saveDraftArticleResponse}
+ );
}
-// object that we're going to use
-var xmlhttp;
-xmlhttp = false;
-
/**
- * the following functions take care of sending requests to
- * save drafts of the current post using the XmlHttpRequest object
- *
- * @param req A valid XmlHttpRequest object
- * @param url The url to which we'd like to send the data
- * @param data The data we'd like to send
- * @return Returns always true, please see the processResponse method
+ * this function is the one called when clicking the "save draft and continue" button
*/
-function sendData(url, data)
+function saveDraftArticleResponse(originalRequest)
{
- xmlhttp.onreadystatechange = processResponse;
- xmlhttp.open("POST", url, true, null, null);
- xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
- xmlhttp.setRequestHeader("Content-Length", data.length);
- xmlhttp.send(data);
-
- return true;
+ //put returned XML in the textarea
+ var xmldoc = originalRequest.responseXML;
+ var message = xmldoc.getElementsByTagName('message')[0].firstChild.nodeValue;
+ window.alert(message);
}
/**
- * sets the 'xmlhttp' var as an XmlHttpRequest obejct or 'false' if it is not supported
- *
- * @return nothing
+ * when adding a new form, checks that there is at least one category selected
*/
-function initXmlHttpRequestObject()
+function submitNewPost(form)
{
- // --
- // the code below uses IE's conditional compilation via jscript... it should
- // not affect other browsers such as Safari or Mozilla
- // --
-
- /*@cc_on @*/
- /*@if (@_jscript_version >= 5)
- // JScript gives us Conditional compilation, we can cope with old IE versions.
- // and security blocked creation of the objects.
- try {
- xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
- } catch (e) {
- try {
- xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
- } catch (E) {
- xmlhttp = false;
- }
- }
- @end @*/
- if (!xmlhttp && typeof XMLHttpRequest!='undefined' && xmlHttpRequestSupportEnabled ) {
- xmlhttp = new XMLHttpRequest();
- }
-
+ if( form.postCategories.selectedIndex == -1 ) {
+ // we have no category selected!
+ window.alert(msgErrorNoCategorySelected);
+ return false;
+ }
+
return true;
}
/**
- * handler that processes asynchronous responses
+ * this function is the one called when clicking the "add category" button
*/
-function processResponse()
+function addArticleCategoryAjax()
{
- // only if req shows "loaded"
- if (xmlhttp.readyState == 4) {
- // only if "OK"
- if (xmlhttp.status == 200) {
- // response successful, let's process the return message
- processResponseMessage( xmlhttp.responseText );
- } else {
- window.status = msgErrorMakingRequest;
- alert("There was a problem retrieving the XML data:\n" + xmlhttp.statusText);
- }
- }
+ var categoryName = $F('newCategory');
+ var url = plogAdminBaseUrl;
+ var params = 'op=addArticleCategoryAjax' + '&categoryName=' + encodeURIComponent(categoryName);
+ var myAjax = new Ajax.Request(
+ url,
+ {method: 'get', parameters: params, onComplete: addArticleCategoryOption}
+ );
}
/**
- * processes a successful xml message
+ * this function is the one called when clicking the "add category" button
*/
-function processResponseMessage( message )
+function addArticleCategoryOption(originalRequest)
{
- // define the regexp... we should problaby be using the dom model for parsing this but I'm too lazy to
- // learn dom. Besides, in this case the format of the response is very easy :)
- var regexp = /^.*<\?xml version="1.0"\?>\n* *<response>\n* *<method>saveXmlDraft<\/method>\n* *<result>(.*)<\/result>\n* *<\/response>$/ig;
-
- // execute the regexp and get the results
- matches = regexp.exec( message );
-
- if( !matches ) {
- postId = "";
- //window.alert( "There was an error in the following response message:\n" + message );
- window.alert( msgErrorSavingDraft );
- window.status = msgErrorSavingDraft;
+ //put returned XML in the textarea
+ var xmldoc = originalRequest.responseXML;
+ var success = xmldoc.getElementsByTagName('success')[0].firstChild.nodeValue;
+ var message = xmldoc.getElementsByTagName('message')[0].firstChild.nodeValue;
+ if (!success) {
+ window.alert(message);
}
- else {
- postId = matches[1];
- if( postId > 0 ) {
- // set the value of the new post identifier
- document.newPost.postId.value = postId;
- // show a message
- window.alert( msgDraftSavedOk + " ( id = " + postId + ")" );
- // and update the status bar
- window.status = msgDraftSavedOk + " ( id = " + postId + ")";
- }
+ else
+ {
+ var catId = xmldoc.getElementsByTagName('id')[0].firstChild.nodeValue;
+ var catName = xmldoc.getElementsByTagName('name')[0].firstChild.nodeValue;
+ $( 'postCategories' ).options.add( new Option( catName, catId ), 0 );
+ for(i=0; i<$( 'postCategories' ).length; i++)
+ {
+ $( 'postCategories' ).options[i].selected = false;
+ }
+ $( 'postCategories' ).options[0].selected = true;
}
}
-
-/**
- * this function is the one called when clicking the "save draft and continue" button
- */
-function saveDraft()
-{
- // if there is no category selected, then we won't save a draft!
- form = document.getElementById( "newPost" );
-
- if( form.postTopic.value == '' ) {
- window.alert( msgErrorPostTopic );
- return false;
- }
-
- // Can't use form.postText.value, becasue the form.postText.value still "null"
- if( htmlAreaEnabled ) {
- postText = tinyMCE.getContent('postText');
- } else {
- postText = form.postText.value;
- }
-
- if (postText == '') {
- window.alert( msgErrorPostText );
- return false;
- }
-
- if( !submitNewPost( form ))
- return false;
-
- // check if xmlhttprequest is supported in our browser by initializing the object
- initXmlHttpRequestObject();
-
- if( !xmlhttp ) {
- // if there is no support for xmlhttprequest, then there's nothing to do!
- window.alert("XmlHttpRequest is not available in this browser!");
- return false;
- }
-
- // if not, then continue as usual...
- var formData = getPostEditFormElements( "newPost" );
-
- // build up the final url
- url = plogAdminBaseUrl;
- data = "op=saveXmlDraft&"+formData;
- //window.alert(url);
- sendData( url, data );
-}
\ No newline at end of file
Modified: plog/trunk/locale/locale_en_UK.php
===================================================================
--- plog/trunk/locale/locale_en_UK.php 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/locale/locale_en_UK.php 2006-01-10 10:38:38 UTC (rev 2763)
@@ -227,7 +227,7 @@
$messages['preview'] = 'Preview';
$messages['add_post'] = 'Blog this!';
$messages['error_saving_draft'] = 'There was an error saving the draft';
-$messages['draft_saved_ok'] = 'Draft saved successfully';
+$messages['draft_saved_ok'] = 'Draft article %s saved successfully';
$messages['error_sending_request'] = 'There was an error sending the request';
$messages['error_no_category_selected'] = 'Please select at least one category';
$messages['error_missing_post_topic'] = 'Please type a post topic';
Modified: plog/trunk/locale/locale_zh_TW.php
===================================================================
--- plog/trunk/locale/locale_zh_TW.php 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/locale/locale_zh_TW.php 2006-01-10 10:38:38 UTC (rev 2763)
@@ -227,7 +227,7 @@
$messages['preview'] = '預覽';
$messages['add_post'] = '發表!';
$messages['error_saving_draft'] = '儲存草稿發生錯誤!';
-$messages['draft_saved_ok'] = '草稿已順利儲存';
+$messages['draft_saved_ok'] = '草稿 「%s」 已順利儲存';
$messages['error_sending_request'] = '傳送要求時發生錯誤';
$messages['error_no_category_selected'] = '你沒有選擇任何分類';
$messages['error_missing_post_topic'] = '請輸入文章標題!';
Modified: plog/trunk/templates/admin/header.template
===================================================================
--- plog/trunk/templates/admin/header.template 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/templates/admin/header.template 2006-01-10 10:38:38 UTC (rev 2763)
@@ -27,7 +27,7 @@
}
</script>
{/literal}
-
+<script type="text/javascript" src="js/prototype/prototype.js"></script>
</head>
<body>
Modified: plog/trunk/templates/admin/newpost.template
===================================================================
--- plog/trunk/templates/admin/newpost.template 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/templates/admin/newpost.template 2006-01-10 10:38:38 UTC (rev 2763)
@@ -24,8 +24,6 @@
{/if}
// some messages that we are going to need in the functions above
- var msgErrorSavingDraft = "{$locale->tr("error_saving_draft")}";
- var msgDraftSavedOk = "{$locale->tr("draft_saved_ok")}";
var msgErrorMakingRequest = "{$locale->tr("error_sending_request")}";
var msgErrorNoCategorySelected = "{$locale->tr("error_no_category_selected")}";
var xmlHttpRequestSupportEnabled = '{$xmlHttpRequestSupportEnabled}';
@@ -134,6 +132,8 @@
<option value="{$category->getId()}" {if $smarty.foreach.categories.first} selected="selected" {/if}>{$category->getName()}</option>
{/foreach}
</select>
+ <input type="text" name="newCategory" id="newCategory" style="width:70%; margin-top:3px;" size="16" value="" />
+ <input type="button" name="addCategory" style="width:20%; margin-top:3px;" value="{$locale->tr("add")}" onclick="javascript:addArticleCategoryAjax()" />
{include file="$admintemplatepath/validate.template" field=postCategories message=$locale->tr("error_no_category_selected")}
</div>
@@ -185,7 +185,7 @@
</fieldset>
<div class="buttons">
{if $browser->has_feature("xmlhttpreq")}
- <input type="button" name="saveDraftAndContinue" value="{$locale->tr("save_draft_and_continue")}" onclick="javascript:saveDraft()" />
+ <input type="button" name="saveDraftAndContinue" value="{$locale->tr("save_draft_and_continue")}" onclick="javascript:saveDraftArticleAjax()" />
{/if}
<input type="button" name="previewPost" value="{$locale->tr("preview")}" onclick="javascript:previewNewPost()" />
<input type="submit" name="addPost" value="{$locale->tr("add_post")}"/>
Modified: plog/trunk/templates/admin/xml/response.template
===================================================================
--- plog/trunk/templates/admin/xml/response.template 2006-01-08 17:43:16 UTC (rev 2762)
+++ plog/trunk/templates/admin/xml/response.template 2006-01-10 10:38:38 UTC (rev 2763)
@@ -1,5 +1,7 @@
<?xml version="1.0"?>
<response>
<method>{$method}</method>
+ <success>{$success}</success>
+ <message><![CDATA[{$message}]]></message>
<result>{$result}</result>
</response>
\ No newline at end of file
More information about the pLog-svn
mailing list