| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | // The Antville Project
 | 
					
						
							|  |  |  |  | // http://code.google.com/p/antville
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2011-02-23 16:24:32 +00:00
										 |  |  |  | // Copyright 2007-2011 by Tobi Schäfer.
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							|  |  |  |  | // Copyright 2001–2007 Robert Gaggl, Hannes Wallnöfer, Tobi Schäfer,
 | 
					
						
							|  |  |  |  | // Matthias & Michael Platzer, Christoph Lincke.
 | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | //
 | 
					
						
							|  |  |  |  | // Licensed under the Apache License, Version 2.0 (the ``License'');
 | 
					
						
							|  |  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  | //   http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | //
 | 
					
						
							|  |  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  |  | // distributed under the License is distributed on an ``AS IS'' BASIS,
 | 
					
						
							|  |  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  |  | //
 | 
					
						
							|  |  |  |  | // $Revision$
 | 
					
						
							| 
									
										
										
										
											2011-03-15 20:22:08 +00:00
										 |  |  |  | // $Author$
 | 
					
						
							|  |  |  |  | // $Date$
 | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | // $URL$
 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2011-03-15 20:22:08 +00:00
										 |  |  |  |  * @fileOverview Defines the Story prototype. | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  */ | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  | markgettext('Story'); | 
					
						
							|  |  |  |  | markgettext('story'); | 
					
						
							| 
									
										
										
										
											2010-05-24 13:32:40 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  | this.handleMetadata('title'); | 
					
						
							|  |  |  |  | this.handleMetadata('text'); | 
					
						
							| 
									
										
										
										
											2011-03-15 20:22:08 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-04-06 19:35:18 +00:00
										 |  |  |  | Story.ALLOWED_MACROS = [ | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   'file', | 
					
						
							|  |  |  |  |   'image', | 
					
						
							|  |  |  |  |   'link', | 
					
						
							|  |  |  |  |   'poll', | 
					
						
							|  |  |  |  |   'story.link' | 
					
						
							| 
									
										
										
										
											2013-04-06 19:35:18 +00:00
										 |  |  |  | ]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2011-03-15 20:22:08 +00:00
										 |  |  |  | /** | 
					
						
							|  |  |  |  |  * @function | 
					
						
							| 
									
										
										
										
											2011-03-15 22:07:24 +00:00
										 |  |  |  |  * @param {Object} data | 
					
						
							|  |  |  |  |  * @param {Site} site | 
					
						
							|  |  |  |  |  * @param {User} user | 
					
						
							| 
									
										
										
										
											2011-03-15 20:22:08 +00:00
										 |  |  |  |  * @returns {Story} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-03-15 22:07:24 +00:00
										 |  |  |  | Story.add = function(data, site, user) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   HopObject.confirmConstructor(Story); | 
					
						
							|  |  |  |  |   site || (site = res.handlers.site); | 
					
						
							|  |  |  |  |   user || (user = session.user); | 
					
						
							|  |  |  |  |   var story = new Story; | 
					
						
							|  |  |  |  |   story.name = String.EMPTY; | 
					
						
							|  |  |  |  |   story.requests = 0; | 
					
						
							|  |  |  |  |   story.created = story.modified = new Date; | 
					
						
							|  |  |  |  |   story.site = site; | 
					
						
							|  |  |  |  |   story.creator = story.modifier = user; | 
					
						
							|  |  |  |  |   story.update(data); | 
					
						
							|  |  |  |  |   site.stories.add(story); | 
					
						
							|  |  |  |  |   return story; | 
					
						
							| 
									
										
										
										
											2011-03-15 20:22:08 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | /** | 
					
						
							|  |  |  |  |  * @function | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | Story.remove = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (this.constructor === Story) { | 
					
						
							|  |  |  |  |     HopObject.remove.call(this.comments); | 
					
						
							|  |  |  |  |     this.setTags(null); | 
					
						
							|  |  |  |  |     this.deleteMetadata(); | 
					
						
							|  |  |  |  |     this.remove(); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2011-03-15 20:22:08 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							|  |  |  |  |  * @function | 
					
						
							|  |  |  |  |  * @returns {String[]} | 
					
						
							|  |  |  |  |  * @see defineConstants | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  | Story.getStatus = defineConstants(Story, markgettext('closed'), | 
					
						
							|  |  |  |  |     markgettext('public'), markgettext('shared'), markgettext('open')); | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							|  |  |  |  |  * @function | 
					
						
							|  |  |  |  |  * @returns {String[]} | 
					
						
							|  |  |  |  |  * @see defineConstants | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  | Story.getModes = defineConstants(Story, markgettext('hidden'), | 
					
						
							|  |  |  |  |     markgettext('featured')); | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							|  |  |  |  |  * @function | 
					
						
							|  |  |  |  |  * @returns {String[]} | 
					
						
							|  |  |  |  |  * @see defineConstants | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  | Story.getCommentModes = defineConstants(Story, markgettext('closed'), | 
					
						
							|  |  |  |  |     /* markgettext('readonly'), markgettext('moderated'), */ | 
					
						
							|  |  |  |  |     markgettext('open')); | 
					
						
							| 
									
										
										
										
											2007-10-11 23:03:17 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							|  |  |  |  |  * @name Story | 
					
						
							|  |  |  |  |  * @constructor | 
					
						
							|  |  |  |  |  * @property {Comment[]} _children | 
					
						
							|  |  |  |  |  * @property {String} commentMode | 
					
						
							|  |  |  |  |  * @property {Comment[]} comments | 
					
						
							|  |  |  |  |  * @property {Date} created | 
					
						
							|  |  |  |  |  * @property {User} creator | 
					
						
							|  |  |  |  |  * @property {Metadata} metadata | 
					
						
							|  |  |  |  |  * @property {String} mode | 
					
						
							|  |  |  |  |  * @property {Date} modified | 
					
						
							|  |  |  |  |  * @property {User} modifier | 
					
						
							|  |  |  |  |  * @property {String} name | 
					
						
							|  |  |  |  |  * @property {Number} parent_id | 
					
						
							|  |  |  |  |  * @property {String} parent_type | 
					
						
							|  |  |  |  |  * @property {String} prototype | 
					
						
							|  |  |  |  |  * @property {Number} requests | 
					
						
							|  |  |  |  |  * @property {Site} site | 
					
						
							|  |  |  |  |  * @property {String} status | 
					
						
							|  |  |  |  |  * @property {TagHub[]} tags | 
					
						
							|  |  |  |  |  * @property {String} text | 
					
						
							|  |  |  |  |  * @property {String} title | 
					
						
							|  |  |  |  |  * @extends HopObject | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-27 17:39:02 +00:00
										 |  |  |  | Story.prototype.constructor = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   HopObject.confirmConstructor(this); | 
					
						
							|  |  |  |  |   return this; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-08-03 19:41:51 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {String} action | 
					
						
							|  |  |  |  |  * @returns {Boolean} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-27 17:39:02 +00:00
										 |  |  |  | Story.prototype.getPermission = function(action) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   if (!this.site.getPermission('main')) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return false; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   switch (action) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case '.': | 
					
						
							|  |  |  |  |     case 'main': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.status !== Story.CLOSED || | 
					
						
							|  |  |  |  |         this.creator === session.user || | 
					
						
							|  |  |  |  |         Membership.require(Membership.MANAGER) || | 
					
						
							|  |  |  |  |         User.require(User.PRIVILEGED); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'comment': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.site.commentMode === Site.ENABLED && | 
					
						
							|  |  |  |  |         (this.commentMode === Story.OPEN || | 
					
						
							|  |  |  |  |         this.commentMode === Story.MODERATED); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'delete': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.creator === session.user || | 
					
						
							|  |  |  |  |         Membership.require(Membership.MANAGER) || | 
					
						
							|  |  |  |  |         User.require(User.PRIVILEGED); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'edit': | 
					
						
							|  |  |  |  |     case 'rotate': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.creator === session.user || | 
					
						
							|  |  |  |  |         Membership.require(Membership.MANAGER) || | 
					
						
							|  |  |  |  |         (this.status === Story.SHARED && | 
					
						
							|  |  |  |  |         Membership.require(Membership.CONTRIBUTOR)) || | 
					
						
							|  |  |  |  |         (this.status === Story.OPEN && | 
					
						
							|  |  |  |  |         Membership.require(Membership.SUBSCRIBER)) || | 
					
						
							|  |  |  |  |         User.require(User.PRIVILEGED); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return false; | 
					
						
							| 
									
										
										
										
											2008-03-17 19:41:10 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | Story.prototype.main_action = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   res.data.title = this.getTitle(10); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   res.data.body = this.renderSkinAsString('Story#main'); | 
					
						
							|  |  |  |  |   this.site.renderSkin('Site#page'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   this.site.log(); | 
					
						
							|  |  |  |  |   this.count(); | 
					
						
							|  |  |  |  |   this.log(); | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Number} limit | 
					
						
							|  |  |  |  |  * @returns {String} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  | Story.prototype.getTitle = function(limit) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   var key = this + ':title:' + limit; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (!res.meta[key]) { | 
					
						
							|  |  |  |  |     if (this.title) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       res.meta[key] = stripTags(this.title).clip(limit, '...', '\\s'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } else if (this.text) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       var parts = stripTags(this.text).embody(limit, '...', '\\s'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       res.meta[key] = parts.head; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       res.meta[this + ':text:' + limit] = parts.tail; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   return String(res.meta[key]) || '...'; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-27 17:39:02 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | Story.prototype.edit_action = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (req.postParams.save) { | 
					
						
							|  |  |  |  |     try { | 
					
						
							|  |  |  |  |       this.update(req.postParams); | 
					
						
							|  |  |  |  |       delete session.data.backup; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       res.message = gettext('The story was successfully updated.'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       res.redirect(this.href()); | 
					
						
							|  |  |  |  |     } catch (ex) { | 
					
						
							|  |  |  |  |       res.message = ex; | 
					
						
							|  |  |  |  |       app.log(ex); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   res.data.action = this.href(req.action); | 
					
						
							|  |  |  |  |   res.data.title = gettext('Edit Story'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   res.data.body = this.renderSkinAsString('Story#edit'); | 
					
						
							|  |  |  |  |   this.site.renderSkin('Site#page'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} data | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-27 17:39:02 +00:00
										 |  |  |  | Story.prototype.update = function(data) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   var site = this.site || res.handlers.site; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (!data.title && !data.text) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     throw Error(gettext('Please enter at least something into the “title” or “text” field.')); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   } | 
					
						
							|  |  |  |  |   if (data.created) { | 
					
						
							|  |  |  |  |     try { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       this.created = data.created.toDate('yyyy-MM-dd HH:mm', site.getTimeZone()); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } catch (ex) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       throw Error(gettext('Cannot parse timestamp {0} as a date.', data.created)); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       app.log(ex); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   // Get difference to current content before applying changes
 | 
					
						
							|  |  |  |  |   var delta = this.getDelta(data); | 
					
						
							|  |  |  |  |   this.title = data.title ? data.title.trim() : String.EMPTY; | 
					
						
							|  |  |  |  |   this.text = data.text ? data.text.trim() : String.EMPTY; | 
					
						
							|  |  |  |  |   this.status = data.status || Story.PUBLIC; | 
					
						
							|  |  |  |  |   this.mode = data.mode || Story.FEATURED; | 
					
						
							|  |  |  |  |   this.commentMode = data.commentMode || Story.OPEN; | 
					
						
							|  |  |  |  |   this.setCustomContent(data); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   // FIXME: To be removed resp. moved to Stories.create_action and
 | 
					
						
							|  |  |  |  |   // Story.edit_action if work-around for Helma bug #607 fails
 | 
					
						
							|  |  |  |  |   // We need persistence for setting the tags
 | 
					
						
							|  |  |  |  |   this.isTransient() && this.persist(); | 
					
						
							|  |  |  |  |   this.setTags(data.tags || data.tag_array); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   if (delta > 50) { | 
					
						
							|  |  |  |  |     this.modified = new Date; | 
					
						
							|  |  |  |  |     if (this.status !== Story.CLOSED) { | 
					
						
							|  |  |  |  |       site.modified = this.modified; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     site.callback(this); | 
					
						
							|  |  |  |  |     // Notification is sent in Stories.create_action()
 | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   this.clearCache(); | 
					
						
							|  |  |  |  |   this.modifier = session.user; | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-09-29 00:58:04 +00:00
										 |  |  |  | Story.prototype.rotate_action = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (this.status === Story.CLOSED) { | 
					
						
							|  |  |  |  |     this.status = this.cache.status || Story.PUBLIC; | 
					
						
							|  |  |  |  |   } else if (this.mode === Story.FEATURED) { | 
					
						
							|  |  |  |  |     this.mode = Story.HIDDEN; | 
					
						
							|  |  |  |  |   } else { | 
					
						
							|  |  |  |  |     this.cache.status = this.status; | 
					
						
							|  |  |  |  |     this.mode = Story.FEATURED; | 
					
						
							|  |  |  |  |     this.status = Story.CLOSED; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return res.redirect(req.data.http_referer || this._parent.href()); | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-29 00:58:04 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | Story.prototype.comment_action = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   // Check if user is logged in since we allow linking here for any user
 | 
					
						
							|  |  |  |  |   if (!User.require(User.REGULAR)) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     User.setLocation(this.href(req.action) + '#form'); | 
					
						
							|  |  |  |  |     res.message = gettext('Please login first.'); | 
					
						
							|  |  |  |  |     res.redirect(this.site.members.href('login')); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   } | 
					
						
							|  |  |  |  |   if (req.postParams.save) { | 
					
						
							|  |  |  |  |     try { | 
					
						
							|  |  |  |  |       var comment = Comment.add(req.postParams, this); | 
					
						
							|  |  |  |  |       comment.notify(req.action); | 
					
						
							|  |  |  |  |       delete session.data.backup; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       res.message = gettext('The comment was successfully created.'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       res.redirect(comment.href()); | 
					
						
							|  |  |  |  |     } catch (ex) { | 
					
						
							|  |  |  |  |       res.message = ex; | 
					
						
							|  |  |  |  |       app.log(ex); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   res.handlers.parent = this; | 
					
						
							|  |  |  |  |   res.data.action = this.href(req.action); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   res.data.title = gettext('Add Comment'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   HopObject.confirmConstructor(Comment); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   res.data.body = (new Comment).renderSkinAsString('Comment#edit'); | 
					
						
							|  |  |  |  |   this.site.renderSkin('Site#page'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-26 22:22:37 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {String} name | 
					
						
							|  |  |  |  |  * @returns {Object} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | Story.prototype.getFormValue = function(name) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (req.isPost()) { | 
					
						
							|  |  |  |  |     return req.postParams[name]; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   switch (name) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'commentMode': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.commentMode || Story.OPEN; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'mode': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.mode || Story.FEATURED; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'status': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.status || Story.PUBLIC; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'tags': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.getTags().join(Tag.DELIMITER); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return this[name] || this.getMetadata(name); | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {String} name | 
					
						
							|  |  |  |  |  * @returns {String[]} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | Story.prototype.getFormOptions = function(name) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   switch (name) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'commentMode': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return Story.getCommentModes(); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'mode': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return Story.getModes(); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'status': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return Story.getStatus(); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'tags': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     // FIXME: This could become a huge select element...
 | 
					
						
							|  |  |  |  |     return []; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2011-02-10 23:35:00 +00:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} data | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-05-15 14:42:54 +00:00
										 |  |  |  | Story.prototype.setCustomContent = function(data) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   var metadata = {}; | 
					
						
							|  |  |  |  |   for (var key in data) { | 
					
						
							|  |  |  |  |     if (this.isCustomContent(key)) { | 
					
						
							|  |  |  |  |       metadata[key] = data[key]; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return HopObject.prototype.setMetadata.call(this, metadata); | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {String} name | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-05-15 14:42:54 +00:00
										 |  |  |  | Story.prototype.isCustomContent = function(key) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   return this[key] === undefined && key !== 'save'; | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							|  |  |  |  |  * Increment the request counter | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | Story.prototype.count = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (session.user === this.creator) { | 
					
						
							|  |  |  |  |     return; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   var story; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   var key = 'Story#' + this._id; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (story = app.data.requests[key]) { | 
					
						
							|  |  |  |  |     story.requests += 1; | 
					
						
							|  |  |  |  |   } else { | 
					
						
							|  |  |  |  |     app.data.requests[key] = { | 
					
						
							|  |  |  |  |       type: this.constructor, | 
					
						
							|  |  |  |  |       id: this._id, | 
					
						
							|  |  |  |  |       requests: this.requests + 1 | 
					
						
							|  |  |  |  |     }; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							|  |  |  |  |  * Calculate the difference of a story’s current and its updated content | 
					
						
							|  |  |  |  |  * @param {Object} data | 
					
						
							|  |  |  |  |  * @returns {Number} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | Story.prototype.getDelta = function(data) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (this.isTransient()) { | 
					
						
							|  |  |  |  |     return Infinity; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   var deltify = function(s1, s2) { | 
					
						
							|  |  |  |  |     var len1 = s1 ? String(s1).length : 0; | 
					
						
							|  |  |  |  |     var len2 = s2 ? String(s2).length : 0; | 
					
						
							|  |  |  |  |     return Math.abs(len1 - len2); | 
					
						
							|  |  |  |  |   }; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   var delta = 0; | 
					
						
							|  |  |  |  |   delta += deltify(data.title, this.title); | 
					
						
							|  |  |  |  |   delta += deltify(data.text, this.text); | 
					
						
							|  |  |  |  |   for (var key in data) { | 
					
						
							|  |  |  |  |     if (this.isCustomContent(key)) { | 
					
						
							|  |  |  |  |       delta += deltify(data[key], this.getMetadata(key)) | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   // In-between updates (1 hour) get zero delta
 | 
					
						
							|  |  |  |  |   var timex = (new Date - this.modified) > Date.ONEHOUR ? 1 : 0; | 
					
						
							|  |  |  |  |   return delta * timex; | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {String} name | 
					
						
							|  |  |  |  |  * @returns {HopObject} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | Story.prototype.getMacroHandler = function(name) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   if (name === 'metadata') { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     return this.getMetadata(); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return null; | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} param | 
					
						
							|  |  |  |  |  * @param {String} action | 
					
						
							|  |  |  |  |  * @param {String} text | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | Story.prototype.link_macro = function(param, action, text) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   switch (action) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     case 'rotate': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     if (this.status === Story.CLOSED) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       text = gettext('Publish'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } else if (this.mode === Story.FEATURED) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       text = gettext('Hide'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       text = gettext('Close'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return HopObject.prototype.link_macro.call(this, param, action, text); | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} param | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  | Story.prototype.summary_macro = function(param) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   param.limit || (param.limit = 15); | 
					
						
							|  |  |  |  |   var keys, summary; | 
					
						
							|  |  |  |  |   if (arguments.length > 1) { | 
					
						
							|  |  |  |  |     res.push(); | 
					
						
							|  |  |  |  |     var content; | 
					
						
							|  |  |  |  |     for (var i=1; i<arguments.length; i+=1) { | 
					
						
							|  |  |  |  |       if (content = this.getMetadata(arguments[i])) { | 
					
						
							|  |  |  |  |         res.write(content); | 
					
						
							|  |  |  |  |         res.write(String.SPACE); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     summary = res.pop(); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   if (!summary) { | 
					
						
							|  |  |  |  |     summary = (this.title || String.EMPTY) + String.SPACE + | 
					
						
							|  |  |  |  |         (this.text || String.EMPTY); | 
					
						
							|  |  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   var clipped = stripTags(summary).clip(param.limit, param.clipping, '\\s'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   var head = clipped.split(/(\s)/, param.limit * 0.6).join(String.EMPTY); | 
					
						
							|  |  |  |  |   var tail = clipped.substring(head.length).trim(); | 
					
						
							|  |  |  |  |   head = head.trim(); | 
					
						
							|  |  |  |  |   if (!head && !tail) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     head = '...'; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   } | 
					
						
							|  |  |  |  |   html.link({href: this.href()}, head); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   res.writeln('\n'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   res.write(tail); | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} param | 
					
						
							|  |  |  |  |  * @param {String} mode | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-29 00:58:04 +00:00
										 |  |  |  | Story.prototype.comments_macro = function(param, mode) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   var story = this.story || this; | 
					
						
							|  |  |  |  |   if (story.site.commentMode === Site.DISABLED || | 
					
						
							|  |  |  |  |       story.commentMode === Site.CLOSED) { | 
					
						
							|  |  |  |  |     return; | 
					
						
							|  |  |  |  |   } else if (mode) { | 
					
						
							|  |  |  |  |     var n = this.comments.size() || 0; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     var text = ngettext('{0} comment', '{0} comments', n); | 
					
						
							|  |  |  |  |     if (mode === 'count' || mode === 'size') { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       res.write(text); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     } else if (mode === 'link') { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       n < 1 ? res.write(text) : | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |           html.link({href: this.href() + '#comments'}, text); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |   } else { | 
					
						
							|  |  |  |  |     this.prefetchChildren(); | 
					
						
							|  |  |  |  |     this.forEach(function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       html.openTag('a', {name: this._id}); | 
					
						
							|  |  |  |  |       html.closeTag('a'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       this.renderSkin(this.parent.constructor === Story ? | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |           'Comment#main' : 'Comment#reply'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     }); | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} param | 
					
						
							|  |  |  |  |  * @param {String} mode | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | Story.prototype.tags_macro = function(param, mode) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   if (mode === 'link') { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     var tags = []; | 
					
						
							|  |  |  |  |     this.tags.list().forEach(function(item) { | 
					
						
							|  |  |  |  |       res.push(); | 
					
						
							|  |  |  |  |       if (item.tag) { | 
					
						
							|  |  |  |  |         renderLink(param, item.tag.href(), item.tag.name); | 
					
						
							|  |  |  |  |         tags.push(res.pop()); | 
					
						
							|  |  |  |  |       } | 
					
						
							|  |  |  |  |     }); | 
					
						
							|  |  |  |  |     return res.write(tags.join(Tag.DELIMITER)); | 
					
						
							|  |  |  |  |   } | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   return res.write(this.getFormValue('tags')); | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-06-23 14:53:39 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} param | 
					
						
							|  |  |  |  |  * @param {Number} limit | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2008-05-15 12:58:26 +00:00
										 |  |  |  | Story.prototype.referrers_macro = function(param, limit) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (!User.require(User.PRIVILEGED) && | 
					
						
							|  |  |  |  |       !Membership.require(Membership.OWNER)) { | 
					
						
							|  |  |  |  |     return; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   limit = Math.min(limit || param.limit || 100, 100); | 
					
						
							|  |  |  |  |   if (limit < 1) { | 
					
						
							|  |  |  |  |     return; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   var self = this; | 
					
						
							|  |  |  |  |   var sql = new Sql; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   sql.retrieve(Sql.REFERRERS, 'Story', this._id); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  |   res.push(); | 
					
						
							|  |  |  |  |   var n = 0; | 
					
						
							|  |  |  |  |   sql.traverse(function() { | 
					
						
							|  |  |  |  |     if (n < limit && this.requests && this.referrer) { | 
					
						
							|  |  |  |  |       this.text = encode(this.referrer.head(50)); | 
					
						
							|  |  |  |  |       this.referrer = encode(this.referrer); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       self.renderSkin('$Story#referrer', this); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     n += 1; | 
					
						
							|  |  |  |  |   }); | 
					
						
							|  |  |  |  |   param.referrers = res.pop(); | 
					
						
							|  |  |  |  |   if (param.referrers) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     this.renderSkin('$Story#referrers', param); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   } | 
					
						
							|  |  |  |  |   return; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2008-03-17 19:41:10 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {Object} value | 
					
						
							|  |  |  |  |  * @param {Object} param | 
					
						
							|  |  |  |  |  * @param {String} mode | 
					
						
							|  |  |  |  |  * @returns {String} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  | Story.prototype.format_filter = function(value, param, mode) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   if (value) { | 
					
						
							|  |  |  |  |     switch (mode) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       case 'plain': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       return this.url_filter(stripTags(value), param, mode); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       case 'quotes': | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       return stripTags(value).replace(/(?:\x22|\x27)/g, function(quote) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |         return '&#' + quote.charCodeAt(0) + ';'; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       }); | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       case 'image': | 
					
						
							|  |  |  |  |       var image = HopObject.getFromPath(value, 'images'); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       if (image) { | 
					
						
							|  |  |  |  |         res.push(); | 
					
						
							|  |  |  |  |         image.render_macro(param); | 
					
						
							|  |  |  |  |         return res.pop(); | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       break; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       default: | 
					
						
							|  |  |  |  |       value = this.macro_filter(format(value), param); | 
					
						
							|  |  |  |  |       return this.url_filter(value, param); | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return String.EMTPY; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2013-04-06 19:35:18 +00:00
										 |  |  |  |  * Enables certain macros for being used in a story or comment – thus, any content object. | 
					
						
							|  |  |  |  |  * @param {String|Skin} value A skin object or a string that is going to be turned into a skin object. | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @returns {String} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2013-04-06 19:35:18 +00:00
										 |  |  |  | Story.prototype.macro_filter = function(value) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   var skin = value.constructor === String ? createSkin(value) : value; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   Story.ALLOWED_MACROS.forEach(function(value, index) { | 
					
						
							|  |  |  |  |     skin.allowMacro(value); | 
					
						
							|  |  |  |  |   }); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   var site; | 
					
						
							|  |  |  |  |   if (this.site !== res.handlers.site) { | 
					
						
							|  |  |  |  |     site = res.handlers.site; | 
					
						
							|  |  |  |  |     res.handlers.site = this.site; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   value = this.renderSkinAsString(skin); | 
					
						
							|  |  |  |  |   site && (res.handlers.site = site); | 
					
						
							|  |  |  |  |   return value; | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  | /** | 
					
						
							| 
									
										
										
										
											2014-07-04 15:10:47 +02:00
										 |  |  |  |  * | 
					
						
							| 
									
										
										
										
											2009-11-02 16:16:41 +00:00
										 |  |  |  |  * @param {String} value | 
					
						
							|  |  |  |  |  * @param {Object} param | 
					
						
							|  |  |  |  |  * @param {String} mode | 
					
						
							|  |  |  |  |  * @returns {String} | 
					
						
							|  |  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  | Story.prototype.url_filter = function(value, param, mode) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |   param.limit || (param.limit = 50); | 
					
						
							|  |  |  |  |   // FIXME: The first RegExp has troubles with <a href=http://... (no quotes)
 | 
					
						
							|  |  |  |  |   //var re = /(^|\/>|\s+)([\w+-_]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim;
 | 
					
						
							|  |  |  |  |   var re = /(^|\/>|\s+)([!fhtpsr]+:\/\/[^\s]+?)([\.,;:\)\]\"]?)(?=[\s<]|$)/gim | 
					
						
							|  |  |  |  |   return value.replace(re, function(str, head, url, tail) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     if (url.startsWith('!')) { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       return head + url.substring(1) + tail; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |     res.push(); | 
					
						
							|  |  |  |  |     res.write(head); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |     if (mode === 'plain') { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       res.write(url.clip(param.limit)); | 
					
						
							|  |  |  |  |     } else { | 
					
						
							|  |  |  |  |       var text, location = /:\/\/([^\/]*)/.exec(url)[1]; | 
					
						
							|  |  |  |  |       text = location; | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       if (mode === 'extended') { | 
					
						
							|  |  |  |  |         text = url.replace(/^.+\/([^\/]*)$/, '$1'); | 
					
						
							| 
									
										
										
										
											2008-05-13 14:48:54 +00:00
										 |  |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       html.link({href: url, title: url}, text.clip(param.limit)); | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |       if (mode === 'extended' && text !== location) { | 
					
						
							|  |  |  |  |         res.write(' <small>(' + location + ')</small>'); | 
					
						
							| 
									
										
										
										
											2007-09-30 23:59:13 +00:00
										 |  |  |  |       } | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |     } | 
					
						
							|  |  |  |  |     res.write(tail); | 
					
						
							|  |  |  |  |     return res.pop(); | 
					
						
							|  |  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2008-04-21 13:57:01 +00:00
										 |  |  |  | } | 
					
						
							| 
									
										
										
										
											2010-02-06 15:13:39 +00:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | /** | 
					
						
							|  |  |  |  |  * @returns {String} | 
					
						
							|  |  |  |  |  */ | 
					
						
							|  |  |  |  | Story.prototype.getConfirmText = function() { | 
					
						
							| 
									
										
										
										
											2014-07-04 15:44:41 +02:00
										 |  |  |  |   return gettext('You are about to delete a story by user {0}.', | 
					
						
							| 
									
										
										
										
											2014-07-04 15:32:18 +02:00
										 |  |  |  |       this.creator.name); | 
					
						
							| 
									
										
										
										
											2010-02-06 15:13:39 +00:00
										 |  |  |  | } |