<commit_before>var WPPresentAdmin;
(function($) {

	WPPresentAdmin = function() {
		this.init();
		return this;
	}

	WPPresentAdmin.prototype = {
		init: function() {
			var self = this;

			// Make the outer container resizeable
			$( "#outer-container" ).resizable();

			$( "#container" ).sortable({
				stop: function( event, ui ) {
					self.updateTaxonomyDescription();
				}
			});

			$( ".column-inner" ).sortable({
				connectWith: ".column-inner",
				stop: function( event, ui ) {
					self.updateTaxonomyDescription();
				}
			});

			self.widgetButtonExpand();
			self.widgetButtonEdit();
			self.widgetButtonDelete();
			self.widgetButtonAdd();
			self.widgetButtonTidy();
			self.bindButtonAddColumn();
			self.bindButtonViewPresentation();
			self.backfillColumns();
			self.refreshUI();

			// Select the first column on load
			self.activateColumn( $('#col-1').children('.widget-top').children('.widget-title') );

			$('.spinner').hide();

			return self;
		},

		/**
		 * Sortables and such
		 */
		refreshUI: function () {
			var self = this;

			$( "#container" ).sortable("refresh");

			// Append an inner column to each column that doesn't contain any slides.
			$('.column' ).not(":has(div.column-inner)").append('

');

			// This is a little bit of hackery.  It would be nice if the sortable("refresh") method worked here.
			// TODO: Investigate hackery
			if ($( '.column-inner' ).data( 'sortable' )) {
				$( ".column-inner" ).sortable("refresh");
			} else {
				$( ".column-inner" ).sortable({
					connectWith: ".column-inner",
					stop: function( event, ui ) {
						self.updateTaxonomyDescription();
					}
				});
			}

			// This really should be called only once inside init
			self.enableColumns();
		},

		/**
		 * Backfill Columns
		 */
		backfillColumns: function () {
			var self = this;
			var numSlides = WPPNumSlides[0];
			var numExisting = $('#container > .column').size();

			for (var col=numExisting+1;col<=numSlides;col++){
				self.addColumn();
			}
			//$('#container').append( '

' );
		},

		/**
		 * Make the column the target for adding new columns
		 */
		activateColumn: function ( $col ) {
			// TODO: cache widget-title
			// Remove the active class from all columns
			$widgetTitle = $('.widget-title');
			$widgetTitle.css({"background":"","color":""});
			$widgetTitle.removeClass('active');

			// Select the given column
			$col.css('background-color', '#0074a2').css('color','#ffffff');
			$col.addClass('active');
		},

		/**
		 * Encode,update, and save the columns data into the hidden taxonomy description field
		 */
		updateTaxonomyDescription: function () {
			var self = this;
			var columns = { }; // Creates a new object
			var i = 1;
			$( '.column-inner' ).each(function( index ) {
				var $order = $(this).sortable( "toArray" );
				columns['col-'+i] = $order;
				i++;
			});
			var encoded = JSON.stringify( columns );
			$('#description').val(encoded);

			// This was a convient time to do this UI clean-up
			self.renumberColumns();

			// Send this change off to ajax land
			self.updatePresentation();
		},

		/**
		 * AJAX request to update the current presentation taxonomy
		 */
		updatePresentation: function () {
			var nonce = $('#wp-present-nonce').val();
			var params = { 'content':$('#description').val(), 'id':presentation, 'nonce':nonce };
			$.ajax({
				url: ajaxurl + '?action=update_presentation',
				type: 'POST',
				data: jQuery.param(params),
				beforeSend: function( xhr ) {
					$('.spinner').show();
				},
				complete: function( xhr ) {
					//$('.spinner').hide();
				},
				success: function(result) {
					$('.spinner').hide();
					// Return the excerpt from the editor
					//console.log('presentation updated');
				}
			});
		},

		/**
		 * Bind Tidy button
		 */
		widgetButtonTidy: function () {
			var self = this;
			$('.action-buttons').on('click', '#tidy-button', function(e) {
				e.preventDefault();
				this.consolidateColumns();
				// Why does this break?
				//updatePresentation();
			});
		},

		/**
		 * Expand slide details
		 */
		widgetButtonExpand: function () {
			$('#container').on('click', '.widget-title-action', function(e) {
				$( this ).parents('.widget').children('.widget-inside').toggle();
			});
		},

		/**
		 * The action taken by the Tidy button
		 */
		consolidateColumns: function () {
			var self = this;
			var numCols = $('.column').length;
			// console.log(numCols);

			$('.column').each(function(outerIndex){

				// Don't have a col 0
				var outerIndex = outerIndex + 1;

				// Fixes the condition where we are looking at the last item
				if( outerIndex >= numCols )
					return;

				var $outerCol = $(this);
				var $innerCol = $outerCol.children('.column-inner');

				var innerHTML = $innerCol.html().trim();
				var outerHTML = $outerCol.html().trim();

				if( typeof(innerHTML) !== 'string' || '' == innerHTML ) {
					var $nextOuterCol = $('#col-'+(outerIndex+1));
					var $nextInnerCol = $nextOuterCol.children('.column-inner');

					var nextInnerHTML = $nextInnerCol.html().trim();
					var nextOuterHTML = $nextOuterCol.html().trim();

					$outerCol.html(nextOuterHTML);
					$nextOuterCol.html(outerHTML);
				}
			} );

			//Finally refresh description array
			$( ".column-inner" ).sortable({
				connectWith: ".column-inner",
				stop: (function( event, ui ) {
					self.updateTaxonomyDescription();
				}),
				create: (function( event, ui ) {
					self.updateTaxonomyDescription();
				})
			});
			self.updateTaxonomyDescription();
		},

		/**
		 * Setup the column to allow for activation
		 */
		enableColumns: function () {
			var self = this;
			$('.column').children('.widget-top').on('click', '.widget-title', function(e) {
				$col = $(this);
				self.activateColumn($col);
			});
		},

		// Bind Edit button
		widgetButtonEdit: function () {
			var self = this;
			$('#container').on('click', '.widget-control-edit', function(e) {
				e.preventDefault();
				var $button = $(this);
				var $parentWidget = $button.parents('.widget');
				var $widgetPreview = $parentWidget.find('.widget-preview');

				// Send the contents from the widget to the editor
				var contentEditor  = $widgetPreview.html();
				var widgetID = $parentWidget.find('.slide-id').val();
				var nonce = $('#wp-present-nonce').val();

				$('#editor_slide-tmce').click(); //Necessary on subsequent loads of the editor
				$( "#dialog" ).dialog({
				  autoOpen: true,
				  width: 640,
				  height: 640,
				  modal: false,
				  buttons: {
					"Update": function() {
						var editorContents = tinymce.get('editor_slide').getContent();
						var params = { 'content':editorContents, 'id':widgetID, 'nonce':nonce };
						// Send the contents of the existing post
						$.ajax({
							url: ajaxurl + '?action=update_slide',
							type: 'POST',
							data: jQuery.param(params),
							beforeSend: function( xhr ) {
								$('.spinner').show();
							},
							complete: function( xhr ) {
								//$('.spinner').hide();
							},
							success: function(result) {
								$('.spinner').hide();
								// Return the excerpt from the editor
								$widgetPreview.html( result );
						  }
						});
						self.closeModal();
					},
					Cancel: function() {
						self.closeModal();
					}
				  },
				  create: function() {
						tinymce.execCommand('mceRemoveControl',true,'editor_slide');
						tinymce.execCommand('mceAddControl',true,'editor_slide');
				  },
				  open: function() {
						// Load the contents of the existing post
						var nonce = $('#wp-present-nonce').val();
						var params = { 'id':widgetID, 'nonce':nonce };
						$.ajax({
							url: ajaxurl + '?action=get_slide',
							data: jQuery.param(params),
							beforeSend: function( xhr ) {
								$('.spinner').show();
							},
							complete: function( xhr ) {
								$('.spinner').hide();
							},
							success: function(contentEditor) {
								tinymce.get('editor_slide').setContent(contentEditor);
							}
						});

						// Hack for getting the reveal class added to tinymce editor body
						// @todo: look at wp_editor in wp/inc/class-wp-editor.php
						var $editorIframe = $('#editor_slide_ifr').contents();
						$editorIframe.find('body').addClass('reveal');
						$editorIframe.css('height','500px');

				  },
				  close: function() {
						self.closeModal();
				  }
				});
			});
		},

		// Bind Delete button
		widgetButtonDelete: function () {
			var self = this;
			$('#container').on('click', '.widget-control-remove', function(e) {
				e.preventDefault();

				var confirmDelete = confirm("You are about to permanently delete the selected slide. 'Cancel' to stop, 'OK' to delete.");
				if( false == confirmDelete )
					return;

				var $button = $(this);
				var $parentWidget = $button.parents('.widget');
				var widgetID = $parentWidget.find('.slide-id').val();
				var nonce = $('#wp-present-nonce').val();
				var params = { 'id':widgetID, 'nonce':nonce };

				$.ajax({
					url: ajaxurl + '?action=delete_slide',
					type: 'POST',
					data: jQuery.param(params),
					beforeSend: function( xhr ) {
						$('.spinner').show();
					},
					complete: function( xhr ) {
						//$('.spinner').hide();
					},
					success: function(result) {
						$('.spinner').hide();
						$parentWidget.remove();
						self.updateTaxonomyDescription();
					}
				});
			});
		},

		// Bind Add button
		widgetButtonAdd: function () {
			var self = this;
			$('.action-buttons').on('click', '#add-button', function(e) {
				e.preventDefault();
				var $button = $(this);
				var $activeColumn = $('.widget-title.active').parent('.widget-top').parent('.column').children('.column-inner');

				$('#editor_slide-tmce').click(); //Necessary on subsequent loads of the editor
				$( "#dialog" ).dialog({
				  autoOpen: true,
				  width: 600,
				  height: 600,
				  modal: false,
				  buttons: {
					"Publish": function() {
						var editorContents = tinymce.get('editor_slide').getContent();
						var nonce = $('#wp-present-nonce').val();
						var params = { content:editorContents,'presentation':presentation, 'nonce':nonce };
						// Send the contents of the existing post
						$.ajax({
							url: ajaxurl + '?action=new_slide',
							type: 'POST',
							data: jQuery.param(params),
							success: function(result) {
								$activeColumn.append(result);
								WPPNumSlides[0]++;
								self.addColumn();
								self.refreshUI();
								self.updateTaxonomyDescription();
						  }
						});
						self.closeModal();
					},
					Cancel: function() {
						self.closeModal();
					}
				  },
				  create: function() {
						tinymce.execCommand('mceRemoveControl',true,'editor_slide');
						tinymce.execCommand('mceAddControl',true,'editor_slide');
				  },
				  open: function() {
						// Clear the editor
						tinymce.get('editor_slide').setContent('');
						// Hack for getting the reveal class added to tinymce editor body
						var $editorIframe = $('#editor_slide_ifr').contents();
						$editorIframe.find('body').addClass('reveal');
				  },
				  close: function() {
						self.closeModal();
				  }
				});
			});
		},

		// Adds a column to the presentation
		addColumn: function () {
			var self = this;
			var col = $('#container > .column').size() + 1;

			$('#container').append( '

'+col+'

' );
			$('#container').width( $('#container').width() + 210 );
		},

		//Bind Add Column button to addColumn()
		bindButtonAddColumn: function () {
			var self = this;
			$('.action-buttons').on('click', '#add-column', function(e) {
				e.preventDefault();
				self.addColumn();
				self.refreshUI();
			});
		},

		//Bind View Presentation button
		bindButtonViewPresentation: function () {
			var self = this;
			$('.action-buttons').on('click', '#view-button', function(e) {
				e.preventDefault();
				window.open(WPPTaxonomyURL,'_blank');
			});
		},

		renumberColumns: function() {
			var i = 1;
			$( '.column' ).each(function( index ) {
				 var self = this;
				 var $self = $(this);
				 $self.find('> .widget-top > .widget-title > h4').html( i );
				i++;
			});
		},

		/**
		 * Close Modal
		 */
		closeModal: function() {
			tinymce.execCommand('mceRemoveControl',true,'editor_slide');
			$( '#dialog' ).dialog( "close" );
		}

	};

})(jQuery);
var slideManager = new WPPresentAdmin();<commit_msg>Updates comments<commit_after>var WPPresentAdmin;
(function($) {

	WPPresentAdmin = function() {
		this.init();
		return this;
	}

	WPPresentAdmin.prototype = {
		init: function() {
			var self = this;

			$( "#outer-container" ).resizable();

			$( "#container" ).sortable({
				stop: function( event, ui ) {
					self.updateTaxonomyDescription();
				}
			});

			$( ".column-inner" ).sortable({
				connectWith: ".column-inner",
				stop: function( event, ui ) {
					self.updateTaxonomyDescription();
				}
			});

			self.widgetButtonExpand();
			self.widgetButtonEdit();
			self.widgetButtonDelete();
			self.widgetButtonAdd();
			self.widgetButtonTidy();
			self.bindButtonAddColumn();
			self.bindButtonViewPresentation();
			self.backfillColumns();
			self.refreshUI();

			// Select the first column on load
			self.activateColumn( $('#col-1').children('.widget-top').children('.widget-title') );

			$('.spinner').hide();
			return self;
		},

		/**
		 * Sortables and such
		 */
		refreshUI: function () {
			var self = this;

			// Refresh the columns
			$( "#container" ).sortable("refresh");

			// Append an inner column to each column that doesn't contain any slides.
			$('.column' ).not(":has(div.column-inner)").append('

');

			// This is a little bit of hackery.  It would be nice if the sortable("refresh") method worked here.
			// TODO: Investigate hackery
			if ($( '.column-inner' ).data( 'sortable' )) {
				$( ".column-inner" ).sortable("refresh");
			} else {
				$( ".column-inner" ).sortable({
					connectWith: ".column-inner",
					stop: function( event, ui ) {
						self.updateTaxonomyDescription();
					}
				});
			}

			// This really should be called only once inside init
			self.enableColumns();
		},

		/**
		 * Backfill Columns
		 */
		backfillColumns: function () {
			var self = this;
			var numSlides = WPPNumSlides[0];
			var numExisting = $('#container > .column').size();

			for (var col=numExisting+1;col<=numSlides;col++){
				self.addColumn();
			}
			//$('#container').append( '

' );
		},

		/**
		 * Make the column the target for adding new columns
		 */
		activateColumn: function ( $col ) {
			// TODO: cache widget-title
			// Remove the active class from all columns
			$widgetTitle = $('.widget-title');
			$widgetTitle.css({"background":"","color":""});
			$widgetTitle.removeClass('active');

			// Select the given column
			$col.css('background-color', '#0074a2').css('color','#ffffff');
			$col.addClass('active');
		},

		/**
		 * Encode,update, and save the columns data into the hidden taxonomy description field
		 */
		updateTaxonomyDescription: function () {
			var self = this;
			var columns = { }; // Creates a new object
			var i = 1;
			$( '.column-inner' ).each(function( index ) {
				var $order = $(this).sortable( "toArray" );
				columns['col-'+i] = $order;
				i++;
			});
			var encoded = JSON.stringify( columns );
			$('#description').val(encoded);

			// This was a convient time to do this UI clean-up
			self.renumberColumns();

			// Send this change off to ajax land
			self.updatePresentation();
		},

		/**
		 * AJAX request to update the current presentation taxonomy
		 */
		updatePresentation: function () {
			var nonce = $('#wp-present-nonce').val();
			var params = { 'content':$('#description').val(), 'id':presentation, 'nonce':nonce };
			$.ajax({
				url: ajaxurl + '?action=update_presentation',
				type: 'POST',
				data: jQuery.param(params),
				beforeSend: function( xhr ) {
					$('.spinner').show();
				},
				complete: function( xhr ) {
					//$('.spinner').hide();
				},
				success: function(result) {
					$('.spinner').hide();
				}
			});
		},

		/**
		 * Bind Tidy button (unused)
		 */
		widgetButtonTidy: function () {
			var self = this;
			$('.action-buttons').on('click', '#tidy-button', function(e) {
				e.preventDefault();
				this.consolidateColumns();
				// Why does this break?
				//updatePresentation();
			});
		},

		/**
		 * Expand slide details
		 */
		widgetButtonExpand: function () {
			$('#container').on('click', '.widget-title-action', function(e) {
				$( this ).parents('.widget').children('.widget-inside').toggle();
			});
		},

		/**
		 * The action taken by the Tidy button (unused)
		 */
		consolidateColumns: function () {
			var self = this;
			var numCols = $('.column').length;
			// console.log(numCols);

			$('.column').each(function(outerIndex){

				// Don't have a col 0
				var outerIndex = outerIndex + 1;

				// Fixes the condition where we are looking at the last item
				if( outerIndex >= numCols )
					return;

				var $outerCol = $(this);
				var $innerCol = $outerCol.children('.column-inner');

				var innerHTML = $innerCol.html().trim();
				var outerHTML = $outerCol.html().trim();

				if( typeof(innerHTML) !== 'string' || '' == innerHTML ) {
					var $nextOuterCol = $('#col-'+(outerIndex+1));
					var $nextInnerCol = $nextOuterCol.children('.column-inner');

					var nextInnerHTML = $nextInnerCol.html().trim();
					var nextOuterHTML = $nextOuterCol.html().trim();

					$outerCol.html(nextOuterHTML);
					$nextOuterCol.html(outerHTML);
				}
			} );

			//Finally refresh description array
			$( ".column-inner" ).sortable({
				connectWith: ".column-inner",
				stop: (function( event, ui ) {
					self.updateTaxonomyDescription();
				}),
				create: (function( event, ui ) {
					self.updateTaxonomyDescription();
				})
			});
			self.updateTaxonomyDescription();
		},

		/**
		 * Setup the column to allow for activation
		 */
		enableColumns: function () {
			var self = this;
			$('.column').children('.widget-top').on('click', '.widget-title', function(e) {
				$col = $(this);
				self.activateColumn($col);
			});
		},

		/**
		 * Setup the slide 'Edit' links
		 */
		widgetButtonEdit: function () {
			var self = this;
			$('#container').on('click', '.widget-control-edit', function(e) {
				e.preventDefault();
				var $button = $(this);
				var $parentWidget = $button.parents('.widget');
				var $widgetPreview = $parentWidget.find('.widget-preview');

				// Send the contents from the widget to the editor
				var contentEditor  = $widgetPreview.html();
				var widgetID = $parentWidget.find('.slide-id').val();
				var nonce = $('#wp-present-nonce').val();

				$('#editor_slide-tmce').click(); //Necessary on subsequent loads of the editor
				$( "#dialog" ).dialog({
				  autoOpen: true,
				  width: 640,
				  height: 640,
				  modal: false,
				  buttons: {
					"Update": function() {
						var editorContents = tinymce.get('editor_slide').getContent();
						var params = { 'content':editorContents, 'id':widgetID, 'nonce':nonce };
						// Send the contents of the existing post
						$.ajax({
							url: ajaxurl + '?action=update_slide',
							type: 'POST',
							data: jQuery.param(params),
							beforeSend: function( xhr ) {
								$('.spinner').show();
							},
							complete: function( xhr ) {
								//$('.spinner').hide();
							},
							success: function(result) {
								$('.spinner').hide();
								// Return the excerpt from the editor
								$widgetPreview.html( result );
						  }
						});
						self.closeModal();
					},
					Cancel: function() {
						self.closeModal();
					}
				  },
				  create: function() {
						tinymce.execCommand('mceRemoveControl',true,'editor_slide');
						tinymce.execCommand('mceAddControl',true,'editor_slide');
				  },
				  open: function() {
						// Load the contents of the existing post
						var nonce = $('#wp-present-nonce').val();
						var params = { 'id':widgetID, 'nonce':nonce };
						$.ajax({
							url: ajaxurl + '?action=get_slide',
							data: jQuery.param(params),
							beforeSend: function( xhr ) {
								$('.spinner').show();
							},
							complete: function( xhr ) {
								$('.spinner').hide();
							},
							success: function(contentEditor) {
								tinymce.get('editor_slide').setContent(contentEditor);
							}
						});

						// Hack for getting the reveal class added to tinymce editor body
						// @todo: look at wp_editor in wp/inc/class-wp-editor.php
						var $editorIframe = $('#editor_slide_ifr').contents();
						$editorIframe.find('body').addClass('reveal');
						$editorIframe.css('height','500px');

				  },
				  close: function() {
						self.closeModal();
				  }
				});
			});
		},

		// Bind Delete button
		widgetButtonDelete: function () {
			var self = this;
			$('#container').on('click', '.widget-control-remove', function(e) {
				e.preventDefault();

				var confirmDelete = confirm("You are about to permanently delete the selected slide. 'Cancel' to stop, 'OK' to delete.");
				if( false == confirmDelete )
					return;

				var $button = $(this);
				var $parentWidget = $button.parents('.widget');
				var widgetID = $parentWidget.find('.slide-id').val();
				var nonce = $('#wp-present-nonce').val();
				var params = { 'id':widgetID, 'nonce':nonce };

				$.ajax({
					url: ajaxurl + '?action=delete_slide',
					type: 'POST',
					data: jQuery.param(params),
					beforeSend: function( xhr ) {
						$('.spinner').show();
					},
					complete: function( xhr ) {
						//$('.spinner').hide();
					},
					success: function(result) {
						$('.spinner').hide();
						$parentWidget.remove();
						self.updateTaxonomyDescription();
					}
				});
			});
		},

		// Bind Add button
		widgetButtonAdd: function () {
			var self = this;
			$('.action-buttons').on('click', '#add-button', function(e) {
				e.preventDefault();
				var $button = $(this);
				var $activeColumn = $('.widget-title.active').parent('.widget-top').parent('.column').children('.column-inner');

				$('#editor_slide-tmce').click(); //Necessary on subsequent loads of the editor
				$( "#dialog" ).dialog({
				  autoOpen: true,
				  width: 600,
				  height: 600,
				  modal: false,
				  buttons: {
					"Publish": function() {
						var editorContents = tinymce.get('editor_slide').getContent();
						var nonce = $('#wp-present-nonce').val();
						var params = { content:editorContents,'presentation':presentation, 'nonce':nonce };
						// Send the contents of the existing post
						$.ajax({
							url: ajaxurl + '?action=new_slide',
							type: 'POST',
							data: jQuery.param(params),
							success: function(result) {
								$activeColumn.append(result);
								WPPNumSlides[0]++;
								self.addColumn();
								self.refreshUI();
								self.updateTaxonomyDescription();
						  }
						});
						self.closeModal();
					},
					Cancel: function() {
						self.closeModal();
					}
				  },
				  create: function() {
						tinymce.execCommand('mceRemoveControl',true,'editor_slide');
						tinymce.execCommand('mceAddControl',true,'editor_slide');
				  },
				  open: function() {
						// Clear the editor
						tinymce.get('editor_slide').setContent('');
						// Hack for getting the reveal class added to tinymce editor body
						var $editorIframe = $('#editor_slide_ifr').contents();
						$editorIframe.find('body').addClass('reveal');
				  },
				  close: function() {
						self.closeModal();
				  }
				});
			});
		},

		// Adds a column to the presentation
		addColumn: function () {
			var self = this;
			var col = $('#container > .column').size() + 1;

			$('#container').append( '

'+col+'

' );
			$('#container').width( $('#container').width() + 210 );
		},

		//Bind Add Column button to addColumn()
		bindButtonAddColumn: function () {
			var self = this;
			$('.action-buttons').on('click', '#add-column', function(e) {
				e.preventDefault();
				self.addColumn();
				self.refreshUI();
			});
		},

		//Bind View Presentation button
		bindButtonViewPresentation: function () {
			var self = this;
			$('.action-buttons').on('click', '#view-button', function(e) {
				e.preventDefault();
				window.open(WPPTaxonomyURL,'_blank');
			});
		},

		renumberColumns: function() {
			var i = 1;
			$( '.column' ).each(function( index ) {
				 var self = this;
				 var $self = $(this);
				 $self.find('> .widget-top > .widget-title > h4').html( i );
				i++;
			});
		},

		/**
		 * Close Modal
		 */
		closeModal: function() {
			tinymce.execCommand('mceRemoveControl',true,'editor_slide');
			$( '#dialog' ).dialog( "close" );
		}

	};

})(jQuery);
var slideManager = new WPPresentAdmin();<|endoftext|>


<commit_before>var csc = require('./csc'),
	Q = require('q'),
	async = require('async'),
	path = require('path'),
	format = require('util').format,
	_ = require('./util')._;

function log(){
	var msg = format.apply(null, _.toArray(arguments));
	console.log('csc: ' + msg);
}

function create_unit(options, m){

	var mod = m;
	var defer = Q.defer();
	var units;
	var deps = []; // dep units

	mod.nologo = true;

	// default out
	if (!mod.out){
		mod.out = mod.name + '.dll';
	}

	// prefix and suffix
	if (options.outprefix){
		mod.out = options.outprefix + mod.out;
	}
	var suffix = options.outsuffix;
	if (suffix){
		var i = mod.out.lastIndexOf('.');
		if (i >= 0) {
			mod.out = mod.out.substring(0, i) + suffix + mod.out.substr(i);
		} else {
			// unusual, but acceptable
			mod.out += suffix;
		}
	}

	// prepend outdir
	if (options.outdir){
		mod.out = path.join(options.outdir, mod.out);
	}

	// default src
	if (!mod.src){
		mod.src = './' + mod.name + '/**/*.cs'
	}

	// prepend src root if specified
	if (options.srcroot){
		var sep = _(options.srcroot).endsWith('/') ? '' : '/';
		mod.src = options.srcroot + sep + mod.src;
	}

	// TODO prepend basedir to src

	// convert module.deps to array
	function depsArray(){
		if (typeof mod.deps === 'string'){
			return mod.deps.split(/[,;]/).map(_.trim).filter(_.identity);
		}
		return (mod.deps || []).map(_.trim).filter(_.identity);
	}

	function compile(){
		log('compiling module %s', mod.name);

		// convert deps to refs
		mod.refs = deps.map(function(d){
			return d.module.out;
		});

		csc(mod, function(err, res){
			if (res){
				res.stdout && log.writeln(res.stdout);
				res.stderr && log.writeln(res.stderr);
			}
			if (err) {
				grunt.log.error(err);
				defer.reject(err);
			} else {
				defer.resolve(mod);
			}
		});
	}

	function run(list){
		log('running module %s', mod.name);

		units = list;

		// resolve dep units
		deps = depsArray().map(function(name){
			var d = _.find(units, function(u){ return u.name == name; });
			if (!d){
				return { name: name };
			}
			return d;
		});

		var depPromises = deps.map(function(d){
			if (!d.promise) {
				return Q.reject('unable to resolve module ' + d.name);
			}
			return d.promise;
		});

		// wait deps then compile
		Q.all(depPromises)
			.then(compile)
			.fail(function(err){
				defer.reject(err);
			});
	}

	return {
		module: mod,
		name: mod.name,
		promise: defer.promise,
		run: run
	};
}

function taskFn(u, units){
	var unit = u;
	return function(callback){
		unit.promise.then(function(){
			callback(null, unit.name);
		});
		unit.promise.fail(function(err){
			callback(err, null);
		});
		unit.run(units);
	};
}

module.exports = function(options, modules){

	if (typeof modules == 'object'){
		// convert modules object to array
		modules = Object.keys(modules).map(function(name){
			var mod = modules[name];
			mod.name = name;
			return mod;
		});
	}

	var defer = Q.defer();

	// build module units
	var units = modules.map(function(m){
		return create_unit(options, m);
	});

	// create async tasks
	var tasks = units.map(function(u){
		return taskFn(u, units);
	});

	async.parallel(tasks, function(err, results){
		if (err) defer.reject(err);
		else defer.resolve(results);
	});

	return defer.promise;
};
<commit_msg>fixed log<commit_after>var csc = require('./csc'),
	Q = require('q'),
	async = require('async'),
	path = require('path'),
	format = require('util').format,
	_ = require('./util')._;

function log(){
	var msg = format.apply(null, _.toArray(arguments));
	console.log('csc: ' + msg);
}

function create_unit(options, m){

	var mod = m;
	var defer = Q.defer();
	var units;
	var deps = []; // dep units

	mod.nologo = true;

	// default out
	if (!mod.out){
		mod.out = mod.name + '.dll';
	}

	// prefix and suffix
	if (options.outprefix){
		mod.out = options.outprefix + mod.out;
	}
	var suffix = options.outsuffix;
	if (suffix){
		var i = mod.out.lastIndexOf('.');
		if (i >= 0) {
			mod.out = mod.out.substring(0, i) + suffix + mod.out.substr(i);
		} else {
			// unusual, but acceptable
			mod.out += suffix;
		}
	}

	// prepend outdir
	if (options.outdir){
		mod.out = path.join(options.outdir, mod.out);
	}

	// default src
	if (!mod.src){
		mod.src = './' + mod.name + '/**/*.cs'
	}

	// prepend src root if specified
	if (options.srcroot){
		var sep = _(options.srcroot).endsWith('/') ? '' : '/';
		mod.src = options.srcroot + sep + mod.src;
	}

	// TODO prepend basedir to src

	// convert module.deps to array
	function depsArray(){
		if (typeof mod.deps === 'string'){
			return mod.deps.split(/[,;]/).map(_.trim).filter(_.identity);
		}
		return (mod.deps || []).map(_.trim).filter(_.identity);
	}

	function compile(){
		log('compiling module %s', mod.name);

		// convert deps to refs
		mod.refs = deps.map(function(d){
			return d.module.out;
		});

		csc(mod, function(err, res){
			if (res){
				res.stdout && log(res.stdout);
				res.stderr && log(res.stderr);
			}
			if (err) {
				grunt.log.error(err);
				defer.reject(err);
			} else {
				defer.resolve(mod);
			}
		});
	}

	function run(list){
		log('running module %s', mod.name);

		units = list;

		// resolve dep units
		deps = depsArray().map(function(name){
			var d = _.find(units, function(u){ return u.name == name; });
			if (!d){
				return { name: name };
			}
			return d;
		});

		var depPromises = deps.map(function(d){
			if (!d.promise) {
				return Q.reject('unable to resolve module ' + d.name);
			}
			return d.promise;
		});

		// wait deps then compile
		Q.all(depPromises)
			.then(compile)
			.fail(function(err){
				defer.reject(err);
			});
	}

	return {
		module: mod,
		name: mod.name,
		promise: defer.promise,
		run: run
	};
}

function taskFn(u, units){
	var unit = u;
	return function(callback){
		unit.promise.then(function(){
			callback(null, unit.name);
		});
		unit.promise.fail(function(err){
			callback(err, null);
		});
		unit.run(units);
	};
}

module.exports = function(options, modules){

	if (typeof modules == 'object'){
		// convert modules object to array
		modules = Object.keys(modules).map(function(name){
			var mod = modules[name];
			mod.name = name;
			return mod;
		});
	}

	var defer = Q.defer();

	// build module units
	var units = modules.map(function(m){
		return create_unit(options, m);
	});

	// create async tasks
	var tasks = units.map(function(u){
		return taskFn(u, units);
	});

	async.parallel(tasks, function(err, results){
		if (err) defer.reject(err);
		else defer.resolve(results);
	});

	return defer.promise;
};
<|endoftext|>


<commit_before>"use strict";
var redis = require('redis');

function Cache(config) {
    var self = this;
    var client = redis.createClient();

    client.on('error', function (err) {
        console.log("Non-fatal cache error: " + err);
    });

    this.get = function (key, callback) {
        client.get(key, function (err, value) {
            value = JSON.parse(value);
            if (typeof callback === 'function') {
                callback(err, value);
            }
        });
    };

    this.set = function (key, value, expiration, callback) {
        value = JSON.stringify(value);
        client.set(key, value, function (err, reply) {
            if (expiration > 0) {
                client.expire(key, expiration);
            }
            if (typeof callback === 'function') {
                callback(err, reply);
            }
        });
    };

    /*jshint unused:false */ /* Not yet implemented */
    this.del = function (key, callback) {
    };
    /*jshint unused:true */

    return self;
}

module.exports = Cache;
<commit_msg>Fix jshint violations<commit_after>"use strict";
var redis = require('redis');

function Cache() {
    var self = this;
    var client = redis.createClient();

    client.on('error', function (err) {
        console.log("Non-fatal cache error: " + err);
    });

    this.get = function (key, callback) {
        client.get(key, function (err, value) {
            value = JSON.parse(value);
            if (typeof callback === 'function') {
                callback(err, value);
            }
        });
    };

    this.set = function (key, value, expiration, callback) {
        value = JSON.stringify(value);
        client.set(key, value, function (err, reply) {
            if (expiration > 0) {
                client.expire(key, expiration);
            }
            if (typeof callback === 'function') {
                callback(err, reply);
            }
        });
    };

    /*jshint unused:false */ /* Not yet implemented */
    this.del = function (key, callback) {
    };
    /*jshint unused:true */

    return self;
}

module.exports = Cache;
<|endoftext|>


<commit_before>
function uuid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
      return v.toString(16);
  });
}

export default {
  uuid
}
<commit_msg>use count based uuid<commit_after>let count = 0
function uuid() {
  return count++
  // return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
  //     var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
  //     return v.toString(16);
  // });
}

export default {
  uuid
}
<|endoftext|>


<commit_before>import React from 'react';
import TestUtils from 'react-dom/test-utils';
import Immutable from 'immutable';
import { TableAjax } from './table-ajax';
import { shallow } from 'enzyme';
import { elementsTagTest, rootTagTest } from '../../utils/helpers/tags/tags-specs';

describe('TableAjax', () => {
  let instance, customInstance, pageSizeInstance, spy;

  beforeEach(() => {
    spy = jasmine.createSpy('onChange spy');

    instance = TestUtils.renderIntoDocument(
      <TableAjax
        className="foo"
        path='/test'
        onChange={ spy }
      >
       foo
      </TableAjax>
    );

    customInstance = TestUtils.renderIntoDocument(
      <TableAjax
        className="foo"
        path='/test'
        onChange={ spy }
        sortOrder='desc'
        sortedColumn='name'
      >
       foo
      </TableAjax>
    );

    pageSizeInstance = TestUtils.renderIntoDocument(
      <TableAjax
        className="foo"
        path='/test'
        onChange={ spy }
        pageSize={ '10' }
      >
       foo
      </TableAjax>

    );
  });

  describe('componentWillUnmount', () => {
    it('calls stopTimeout', () => {
      spyOn(instance, 'stopTimeout');
      instance.componentWillUnmount();
      expect(instance.stopTimeout).toHaveBeenCalled();
    });
  });

  describe('componentDidMount', () => {
    it('calls emitOnChange to get initial table data', () => {
      spyOn(instance, 'emitOnChangeCallback');
      instance.componentDidMount();
      expect(instance.emitOnChangeCallback).toHaveBeenCalledWith('data', {
        currentPage: '1',
        pageSize: '10',
        sortOrder: '',
        sortedColumn: '',
        filter: {}
      }, 0);
    });

    describe('when custom props are passed', () => {
      it('sends the custom props', () => {
        spyOn(customInstance, 'emitOnChangeCallback');
        customInstance.componentDidMount();
        expect(customInstance.emitOnChangeCallback).toHaveBeenCalledWith('data', {
          currentPage: '1',
          pageSize: '10',
          sortOrder: 'desc',
          sortedColumn: 'name',
          filter: {}
        }, 0);
      });
    });

    describe('when custom props are passed', () => {
      it('sends the custom props', () => {
        spyOn(customInstance, 'emitOnChangeCallback');
        customInstance.componentDidMount();
        expect(customInstance.emitOnChangeCallback).toHaveBeenCalledWith('data', {
          currentPage: '1',
          pageSize: '10',
          sortOrder: 'desc',
          sortedColumn: 'name',
          filter: {}
        }, 0);
      });
    });
  });

  describe('componentDidUpdate', () => {
    it('does not call emitOnChangeCallback with the same pageSize', () => {
      spyOn(pageSizeInstance, 'emitOnChangeCallback');
      pageSizeInstance.componentDidUpdate({},{ pageSize: '10' });
      expect(pageSizeInstance.emitOnChangeCallback).not.toHaveBeenCalled();
    });

    it('calls emitOnChangeCallback when pageSize changes', () => {
      spyOn(pageSizeInstance, 'emitOnChangeCallback');
      pageSizeInstance.componentDidUpdate({},{ pageSize: '20' });
      expect(pageSizeInstance.emitOnChangeCallback).toHaveBeenCalled();
    });

    it('calls to resize the table', () => {
      spyOn(instance, 'resizeTable');
      instance.componentDidUpdate({},{});
      expect(instance.resizeTable).toHaveBeenCalled();
    });
  });

  describe('componentWillReceiveProps', () => {
    it('does not call setState with the same pageSize', () => {
      spyOn(pageSizeInstance, 'setState');
      pageSizeInstance.componentWillReceiveProps({pageSize: '10'});
      expect(pageSizeInstance.setState).not.toHaveBeenCalled();
    });

    it('calls emitOnChangeCallback when pageSize changes', () => {
      spyOn(pageSizeInstance, 'setState');
      pageSizeInstance.componentWillReceiveProps({pageSize: '20'});
      expect(pageSizeInstance.setState).toHaveBeenCalledWith({ pageSize: '20' });
    });
  });

  describe('pageSize', () => {
    it('gets the current pageSize', () => {
      instance.setState({ pageSize: '10' });
      expect(instance.pageSize).toEqual('10');
    });
  });

  describe('emitOnChangeCallback', () => {
    let options, request;

    beforeEach(() => {
      jasmine.Ajax.install();
      jasmine.clock().install();

      options = { currentPage: '1',
                  pageSize: '10',
                  sortOrder: undefined,
                  sortedColumn: undefined
                }
    });

    afterEach(() => {
      jasmine.Ajax.uninstall();
      jasmine.clock().uninstall();
    });

    it('resets the select all component', () => {
      let selectAllComponent = {
        setState: jasmine.createSpy()
      };
      instance.selectAllComponent = selectAllComponent;
      instance.emitOnChangeCallback('data', options);
      expect(selectAllComponent.setState).toHaveBeenCalledWith({ selected: false });
      expect(instance.selectAllComponent).toBe(null);
    });

    it('Sets the new pageSize and currentPage in state', () => {
      spyOn(instance, 'setState');
      instance.emitOnChangeCallback('data', options);
      expect(instance.setState).toHaveBeenCalledWith(options);
    });

    it('sets current page to 1 if filter has been updated', () => {
      spyOn(instance, 'setState');
      options.currentPage = "2";
      instance.emitOnChangeCallback('filter', options);
      options.currentPage = "1";
      expect(instance.setState).toHaveBeenCalledWith(options);
    });

    it('queries for the data after the set timeout', () => {
      instance.emitOnChangeCallback('data', options, 50);

      request = jasmine.Ajax.requests.mostRecent();
      expect(request).toBe(undefined);

      jasmine.clock().tick(51);
      request = jasmine.Ajax.requests.mostRecent();
      expect(request.url).toEqual('/test?page=1&rows=10');
    });

    it('queries for the data after 250ms', () => {
      instance.emitOnChangeCallback('data', options);

      request = jasmine.Ajax.requests.mostRecent();
      expect(request).toBe(undefined);

      jasmine.clock().tick(251);
      request = jasmine.Ajax.requests.mostRecent();
      expect(request.url).toEqual('/test?page=1&rows=10');
    });

    it('stores the request', () => {
      expect(instance._request).toBe(null);
      instance.emitOnChangeCallback('data', options);
      jasmine.clock().tick(251);
      request = jasmine.Ajax.requests.mostRecent();
      expect(instance._request).toBeDefined();
    });

    it('on success emits the returned data', () => {
        instance.emitOnChangeCallback('data', options);
        jasmine.clock().tick(251);
        request = jasmine.Ajax.requests.mostRecent();
        request.respondWith({
          "status": 200,
          "contentType": 'application/json',
          "responseText": "{\"data\": [\"foo\"]}"
        });
        expect(spy).toHaveBeenCalledWith({ data: ['foo'] });
    });

    it('on success sets the totalRecords', () => {
      spyOn(instance, 'setState');
      instance.emitOnChangeCallback('data', options);
      jasmine.clock().tick(251);

      request = jasmine.Ajax.requests.mostRecent();
      request.respondWith({
        "status": 200,
        "contentType": 'application/json',
        "responseText": "{\"records\": 1}"
      });
      expect(instance.setState).toHaveBeenCalledWith({ totalRecords: '1' });
    });

    describe('when page size is less than previous page size', () => {
      it('calls resetTableHeight on successful response', () => {
        spyOn(instance, 'resetTableHeight');
        options = { currentPage: '1', pageSize: '5' }

        instance.emitOnChangeCallback('data', options);
        jasmine.clock().tick(251);

        request = jasmine.Ajax.requests.mostRecent();
        request.respondWith({
          "status": 200,
          "contentType": 'application/json',
          "responseText": "{\"data\": [\"foo\"]}"
        });

        expect(instance.resetTableHeight).toHaveBeenCalled();
      });
    });
  });

  describe('stopTimeout', () => {
    describe('when timeout is present', () => {
      it('clears the timeout', () => {
        spyOn(window, 'clearTimeout');
        instance.timeout = 'foo'
        instance.stopTimeout();
        expect(window.clearTimeout).toHaveBeenCalledWith('foo');
      });
    });

    describe('when request is present', () => {
      it('aborts the request', () => {
        let spy = jasmine.createSpy(),
            req = { abort: spy };

        instance._request = req;
        instance.stopTimeout();
        expect(spy).toHaveBeenCalled();
      });
    });
  });

  describe('query params', () => {
    it('returns formatted params for server request', () => {
      let options = { currentPage: 10, pageSize: 20 };
      let expected = "page=10&rows=20";
      expect(instance.queryParams('', options)).toEqual(expected);
    });

    it('returns formatted params for server request with filter', () => {
      let options = { currentPage: 10, pageSize: 20, sortOrder: 'asc', sortedColumn: 'name', filter: { foo: "bar" } };
      let expected = "foo=bar&page=10&rows=20&sord=asc&sidx=name";
      expect(instance.queryParams('', options)).toEqual(expected);
    });

    it('returns currentPage as 1 if element is filter', () => {
      let options = { currentPage: 10, pageSize: 20, sortOrder: 'asc', sortedColumn: 'name', filter: { foo: "bar" } };
      let expected = "foo=bar&page=1&rows=20&sord=asc&sidx=name";
      expect(instance.queryParams('filter', options)).toEqual(expected);
    });
  });

  describe('emitOptions', () => {
    it('gathers all relevent state variables for endpoint', () => {
      expect(instance.emitOptions()).toEqual({
        currentPage: '1',
        filter: {},
        pageSize: '10',
        sortedColumn: '',
        sortOrder: ''
      });
    });

    it('gathers all relevent state variables for endpoint with passed props', () => {
      let props = {
        filter: Immutable.fromJS({
          foo: "bar"
        })
      };
      expect(instance.emitOptions(props)).toEqual({
        currentPage: '1',
        filter: { foo: "bar" },
        pageSize: '10',
        sortedColumn: '',
        sortOrder: ''
      });
    });
  });

  describe('pagerProps', () => {
    it('gathers all variables that apply to the pager', () => {
      let props = instance.pagerProps;
      expect(props.currentPage).toEqual('1')
      expect(props.pageSize).toEqual('10')
      expect(props.totalRecords).toEqual('0')
    });
  });

  describe("tags on component", () => {
    let wrapper = shallow(
      <TableAjax
        data-element='bar'
        data-role='baz'
        path='test'
      />
    );

    it('include correct component, element and role data tags', () => {
      rootTagTest(wrapper, 'table-ajax', 'bar', 'baz');
    });
  });
});
<commit_msg>Replace Jasmine clock with Jest mock timers<commit_after>import React from 'react';
import TestUtils from 'react-dom/test-utils';
import Immutable from 'immutable';
import { TableAjax } from './table-ajax';
import { shallow } from 'enzyme';
import { elementsTagTest, rootTagTest } from '../../utils/helpers/tags/tags-specs';

describe('TableAjax', () => {
  let instance, customInstance, pageSizeInstance, spy;

  beforeEach(() => {
    spy = jasmine.createSpy('onChange spy');

    instance = TestUtils.renderIntoDocument(
      <TableAjax
        className="foo"
        path='/test'
        onChange={ spy }
      >
       foo
      </TableAjax>
    );

    customInstance = TestUtils.renderIntoDocument(
      <TableAjax
        className="foo"
        path='/test'
        onChange={ spy }
        sortOrder='desc'
        sortedColumn='name'
      >
       foo
      </TableAjax>
    );

    pageSizeInstance = TestUtils.renderIntoDocument(
      <TableAjax
        className="foo"
        path='/test'
        onChange={ spy }
        pageSize={ '10' }
      >
       foo
      </TableAjax>

    );
  });

  describe('componentWillUnmount', () => {
    it('calls stopTimeout', () => {
      spyOn(instance, 'stopTimeout');
      instance.componentWillUnmount();
      expect(instance.stopTimeout).toHaveBeenCalled();
    });
  });

  describe('componentDidMount', () => {
    it('calls emitOnChange to get initial table data', () => {
      spyOn(instance, 'emitOnChangeCallback');
      instance.componentDidMount();
      expect(instance.emitOnChangeCallback).toHaveBeenCalledWith('data', {
        currentPage: '1',
        pageSize: '10',
        sortOrder: '',
        sortedColumn: '',
        filter: {}
      }, 0);
    });

    describe('when custom props are passed', () => {
      it('sends the custom props', () => {
        spyOn(customInstance, 'emitOnChangeCallback');
        customInstance.componentDidMount();
        expect(customInstance.emitOnChangeCallback).toHaveBeenCalledWith('data', {
          currentPage: '1',
          pageSize: '10',
          sortOrder: 'desc',
          sortedColumn: 'name',
          filter: {}
        }, 0);
      });
    });

    describe('when custom props are passed', () => {
      it('sends the custom props', () => {
        spyOn(customInstance, 'emitOnChangeCallback');
        customInstance.componentDidMount();
        expect(customInstance.emitOnChangeCallback).toHaveBeenCalledWith('data', {
          currentPage: '1',
          pageSize: '10',
          sortOrder: 'desc',
          sortedColumn: 'name',
          filter: {}
        }, 0);
      });
    });
  });

  describe('componentDidUpdate', () => {
    it('does not call emitOnChangeCallback with the same pageSize', () => {
      spyOn(pageSizeInstance, 'emitOnChangeCallback');
      pageSizeInstance.componentDidUpdate({},{ pageSize: '10' });
      expect(pageSizeInstance.emitOnChangeCallback).not.toHaveBeenCalled();
    });

    it('calls emitOnChangeCallback when pageSize changes', () => {
      spyOn(pageSizeInstance, 'emitOnChangeCallback');
      pageSizeInstance.componentDidUpdate({},{ pageSize: '20' });
      expect(pageSizeInstance.emitOnChangeCallback).toHaveBeenCalled();
    });

    it('calls to resize the table', () => {
      spyOn(instance, 'resizeTable');
      instance.componentDidUpdate({},{});
      expect(instance.resizeTable).toHaveBeenCalled();
    });
  });

  describe('componentWillReceiveProps', () => {
    it('does not call setState with the same pageSize', () => {
      spyOn(pageSizeInstance, 'setState');
      pageSizeInstance.componentWillReceiveProps({pageSize: '10'});
      expect(pageSizeInstance.setState).not.toHaveBeenCalled();
    });

    it('calls emitOnChangeCallback when pageSize changes', () => {
      spyOn(pageSizeInstance, 'setState');
      pageSizeInstance.componentWillReceiveProps({pageSize: '20'});
      expect(pageSizeInstance.setState).toHaveBeenCalledWith({ pageSize: '20' });
    });
  });

  describe('pageSize', () => {
    it('gets the current pageSize', () => {
      instance.setState({ pageSize: '10' });
      expect(instance.pageSize).toEqual('10');
    });
  });

  describe('emitOnChangeCallback', () => {
    let options, request;

    beforeEach(() => {
      jasmine.Ajax.install();
      jest.useFakeTimers();

      options = { currentPage: '1',
                  pageSize: '10',
                  sortOrder: undefined,
                  sortedColumn: undefined
                }
    });

    afterEach(() => {
      jasmine.Ajax.uninstall();
    });

    it('resets the select all component', () => {
      let selectAllComponent = {
        setState: jasmine.createSpy()
      };
      instance.selectAllComponent = selectAllComponent;
      instance.emitOnChangeCallback('data', options);
      expect(selectAllComponent.setState).toHaveBeenCalledWith({ selected: false });
      expect(instance.selectAllComponent).toBe(null);
    });

    it('Sets the new pageSize and currentPage in state', () => {
      spyOn(instance, 'setState');
      instance.emitOnChangeCallback('data', options);
      expect(instance.setState).toHaveBeenCalledWith(options);
    });

    it('sets current page to 1 if filter has been updated', () => {
      spyOn(instance, 'setState');
      options.currentPage = "2";
      instance.emitOnChangeCallback('filter', options);
      options.currentPage = "1";
      expect(instance.setState).toHaveBeenCalledWith(options);
    });

    it('queries for the data after the set timeout', () => {
      instance.emitOnChangeCallback('data', options, 50);

      request = jasmine.Ajax.requests.mostRecent();
      expect(request).toBe(undefined);

      jest.runTimersToTime(51);
      request = jasmine.Ajax.requests.mostRecent();
      expect(request.url).toEqual('/test?page=1&rows=10');
    });

    it('queries for the data after 250ms', () => {
      instance.emitOnChangeCallback('data', options);

      request = jasmine.Ajax.requests.mostRecent();
      expect(request).toBe(undefined);

      jest.runTimersToTime(251);
      request = jasmine.Ajax.requests.mostRecent();
      expect(request.url).toEqual('/test?page=1&rows=10');
    });

    it('stores the request', () => {
      expect(instance._request).toBe(null);
      instance.emitOnChangeCallback('data', options);
      jest.runTimersToTime(251);
      request = jasmine.Ajax.requests.mostRecent();
      expect(instance._request).toBeDefined();
    });

    it('on success emits the returned data', () => {
      instance.emitOnChangeCallback('data', options);
      rest.runTimersToTime(251);
      request = jasmine.Ajax.requests.mostRecent();
      request.respondWith({
        "status": 200,
        "contentType": 'application/json',
        "responseText": "{\"data\": [\"foo\"]}"
      });
      expect(spy).toHaveBeenCalledWith({ data: ['foo'] });
    });

    it('on success sets the totalRecords', () => {
      spyOn(instance, 'setState');
      instance.emitOnChangeCallback('data', options);
      jest.runTimersToTime(251);

      request = jasmine.Ajax.requests.mostRecent();
      request.respondWith({
        "status": 200,
        "contentType": 'application/json',
        "responseText": "{\"records\": 1}"
      });
      expect(instance.setState).toHaveBeenCalledWith({ totalRecords: '1' });
    });

    describe('when page size is less than previous page size', () => {
      it('calls resetTableHeight on successful response', () => {
        spyOn(instance, 'resetTableHeight');
        options = { currentPage: '1', pageSize: '5' }

        instance.emitOnChangeCallback('data', options);
        jest.runTimersToTime(251);

        request = jasmine.Ajax.requests.mostRecent();
        request.respondWith({
          "status": 200,
          "contentType": 'application/json',
          "responseText": "{\"data\": [\"foo\"]}"
        });

        expect(instance.resetTableHeight).toHaveBeenCalled();
      });
    });
  });

  describe('stopTimeout', () => {
    describe('when timeout is present', () => {
      it('clears the timeout', () => {
        spyOn(window, 'clearTimeout');
        instance.timeout = 'foo'
        instance.stopTimeout();
        expect(window.clearTimeout).toHaveBeenCalledWith('foo');
      });
    });

    describe('when request is present', () => {
      it('aborts the request', () => {
        let spy = jasmine.createSpy(),
            req = { abort: spy };

        instance._request = req;
        instance.stopTimeout();
        expect(spy).toHaveBeenCalled();
      });
    });
  });

  describe('query params', () => {
    it('returns formatted params for server request', () => {
      let options = { currentPage: 10, pageSize: 20 };
      let expected = "page=10&rows=20";
      expect(instance.queryParams('', options)).toEqual(expected);
    });

    it('returns formatted params for server request with filter', () => {
      let options = { currentPage: 10, pageSize: 20, sortOrder: 'asc', sortedColumn: 'name', filter: { foo: "bar" } };
      let expected = "foo=bar&page=10&rows=20&sord=asc&sidx=name";
      expect(instance.queryParams('', options)).toEqual(expected);
    });

    it('returns currentPage as 1 if element is filter', () => {
      let options = { currentPage: 10, pageSize: 20, sortOrder: 'asc', sortedColumn: 'name', filter: { foo: "bar" } };
      let expected = "foo=bar&page=1&rows=20&sord=asc&sidx=name";
      expect(instance.queryParams('filter', options)).toEqual(expected);
    });
  });

  describe('emitOptions', () => {
    it('gathers all relevent state variables for endpoint', () => {
      expect(instance.emitOptions()).toEqual({
        currentPage: '1',
        filter: {},
        pageSize: '10',
        sortedColumn: '',
        sortOrder: ''
      });
    });

    it('gathers all relevent state variables for endpoint with passed props', () => {
      let props = {
        filter: Immutable.fromJS({
          foo: "bar"
        })
      };
      expect(instance.emitOptions(props)).toEqual({
        currentPage: '1',
        filter: { foo: "bar" },
        pageSize: '10',
        sortedColumn: '',
        sortOrder: ''
      });
    });
  });

  describe('pagerProps', () => {
    it('gathers all variables that apply to the pager', () => {
      let props = instance.pagerProps;
      expect(props.currentPage).toEqual('1')
      expect(props.pageSize).toEqual('10')
      expect(props.totalRecords).toEqual('0')
    });
  });

  describe("tags on component", () => {
    let wrapper = shallow(
      <TableAjax
        data-element='bar'
        data-role='baz'
        path='test'
      />
    );

    it('include correct component, element and role data tags', () => {
      rootTagTest(wrapper, 'table-ajax', 'bar', 'baz');
    });
  });
});
<|endoftext|>


<commit_before>'use strict'

var $ = require('NodObjC');
$.framework('Cocoa');

var pool;

var ptX = 0;
var ptY = 0;

var init = function() {
    pool = $.NSAutoreleasePool('alloc')('init');
    var pos = getRealPos();
    setPos(pos.x, pos.y);
}

var getRealPos = function() {
    var pos = $.NSEvent("mouseLocation");
    return { x: pos.x, y: pos.y };
}

var getPos = function() {
    return { x: ptX, y: ptY };
}

var setPos = function(x, y) {
    ptX = x;
    ptY = y;
}

var Place = function(x, y) {
    setPos(x, y);
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventMouseMoved, $.CGPointMake(x, y), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var DragPlace = function(x, y) {
    setPos(x, y);
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseDragged, $.CGPointMake(x, y), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var Move = function(dx, dy) {
    ptX += dx;
    ptY += dy;
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventMouseMoved, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var DragMove = function(dx, dy) {
    ptX += dx;
    ptY += dy;
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseDragged, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var LeftButtonPress = function() {
    var clickDown = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseDown, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, clickDown);
}

var LeftButtonRelease = function() {
    var clickUp = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseUp, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, clickUp);
}

var RightButtonPress = function() {
    var clickDown = $.CGEventCreateMouseEvent(null, $.kCGEventRightMouseDown, $.CGPointMake(ptX, ptY), $.kCGEventRightMouseDown);
    $.CGEventPost($.kCGHIDEventTap, clickDown);
}

var RightButtonRelease = function() {
    var clickUp = $.CGEventCreateMouseEvent(null, $.kCGEventRightMouseUp, $.CGPointMake(ptX, ptY), $.kCGEventRightMouseDown);
    $.CGEventPost($.kCGHIDEventTap, clickUp);
}

var quit = function() {
    pool('drain');
}

module.exports = {
    init: init,
    getRealPos: getRealPos,
    getPos: getPos,
    setPos: setPos,
    Place: Place,
    DragPlace: DragPlace,
    Move: Move,
    DragMove: DragMove,
    LeftButtonPress: LeftButtonPress,
    LeftButtonRelease: LeftButtonRelease,
    RightButtonPress: RightButtonPress,
    RightButtonRelease: RightButtonRelease,
    quit: quit
}
<commit_msg>no reason to expose setPos<commit_after>'use strict'

var $ = require('NodObjC');
$.framework('Cocoa');

var pool;

var ptX = 0;
var ptY = 0;

var init = function() {
    pool = $.NSAutoreleasePool('alloc')('init');
    var pos = getRealPos();
    setPos(pos.x, pos.y);
}

var getRealPos = function() {
    var pos = $.NSEvent("mouseLocation");
    return { x: pos.x, y: pos.y };
}

var getPos = function() {
    return { x: ptX, y: ptY };
}

var setPos = function(x, y) {
    ptX = x;
    ptY = y;
}

var Place = function(x, y) {
    setPos(x, y);
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventMouseMoved, $.CGPointMake(x, y), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var DragPlace = function(x, y) {
    setPos(x, y);
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseDragged, $.CGPointMake(x, y), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var Move = function(dx, dy) {
    ptX += dx;
    ptY += dy;
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventMouseMoved, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var DragMove = function(dx, dy) {
    ptX += dx;
    ptY += dy;
    var moveEvent = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseDragged, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, moveEvent);
}

var LeftButtonPress = function() {
    var clickDown = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseDown, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, clickDown);
}

var LeftButtonRelease = function() {
    var clickUp = $.CGEventCreateMouseEvent(null, $.kCGEventLeftMouseUp, $.CGPointMake(ptX, ptY), $.kCGMouseButtonLeft);
    $.CGEventPost($.kCGHIDEventTap, clickUp);
}

var RightButtonPress = function() {
    var clickDown = $.CGEventCreateMouseEvent(null, $.kCGEventRightMouseDown, $.CGPointMake(ptX, ptY), $.kCGEventRightMouseDown);
    $.CGEventPost($.kCGHIDEventTap, clickDown);
}

var RightButtonRelease = function() {
    var clickUp = $.CGEventCreateMouseEvent(null, $.kCGEventRightMouseUp, $.CGPointMake(ptX, ptY), $.kCGEventRightMouseDown);
    $.CGEventPost($.kCGHIDEventTap, clickUp);
}

var quit = function() {
    pool('drain');
}

module.exports = {
    init: init,
    getRealPos: getRealPos,
    getPos: getPos,
    Place: Place,
    DragPlace: DragPlace,
    Move: Move,
    DragMove: DragMove,
    LeftButtonPress: LeftButtonPress,
    LeftButtonRelease: LeftButtonRelease,
    RightButtonPress: RightButtonPress,
    RightButtonRelease: RightButtonRelease,
    quit: quit
}
<|endoftext|>


<commit_before>"use strict";

var when = require('when'),
    browserify = require('browserify'),
    templatify = require('templatify'),
    common = require('./common'),
    sequence = require('sequence'),
    uglify = require('uglify-js'),
    nconf = require('nconf'),
    path = require('path'),
    less = require('less'),
    hbs = require('hbs'),
    compileStrings = require('./compile-strings'),
    generateConfig = require('./generate-config'),
    fileInfo = require('./file-info'),
    glob = require('glob');

// Compile all JS and LESS.
module.exports = function build(platform){
    var start = new Date(),
        platforms = (platform) ? [platform] : nconf.get('PLATFORMS');

    return when.all(platforms.map(function(platform){
        return generateConfig(platform);
    })).then(function(){
        return compileStrings();
    }).then(function(){
        return module.exports.less(platforms);
    }).then(function(){
        return module.exports.js(platforms);
    }).then(function(){
        common.logStat('build', start, 5000);
        common.success('<= built!');
    });
};

module.exports.findHelpers = function(platform){
    var assets = path.resolve(nconf.get('ASSETS')),
        files = [],
        s = [];

    files.push.apply(files, glob.sync(assets + '/common/js/helpers/*.js'));
    files.push.apply(files, glob.sync(assets + '/'+platform+'/js/helpers/*.js'));

    files.forEach(function(file){
        var name = new RegExp('[^/]*$', 'g').exec(file)[0].replace('.js', ''),
            p = file;
        s.push([name, p]);
    });

    return s;
};

module.exports.findPartials = function(platform){
    var assets = path.resolve(nconf.get('ASSETS')),
        files = [],
        s = [];

    files.push.apply(files, glob.sync(assets + '/common/templates/partials/*.html'));
    files.push.apply(files, glob.sync(assets + '/'+platform+'/templates/partials/*.html'));

    files.forEach(function(file){
        var name = new RegExp('[^/]*$', 'g').exec(file)[0].replace('.html', ''),
            p = file;
        s.push([name, p]);
    });

    return s;
};

module.exports.getHandlebarsEnvironment = function(platform){
    var partials = module.exports.findPartials(platform),
        helpers = module.exports.findHelpers(platform),
        s = ["var Handlebars = require('handlebars-runtime');"];

    partials.forEach(function(p){
        s.push("Handlebars.registerPartial('"+p[0]+"', require('"+p[1]+"'));");
    });

    helpers.forEach(function(h){
        s.push("Handlebars.registerHelper('"+h[0]+"', require('"+h[1]+"'));");
    });
    return s.join("\n");
};

module.exports.createBundle = function(platform){
    var bundle,
        assets = path.resolve(nconf.get('ASSETS')),
        d = when.defer();
    common.log('writing '+platform+' bundle');

    bundle = browserify([
        assets + '/'+platform+'/handlebars-environment.js',
        assets + '/'+platform+'/js/main.js'
    ]);

    bundle.transform(require('./handlebars'));

    bundle.bundle({debug: (nconf.get('NODE_ENV') === 'development')}, function(err, src){
    // bundle.bundle({debug: false}, function(err, src){
        if(err){
            common.error(err);
        }
        if(nconf.get('MINIFY')){
            src = uglify(src);
        }

        common.writeFile(assets + '/' + platform + '/app.js', src).then(function(){
            d.resolve(platform);
        });
    });
    return d.promise;
};

// Use browserify and templatify to compile all of the JS.
module.exports.js = function(platforms){
    var bundles,
        templateBundles = {},
        assets = path.resolve(nconf.get('ASSETS')),
        start = new Date();

    return when.all(platforms.map(function(platform){
        var hbsContent = module.exports.getHandlebarsEnvironment(platform);

        return common.writeFile(assets + '/' + platform + '/handlebars-environment.js', hbsContent).then(function(){
            return module.exports.createBundle(platform);
        }).then(function(){
            return module.exports.bootstrap(platform);
        });
    }), function(){
        common.logStat('build js', start, 5000);
    });
};

// Compiles less files for all platforms.
module.exports.less = function(platforms){
    var options = {
            'compress': nconf.get('MINIFY'),
            'yuicompress': false,
            'optimization': 1,
            'strictImports': false
        },
        assets = nconf.get('ASSETS'),
        start = new Date();

    return when.all(platforms.map(function(platform){
        var entrypoint = assets + '/' + platform + '/less/main.less';
        return common.readFile(entrypoint, 'utf-8').then(function(data){
            var p = when.defer();
            new less.Parser({
                paths: [path.dirname(entrypoint)],
                optimization: options.optimization,
                filename: entrypoint,
                strictImports: options.strictImports
            }).parse(data, function (err, tree) {
                console.error(err);
                if (err){
                    throw err;
                }
                p.resolve({
                    'path': entrypoint,
                    'data': data,
                    'css': tree.toCSS({
                        compress: options.compress,
                        yuicompress: options.yuicompress
                    })
                });
            });
            return p.promise;
        }).then(function(result){
            var buffer = result.css,
                regex = /url\(\/"?([\w\d\/\-\.\?\#\@]+)"?\)/g,
                replacement = (platform === 'web' || platform === 'chromeapp') ? "url(/$1)" :  "url($1)";
                buffer = buffer.replace(regex, replacement);

            return common.writeFile(assets + '/' + platform + '/app.css', buffer,'utf-8');
        });
    })).then(function(){
        common.logStat('build less', start, 1000);
    });
};

module.exports.bootstrap = function(platform){
    var template,
        tplsVars,
        assets = path.resolve(nconf.get('ASSETS')),
        socketioUrl = nconf.get('BASE_URL').replace(/\:\d+/, '') + ':7002/',
        version = nconf.get('VERSION'),
        versionCode = nconf.get('VERSION_CODE'),
        paths = [
            assets + '/' + platform + '/app.js',
            assets + '/' + platform + '/app.css'
        ];
    common.log('creating ' + platform + ' bootstrap');

    function writeBootstrap(){
        return common.readFile(assets + '/' + platform + '/bootstrap.tpl', 'utf-8').then(function(data){
            return hbs.handlebars.compile(data);
        }).then(function(template){
            return template(tplsVars);
        }).then(function(bootstrap){
            return common.writeFile(assets + '/' + platform + '/bootstrap.js', bootstrap);
        });
    }

    if(nconf.get('NODE_ENV') === 'development'){
        if(!nconf.get('SOCKETIO')){
            socketioUrl = null;
        }

        tplsVars = {
            'JSURL': nconf.get('BASE_URL') + '/' + platform + '/app.js',
            'JSVersion': '',
            'CSSURL': nconf.get('BASE_URL') + '/' + platform + '/app.css',
            'CSSVersion': '',
            'version': version,
            'versionCode': versionCode,
            'env': 'development',
            'socketio': socketioUrl,
            'weinre': nconf.get('WEINRE')
        };

        return when.all(paths.map(function(p){
            return fileInfo(p).then(function(info){
                if(p.indexOf('.css') > -1){
                    tplsVars.CSSVersion = info.sha;
                }
                else {
                    tplsVars.JSVersion = info.sha;
                }
            });
        })).then(function(){
            return writeBootstrap();
        });
    }

    tplsVars = {
        'JSURL': nconf.get('BASE_URL') + '/' + platform + '/app.js',
        'JSVersion': '',
        'CSSURL': nconf.get('BASE_URL') + '/' + platform + '/app.css',
        'CSSVersion': '',
        'version': version,
        'versionCode': versionCode,
        'env': nconf.get('NODE_ENV')
    };

    return when.all(paths.map(function(p){
        return fileInfo(p).then(function(info){
            if(p.indexOf('.css') > -1){
                tplsVars.CSSURL = info.url;
                tplsVars.CSSVersion = info.sha;
            }
            else{
                tplsVars.JSURL = info.url;
                tplsVars.JSVersion = info.sha;
            }
        });
    })).then(function(){
        return writeBootstrap();
    });
};<commit_msg>First pass at adding back in appcache manifest builds #1<commit_after>"use strict";

var when = require('when'),
    browserify = require('browserify'),
    templatify = require('templatify'),
    common = require('./common'),
    sequence = require('sequence'),
    uglify = require('uglify-js'),
    nconf = require('nconf'),
    path = require('path'),
    less = require('less'),
    hbs = require('hbs'),
    compileStrings = require('./compile-strings'),
    generateConfig = require('./generate-config'),
    fileInfo = require('./file-info'),
    glob = require('glob'),
    findit = require('findit');

// Compile all JS and LESS.
module.exports = function build(platform){
    var start = new Date(),
        platforms = (platform) ? [platform] : nconf.get('PLATFORMS');

    return when.all(platforms.map(function(platform){
        return generateConfig(platform);
    })).then(function(){
        return compileStrings();
    }).then(function(){
        return module.exports.less(platforms);
    }).then(function(){
        return module.exports.js(platforms);
    }).then(function(){
        return when.all(platforms.map(function(platform){
            return module.exports.buildManifest(platform);
        }));
    }).then(function(){
        common.logStat('build', start, 5000);
        common.success('<= built!');
    });
};

module.exports.findHelpers = function(platform){
    var assets = path.resolve(nconf.get('ASSETS')),
        files = [],
        s = [];

    files.push.apply(files, glob.sync(assets + '/common/js/helpers/*.js'));
    files.push.apply(files, glob.sync(assets + '/'+platform+'/js/helpers/*.js'));

    files.forEach(function(file){
        var name = new RegExp('[^/]*$', 'g').exec(file)[0].replace('.js', ''),
            p = file;
        s.push([name, p]);
    });

    return s;
};

module.exports.findPartials = function(platform){
    var assets = path.resolve(nconf.get('ASSETS')),
        files = [],
        s = [];

    files.push.apply(files, glob.sync(assets + '/common/templates/partials/*.html'));
    files.push.apply(files, glob.sync(assets + '/'+platform+'/templates/partials/*.html'));

    files.forEach(function(file){
        var name = new RegExp('[^/]*$', 'g').exec(file)[0].replace('.html', ''),
            p = file;
        s.push([name, p]);
    });

    return s;
};

module.exports.getHandlebarsEnvironment = function(platform){
    var partials = module.exports.findPartials(platform),
        helpers = module.exports.findHelpers(platform),
        s = ["var Handlebars = require('handlebars-runtime');"];

    partials.forEach(function(p){
        s.push("Handlebars.registerPartial('"+p[0]+"', require('"+p[1]+"'));");
    });

    helpers.forEach(function(h){
        s.push("Handlebars.registerHelper('"+h[0]+"', require('"+h[1]+"'));");
    });
    return s.join("\n");
};

module.exports.createBundle = function(platform){
    var bundle,
        assets = path.resolve(nconf.get('ASSETS')),
        d = when.defer();
    common.log('writing '+platform+' bundle');

    bundle = browserify([
        assets + '/'+platform+'/handlebars-environment.js',
        assets + '/'+platform+'/js/main.js'
    ]);

    bundle.transform(require('./handlebars'));

    bundle.bundle({debug: (nconf.get('NODE_ENV') === 'development')}, function(err, src){
        if(err){
            common.error(err);
        }
        if(nconf.get('MINIFY')){
            src = uglify(src);
        }

        common.writeFile(assets + '/' + platform + '/app.js', src).then(function(){
            d.resolve(platform);
        });
    });
    return d.promise;
};

// Use browserify and templatify to compile all of the JS.
module.exports.js = function(platforms){
    var bundles,
        templateBundles = {},
        assets = path.resolve(nconf.get('ASSETS')),
        start = new Date();

    return when.all(platforms.map(function(platform){
        var hbsContent = module.exports.getHandlebarsEnvironment(platform);

        return common.writeFile(assets + '/' + platform + '/handlebars-environment.js', hbsContent).then(function(){
            return module.exports.createBundle(platform);
        }).then(function(){
            return module.exports.bootstrap(platform);
        });
    }), function(){
        common.logStat('build js', start, 5000);
    });
};

// Compiles less files for all platforms.
module.exports.less = function(platforms){
    var options = {
            'compress': nconf.get('MINIFY'),
            'yuicompress': false,
            'optimization': 1,
            'strictImports': false
        },
        assets = nconf.get('ASSETS'),
        start = new Date();

    return when.all(platforms.map(function(platform){
        var entrypoint = assets + '/' + platform + '/less/main.less';
        return common.readFile(entrypoint, 'utf-8').then(function(data){
            var p = when.defer();
            new less.Parser({
                paths: [path.dirname(entrypoint)],
                optimization: options.optimization,
                filename: entrypoint,
                strictImports: options.strictImports
            }).parse(data, function (err, tree) {
                console.error(err);
                if (err){
                    throw err;
                }
                p.resolve({
                    'path': entrypoint,
                    'data': data,
                    'css': tree.toCSS({
                        compress: options.compress,
                        yuicompress: options.yuicompress
                    })
                });
            });
            return p.promise;
        }).then(function(result){
            var buffer = result.css,
                regex = /url\(\/"?([\w\d\/\-\.\?\#\@]+)"?\)/g,
                replacement = (platform === 'web' || platform === 'chromeapp') ? "url(/$1)" :  "url($1)";
            buffer = buffer.replace(regex, replacement);

            return common.writeFile(assets + '/' + platform + '/app.css', buffer,'utf-8');
        });
    })).then(function(){
        common.logStat('build less', start, 1000);
    });
};

module.exports.bootstrap = function(platform){
    var template,
        tplsVars,
        assets = path.resolve(nconf.get('ASSETS')),
        socketioUrl = nconf.get('BASE_URL').replace(/\:\d+/, '') + ':7002/',
        version = nconf.get('VERSION'),
        versionCode = nconf.get('VERSION_CODE'),
        paths = [
            assets + '/' + platform + '/app.js',
            assets + '/' + platform + '/app.css'
        ];
    common.log('creating ' + platform + ' bootstrap');

    function writeBootstrap(){
        return common.readFile(assets + '/' + platform + '/bootstrap.tpl', 'utf-8').then(function(data){
            return hbs.handlebars.compile(data);
        }).then(function(template){
            return template(tplsVars);
        }).then(function(bootstrap){
            return common.writeFile(assets + '/' + platform + '/bootstrap.js', bootstrap);
        });
    }

    if(nconf.get('NODE_ENV') === 'development'){
        if(!nconf.get('SOCKETIO')){
            socketioUrl = null;
        }

        tplsVars = {
            'JSURL': nconf.get('BASE_URL') + '/' + platform + '/app.js',
            'JSVersion': '',
            'CSSURL': nconf.get('BASE_URL') + '/' + platform + '/app.css',
            'CSSVersion': '',
            'version': version,
            'versionCode': versionCode,
            'env': 'development',
            'socketio': socketioUrl,
            'weinre': nconf.get('WEINRE')
        };

        return when.all(paths.map(function(p){
            return fileInfo(p).then(function(info){
                if(p.indexOf('.css') > -1){
                    tplsVars.CSSVersion = info.sha;
                }
                else {
                    tplsVars.JSVersion = info.sha;
                }
            });
        })).then(function(){
            return writeBootstrap();
        });
    }

    tplsVars = {
        'JSURL': nconf.get('BASE_URL') + '/' + platform + '/app.js',
        'JSVersion': '',
        'CSSURL': nconf.get('BASE_URL') + '/' + platform + '/app.css',
        'CSSVersion': '',
        'version': version,
        'versionCode': versionCode,
        'env': nconf.get('NODE_ENV')
    };

    return when.all(paths.map(function(p){
        return fileInfo(p).then(function(info){
            if(p.indexOf('.css') > -1){
                tplsVars.CSSURL = info.url;
                tplsVars.CSSVersion = info.sha;
            }
            else{
                tplsVars.JSURL = info.url;
                tplsVars.JSVersion = info.sha;
            }
        });
    })).then(function(){
        return writeBootstrap();
    });
};

module.exports.buildManifest = function(platform){
    var assets = path.resolve(nconf.get('ASSETS')),
        d = when.defer(),
        template = [
            'CACHE MANIFEST',
            '# GENERATED: ' + new Date().toString(),
            '# PLATFORM: ' + platform,
            '# Auto generated by mott.  Do not check in.',
            'CACHE:',
            '{{files}}',
            'NETWORK:',
            '*'
        ].join('\n'),
        pRegex = new RegExp(platform + '|common'),

    allPaths = findit.sync(nconf.get('ASSETS')).filter(function(p){
                var i = p.indexOf('.tpl') === -1 && p.indexOf('.less') === -1 &&
                p.indexOf('/js/') === -1 && p.indexOf('/templates/') === -1 &&
                p.indexOf('/lang/') === -1 && p.indexOf('templates.js') === -1 &&
                p.indexOf('handlebars-environment.js') === -1 &&
                p.indexOf('bootstrap') === -1 &&
                p.indexOf('index.html') === -1 &&
                p.indexOf('.') > -1;
                if(!i){
                    return i;
                }
                i = pRegex.test(p);
                return i;
            }).map(function(f){
                return f.replace(nconf.get('ASSETS') + '/', '/').replace('/web/', '/');
            });

    common.writeFile(assets + '/' + platform + '/app.appcache',
        template.replace('{{files}}', allPaths.join('\n'))).then(d.resolve, d.reject);

    return d.promise;
};<|endoftext|>