PageSourceSearch

https://maestrocares.org/res/blogs/js/blogs.js

js maestrocares.org collected 2026-10-01 14:42:14 UTC 76,643 bytes, 3,048 lines download raw bytes

1
2var mwPostEd = {
3	
4	/* ---- jQuery shortcuts ---- */	
5	
6	windowId		: 'wPostEd',			// Editor window ID
7	window			: false,			// Editor window object
8	
9	postEdit		: false,			// Specal flag for Access Ping process
10	
11	dom			: {},				// Stores interesting window elements
12	
13	Defaults		: {
14		
15		is_news	: 0,
16		
17	},
18	
19	/* ---- Init ---------------------------------------------------------------------------------------------------------------- */
20	
21	initDom		: function () {
22		
23		var $this = this;
24		
25		// Creating shortcuts to window and it's body
26		$this.window		= mwWindow($this.windowId);
27		$this.dom.body		= $this.window.Body;
28		
29		// Defining complete element prefix
30		var $pfx		= $this.windowId+'_';
31		
32		// Looking for special elements in entire window 
33		$this.window.Window.find('[id^='+$pfx+']').each( function () {
34			
35			var $el		= jQuery(this);
36			
37			// Cutting element name from ID
38			var $name	= this.id.substr($pfx.length); 
39
40			// Adding class marker to these items
41			$el.addClass($name);
42
43			// Storing it as part of DOM set
44			$this.dom[$name] = $el;
45			
46		}); //FUNC each.id
47		
48		// Reordering element for fast debug
49		// For this - recreating object in order
50		var $keys	= Object.keys($this.dom).sort();
51		var $tmp	= {};
52		
53		for ( var $i in $keys )
54			$tmp[ $keys[$i] ] = $this.dom[$keys[$i]];
55		
56		// Resaving back in dom
57		$this.dom = $tmp;
58
59		//___(this.dom);
60		
61	}, //FUNC initDom
62	
63	initDimensions		: function () {
64		
65		var $this = this;
66		
67		// Maximum content width. Browser width and some white space on sides
68		var $maxWidth		= jQuery(window).width() - 80;
69		
70		// Setting body width
71		$this.dom.body.width($maxWidth);
72		
73	}, //FUNC initDimensions
74	
75	init		: function () {
76
77		var $this = this;
78		
79		//init counters once
80		if ( !$this.meta_title_counter ) {
81			
82			$this.meta_title_counter = mwTextLengthCounter('#w_wPostEd [name=meta_title]', '#w_wPostEd .meta-title-counter');
83			$this.meta_title_counter.min = 10;
84			$this.meta_title_counter.max = 60;
85			$this.meta_description_counter = mwTextLengthCounter('#w_wPostEd [name=meta_description]', '#w_wPostEd .meta-description-counter');
86			$this.meta_description_counter.min = 100;
87			$this.meta_description_counter.max = 160;
88			
89		}//init counters
90		
91		if ( $this.window ) return;
92		
93		$this.initDom();
94		//$this.initDimensions();
95		$this.hidePanel();
96		
97		$this.Form = jQuery('#mwPostEd_form');
98		$this.TabsControl = jQuery('#mwPostEd_toolsRight');
99		$this.PostContent = jQuery('.mwPostEd_PostContent');
100		$this.Tabs = jQuery('.mwPostEd_Tabs');
101		$this.hideTabsButton = this.TabsControl.find('td[rel=hideTabs]');
102		$this.TagTitleInput = jQuery('#tagsFilterPostEd');
103		
104		if ( mwData.show_post_id ) {
105			
106			setTimeout(function(){ mwPostEd.edit(mwData.show_post_id); }, 500);
107			
108		}
109		
110		$this.Form.find('.datepicker_icon').click( function(event) {
111			//___(this);
112			//mwPostEd.Form.find('.name-published_date input').click();
113			jQuery(this).closest('dd').find('input[type=text]').click();
114			
115		 } );
116		
117		jQuery('select[name=header_select]').change(function(e){
118			
119			var el = jQuery(this);
120			if ( el.val() == 'none' ) {
121				
122				jQuery('.header-row').hide();
123				
124			} else if ( el.val() == 'single' ) {
125				
126				jQuery('.header-row').hide();
127				jQuery('.header-row.single').show();
128				
129			} else if ( el.val() == 'gallery' ) {
130				
131				jQuery('.header-row').hide();
132				jQuery('.header-row.gallery').show();
133				
134			}
135			
136		})
137		
138		
139		
140		return false;
141		
142		
143	}, //FUNC init
144	
145	initAccessPing	: function() {
146		___('initAccessPing');
147		var $this = this;
148		
149		//check is access icon enabled
150		if ( mwData.accessIcon && $this.ID ) {
151			
152			var doPing = function() {
153				
154				mwAjax('/site/ajax/blogs/accessPing/' + $this.ID, null, false )
155					.go()
156					.success( function($data) {
157						//___($data);
158						if ( typeof($data.content) != 'undefined' ) {
159							
160							
161							//check is there are some other users in same post
162							if ( $data.content.accessUsers ) {
163								
164								___('we have some users', $data.content.accessUsers);
165								$this.accessInfo = $data.content.accessUsers;
166								
167								$this.showAccessInfo(false);
168								
169								jQuery('#accessIcon').css('background-image', "url('/res/blogs/images/block-user-red.svg')");
170								
171							}//there are other users in same post
172							else {
173								___('no access users');
174								$this.accessInfo = [];
175								
176								//clean up messages
177								mwState(false, 'wPostEd');
178								
179								jQuery('#accessIcon').css('background-image', "url('/res/blogs/images/block-user-grey.svg')");
180								
181							}//no users
182							
183							___($data.content);
184							
185						} else {
186							
187							___('no data');
188							return false;
189							
190						}
191					} );
192				
193			}//FUNC doPing
194			
195			//access icon config value should store period in seconds
196			var timer = mwData.accessIcon;
197			
198			//do 1st ping without delay
199			doPing();
200			
201			//loop function
202			(function myLoop() {
203				
204				//prevent double run
205				if ( $this.loopTimer ) clearTimeout($this.loopTimer);
206				
207				$this.loopTimer = setTimeout( function() {
208					
209					//make ping call
210					doPing();
211					
212					//continue
213					if ( $this.postEdit ) myLoop();
214					
215				}, timer * 1000)
216				
217			})(); 
218			
219		}//access icon enabled
220		
221	}, //FUNC initAccessPing
222	
223	showAccessInfo	: function(asPopup = false) {
224		
225		var $this = this;
226		
227		if ( $this.accessInfo.length ) {
228			
229			var spl = '';
230			var t = '';
231			for ( i in $this.accessInfo ) {
232				
233				t += spl + '<b>' + $this.accessInfo[i].email + '</b>';
234				spl = ', ';
235				
236			}
237			
238			if ( !asPopup ) {
239				
240				//mwState( mwError('User(s) editing this post: ' + t), 'wPostEd')
241				
242			}
243			else
244				mwConfirmation( function() { mwWindow('systemConfirmation').hide(); }
245				, 'User(s) viewing this post: ' + t);
246			
247		}
248		
249		
250	}, //FUNC showAccessInfo
251	
252	showUsersInPost	: function(post_id = 0) {
253		
254		var $this = this;
255		
256		if ( !post_id ) return;
257		
258		mwAjax('/site/ajax/blogs/accessPing/' + post_id, null, false )
259			.go()
260			.success( function($data) {
261				//___($data);
262				if ( typeof($data.content) != 'undefined' ) {
263					
264					
265					//check is there are some other users in same post
266					if ( $data.content.accessUsers ) {
267						
268						___('we have some users', $data.content.accessUsers);
269						$this.accessInfo = $data.content.accessUsers;
270						
271						$this.showAccessInfo(true);
272						
273						
274						
275					}//there are other users in same post
276					else {
277						___('no access users');
278						$this.accessInfo = [{'email' : 'None! Update active User by <a href="">refreshing</a> the page.'}];
279						
280						$this.showAccessInfo(true);
281						
282					}//no users
283					
284					___($data.content);
285					
286				} else {
287					
288					___('no data');
289					return false;
290					
291				}
292			} );
293		
294	}, //FUNC showUsersInPost
295	
296	edit		: function (id, open_drafts = 0) {
297		
298		var $this = this;
299		
300		//clean up messages
301		mwState(false, 'wPostEd');
302		
303		//clean up icon
304		jQuery('#accessIcon').css('background-image', "url('/res/blogs/images/block-user.png')");
305		
306		$this.postEdit = true;
307		
308		$this.init();
309		
310		//init access ping script
311		$this.initAccessPing();
312		
313		$this.hidePanel();
314		
315		$this.window.maximized = true;
316		//___($this.window);
317		$this.window.show();
318		
319		//?
320		mwPostEd.Form.get(0).reset();
321		
322		// clear temporary selected tags
323		mwPostEd.checked_tags = [];
324		
325		$this.tiny4_body = jQuery('.mwPostEd_PostContent iframe').off('keyup');
326		$this.post_title = mwPostEd.Form.find('input[name=title]').off('keyup');
327		
328		$this.post_title.off('change').change( function(e) {
329			
330			if ( mwPostEd.Form.find('input[name=alias_custom]').val() != '1' )
331				mwPostEd.Form.find('input[name=alias]').val( $this.post_title.val() )
332			 
333		} );
334		
335		$this.alias_input = mwPostEd.Form.find('input[name=alias]').off('keyup').keyup( function(e) {
336			
337			$this.post_title.off('change');
338			mwPostEd.Form.find('input[name=alias_custom]').val('1');
339			$this.checkAliasValid(this);
340			
341		} );
342		
343		$this.unpublish_start = false;
344		
345		jQuery('.publish-on-soc-button').show();
346		jQuery('.publish-on-soc-success').hide();
347		//jQuery('#mwPostEd_form .mce-tinymce').height(517);
348		//jQuery('#mwPostEd_form #tinyPostEditor_ifr').height(453);
349		jQuery('.socials-custom-wrapper').hide();
350		
351		delete mwData.temp_thumb_name; // remove temporary pictures names
352		delete mwData.temp_banner_name;
353		
354		var slider_internal_option = jQuery('#mwPostEd_form select[name=slider_gallery] option#internal');
355		
356		//clear error hightlight for tabs controls
357		mwPostEd.Form.find('.mwWinTabs .error').removeClass('error');
358		
359		//for kind select category for new and existing posts - hide categories section and rename tab to TAGS
360		/*
361		if ( mwData.kind_category_id ) {
362			
363			//$this.Tabs.find('#wPostEdCategories').hide();
364			$this.TabsControl.find('td[rel=postCategoriesTags]').html('Tags');
365			//make tags block full width
366			//$this.Tabs.find('#wPostEdTags').removeClass('cell-even');
367			
368		} else {
369			
370			//$this.Tabs.find('#wPostEdCategories').show();
371			$this.TabsControl.find('td[rel=postCategoriesTags]').html('Categories');
372			//make tags block half width
373			//$this.Tabs.find('#wPostEdTags').addClass('cell-even');
374			
375		}
376		*/
377		
378		if ( !id ) {
379			
380			slider_internal_option.hide().val('none');
381			
382			mwPostEd.Form.fromArray(this.Defaults);
383			mwWindow('wPostEd').Title('Add New Post').show(
384				
385				function() { mwPostEd.resetTabs(); }
386				
387			);
388			this.ID = 0;
389			mwPostEd.refreshCategoriesSelect();
390			mwPostEd.refreshTagsSelect();
391			mwPostEd.doDemoThumb();
392			
393			jQuery('td[rel=postHistory]').hide();
394			
395			if ( mwPostEd.live ) {
396				
397				var page = [];
398				page['published'] = 1; // for live Ed new post published by default 
399				mwPostEd.Form.fromArray(page);
400				mwPostEd.publishSwitch(1, true);
401				
402			} else
403				mwPostEd.publishSwitch(0);
404			
405			mwPostEd.unpublishSwitch();
406			
407			mwPostEd.secondarySwitch();
408			
409			//for kind select category by default for new post
410			if ( mwData.kind_category_id ) {
411				
412				$this.Form.find('#postEdCategoriesList .item>input[value=' + mwData.kind_category_id + ']').click();
413				
414			}
415			
416			return false;
417			
418		}
419		
420		this.ID = id;
421		
422		//regualr load from cache
423		//var page = mwData.Posts[id];
424		
425		//try to load from last loaded via ajax post
426		if ( mwPostEd.lastAjaxPost )
427			page = mwPostEd.lastAjaxPost
428			
429		//___(id, page);
430		if ( !page ) { //page is not loaded
431			
432			mwAjax('/site/ajax/blogs/getPostListDB/' + id + '/0/0', null, true )
433			.go()
434			.success( function($data) {
435				//___($data);
436				if ( typeof($data.content) != 'undefined' ) {
437					
438					mwData.Posts[id] = $data.content[id];
439					mwPostEd.lastAjaxPost = $data.content[id];
440					mwPostEd.edit(id, open_drafts);
441					
442				} else {
443					
444					return false;
445					
446				}
447			} );
448			
449			return false;
450			
451		}
452		else { //page is loaded
453			
454			//we need to clear last ajax post
455			mwPostEd.lastAjaxPost = false;
456			
457		} //page is loaded
458		
459		// set value for internal gallery (if exist)
460		if ( page.slider_gallery_internal != 0 ) {
461			
462			slider_internal_option.show().val(page.slider_gallery_internal);
463			
464		} else {
465			
466			slider_internal_option.hide().val('none');
467			
468		}
469		
470		// Resetting form
471		mwPostEd.Form.fromArray(page);
472                
473                // store prev custom values for marge on save - dont lose empty file inputs data
474		mwPostEd.Form.find('input[name=prev_custom_fields]').val(JSON.stringify(mwData.Posts[id].custom_fields));
475		//__(JSON.stringify(mwData.Posts[id].custom_fields));
476                
477		mwWindow('wPostEd').Title('Edit post (<span>' + page.title + '</span>)').show(
478			
479			function() { mwPostEd.resetTabs(id); /*mwWindow('wPostEd').adjustHeights(); mwWindow('wPostEd').align();*/ }
480			
481		); // mwWindow
482		
483		var show_current_unsaved = function(event) {
484			
485			if ( id ) { // dont run for new posts
486			
487				mwPostEd.CurrentUnsaved_text = mwPostEd.tiny4_body.contents().find('body').html();
488				mwPostEd.CurrentUnsaved_title = mwPostEd.post_title.val();
489				
490				mwPostEd.doHistoryTab();
491				
492				if ( $this.CurrentUnsaved )
493					if ( mwPostEd.CurrentUnsaved_text != mwData.Posts[id].content || mwPostEd.CurrentUnsaved_title != mwData.Posts[id].title  ) {
494					
495						$this.CurrentUnsaved.show();
496						//$this.CurrentUnsaved.change();
497						//jQuery('#postHistory div.Item').removeClass('Selected');
498						//jQuery('#postHistory div.Item:has(input[value=edited])>div').addClass('Selected');
499						//jQuery('#postHistory div.Item:has(input[value=edited])').mouseup();
500						
501					} else {
502						
503						$this.CurrentUnsaved.hide();
504						//$this.LastSaved.show().change();
505						//jQuery('#postHistory div.Item').removeClass('Selected');
506						//jQuery('#postHistory div.Item:has(input[value=saved])>div').addClass('Selected');
507						//jQuery('#postHistory div.Item:has(input[value=saved])').mouseup();
508						
509					}
510			}
511		};
512		
513		jQuery('td[rel=postHistory]').show();
514		
515		mwPostEd.CurrentUnsaved_text = mwData.Posts[id].content;
516		mwPostEd.CurrentUnsaved_title = mwData.Posts[id].title;
517		
518		$this.tiny4_body.contents().find('body').keyup(show_current_unsaved);
519		$this.post_title.keyup(show_current_unsaved);
520		
521		mwPostEd.refreshCategoriesSelect(id);
522		mwPostEd.refreshTagsSelect(id);
523		mwPostEd.doDemoThumb(id);
524		mwPostEd.publishSwitch(mwData.Posts[id].published);
525		
526		mwPostEd.unpublishSwitch();
527		
528		mwPostEd.secondarySwitch();
529		
530		//reset counters
531		$this.meta_title_counter.reset();
532		$this.meta_description_counter.reset();
533		
534		//add href for links with same class as custom field name in custom tabs
535		if ( typeof page.custom_fields != 'undefined') {
536			
537			for(var i in page.custom_fields) {
538			
539				mwPostEd.Form.find('#postCustom a.' + i).attr('href', page.custom_fields[i]);
540			
541			}
542			
543		}//loop custom fields
544		
545		//store last opened post data
546		$this.post_data = page;
547		
548		//open drafts tab if requested
549		if ( open_drafts ) mwPostEd.Form.find('[rel=postHistory]').click();
550		
551		return false;
552		
553	}, //FUNC edit
554	
555	showPanel	: function ($el) {
556		
557		var $this = this;
558		
559		$this.dom.panel.removeClass('hidden');
560		
561		if ( jQuery($el).attr('rel') == 'postHistory' )
562			mwPostEd.doHistoryTab($this);
563		
564		mwSwitchTab($el, false, false);
565		
566	}, //FUNC showPanel
567	
568	hidePanel	: function () {
569		
570		var $this = this;
571		
572		$this.dom.panel.addClass('hidden');
573		
574		mwSwitchTab($this.dom.hidePanel, false, false);
575		
576	}, //FUNC showPanel
577	
578	deletePost	: function(id) {
579		
580		mwConfirmation( function() {
581			
582			var data = {};
583			
584			//check is current category exist (if no - there are no category filter, this means its filtered by kind)
585			var cur_cat = mwCategoryEd.getCurrentFilterCategoryID();
586			if ( cur_cat ) {
587				
588				data.filter_by_category_id = cur_cat;
589				
590			} else {
591				
592				data.filter_by_category_id = mwData.kind_category_id;
593				data.kind_category_id = mwData.kind_category_id;
594				
595			}
596			
597			mwAjax( '/site/ajax/blogs/deletePostDB/' + id, data, 'systemConfirmation' )
598			.content()
599			.success( function($data) {
600				
601				mwPostEd.manualOrder_sort();
602				mwWindow('systemConfirmation').hide();
603				
604			} );									
605		}
606		, 'Delete Post: ' + mwData.Posts[id]['title'] + '?');
607		
608	}, //FUNC deletePost
609	
610	open_gallery	: function(type, gallery_id) {
611		
612		var id = this.ID;
613		var $this = this;
614		
615		var options = {}
616		var show_selector = false;
617		
618		if ( type == 'thumb' || type == 'banner' ) {
619			
620			options = {
621				
622				'Apply' : {
623				
624				'class'  : 'hi',
625				'action' : function ($file) {
626							
627						//__(type, $file);
628						if ( isEmpty($file) ) return;
629						
630						jQuery('input[name=' + type + ']').val($file['id']);
631						mwData['temp_' + type + '_name'] = $file['base'] + '.' + $file['ext'];
632						mwPostEd.doDemoThumb(id);
633						
634					} //FUNC setActions.apply.action
635				}
636			}
637			
638			show_selector = true; // need to have selector on thumb/banner choosing
639			
640		}
641		
642		if ( type == 'og_image' ) {
643			
644			options = {
645				
646				'Apply' : {
647				
648				'class'  : 'Hi',
649				'action' : function ($file) {
650							
651						//___(type, $file);
652						if ( isEmpty($file) ) return;
653						
654						
655						$this.Form.find('[name=og_image]').val( location.protocol + '//' + location.host + $file.__thumb); 
656						
657					} //FUNC setActions.apply.action
658				}
659			}
660			
661			show_selector = true;
662			
663		}
664		
665		//file id false by default
666		var file_id = false;
667		
668		if ( !jQuery.isNumeric(gallery_id) ) {
669			
670			//for new post there are no post data
671			if ( typeof $this.post_data == 'undefined' ) {
672				
673				gallery_id = false;
674				
675			}//new post
676			else {//existing post
677				
678				//use internal post gallery as default
679				gallery_id = $this.post_data.slider_gallery_internal;
680				
681			}//existing post
682			
683		}
684		
685		//not new post
686		//post already have some file selected in some gallery
687		if ( typeof $this.post_data != 'undefined' && jQuery.isNumeric($this.post_data.thumb) ) {
688			
689			//clean up gallery id - let gallery to find itself
690			gallery_id = false;
691			
692			//provide gallery with selected file id
693			var file_id = $this.post_data.thumb
694			
695		}
696		
697		//___('show_selector', show_selector);
698		mwFilesEd.galleriesSelector = show_selector;
699		mwFilesEd
700		.setActions( options ) //OBJECT mwFilesEd.setActions.actions
701		.load(gallery_id, file_id);
702		//___('mwFilesEd.galleriesSelector', mwFilesEd.galleriesSelector);
703	}, //FUNC open_gallery
704	
705	open_selected_gallery	: function() {
706		
707		var gallery_id = jQuery('select[name=slider_gallery]').val();
708		
709		this.open_gallery('', gallery_id);
710		
711	}, //FUNC open_selected_gallery
712	
713	savePost	: function () {
714		
715		if ( mwData.saveSecureValidation )
716			
717			//run save secure validation
718			mwPostEd.validateSecureSave(mwPostEd.save);
719			
720		else {
721			
722			mwPostEd.save();
723			
724		}
725			
726	}, //FUNC savePost
727	
728	save	: function (dont_hide) {
729		
730		var $this = this;
731		
732		//post is closing
733		$this.postEdit = false;
734		___('save', $this.postEdit);
735		mwPostEd.tags_temp = mwData.Tags;
736		delete mwData.Tags;
737		if ( mwPostEd.ID ) {
738			
739			delete mwData.Posts[mwPostEd.ID].tag_selected;
740			mwPostEd.post_tags_temp = mwData.Posts[mwPostEd.ID].tag_selected;
741		
742		}
743		
744		if (mwData.Archive && mwData.Archive[mwPostEd.ID] === null) delete mwData.Archive[mwPostEd.ID];
745		
746		//check is current category exist (if no - there are no category filter, this means its filtered by kind)
747		var cur_cat = mwCategoryEd.getCurrentFilterCategoryID();
748		if ( cur_cat ) {
749			
750			mwPostEd.Form.find('input[name=filter_by_category_id]').val( cur_cat );
751			
752		} else {
753			
754			mwPostEd.Form.find('input[name=filter_by_category_id]').val( mwData.kind_category_id );
755			mwPostEd.Form.find('input[name=kind_category_id]').val( mwData.kind_category_id );
756			
757		}
758		
759		var alias_new = jQuery('#mwPostEd_form').find('input[name=alias]').val();
760		
761		//clear error hightlight for tabs controls
762		mwPostEd.Form.find('.mwWinTabs .error').removeClass('error');
763		
764		___('save start');
765		mwAjax('/site/ajax/blogs/savePostDB', '#mwPostEd_form', 'wPostEd')
766			.go()
767			.success( function($data) {
768				___('save success');
769				if ( mwPostEd.live ) {
770					
771					var uri = window.location.pathname.split('/');
772					var alias_old = uri[uri.length - 1];
773					
774					if ( alias_old == alias_new ) {
775						
776						mwPostEd.liveCallback($data.block);
777						mwWindow('wPostEd').hide();
778						
779					} else {
780						
781						//___(alias_old, alias_new, window.location);
782						var pre_slash = '/';
783						if ( !uri[0] ) pre_slash = '';
784						uri[uri.length - 1] = alias_new;
785						var path = uri.join('/');
786						var new_url = window.location.origin + pre_slash + path;
787						window.location = new_url;
788						
789					}
790					
791				} else {
792
793					//if ( $data.fb_publishing == 'fail' ) mwState( mwError('FB publishing fail!')); 
794					
795					if ( !dont_hide ) {
796						
797						mwPostEd.resetTabs();
798						mwWindow('wPostEd').hide();
799						
800					} else {
801						
802						//jQuery('.publish-on-soc-button').hide();
803						jQuery('.publish-on-soc-success').show();
804						setTimeout( function() {mwState( mwSuccess('Social Posting Complete'), 'wPostEd' )}, 10);
805						
806					}
807					
808					mwPostEd.manualOrder_sort();
809					
810				}
811			} )
812			.error( function($data) {
813			
814				//___('save error', $data);
815				
816				mwData.Tags = mwPostEd.tags_temp;
817				if ( mwPostEd.ID )
818					mwData.Posts[mwPostEd.ID].tag_selected = mwPostEd.post_tags_temp;
819				
820				//check is data contain validation and post editor form
821				if ( typeof $data._validations != 'undefined' && typeof $data._validations.mwPostEd_form != 'undefined' ) {
822					
823					//loop all validation items and highlight tabs
824					for( var i in $data._validations.mwPostEd_form ) {
825						
826						//get the input tab id
827						var tab_id = jQuery(mwPostEd.Form.find('[name=' + i + ']')).parents('.tabs-container').attr('id');
828						
829						//check is current input in some tab
830						if ( tab_id != undefined ) {
831							
832							//add error class to highlight tab with validation error input
833							mwPostEd.Form.find('.mwWinTabs [rel=' + tab_id + ']').addClass('error');
834							
835						}
836					}
837				}
838				
839			} )
840		; // mwAjax
841		___('save end');
842	}, //FUNC save
843	
844	saveDraft	: function () {
845		
846		if ( mwData.saveSecureValidation )
847			
848			//run save secure validation
849			mwPostEd.validateSecureSave(mwPostEd.saveDraft_origin);
850			
851		else {
852			
853			mwPostEd.saveDraft_origin();
854			
855		}
856			
857	}, //FUNC saveDraft
858	
859	saveDraft_origin : function () {
860	
861		//jQuery('#mwPostEd_form .published_now input').click();
862		mwPostEd.Form.find('[name="publish_button"]').remove();
863		mwPostEd.save(false);
864		mwWindow('systemConfirmation').hide();
865			
866	}, //FUNC saveDraft
867	
868	PublishNow	: function (dont_hide) {
869		
870		if ( mwData.saveSecureValidation )
871			
872			//run save secure validation
873			mwPostEd.validateSecureSave(mwPostEd.PublishNow_origin);
874			
875		else {
876			
877			mwPostEd.PublishNow_origin();
878			
879		}
880		
881	}, //FUNC PublishNow
882	
883	PublishNow_origin : function (dont_hide) {
884		
885		//jQuery('#mwPostEd_form .published_now input').click();
886		mwPostEd.Form.append('<input type="hidden" name="publish_button" value="1"/>');
887		mwPostEd.save(dont_hide);
888		mwWindow('systemConfirmation').hide();
889		
890	}, //FUNC PublishNow
891	
892	validateSecureSave : function (callback) {
893		
894		var post_id = this.ID;
895		
896		//validate only existing post
897		if ( post_id ) {
898			
899			___('validateSecureSave - post id: ' + post_id);
900			
901			mwAjax('/site/ajax/blogs/checkSaveSecureValidation/' + post_id, null, true )
902				.go()
903				.success( function($data) {
904					//___($data);
905					if ( typeof($data.content) != 'undefined' ) {
906						
907						//var current_data = $data.content[post_id];
908						var current_data = $data.content;
909						___('current_data', current_data.date, current_data.user_id);
910						___('post data', mwData.Posts[post_id].date, mwData.Posts[post_id].user_id);
911						
912						//post saved by other user - warning!
913						if ( current_data.date != mwData.Posts[post_id].date ) {
914							
915							___('post saved by other user - warning!');
916							
917							var $new_tab = '<a href="/site/blogs/" onclick="document.getElementById(\'open_post_in_new_tab\').submit(); return false;">view the latest saved post in a new tab.</a>';
918							$new_tab += '<form target="_blank" action="/site/blogs/" method="post" id="open_post_in_new_tab"><input type="hidden" name="show_post_id" value="' + post_id + '"/></form>';
919							
920							mwConfirmation( function() { callback(); }
921							//, ' Post Saved by other User at ' + current_data.date + ' (' + current_data.login + '|' + current_data.email + '): you may overwrite content! Proceed?');
922							, ' Caution! The post was recently modified by ' + current_data.login + '|' + current_data.email + ' on '  + current_data.date +  '. If you continue, your changes will overwrite theirs. Click save to overwrite or ' + $new_tab);
923							
924						}
925						else {//post safe to save
926							
927							callback();
928							
929						}
930						
931					} else {
932						
933						return false;
934						
935					}
936					
937				} );
938				
939		}//existing post
940		else {//new post - ignore validation
941		
942			___('validateSecureSave - new post - ignore!');
943			callback();
944			
945		}//new post
946		
947	}, //FUNC validateSecureSave
948	
949	closePost	: function() {
950		
951		var $this = this;
952		
953		//post is closing
954		$this.postEdit = false;
955		
956	}, //FUNC closePost
957	
958	UnPublishNow	: function () {
959		
960		this.unpublish_start = true;
961		mwPostEd.publishSwitch(0);
962		mwPostEd.Form.find('.unpublished_now input').click();
963		
964	}, //FUNC UnPublishNow
965	
966	resetTabs	: function (id) {
967		
968		return false;
969		
970		/*
971		this.tabsWidth = this.TabsControl.width();
972		this.contentWidth = jQuery('#mwPostEd_toolsLeft').width();
973		this.basePadding = this.TabsControl.outerWidth() - this.tabsWidth;
974		___(this.tabsWidth, this.contentWidth, this.basePadding);
975		
976		mwSwitchTab(mwPostEd.hideTabsButton);
977		// Total width: content min width (with scroll):700 + tabs:450
978		mwPostEd.PostContent.css('margin-right', '0px').width( this.tabsWidth + this.contentWidth + this.basePadding * 1.5 ); //1145 1079
979		mwPostEd.Tabs.width(0);
980		//mwPostEd.hideTabsButton.hide();
981		
982		//mwWindow('wPostEd').Body.width(mwWindow('wPostEd').Body.width());
983		*/
984		
985	}, //FUNC resetTabs
986	
987	refreshCategoriesSelect	: function (id) {
988		
989		var $sel = jQuery('.name-categories_list');
990		
991		//there are no categories list for kind posts
992		if ( $sel.length > 0 ) {
993			
994			$o = {};
995			$k = {};
996			for ( var $i in mwData.Categories ) {
997				
998				if ( mwData.nav_list[ mwData.Categories[$i]['title'].toLowerCase() ] != undefined ) {
999					
1000					$k[ mwData.Categories[$i].id ] = '* ' + mwData.Categories[$i].title;
1001			
1002				}
1003				else {
1004					$o[ mwData.Categories[$i].id ] = mwData.Categories[$i].title;
1005				}
1006			}
1007			
1008			$selected = null;
1009			if ( id ) $selected = mwData.Posts[id].category_selected
1010			
1011			//add 'id' prefix to selected list
1012			if ( $selected != null )
1013				for(var $i in $selected) $selected[$i] = 'id' + $selected[$i];
1014			
1015			//loop selected to move on top
1016			for (var $i in $selected) {
1017				
1018				//ignore some trash categories
1019				if ( typeof($o[$selected[$i]]) != 'undefined' ) {
1020					
1021					//add selected item to list
1022					$k[$selected[$i]] = $o[$selected[$i]];
1023					
1024					//remove selected item from list
1025					delete($o[$selected[$i]]);
1026					
1027				}//real category
1028				
1029			}//loop selected
1030			
1031			//apply all items to list
1032			for (var $i in $o) $k[$i] = $o[$i];
1033			
1034			//generate select ordered by title
1035			//___($sel, $o, $selected, $k, jQuery.extend({}, $k, $o));
1036			mwUpdateSelector($sel, $k, $selected);
1037			
1038			//remove id prefix from values
1039			jQuery('.name-categories_list .item input').each(function(i){
1040				
1041				var el = jQuery(this);
1042				el.val(el.val().substring(2));			
1043												
1044			});
1045									
1046			mwCategoryEd.doFilterCategories( mwCategoryEd.catInputPostEd, jQuery('#postEdCategoriesList .Item'), '.title' ); // add filter
1047			mwCategoryEd.catInputPostEd.keyup( function() { mwState(false, 'wPostEd'); jQuery('.name-categoriesFilterPostEd').removeClass('error'); } )
1048			
1049		}
1050		
1051	}, //FUNC refreshCategoriesSelect
1052	
1053	refreshTagsSelect	: function (id, selected) {
1054		
1055		/*
1056		$o = {};
1057		for ( var $i in mwData.Tags )
1058			$o[$i] = mwData.Tags[$i].title;
1059		
1060		$selected = null;
1061		if ( id ) $selected = mwData.Posts[id].tag_selected
1062		
1063		var $sel = jQuery('.name-tags_list');
1064		mwUpdateSelector($sel, $o, $selected);
1065		
1066		mwCategoryEd.doFilterCategories( mwPostEd.TagTitleInput, jQuery('#postEdTagsList .Item'), '.title' ); // add filter
1067		mwPostEd.TagTitleInput.keyup( function() { mwState(false, 'wPostEd'); jQuery('.name-tagsFilterPostEd').removeClass('error'); } )
1068		*/
1069		
1070		$selected = null;
1071		
1072		$o = {};
1073		
1074		if ( mwData.ShowAllTagsInPostEd ) {
1075			for ( var $i in mwData.Tags )
1076				$o[ mwData.Tags[$i].id ] = mwData.Tags[$i].title;
1077			
1078		}
1079		
1080		if ( id ) {
1081			//___(selected);
1082			if ( typeof(selected) != 'undefined' && selected.length > 0 )
1083				$selected = selected;
1084			else {
1085				
1086				$selected = mwData.Posts[id].tag_selected;
1087				//add 'id' prefix to selected list
1088				for(var $i in $selected) $selected[$i] = 'id' + $selected[$i];
1089				
1090			}
1091			
1092			//___('$selected', $selected);
1093			
1094			//$selected = jQuery.extend($selected, mwData.Posts[id].tag_selected);
1095			if ( typeof $selected[0] != 'undefined' ) //check is 1st element not empty string ""
1096				for ( var $i in $selected ) {
1097					//___($i, $selected[$i], mwData.Tags[$selected[$i]]);
1098					if ( typeof mwData.Tags[$selected[$i]] != 'undefined' )
1099						$o[$selected[$i]] = mwData.Tags[$selected[$i]].title;
1100					
1101				}
1102		}
1103		//___(jQuery('.name-tags_list'), $o, $selected);
1104		
1105		//new list
1106		var $new_o = [];
1107		
1108		//loop selected to move on top
1109		for (var $i in $selected) {
1110			
1111			//ignore some trash categories
1112			if ( typeof($o[$selected[$i]]) != 'undefined' ) {
1113				
1114				//add selected item to list
1115				$new_o[$selected[$i]] = $o[$selected[$i]];
1116				
1117				//remove selected item from list
1118				delete($o[$selected[$i]]);
1119				
1120			}//real category
1121			
1122		}//loop selected
1123		
1124		//apply all items to list
1125		for (var $i in $o) $new_o[$i] = $o[$i];
1126		
1127		mwUpdateSelector(jQuery('.name-tags_list'), $new_o, $selected);
1128		
1129		//mwCategoryEd.doFilterCategories( mwPostEd.TagTitleInput, jQuery('#postEdTagsList .Item'), '.title' ); // add filter
1130		//doFilterCategories	: function ( input, elements, searchSelector )
1131		
1132		var delay = (function(){
1133			var timer = 0;
1134			return function(callback, ms){
1135				clearTimeout (timer);
1136				timer = setTimeout(callback, ms);
1137			};
1138		})();
1139		
1140		mwPostEd.TagTitleInput.keyup( function(event) {
1141			
1142			var $this = this;
1143			
1144			delay( function() {
1145				
1146				$selected = [];
1147				//___('before', $selected);
1148				//___(jQuery('.name-tags_list').find(':checked'));
1149				jQuery('.name-tags_list').find(':checked').each(function() {
1150					$selected.push(jQuery(this).val());
1151				});
1152				//___('after', $selected);
1153				
1154				var text = jQuery($this).val();
1155				
1156				if (text.length >= mwData.minTagsFilterLength) {
1157					
1158					//$o_new = jQuery.extend({}, $o);
1159					$o_new = [];
1160					jQuery.each($selected, function(i) {
1161						$o_new[$selected[i]] = mwData.Tags['id' + $selected[i]].title;
1162						//___('selected add', $selected[i], mwData.Tags[$selected[i]].title);
1163					} );
1164					
1165					jQuery.each(mwData.Tags, function(i) {
1166						
1167						var reg = new RegExp(text, "gi");
1168						
1169						if ( reg.test(mwData.Tags[i].title) ) {
1170							
1171							//___('regexp add', i, mwData.Tags[i].title);
1172							$o_new[i] = mwData.Tags[i].title;
1173							
1174						}
1175					} );
1176					//___($o_new);
1177					mwUpdateSelector(jQuery('.name-tags_list'), $o_new, $selected);
1178					
1179				} else {
1180					
1181					$o_new = [];
1182					jQuery.each($selected, function(i) {
1183						$o_new[$selected[i]] = mwData.Tags[$selected[i]].title;
1184					} );
1185					
1186					mwUpdateSelector(jQuery('.name-tags_list'), $o_new, $selected);
1187					
1188				}
1189				
1190				cleanUpIds();
1191				
1192			}, 500);
1193				
1194		} );
1195		
1196		//remove id prefix from values
1197		var cleanUpIds = function() {
1198			
1199			jQuery('.name-tags_list .item input').each(function(i){
1200				
1201				var el = jQuery(this);
1202				var val = el.val();
1203				
1204				//clean up only ids
1205				if ( val.indexOf('id') != -1 )
1206					el.val(val.substring(2));			
1207				
1208			});
1209			 
1210		};//cleanUpIds 
1211		
1212		cleanUpIds();
1213		
1214		mwPostEd.TagTitleInput.keyup( function() { mwState(false, 'wPostEd'); jQuery('.name-tagsFilterPostEd').removeClass('error'); } )
1215		
1216	}, //FUNC refreshTagsSelect
1217	
1218	addTag	: function () {
1219		
1220		var $this = this;
1221		
1222		var data = {};
1223		data.id = 0;
1224		data.title = mwPostEd.TagTitleInput.val();
1225		
1226		var is_valid = true;
1227		
1228		if ( data.title.length == 0 ) {
1229			
1230			is_valid = false;
1231			mwState(mwError('Title is required'), 'wPostEd');
1232			
1233		} else {
1234			
1235			for ( var $i in mwData.Tags )
1236				if ( mwData.Tags[$i].title == data.title ) {
1237					
1238					is_valid = false;
1239					mwState(mwError('Title already exist'), 'wPostEd');
1240					
1241				}
1242		}
1243		
1244		//check is current category exist (if no - there are no category filter, this means its filtered by kind)
1245		var cur_cat = mwCategoryEd.getCurrentFilterCategoryID();
1246		if ( cur_cat ) {
1247			
1248			data.filter_by_category_id = cur_cat;
1249			
1250		} else {
1251			
1252			data.filter_by_category_id = mwData.kind_category_id;
1253			data.kind_category_id = mwData.kind_category_id;
1254			
1255		}
1256		
1257		if ( is_valid ) {
1258			
1259			mwState(false, 'wPostEd');
1260			jQuery('.name-tagsFilterPostEd').removeClass('error');
1261			
1262			mwAjax( '/site/ajax/blogs/saveTagDB', data )
1263				.content()
1264				.success( function() {
1265					
1266					$selected = [];
1267					jQuery('.name-tags_list').find(':checked').each(function() {
1268						$selected.push(jQuery(this).val());
1269					});
1270					
1271					mwPostEd.refreshTagsSelect($this.ID, $selected);
1272					mwPostEd.manualOrder_sort();
1273					mwPostEd.TagTitleInput.keyup();
1274					
1275				} );
1276				
1277		} else {
1278			
1279			jQuery('.name-tagsFilterPostEd').addClass('error');
1280			
1281		}
1282		
1283	}, //FUNC addTag
1284	
1285	publish	: function (id, published, published_date) {
1286		
1287		var phrase_start = 'Publish';
1288		if( !published ) phrase_start = 'Unpublish';
1289		
1290		mwConfirmation( function() {
1291			
1292			var data = {};
1293			
1294			data.id = id;
1295			data.published = published;
1296			if ( published_date ) data.published_date = published_date;
1297			
1298			//check is current category exist (if no - there are no category filter, this means its filtered by kind)
1299			var cur_cat = mwCategoryEd.getCurrentFilterCategoryID();
1300			if ( cur_cat ) {
1301				
1302				data.filter_by_category_id = cur_cat;
1303				
1304			} else {
1305				
1306				data.filter_by_category_id = mwData.kind_category_id;
1307				data.kind_category_id = mwData.kind_category_id;
1308				
1309			}
1310			
1311			mwAjax( '/site/ajax/blogs/doPublish', data, 'systemConfirmation' )
1312			.index('#categoriesListContent, #categoriesTreeContent')
1313			.success( function($data) { mwPostEd.manualOrder_sort(); } )
1314												
1315		}
1316		, phrase_start + ' Post: ' + mwData.Posts[id]['title'] + '?');
1317		
1318	}, //FUNC publish
1319	
1320	publishSwitch	: function (state, dont_hide) {
1321		
1322		var $this = this;
1323		
1324		var publish_tr = mwPostEd.Form.find('.post_publish_tr');
1325                var unpublish_tr = mwPostEd.Form.find('.post_unpublish_tr');
1326                var date_time_tr = mwPostEd.Form.find('.date_time_tr');
1327                var publish_button = jQuery('#publish_button_body');
1328                var save_button = jQuery('#save_button_body');
1329                var draft_button = jQuery('#draft_button_body');
1330		var input_published = mwPostEd.Form.find('input[name=published]');
1331		
1332		if ( state == 2 ) {
1333			
1334			date_time_tr.show();
1335			
1336		} else {
1337			
1338			date_time_tr.hide();
1339			
1340		}
1341		
1342                if ( state > 0 && !dont_hide ) {
1343			
1344			publish_tr.hide();
1345                	unpublish_tr.show();
1346                	date_time_tr.hide();
1347                	
1348                } else {
1349                	
1350                	publish_tr.show();
1351                	unpublish_tr.hide();
1352                	
1353                }
1354		
1355		if ( this.ID ) {
1356			
1357			if ( mwData.Posts[this.ID]['published_date'] != '' )
1358				jQuery('#published_date_span').html('Post Published by Schedule: ' + mwData.Posts[this.ID]['published_date_view']);
1359			else
1360				jQuery('#published_date_span').html('Post Published: ' + mwData.Posts[this.ID]['published_date_min']);
1361		
1362		}
1363		
1364		if ( typeof(mwData.Posts[this.ID]) == 'undefined' || mwData.Posts[this.ID]['published'] == 0 || this.unpublish_start ) {
1365			
1366			$this.dom.submitDraft.show();
1367			$this.dom.submitPublish.show();
1368			
1369			$this.dom.submitSave.hide();
1370			
1371			//publish_button.show();
1372			//draft_button.show();
1373			//save_button.removeClass('hi');
1374			//save_button.html('Save Draft');
1375			input_published.val(0);
1376			
1377		} else {
1378			
1379			$this.dom.submitDraft.hide();
1380			$this.dom.submitPublish.hide();
1381			
1382			$this.dom.submitSave.show();
1383			
1384			//publish_button.hide();
1385			//save_button.addClass('hi');
1386			//save_button.html('Save');
1387			input_published.val(state);
1388			
1389		}
1390		
1391	}, //FUNC publishSwitch
1392	
1393	unpublishSwitch	: function(state) {
1394		//___('unpublishSwitch', 111, state);
1395		var input_unpublish = mwPostEd.Form.find('input[name=unpublish]');
1396		var unpublish_tr = mwPostEd.Form.find('.unpublish_time_tr');
1397		var unpublished_flag = jQuery('input[name=unpublished_flag]');
1398		
1399		if ( typeof(state) == 'undefined' ) {
1400			
1401			state = input_unpublish.val() * 1;
1402			
1403		} else {
1404			
1405			state = input_unpublish.val() * 1;
1406			
1407			if ( state )
1408				state = 0;
1409			else
1410				state = 1;
1411			
1412			input_unpublish.val(state);
1413			
1414			//___('unpublishSwitch', 222, state);
1415			input_unpublish.val(state);
1416			
1417		}
1418		//___('unpublishSwitch', 333, state);
1419		if ( state ) {
1420			
1421			unpublish_tr.show();
1422			
1423		} else {
1424			
1425			unpublish_tr.hide();
1426			
1427		}
1428		
1429		/*
1430		if ( typeof(mwData.Posts[this.ID]) != 'undefined' && mwData.Posts[this.ID]['unpublished_date'] != '' ) {
1431			
1432			unpublish_status.show();
1433			jQuery('#unpublished_date_span').html('Post Unpublished by Schedule: ' + mwData.Posts[this.ID]['unpublished_date_view']);
1434			
1435			
1436		} else {
1437			
1438			unpublish_status.hide();
1439		
1440		}
1441		*/
1442		
1443	}, //FUNC unpublishSwitch
1444	
1445	secondarySwitch	: function(state) {
1446		
1447		setTimeout(function(){
1448			
1449			var tr = mwPostEd.Form.find('.secondary_time_tr');
1450			var input = mwPostEd.Form.find('[name=secondary_flag]');
1451			//___(state, tr, input);
1452			if ( typeof(state) == 'undefined' ) {
1453				
1454				if ( this.ID ) {
1455					
1456					state = mwData.Posts[this.ID]['secondary_flag'];
1457					
1458				} else {
1459					
1460					state = input.parent().find('.checked').length;
1461					
1462				}
1463			}
1464			//___(state);
1465			if ( state ) {
1466				
1467				tr.show();
1468				
1469			} else {
1470				
1471				tr.hide();
1472				
1473			}
1474			
1475		}, 1)
1476		
1477	}, //FUNC secondarySwitch
1478	
1479	doDemoThumb	: function (id) {
1480		
1481		/*if ( !id ) {
1482			
1483			jQuery('#demo_thumb_icon, #demo_banner_icon').hide();
1484			return false;
1485			
1486		} */
1487		
1488		if ( id ) {
1489			
1490			mwData.Posts[id].delete_thumb = false;
1491			mwData.Posts[id].delete_banner = false;
1492		
1493		}
1494		
1495		/*
1496		var del_pic_ajax = function(type) {
1497			
1498			var data = {};
1499			data.id = id;
1500			data.img_type = type;
1501			
1502			mwAjax( '/site/ajax/blogs/deletePicture', data )
1503				.content()
1504				.success( function($response) { mwPostEd.doDemoThumb(id); } );
1505			
1506		};
1507		*/
1508		
1509		var del_pic = function(type) {
1510			
1511			if ( type == 'thumb' ) {
1512				
1513				mwData.Posts[id].delete_thumb = true;
1514				delete mwData.Posts[id].temp_thumb_name;
1515				
1516			}
1517			
1518			if ( type == 'banner' ) {
1519				
1520				mwData.Posts[id].delete_banner = true;
1521				delete mwData.Posts[id].temp_banner_name;
1522				
1523			}
1524			
1525			var img_div = jQuery('#demo_' + type + '_icon');
1526			img_div.slideUp( function() {
1527				
1528				img_div.html('<input type="hidden" name="delete_' + type + '" value=""/>');
1529				
1530		 	} );
1531		 	//reinit_file_input( jQuery('#demo_' + type + '_icon_td') );
1532			
1533		};
1534		
1535		/*
1536		var reinit_file_input = function(name) {
1537			
1538			var wrapper = jQuery('#demo_' + n
1538ame + '_icon_td span');
1539			if ( name == 'banner' ) name = 'header';
1540			wrapper.html('<input type="file" name="' + name + '_icon">');	
1541			styleDialog(wrapper);
1542			
1543		}
1544		*/
1545		
1546		/*
1547		var do_field = function(type, animate) {
1548			
1549			var pic = '';
1550			
1551			if ( type == 'thumb' && mwData.Posts[id].thumb && !mwData.Posts[id].delete_thumb )
1552				var pic = '<img src="/files/galleries/' + mwData.Posts[id].thumb + '">';
1553			
1554			if ( type == 'banner' && mwData.Posts[id].banner && !mwData.Posts[id].delete_banner )
1555				var pic = '<img src="/files/galleries/' + mwData.Posts[id].banner + '">';
1556			
1557			var img_div = jQuery('#demo_' + type + '_icon');
1558			
1559			if ( pic != '' )
1560				img_div.html(pic)
1561					.append('<div class="demo_delete"></div>')
1562					.show()
1563					.find('.demo_delete')
1564					.click( function(event) { del_pic(type); } );
1565			else
1566				img_div.html('').hide();
1567			
1568			//reinit_file_input(type);
1569			
1570		};
1571		*/
1572		
1573		var do_field = function(type) {
1574			
1575			//var pic_start = '<img src="/files/galleries/';
1576			var pic_start = '<img src="';
1577			var pic_end = '">';
1578			var pic = '';
1579			
1580			if ( type == 'thumb' ) {
1581				
1582				
1583				
1584				if ( mwData.temp_thumb_name ) {
1585					
1586					//add files/galleries folder in case images selected from gallery just right now
1587					if (mwData.temp_thumb_name.indexOf('/') == -1  )
1588						pic_start += '/files/galleries/';
1589					
1590					pic = pic_start + mwData.temp_thumb_name + pic_end;
1591					
1592				}
1593				else if ( id && mwData.Posts[id].thumb_file ) {
1594				
1595					pic = pic_start + mwData.Posts[id].thumb_file + pic_end;
1596					
1597				}
1598			
1599			}
1600			
1601			if ( type == 'banner' ) {
1602			
1603				if ( mwData.temp_banner_name ) {
1604					
1605					//add files/galleries folder in case images selected from gallery just right now
1606					if (mwData.temp_banner_name.indexOf('/') == -1  )
1607						pic_start += '/files/galleries/';
1608					
1609					pic = pic_start + mwData.temp_banner_name + pic_end;
1610				
1611				}
1612				else if ( id && mwData.Posts[id].banner_file ) {
1613				
1614					pic = pic_start + mwData.Posts[id].banner_file + pic_end;
1615					
1616				}
1617			
1618			}
1619			
1620			var img_div = jQuery('#demo_' + type + '_icon');
1621			//__(img_div, pic);
1622			if ( pic != '' ) {
1623				img_div.html(pic)
1624					.append('<div class="demo_delete"></div>')
1625					.show();
1626				
1627				jQuery('#demo_' + type + '_icon_td')
1628					.find('.demo_delete')
1629					.click( function(event) { del_pic(type); } );
1630			}
1631			else {
1632				img_div.html('').hide();
1633			}
1634			
1635		};
1636		
1637		do_field('thumb');
1638		do_field('banner');
1639		
1640	}, //FUNC doDemoThumb
1641	
1642	dataSocialsUpload	: function() {
1643		
1644		var form = mwPostEd.Form;
1645		
1646		var data = {};
1647		data.message = mwSocials().removeTags( form.find('textarea[name=content]').val() );
1648		data.picture = window.location.host + '/' + form.find('div#demo_thumb_icon img').attr('src');
1649		data.link = mwData.postPageURL + '/' + this.ID + '/' + mwData.Posts[this.ID].title_url;
1650		data.name = form.find('input[name=title]').val();
1651		data.description = form.find('textarea[name=description]').val();
1652		
1653		return data;
1654		
1655	}, //FUNC dataSocialsUpload
1656	
1657	postOnSocials	: function() {
1658		
1659		mwSocials().publishOnSoc(this.dataSocialsUpload());
1660		
1661	}, //FUNC postOnSocials
1662	
1663	manualOrderInit	: function() {
1664		
1665		jQuery('.sort_td').hide();
1666		
1667		mwPostEd.is_manually_sort = false;
1668		
1669		jQuery('#order_select').change( function(event) {
1670			
1671			var $el		= jQuery(this);
1672			var $val	= $el.val(); 
1673			
1674			// Special case for manual sorting
1675			mwPostEd.is_manually_sort = ($val == 'manual'); 
1676			
1677			// Sorting things
1678			mwPostEd.doSortTable($val); 
1679		} );
1680		
1681		mwPostEd.manualOrder_sort();
1682		
1683	}, //FUNC manualOrderInit
1684	
1685	manualOrder_sort : function() {
1686			
1687		mwPostEd.posts_list = jQuery('.mwIndexTable tbody');
1688		
1689		mwPostEd.posts_list.sortable( {
1690			
1691			handle			: '.manual_sort_handle',
1692			forceHelperSize		: true,
1693			forcePlaceholderSize	: true,
1694			placeholder		: 'Placeholder',
1695			errorClass		: 'PlaceholderErr',
1696			helper			: 'clone',
1697			appendTo		: 'parent',
1698			axis			: 'y',
1699			scroll			: false,
1700			forceHelperSize		: true,
1701			update			: function(event, ui) {
1702				
1703				var data = {};
1704				data.posts_list = mwPostEd.posts_list.sortable( "toArray" );
1705				
1706				mwAjax('/site/ajax/blogs/savePostsOrder', data, false)
1707				.index('#postListContent')
1708				.success( function($data) { mwPostEd.manualOrder_sort(); } )
1709				.error( function() { } )
1710				; // mwAjax
1711				
1712			},
1713			start			: function(event, ui) {
1714				
1715				var tds_helper = ui.helper.find('th, td');
1716				var tds_table = jQuery('.mwIndexTable thead').find('th, td');
1717				
1718				jQuery.each(tds_helper, function(i) {
1719					
1720					jQuery(this).attr('id', 'no_transition_width').width( jQuery(tds_table.get(i)).width() );
1721					
1722				} );
1723			}
1724		} );
1725		
1726		jQuery('#order_select').change();
1727		
1728		if ( typeof mwData.AjaxFilter == "undefined" ) {
1729			
1730			jQuery('#categories_filter').change();
1731			
1732		}
1733		
1734	}, //FUNC manualOrder_sort
1735				
1736	doSortTable	: function (sort_by) {
1737		
1738		sort_by_parts = sort_by.split('_');
1739		//___('sort_by', sort_by, sort_by_parts);
1740		
1741		var rows = mwPostEd.posts_list.find('tr');
1742		
1743		if ( mwPostEd.is_manually_sort ) sort_by = 'manual';
1744		
1745		if ( sort_by == 'default' ) sort_by = 'id';
1746		
1747		if ( sort_by == 'manual' )
1748			jQuery('.manual_sort_handle').show();
1749		else
1750			jQuery('.manual_sort_handle').hide();
1751		
1752		rows.sort( function(a, b){
1753			
1754			var compA = jQuery(a).attr(sort_by_parts[0]);
1755			var compB = jQuery(b).attr(sort_by_parts[0])
1756			
1757			//___(sort_by, compA, compB);
1758			
1759			if ( sort_by_parts[0] != 'alpha' ) {
1760				
1761				compA = parseInt(compA, 10);
1762				compB = parseInt(compB, 10);
1763				
1764				var intRegex = /^\d+$/;
1765				if( ! intRegex.test(compA) ) { compA = 0; }
1766				if( ! intRegex.test(compB) ) { compB = 0; }
1767				
1768				if ( sort_by_parts[1] == 'asc' )
1769					return (compA < compB) ? 1 : (compA > compB) ? -1 : 0;
1770				else
1771					return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
1772				
1773			} else {
1774				//___(compA, compB, compA.localeCompare(compB));
1775				//return compA.localeCompare(compB);
1776				
1777				compA = compA.toLocaleLowerCase();
1778				compB = compB.toLocaleLowerCase();				
1779				
1780				if ( sort_by_parts[1] == 'asc' )
1781					return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
1782				else
1783					return (compA < compB) ? 1 : (compA > compB) ? -1 : 0;
1784					
1785			}
1786			
1787			
1788		} );
1789		
1790		jQuery.each( rows, function(i) {
1791			
1792			mwPostEd.posts_list.append(this);
1793			
1794		} );
1795			
1796	}, //FUNC doSortTable
1797	
1798	doSortTableButton : function () {
1799		
1800		var rows = mwPostEd.posts_list.find('tr');
1801		
1802		if ( jQuery('.manual_sort_handle').is(':visible') ) {
1803			
1804			mwPostEd.is_manually_sort = false;
1805			mwPostEd.doSortTable( jQuery('#order_select').val() );
1806			
1807		} else {
1808			
1809			mwPostEd.is_manually_sort = true;
1810			mwPostEd.doSortTable( 'manual' );
1811			
1812		}
1813			
1814	}, //FUNC doSortTableButton
1815	
1816	doHistoryTab : function ($this) {
1817		
1818		var obj = this;
1819		
1820		var doIt = function() {
1821			
1822			//special check - bugfix
1823			//sometimes, rly rare mwData.Posts[obj.ID] doesnt exists
1824			if ( !mwData.Posts || !mwData.Posts[obj.ID] ) return;
1825			
1826			var tiny_content = obj.PostContent.find('textarea[name=content]');
1827			
1828			var post_title = jQuery('input[name=title]');
1829			
1830			var $o = {};
1831			$o['edited'] = 'Current Unsaved';
1832			$o['saved'] = 'Last Saved';
1833			
1834			var selected = 'saved';
1835			if ( mwPostEd.CurrentUnsaved_text != mwData.Posts[obj.ID].content || mwPostEd.CurrentUnsaved_title != mwData.Posts[obj.ID].title )
1836				selected = 'edited';
1837			
1838			for ( var $i in mwData.Archive[obj.ID] )
1839				$o[ 'id' + $i ] = mwData.Archive[obj.ID][$i].create_date + ' (' + mwData.Archive[obj.ID][$i].user_display_name + ')';
1840			
1841			var $sel = jQuery('.name-postEdHistoryList');
1842			mwUpdateSelector($sel, $o, selected);
1843			
1844			obj.CurrentUnsaved = jQuery('div.item:has(input[value=edited])');
1845			obj.LastSaved = jQuery('div.item:has(input[value=saved])');
1846			
1847			if ( selected != 'edited' ) obj.CurrentUnsaved.hide();
1848				
1849			jQuery('.name-postEdHistoryList').click( function(event) {
1850				
1851				var clicked_id = jQuery(event.target).val();
1852				
1853				//___(mwData.Archive[obj.ID], clicked_id, mwData.Archive[obj.ID][clicked_id] )
1854				
1855				if ( clicked_id )
1856					if ( clicked_id == 'saved' ) {
1857						
1858						tiny_content.val(mwData.Posts[obj.ID].content);
1859						post_title.val(mwData.Posts[obj.ID].title);
1860						
1861					} else if (clicked_id == 'edited') {
1862						
1863						tiny_content.val(mwPostEd.CurrentUnsaved_text);
1864						post_title.val(mwPostEd.CurrentUnsaved_title);
1865						
1866					} else {
1867						
1868						tiny_content.val(mwData.Archive[obj.ID][clicked_id.substring(2)].content);
1869						post_title.val(mwData.Archive[obj.ID][clicked_id.substring(2)].title);
1870						
1871					}
1872			});
1873			
1874			//mwSwitchTab($this);
1875			
1876		}
1877		
1878		if ( mwData.saveSecureValidation || !mwData.Archive || ( !mwData.Archive[obj.ID] && mwData.Archive[obj.ID] !== null ) )
1879			mwAjax( '/site/ajax/blogs/getHistorySelect', { 'ID' : obj.ID }, 'wPostEd' )
1880				.content()
1881				.success( function($data) { doIt(); } )
1882				.error( function() { } )
1883		else
1884			doIt();
1885		
1886	}, //FUNC doHistoryTab
1887	
1888	show_hide_soc_customs : function ($this) {
1889		
1890		var soc = jQuery($this).attr('rel');
1891		jQuery('.socials-custom-wrapper.' + soc).toggle(400);
1892			
1893	}, //FUNC show_hide_soc_customs
1894	
1895	isValidChr		: function(str){
1896		
1897		return !/[~`!#$%\^&*@()+=\[\]\\';,/{}\\":<>\?]/g.test(str);
1898		
1899	}, //FUNC isValidChr
1900	
1901	checkAliasValid		: function($this) {
1902		
1903		if ( !mwPostEd.isValidChr(jQuery($this).val()) ) {
1904			
1905			mwState(mwError('"-", "_", "|" are only special character allowed for alias, all other characters will be removed on save'), 'wPostEd');
1906			jQuery('.name-alias').addClass('error');
1907			
1908		} else {
1909			
1910			jQuery('.name-alias').removeClass('error');
1911			mwState(false, 'wPostEd');
1912			
1913		}
1914		
1915	}, //FUNC checkAliasValid
1916	
1917}; //CLASS mwPostEd
1918
1919//---------------------------------------------------------------------------------------------------------------------------------------------------
1920
1921var mwCategoryEd = {
1922	
1923	ID		: 0,		// Current category ID
1924	
1925	LastItem	: 0,		// last used item from list - dom object
1926	
1927	NewCounter	: 0,
1928	
1929	Defaults	: {		// Form defaults for resetting dialog
1930	
1931		id		: 0,
1932		parent_id	: 0,
1933		title		: '',
1934		comment		: '',
1935		is_news		: 0,
1936		no_index	: 0,
1937		no_follow	: 0,
1938		
1939	}, //OBJECT Defaults
1940	
1941	init	: function() {
1942		
1943		mwCategoryEd.updateCategories = {};
1943 // array for updating existing categories on save
1944		mwCategoryEd.deleteCategories = []; // array for delete existing categories on save
1945		mwCategoryEd.newCategories = {}; // array for create new categories on save
1946		mwCategoryEd.ID = 0;
1947		mwCategoryEd.LastItem = 0;
1948		mwCategoryEd.NewCounter = 0;
1949		
1950		mwCategoryEd.form = jQuery('#saveCategory_form');
1951		mwCategoryEd.listContainer = jQuery('.categories_list_container');
1952		mwCategoryEd.catInputPostEd = jQuery('#categoriesFilterPostEd');
1953		
1954		//mwCategoryEd.buildCategoriesList();
1955		mwCategoryEd.buildCategoriesTree();
1956		mwCategoryEd.doCategoriesMainFilter();
1957		mwCategoryEd.doDraggableItems();
1958		mwCategoryEd.doFilterCategoriesTree( jQuery('#categoriesFilter'), jQuery('.categories_list li'), 'a span' );
1959		
1960	}, //FUNC init
1961	
1962	refreshCategoriesList	: function (id) { // this function using with special control (folders-like)
1963		
1964		this.ID = id;
1965		mwAjax( '/site/ajax/blogs/index', { 'categoryID' : this.ID } )
1966			.index('#categoriesListContent, #categoriesTreeContent');
1967		
1968	}, //FUNC refreshCategoriesList
1969	
1970	manageCategories	: function () {
1971		
1972		//this.init();
1973		
1974		//hide special (kind) categories
1975		for(var c in mwData.Categories) {
1976			
1977			if ( mwData.nav_list[ mwData.Categories[c]['title'].toLowerCase() ] != undefined ) {
1978				
1979				mwCategoryEd.listContainer.find('li#' + c).hide();
1980				
1981			}
1982		}
1983		
1984		mwWindow('wManageCategories').show();
1985		
1986		mwCategoryEd.editItemGrant = false; // this flag using for disable/enable change event on form fields
1987		this.form.hide().fromArray(this.Defaults);
1988		
1989		return false;
1990		
1991	}, //FUNC manageCategories
1992	
1993	saveCategoriesEd	: function () {
1994		
1995		var data = {};
1996		
1997		//check is current category exist (if no - there are no category filter, this means its filtered by kind)
1998		var cur_cat = mwCategoryEd.getCurrentFilterCategoryID();
1999		if ( cur_cat ) {
2000			
2001			data.filter_by_category_id = cur_cat;
2002			
2003		} else {
2004			
2005			data.filter_by_category_id = mwData.kind_category_id;
2006			data.kind_category_id = mwData.kind_category_id;
2007			
2008		}
2009		
2010		data.updateCategories = [];
2011		for ( var $i in this.updateCategories )
2012			data.updateCategories.push( this.updateCategories[$i] );
2013		
2014		data.deleteCategories = this.deleteCategories;
2015		
2016		data.newCategories = [];
2017		for ( var $i in this.newCategories )
2018			data.newCategories.push( this.newCategories[$i] );
2019		
2020		if ( mwCategoryEd.isSorted )
2021			data.orderCategories = mwCategoryEd.treeToArray();
2022		
2023		/*
2024		__('update',mwCategoryEd.updateCategories);
2025		__('delete',mwCategoryEd.deleteCategories);
2026		__('new',mwCategoryEd.newCategories);
2027		__('order',mwCategoryEd.orderCategories);
2028		*/
2029		
2030		mwCategoryEd.cat_temp = mwData.Categories;
2031		delete mwData.Categories;
2032		
2033		mwAjax('/site/ajax/blogs/saveCategoryDB', data, 'wManageCategories')
2034			.index('#categoriesListContent, #categoriesTreeContent')
2035			.success( function() {
2036				
2037				//mwCategoryEd.deleteCategories.forEach( function(value) { delete mwData.Categories[value]; } ); // remove all deleted categories from mwData (after succes)
2038				mwPostEd.refreshCategoriesSelect(mwPostEd.ID); // refresh categories list on postEd categories tab
2039				mwCategoryEd.init();
2040				mwPostEd.manualOrder_sort();
2041				
2042				//refresh categories on desktop
2043				mwCategoryEd.doCategoriesMainFilter();
2044				
2045			} )
2046			.error( function() {
2047				
2048				mwData.Categories = mwCategoryEd.cat_temp;
2049				
2050			} )
2051		;
2052		
2053	}, //FUNC save
2054	
2055	addCategory		: function () {
2056		
2057		var cat_data = {};
2058		cat_data.id = 0;
2059		cat_data.parent_id = 0;
2060		cat_data.title = jQuery('#categoriesFilterPostEd').val();
2061		
2062		var is_valid = true;
2063		
2064		if ( cat_data.title.length == 0 ) {
2065			
2066			is_valid = false;
2067			mwState(mwError('Title is required'), 'wPostEd');
2068			
2069		} else {
2070			
2071			for ( var $i in mwData.Categories )
2072				if ( mwData.Categories[$i].title == cat_data.title ) {
2073					
2074					is_valid = false;
2075					mwState(mwError('Title already exist'), 'wPostEd');
2076					
2077				}
2078		}
2079		___(is_valid);
2080		if ( is_valid ) {
2081			
2082			mwState(false, 'wPostEd');
2083			jQuery('.name-categoriesFilterPostEd').removeClass('error');
2084			
2085			var data = {};
2086			data.newCategories = [];
2087			data.newCategories.push( cat_data );
2088			
2089			//check is current category exist (if no - there are no category filter, this means its filtered by kind)
2090			var cur_cat = mwCategoryEd.getCurrentFilterCategoryID();
2091			if ( cur_cat ) {
2092				
2093				data.filter_by_category_id = cur_cat;
2094				
2095			} else {
2096				
2097				data.filter_by_category_id = mwData.kind_category_id;
2098				data.kind_category_id = mwData.kind_category_id;
2099				
2100			}
2101			___(data);
2102			mwAjax( '/site/ajax/blogs/saveCategoryDB', data )
2103				.content()
2104				.success( function() {
2105					
2106					mwPostEd.refreshCategoriesSelect(mwPostEd.ID);
2107					
2108					mwCategoryEd.doCategoriesMainFilter();
2109					
2110				} );
2111				
2112		} else {
2113			
2114			jQuery('.name-categoriesFilterPostEd').addClass('error');
2115			
2116		}
2117		
2118	}, //FUNC addCategory
2119	
2120	treeToArray		: function() {
2121		
2122		var cat_list = [];
2123		
2124		jQuery('.categories_list>ul').find('li[id]').each( function(i) {
2125			
2126			el = jQuery(this);
2127			var id = el.attr('id');
2128			var parent_id = el.parent().parent('li[id]').attr('id');
2129			if ( parent_id == undefined ) parent_id = 0;
2130			
2131			cat_list.push( { id : id, parent_id : parent_id } );
2132			
2133			//__(i + ' | id - ' + id + ' | parent_id - ' + parent_id + ' | ' + el.find('span').html());
2134			
2135		} );
2136		
2137		return cat_list;
2138		
2139	}, //FUNC toArray
2140	
2141	editItem	: function (id, $this) {
2142	//	___('EDIT START', id);
2143		if ( mwCategoryEd.ID != 0 ) // if there was already some edition of items - save changes (fix bug - click on sortable items after editing fields not trigger onchange)
2144			if ( ! mwCategoryEd.saveItem() ) return false; // if cant save - dont let edit new item
2145		
2146		mwCategoryEd.ID = id;
2147		mwCategoryEd.LastItem = $this;
2148		
2149		var page = mwCategoryEd.Defaults;
2150		
2151		id = id.substring(2); // remove "id" symbols
2152	//	___('page Defaults', page);
2153		if ( !isNaN(id-0) ) { // if ID numeric - its existing category, else - new
2154			
2155			id = 'id' + id;
2156			
2157			page = mwCategoryEd.updateCategories[id]; // try check category on update list (mb its already changed)
2158	//		___('!page start', !page, page);
2159			if ( !page ) page = mwData.Categories[id]; // if not changed then try default
2160	//		___('!page', !page, page);
2161			if ( !page ) { throw 'ERROR: wrong ID provided for mwCategoryEd.editItem()'; return false; }
2162	//		___('!page 2', !page, page);
2163		} else {
2164			
2165			id = 'ne' + id;
2166			page = jQuery.extend(true, {}, mwCategoryEd.newCategories[id]);
2167	//		___('else page', page);
2168		}
2169	//	___('final page', page);
2170		mwCategoryEd.form.fadeOut( 'fast', function() {
2171			
2172			setTimeout( function() {
2173			 	
2174			 	mwCategoryEd.editItemGrant = false;
2175			 	mwCategoryEd.form.fromArray(page)
2176				mwCategoryEd.form.find('input[name=title]').focus();
2177				mwCategoryEd.editItemGrant = true;
2178				 
2179			}, 1 ); // set focus on title input
2180			
2181		} ).fadeIn('fast', function() {
2182			
2183			
2184			
2185		} );
2186		jQuery('.categories_list').find('.Selected').removeClass('Selected');
2187		jQuery($this).parent().addClass('Selected');
2188		
2189		return false;
2190		
2191	}, //FUNC editItem
2192	
2193	saveItem	: function () {
2194		
2195		if ( mwCategoryEd.editItemGrant && ! mwCategoryEd.form.is(':animated') ) {
2196			
2197			var item = {};
2198			item.id = this.form.find('input[name=id]').val();
2199			item.parent_id = this.form.find('input[name=parent_id]').val();
2200			item.title = this.form.find('input[name=title]').val();
2201			item.comment = this.form.find('textarea[name=comment]').val();
2202			item.is_news = this.form.find('input[name=is_news]').is(':checked') ? 1 : 0;
2203			item.no_index = this.form.find('input[name=no_index]').is(':checked') ? 1 : 0;
2204			item.no_follow = this.form.find('input[name=no_follow]').is(':checked') ? 1 : 0;
2205			
2206			//___('save item', item);
2207			if ( ! mwCategoryEd.validateItem(item) ) return false;
2208			
2209			item.id = item.id.substring(2); // remove "id" symbols
2210			
2211			if ( !isNaN(item.id-0) ) { // if is numeric - its existing category, else - new
2212				
2213				item.id = 'id' + item.id;
2214				
2215				//if ( item.title == mwData.Categories[item.id].title && item.comment == mwData.Categories[item.id].comment && item.is_news == mwData.Categories[item.id].is_news ) {
2216					
2217				//	if ( mwCategoryEd.updateCategories[item.id] ) delete mwCategoryEd.updateCategories[item.id]; // if category changed back on default - remove it from update list
2218					
2219				//} else {
2220					
2221					mwCategoryEd.updateCategories[item.id] = item;
2222					
2223				//}
2224				
2225			} else {
2226				
2227				item.id = 'ne' + item.id;
2228				if ( mwCategoryEd.newCategories[item.id] ) // protection from click on droping new category
2229					mwCategoryEd.newCategories[item.id] = item;
2230				
2231			}
2232			
2233			jQuery(mwCategoryEd.LastItem).find('span').html(item.title);
2234			
2235		}
2236		
2237		return true;
2238		
2239	}, //FUNC saveItem
2240	
2241	validateItem	: function(item) {
2242		
2243		var is_valid = true;
2244		
2245		if ( item.title.length == 0 ) {
2246			
2247			is_valid = false;
2248			mwState(mwError('Title is required'), 'wManageCategories');
2249			
2250		} else {
2251			
2252			var items = jQuery.extend( {}, mwData.Categories, mwCategoryEd.updateCategories )
2253			
2254			mwCategoryEd.deleteCategories.forEach( function(value) { delete items[value]; } );
2255			
2256			delete items[item.id];
2257			
2258			for ( var $i in items )
2259				if ( items[$i].title == item.title ) {
2260					
2261					is_valid = false;
2262					mwState(mwError('Title already exist'), 'wManageCategories');
2263					
2264				}
2265		}
2266		
2267		if ( is_valid ) {
2268			
2269			mwState(false, 'wManageCategories');
2270			jQuery('#saveCategory_form .name-title').removeClass('error');
2271			
2272		} else {
2273			
2274			jQuery('#saveCategory_form .name-title').addClass('error');
2275			
2276		}
2277		
2278		return is_valid;
2279		
2280	}, //FUNC validateItem
2281	
2282	deleteItem	: function( event, ui ) {
2283		
2284		var el = jQuery(ui.draggable);
2285		
2286		var del_item = function(item) { // take jQuery wrapped item
2287			
2288			var id = item.attr('id');
2289			
2290			id = id.substring(2); // remove "id" symbols
2291			
2292			if ( !isNaN(id-0) ) { // if ID numeric - its existing category, else - new
2293				
2294				id = 'id' + id;
2295				delete mwCategoryEd.updateCategories[id]; // no need update category before delete it
2296				mwCategoryEd.deleteCategories.push( id );
2297				
2298			} else { // new category
2299				
2300				id = 'ne' + id;
2301				delete mwCategoryEd.newCategories[id];	
2302				
2303			}
2304			
2305		};
2306		
2307		mwConfirmation(
2308		
2309			function() {
2310				
2311				if ( el.attr('id') == mwCategoryEd.ID ) { // if delete selected item disable validation and hide inputs
2312					
2313					mwCategoryEd.ID = 0;
2314					mwCategoryEd.form.fadeOut('fast');
2315				
2316				}
2317				
2318				del_item(el);
2319				
2320				el.find('li[id]').each( function() {
2321				
2322					del_item(jQuery(this)); // delete all childrens
2323					 
2324				} );
2325				
2326				mwWindow('systemConfirmation').hide();
2327				el.remove();
2328				
2329				if( jQuery('.categories_list li').size() == 0)
2330					mwCategoryEd.listContainer.addClass('winBgHint');
2331				
2332			},
2333			'Delete Category "' + el.find('span').html() + '" and all child categories?'
2334			
2335		);
2336	}, //FUNC deleteItem
2337	
2338	addItem	: function() {
2339		
2340		mwCategoryEd.NewCounter += 1;
2341		
2342		jQuery('.categories_list #no_items').slideUp();
2343		
2344		var item = jQuery.extend(true, {}, mwCategoryEd.Defaults)
2345		//jQuery.extend(item, mwCategoryEd.Defaults);
2346		item.id = 'new' + mwCategoryEd.NewCounter;
2347		
2348		var el = mwCategoryEd.listContainer.find('.ui-draggable-new-category');
2349		el.removeClass('ui-draggable-new-category')
2350			.addClass('draggable_item')
2351			.attr('id', item.id);
2352		
2353		el = el.find('a')
2354			.click( function() { mwCategoryEd.editItem(item.id, el); } )
2355		;
2356		
2357		el.find('span').html(item.title);
2358		
2359		mwCategoryEd.newCategories[item.id] = item;
2360		
2361		el.click();
2362		
2363	}, //FUNC addItem
2364	
2365	buildCategoriesList	: function () {
2366		
2367		var html = '<div class="winSideTabs winContent thinpads categories_list">';
2368		html += '<ul class="ui-sortable-categories-list">';
2369		
2370		for ( var $i in mwData.Categories ) {
2371			
2372			var item = mwData.Categories[$i];
2373			html += '<li id="' + item.id + '" class="newItem draggable_item" title="' + item.comment + '">';
2374			html += '<a onclick="mwCategoryEd.editItem(\'' + item.id + '\', this);"><span class="Title">' + item.title + '</span></a>';
2375			html += '</li>';
2376			
2377		}
2378		
2379		html += '</ul>';
2380		html += '</div>';
2381		mwCategoryEd.listContainer.html(html);
2382			
2383	}, //FUNC buildCategoriesList
2384	
2385	buildCategoriesTree	: function () {
2386		
2387		var build_childrens = function (id) {
2388			
2389			var html = '';
2390			
2391			for ( var $i in mwData.Categories )
2392				if ( mwData.Categories[$i].parent_id == id ) {
2393					
2394					var item = mwData.Categories[$i];
2395					html += '<li id="' + item.id + '" class="newItem draggable_item dragItem">';
2396					html += '<a onclick="mwCategoryEd.editItem(\'' + item.id + '\', this);"><span class="Title">' + item.title + '</span></a>';
2397					html += build_childrens(item.id);
2398					html += '</li>';
2399					
2400				}
2401			
2402			if ( html != '' ) html = '<ul>' + html + '</ul>';
2403			
2404			return html;
2405			
2406		}
2407		
2408		var html = '<div class="categories_list">';
2409			
2410	 	html_items = build_childrens('id0');
2411	 	//html += '<ul>';
2412	 	//html += '<div id="no_items">No Categories. Drop New Category here.</div>';
2413	 	//___(html_items);
2414	 	if ( html_items == '' )
2415			mwCategoryEd.listContainer.addClass('winBgHint');
2416		else
2417			mwCategoryEd.listContainer.removeClass('winBgHint');
2418	 	
2419	 	if ( html_items == '' )
2420			html += '<ul></ul>';
2421		else
2422			html += html_items;
2423		
2424		//html += '</ul>';
2425		html += '</div>';
2426		mwCategoryEd.listContainer.html(html);
2427		
2428		//jQuery('.categories_list ul:first').append('<div id="no_items">No Categories. Drop New Category here.</div>');
2429		
2430	}, //FUNC buildCategoriesTree
2431	
2432	doCategoriesMainFilter	: function () {
2433		
2434		var html = '<option value="0">
2434Filter</option>';
2435		html += '<option value="-1">no category</option>';
2436		for ( var $i in mwData.Categories ) {
2437			
2438			html +='<option ';
2439			html += 'value="' + mwData.Categories[$i].id + '">' + mwData.Categories[$i].title + '</option>'
2440			
2441			
2442			
2443		}
2444		
2445		var sel = jQuery('#categories_filter');
2446		
2447		sel.html(html);
2448		
2449		//get select parent
2450		var parent = sel.parent()
2451		
2452		//check is parent already generated select (skip this on page init)
2453		if ( parent.hasClass('mwDskSelect') ) {
2454			
2455			//move select to main panel
2456			parent.before(sel);
2457			
2458			//delete old one
2459			parent.remove();
2460			
2461			//regenerate it
2462			mwDskControls.Types['SELECT'](sel);
2463			
2464			//show generated select
2465			jQuery('.mwDskSelect .New').show();
2466			
2467		}
2468		
2469		sel.change(
2470			function(event) {
2471				
2472				var categoryID = jQuery(this).val();
2473				
2474				if ( categoryID.length > 2 )
2475					categoryID = categoryID.substring(2); // remove "id" symbols
2476				
2477				if ( typeof mwData.AjaxFilter !== "undefined" ) {
2478					
2479					mwCategoryEd.doAjaxFilter(categoryID);
2480					
2481				} else {
2482					
2483					if ( categoryID != 0 ) {
2484						
2485						jQuery('.tr_post').hide(); 
2486						jQuery( '.category' + categoryID ).show();
2487						
2488						if ( categoryID == -1 ) jQuery( '[class="tr_post "]' ).show();
2489						
2490					} else {
2491						
2492						jQuery('.tr_post').show();
2493						
2494					}
2495				}
2496			}
2497		);
2498			
2499	}, //FUNC doCategoriesMainFilter
2500	
2501	doAjaxFilter	: function (category_id) {
2502	
2503		//___('doAjaxFilter', category_id);
2504		var temp_posts = mwData.Posts;
2505		delete mwData.Posts;
2506		
2507		mwAjax('/site/ajax/blogs/index', { 'filter_by_category_id' : category_id })
2508			.go()
2509			.success( function($data) {
2510				
2511				mwPostEd.manualOrder_sort();
2512				delete temp_posts;
2513				
2514			} )
2515			.error( function() {
2516				
2517				mwData.Posts = temp_posts;
2518				
2519			} )
2520		; // mwAjax
2521			
2522	}, //FUNC doAjaxFilter
2523	
2524	getCurrentFilterCategoryID	: function () {
2525		
2526		if ( typeof(mwLiveEd) != 'undefined' ) return 0;
2527		
2528		var categoryID = jQuery('#categories_filter').val();
2529		
2530		if ( categoryID && categoryID.length > 2 )
2531			categoryID = categoryID.substring(2); // remove "id" symbols
2532
2533		return categoryID;
2534		
2535	}, //FUNC getCurrentFilterCategoryID
2536	
2537	doDraggableItems	: function () {
2538		
2539		jQuery('.categories_list>ul').nestedSortable( {
2540			
2541			listType		: 'ul',
2542			items			: 'li',
2543			handle			: 'a',
2544
2545			toleranceElement	: '> a',
2546			tolerance		: 'pointer',
2547			tabSize			: 20,
2548
2549			maxLevels		: 0,
2550			disableNesting		: 'no-childs',
2551			
2552			opacity			: 0.5,
2553
2554			forceHelperSize		: true,
2555			forcePlaceholderSize	: true,
2556			placeholder		: 'Placeholder',
2557			errorClass		: 'PlaceholderErr',
2558			
2559			receive			: function( event, ui ) { mwCategoryEd.addItem(); },
2560			update			: function(event, ui) { mwCategoryEd.isSorted = true; },
2561			
2562		} );
2563		
2564		
2565		jQuery('.ui-draggable-new-category').draggable( {
2566			
2567			connectToSortable	: '.categories_list>ul',
2568			helper			: 'clone',
2569			
2570		} )
2571		.disableSelection();
2572		
2573		jQuery('.cat_recycle_droppable' ).droppable( {
2574			
2575			activeClass	: "dragHover",
2576			hoverClass	: "drag",
2577			tolerance	: "pointer",
2578			drop		: mwCategoryEd.deleteItem,
2579			accept		: ".draggable_item",
2580			
2581		} );
2582			
2583	}, //FUNC doDraggableItems
2584	
2585	// input		- jQuery wrapped input for event
2586	// elements		- jQuery wrapped list of elements (for show/hide)
2587	// searchSelector	- jQuery selector for serch into elements filtered text
2588	
2589	doFilterCategories	: function ( input, elements, searchSelector ) {
2590		
2591		input.keyup( function(event) {
2592			
2593			var input = jQuery(this);
2594			
2595			elements.hide().each( function() {
2596				
2597				$this = jQuery(this);
2598				
2599				var reg = new RegExp(input.val(), "gi");
2600				
2601				if ( reg.test($this.find(searchSelector).html()) )
2602					$this.show();
2603					
2604			} )
2605			
2606		} );
2607		
2608	}, //FUNC doFilterCategories
2609	
2610	doFilterCategoriesTree	: function ( input, elements, searchSelector ) {
2611		
2612		input.keyup( function(event) {
2613			
2614			var input = jQuery(this);
2615			
2616			elements.hide().each( function() {
2617				
2618				$this = jQuery(this);
2619				
2620				var reg = new RegExp(input.val(), "gi");
2621				
2622				if ( reg.test($this.find(searchSelector).html()) ) {
2623					
2624					$this.show().parents().filter( function(index) {
2625						
2626						var res = false;
2627						if( jQuery.inArray(this, elements) >= 0 ) res = true; // if in elements list - no need remove
2628						
2629						return res;
2630						
2631					} ).show();
2632				}
2633			} )
2634		} );
2635		
2636	}, //FUNC doFilterCategoriesTree
2637	
2638}; //OBJECT mwCategoryEd
2639
2640var mwBlogsOptionsEd = {
2641	
2642	ID	: 1,	// blog id (future options - possibility save more then 1 blog options)
2643	init	: function() {
2644		
2645	}, //FUNC init
2646	
2647	edit	: function (id) {
2648		
2649		this.ID = id;
2650		var page = mwData.BlogsOptions[id];
2651		if ( !page ) return false;
2652		
2653		page = mwBlogsOptionsEd.add_default_soc_page(page);
2654		
2655		// Resetting form
2656		jQuery('#mwBlogsOptions_form').fromArray(page);
2657		
2658		if ( !this.soc_inited ) {
2659			
2660			this.soc_inited = true;
2661			mwSocials().initConnectButtons(jQuery('#mwBlogsOptions_form tr td div[rel]'));
2662			
2663		}
2664		
2665		mwWindow('wBlogsOptions').Title('Blog Options <span>' + '' + '</span>').show(
2666			
2667			function() {}
2668			
2669		); // mwWindow
2670		
2671		//mwWindow().align()
2672		
2673		return false;
2674		
2675	}, //FUNC edit
2676	
2677	save	: function () {
2678		
2679		mwAjax('/site/ajax/blogs/saveBlogsOptionsDB', '#mwBlogsOptions_form', 'wBlogsOptions')
2680			.index()
2681			.success( function($data) {
2682				
2683				mwPostEd.manualOrder_sort();
2684				
2685			} )
2686		; // mwAjax
2687
2688	}, //FUNC save
2689	
2690	add_default_soc_page : function(page) {
2691		
2692		for (key in mwData.BlogsOptions[1]['publish_socials'])
2693			page['publish_' + key] = mwData.BlogsOptions[1]['publish_socials'][key];
2694		
2695		return page;
2696		
2697	}, //FUNC add_default_soc_page
2698	
2699} // CLASS mwBlogsOptionsEd
2700
2701var mwBlogsAjaxUpload = {
2702	
2703	uploading_doing	: false,
2704	
2705	slideDownSpeed	: 500,
2706	
2707	init		: function(posts_data, type) {
2708		
2709	//	__(type);
2710	//	__(posts_data);
2711		
2712		this.posts_data = posts_data;
2713		
2714		this.uploading_doing = false;
2715		this.load_pos = jQuery("#blogs_posts_list_ajax_position_" + this.posts_data.ID);
2716		this.loader = jQuery("#blogs_list_loader_" + this.posts_data.ID);
2717		
2718		if ( type == 1 ) this.doScrollAjax();
2719		if ( type == 2 ) this.doClickAjax();
2720		
2721	},
2722	
2723	doLoad		: function() {
2724	//	___('posts loading');
2725	//	___(this);
2726		
2727		if ( ! this.uploading_doing && this.posts_data.posts_limit > this.posts_data.posts_counter ) {
2728			
2729			this.uploading_doing = true;
2730			//___('indexAjax', this.posts_data);
2731			mwAjax("/ajax/blogs/indexAjax", this.posts_data)
2732			.start( function () {
2733				mwBlogsAjaxUpload.loader.slideDown();
2734			}) //FUNC mwAjax.success.callback
2735			.stop( function () {
2736			//	mwBlogsAjaxUpload.uploading_doing = false;
2737				setTimeout(function() { mwBlogsAjaxUpload.loader.slideUp(); }, 2000);
2738			}) //FUNC mwAjax.success.callback
2739			.success( function($data) {
2740					
2741					//__($data);
2742					if ( typeof $data.content !== "undefined" ) {
2743						
2744						if ( $data.content.length > 0 ) {
2745							
2746							//setTimeout(function() { mwBlogsAjaxUpload.loader.slideUp(); }, 3000);
2747							
2748							jQuery("<div>" + $data.content + "</div>")
2749								.hide().insertBefore(mwBlogsAjaxUpload.load_pos)
2750								.delay(2000)
2751								.slideDown(mwBlogsAjaxUpload.posts_data.posts_per_once * mwBlogsAjaxUpload.slideDownSpeed, function() {
2752									
2753									mwBlogsAjaxUpload.uploading_doing = false;
2754									jQuery(window).scroll();
2755									
2756								});
2757							
2758							mwBlogsAjaxUpload.posts_data.posts_counter = mwBlogsAjaxUpload.posts_data.posts_counter + mwBlogsAjaxUpload.posts_data.posts_per_once;
2759							
2760						}
2761					}
2762				}
2763			)
2764			.go();
2765			
2766		} else {
2767			
2768			mwBlogsAjaxUpload.uploading_doing = true; // stop uploading if there no more to upload
2769			 
2770		}		
2771	},						
2772	
2773	doScrollAjax	: function() {
2774
2775		jQuery(window).scroll(
2776			function(event) {
2777				
2778				var block = jQuery(".blogs_posts_list_ajax_position").parent();
2779				//___(1, block.offset().top + block.height(), jQuery(window).scrollTop() + jQuery(window).height());
2780				//___(2, jQuery(window).scrollTop() + jQuery(window).height() - block.offset().top - block.height(), jQuery(window).height());
2781				//___('doScrollAjax - block', block);
2782				//if ( jQuery(document).height() - jQuery(window).height() <= jQuery(window).scrollTop() + 250 ) {
2783				if ( block.offset().top + block.height() < jQuery(window).scrollTop() + jQuery(window).height()
2784					&& jQuery(window).scrollTop() + jQuery(window).height() - block.offset().top - block.height() < jQuery(window).height() ) {	
2785					
2786					mwBlogsAjaxUpload.doLoad();
2787					
2788				}
2789				
2790			}
2791		);
2792	},
2793	
2794	doClickAjax	: function() {
2795		
2796		this.load_pos.after('<div class="blogs-show-more" onclick="mwBlogsAjaxUpload.doLoad();">Show More</div>');
2797		
2798	},
2799	
2800} //OBJECT mwBlogsAjaxUpload
2801
2802mwTextLengthCounter = function(input, display){
2803	
2804	//counter object
2805	var counter = {
2806		
2807		min		: 10, //allowed text length minimum
2808		max		: 60, //allowed text length maximum
2809		input		: {}, //jQuery object of input to track text length
2810		display		: {}, //jQuery object of some element to display text length
2811		
2812		init		: function(input, display) {
2813			
2814			var $this = this;
2815			
2816			//expecting selector or jquery element
2817			$this.input = jQuery(input);
2818			
2819			//expecting selector or jquery element
2820			$this.display = jQuery(display); 
2821			
2822			$this.input.keyup(function(){
2823				
2824				var l = $this.input.val().length;
2825				var html = l;
2826				
2827				//length less minimum
2828				if ( l < $this.min ) {
2829					
2830					$this.display.addClass('counter-red');
2831					html += ' (+' + ($this.min - l) + ')';
2832					
2833				}//length more maximum
2834				else if ( l > $this.max ) {
2835					
2836					$this.display.addClass('counter-red');
2837					html += ' (-' + (l - $this.max) + ')';
2838					
2839				}//length match
2840				else {
2841					
2842					$this.display.removeClass('counter-red');
2843					
2844				}//length match range
2845				
2846				$this.display.html(html);
2847				
2848			});
2849			
2850		}, //FUNC init
2851		
2852		reset		: function() {
2853			
2854			var $this = this;
2855			
2856			$this.input.keyup();
2857			
2858		}, //FUNC reset
2859		
2860	}//counter object
2861	
2862	counter.init(input, display);
2863	
2864	//return initialized object
2865	return counter;
2866	
2867}//mwTextLengthCounter
2868
2869jQuery( function () {
2870	
2871	//special function to overwrite in templates
2872	if ( typeof onBlogsPostAliasUpdate == 'undefined' ) onBlogsPostAliasUpdate = function(alias) {};
2873	
2874	if ( typeof mwData != "undefined" ) {
2875		
2876		//mwPostEd.init();
2877		mwCategoryEd.init();
2878		mwPostEd.manualOrderInit();
2879		
2880		//jQuery('#mwPostEd_form #published_date').datepicker();
2881		
2882	}
2883	//load without liveEd
2884	else {
2885		
2886		//prepare socials variable - its only stored once
2887		var socials = '';
2888		var soc_template = '';
2889		
2890		//load on scroll add
2891		if ( jQuery('.update-alias-on-scroll-bot').length > 0 ) {
2892			
2893			var update_alias = function(alias, title) {
2894				//___('alias', alias);
2895				//___('title', title);
2896				var path = location.pathname.split('/');
2897				//___(path);
2898				var url = location.origin;
2899				var current_alias = path[path.length - 1];
2900				//___('current_alias', current_alias);
2901				//update only if current alias is different
2902				if ( current_alias != alias ) {
2903					
2904					for ( var i in path ) {
2905						
2906						if ( path[i] && i < path.length - 1 ) url += '/' + path[i];
2907						
2908					}
2909					
2910					url += '/' + alias;
2911					
2912					//___(url);
2913					//___('update alias', url, alias);
2914					window.history.pushState( title, title, url );
2915					
2916					//call event-function for templates usage
2917					onBlogsPostAliasUpdate(alias);
2918					
2919				}
2920			};
2921			
2922			//special flag to prevent loads while load is on run
2923			var load_in_process = false;
2924			
2925			//loop reload waupoints on timer
2926			var loop_waypoints = function() {
2927				
2928				Waypoint.refreshAll();
2929				setTimeout(loop_waypoints, 1000);
2930				
2931			}
2932			loop_waypoints();
2933			
2934			var addLoadNewPostOnScroll = function(load_el_old) {
2935				
2936				//do nothing if load already on process
2937				if ( load_in_process ) return;
2938				___('run load');
2939				
2940				//set the load process flag
2941				load_in_process = true;
2942				
2943				var load_id = load_el_old.attr('post-id');
2944				var template = load_el_old.attr('post-template');
2945				var categories = JSON.parse(load_el_old.attr('post-categories'));
2946				var order = load_el_old.attr('post-order');
2947				
2948				if ( !socials ) socials = load_el_old.attr('post-socials-list');
2949				if ( !soc_template ) soc_template = load_el_old.attr('post-socials-template');
2950				
2951				mwAjax(
2952					'/ajax/blogs/renderPost/',
2953					{ 	'postID': load_id,
2954						'template': template, 
2955						'PostsCategoriesList': categories, 
2956						'PostsOrder': order, 
2957						'SocialsList': socials, 
2958						'SocialsTemplate' : soc_template
2959					})
2960					.go()
2961					.success( function(response) {
2962						
2963						___('next post load response', response);
2964						
2965						var PostData = response.content.PostData;
2966						
2967						//add new post content
2968						load_el_old.after(response.content.html);
2969						
2970						//no need to load again
2971						load_el_old.attr('post-do-load', 'no');
2972						
2973						//add waypoints
2974						addWaypoints();
2975						
2976						//set the load process flag
2977						load_in_process = false;
2978						
2979					});
2980				
2981			}; //FUNC addLoadNewPostOnScroll
2982			
2983			var addWaypoints = function() {
2984				
2985				jQuery('.update-alias-on-scroll-bot')
2986					.waypoint({
2987						handler: function(direction) {
2988						
2989							var el = jQuery(this.element);
2990							//___(el);
2991							___('scroll: ' + this.triggerPoint + ', direction: ' + direction);
2992							
2993							if (el.attr('post-do-load') == 'yes') {
2994								___('load', el.attr('post-alias'), el);
2995								addLoadNewPostOnScroll(el);
2996								
2997							}
2998							
2999						},
3000						offset: '100%'
3001					});
3002				
3003				jQuery('.update-alias-on-scroll-bot')
3004					.removeClass('update-alias-on-scroll-bot')
3005					.addClass('update-alias-on-scroll-bot-updated')
3006					.waypoint({
3007						handler: function(direction) {
3008						
3009							var el = jQuery(this.element);
3010							
3011							//update alias for current post
3012							if ( direction == 'down' ) {
3013								___('down', el.attr('post-alias'), el);
3014								update_alias(el.attr('post-alias'), el.attr('post-title'));
3015								
3016							}
3017							
3018						},
3019						offset: '100%'
3020					});
3021				
3022				jQuery('.update-alias-on-scroll-up')
3023					.removeClass('update-alias-on-scroll-up')
3024					.addClass('update-alias-on-scroll-up-updated')
3025					.waypoint({
3026						handler: function(direction) {
3027						
3028							var el = jQuery(this.element);
3029							
3030							//update alias for current post
3031							if ( direction == 'up' ) {
3032								___('up', el.attr('post-alias'), el);
3033								update_alias(el.attr('post-alias'), el.attr('post-title'));
3034								
3035							}
3036							
3037						},
3038						offset: '100%'
3039					});
3040				
3041			};
3042			
3043			addWaypoints();
3044			
3045		}
3046	}
3047	
3048});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.