<commit_before>var AUAudioRecorder = function() {
	navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);

	var permission = false;

	var mediaRecorder;

	var outputType; // Default is mp3

	var audio;	// This "audio" variable serves as the final recording by the user.

    var theblob;   // The blob that can be used for file operations.

	var mediaStream;

	var shouldLoop = false;

    var playing = false;
};

/************************
*
*       Modifiers
*
*************************/

/* Asks the user for their permission to access the computer's microphone. */
AUAudioRecorder.prototype.requestPermission = function() {
	if(navigator.getUserMedia) {
        outputType = "audio/mp3; codecs=opus";
		// Definitions
		var constraints = { audio: true };
		var chunks = [];

		var onSuccess = function(stream) {
			// Initialize the media recorder
			mediaRecorder = new MediaRecorder(stream);
			mediaStream = stream;

			mediaRecorder.onstop = function(e) {
				// Create some new elements in the html
				var clipContainer = document.createElement('article');
				audio = document.createElement('audio');
				clipContainer.classList.add('clip');
				audio.setAttribute('controls', '');
				clipContainer.appendChild(audio);

				// Set some properties
				audio.controls = true;
  				var blob = new Blob(chunks, { 'type' : outputType });
  				chunks = [];
  				var audioURL = window.URL.createObjectURL(blob);
				audio.src = audioURL;
                theblob = blob;
			} // End of onstop action.

			mediaRecorder.ondataavailable = function(e) {
				chunks.push(e.data);
			} // End of ondataavailable action.

		} // End of onSuccess

		var onError = function(err) {
			console.log("ERROR: " + err);
		} // End of onError

		this.permission = true;
		navigator.getUserMedia(constraints, onSuccess, onError);
	} // End of if-supported-statement.
};

/* Starts the recording. */
AUAudioRecorder.prototype.startRecording = function() {
	if(mediaRecorder != null) {
        mediaRecorder.start();
    }
};

/* Stops the recording. */
AUAudioRecorder.prototype.stopRecording = function() {
    if(mediaRecorder != null) {
	   mediaRecorder.stop();
    }
};

/* Plays the recording. */
AUAudioRecorder.prototype.play = function() {
	if(audio != null) {
        audio.play();
        playing = true;
    }
};

/* Pauses the recording. */
AUAudioRecorder.prototype.pause = function() {
	if(audio != null) {
        audio.pause();
        playing = false;
    }
};

/* Stops the recording from playing. Calling 'play' will start it from the beginning. */
AUAudioRecorder.prototype.stop = function() {
    if(audio != null) {
        audio.pause();
        audio.currentTime = 0;
        playing = false;
    }
};

/* Loops the recorded audio. */
AUAudioRecorder.prototype.loop = function(bool) {
    if( audio != null ) {
        (bool == true) ? audio.loop = true : audio.loop = false;
    }
};

/* Goes to the beginning of the audio. */
AUAudioRecorder.prototype.stepBackward = function() {
	if(audio != null) {
        audio.currentTime = 0;
    }
};

/* Goes to the end of the audio. */
AUAudioRecorder.prototype.stepForward = function() {
    if(audio != null) {
	   audio.currentTime = audio.duration;
    }
};

/* Clears the current recording. */
AUAudioRecorder.prototype.clear = function() {
	audio = null;
    playing = false;
};

/* Sets the file type for the audio recording.
Ex.) mp3, wav, ogg, etc.... */
AUAudioRecorder.prototype.setOutputFileType = function(fileType) {
	outputType = "audio/" + fileType + "; codecs=opus";
};

/************************
*
*       Accessors
*
*************************/

/* Returns whether or not the program has the user's permission to use the microphone. */
AUAudioRecorder.prototype.hasPermission = function() {
	if(this.permission == undefined) return false;
	return (this.permission == true) ? true : false;
};

/* Returns whether or not the audio will loop. */
AUAudioRecorder.prototype.isLooping = function() {
    if(audio != null) {
        if(audio.loop == true) { return true; } else { return false; }
    }
};

/* Returns whether or not the audio is currently playing. */
AUAudioRecorder.prototype.isPlaying = function() {
    if(audio != null) {
        if( (audio.currentTime == audio.duration && audio.loop == false) || (audio.currentTime == 0) || (AUAudioRecorder.prototype.isFinished())) {
            return false;
        } else {
            return true;
        }
    }
    return undefined;
};

/* Returns the audio object that contains the final recording. */
AUAudioRecorder.prototype.getRecording = function() {
    if(audio != null && audio != undefined) { return audio; }
	return null;
};

/* Returns a Blob object, which can be used for file operations. */
AUAudioRecorder.prototype.getRecordingFile = function() {
    return theblob;
};

/* This returns the media stream from the web audio API. */
AUAudioRecorder.prototype.getStream = function() {
    if(mediaStream != null && audio != undefined) { return mediaStream; }
	return null;
};

/* Returns the output file type. */
AUAudioRecorder.prototype.getOutputType = function() {
    if(outputType != null && audio != undefined) { return outputType; }
    return null;
};

/* Returns whether or not the audio is finished playing. */
AUAudioRecorder.prototype.isFinished = function() {
	if(audio != null && audio != undefined) { return audio.ended; }
	return null;
};<commit_msg>More error checking<commit_after>var AUAudioRecorder = function() {
	navigator.getUserMedia = (navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia);

	var permission = false;

	var mediaRecorder;

	var outputType; // Default is mp3

	var audio;	// This "audio" variable serves as the final recording by the user.

    var theblob;   // The blob that can be used for file operations.

	var mediaStream;

	var shouldLoop = false;

    var playing = false;
};

/************************
*
*       Modifiers
*
*************************/

/* Asks the user for their permission to access the computer's microphone. */
AUAudioRecorder.prototype.requestPermission = function() {
	if(navigator.getUserMedia) {
        outputType = "audio/mp3; codecs=opus";
		// Definitions
		var constraints = { audio: true };
		var chunks = [];

		var onSuccess = function(stream) {
			// Initialize the media recorder
			mediaRecorder = new MediaRecorder(stream);
			mediaStream = stream;

			mediaRecorder.onstop = function(e) {
				// Create some new elements in the html
				var clipContainer = document.createElement('article');
				audio = document.createElement('audio');
				clipContainer.classList.add('clip');
				audio.setAttribute('controls', '');
				clipContainer.appendChild(audio);

				// Set some properties
				audio.controls = true;
  				var blob = new Blob(chunks, { 'type' : outputType });
  				chunks = [];
  				var audioURL = window.URL.createObjectURL(blob);
				audio.src = audioURL;
                theblob = blob;
			} // End of onstop action.

			mediaRecorder.ondataavailable = function(e) {
				chunks.push(e.data);
			} // End of ondataavailable action.

		} // End of onSuccess

		var onError = function(err) {
			console.log("ERROR: " + err);
		} // End of onError

		this.permission = true;
		navigator.getUserMedia(constraints, onSuccess, onError);
	} // End of if-supported-statement.
};

/* Starts the recording. */
AUAudioRecorder.prototype.startRecording = function() {
	if(mediaRecorder != null) {
        mediaRecorder.start();
    }
};

/* Stops the recording. */
AUAudioRecorder.prototype.stopRecording = function() {
    if(mediaRecorder != null) {
	   mediaRecorder.stop();
    }
};

/* Plays the recording. */
AUAudioRecorder.prototype.play = function() {
	if(audio != null) {
        audio.play();
        playing = true;
    }
};

/* Pauses the recording. */
AUAudioRecorder.prototype.pause = function() {
	if(audio != null) {
        audio.pause();
        playing = false;
    }
};

/* Stops the recording from playing. Calling 'play' will start it from the beginning. */
AUAudioRecorder.prototype.stop = function() {
    if(audio != null) {
        audio.pause();
        audio.currentTime = 0;
        playing = false;
    }
};

/* Loops the recorded audio. */
AUAudioRecorder.prototype.loop = function(bool) {
    if( audio != null ) {
        (bool == true) ? audio.loop = true : audio.loop = false;
    }
};

/* Goes to the beginning of the audio. */
AUAudioRecorder.prototype.stepBackward = function() {
	if(audio != null) {
        audio.currentTime = 0;
    }
};

/* Goes to the end of the audio. */
AUAudioRecorder.prototype.stepForward = function() {
    if(audio != null) {
	   audio.currentTime = audio.duration;
    }
};

/* Clears the current recording. */
AUAudioRecorder.prototype.clear = function() {
	audio = null;
    playing = false;
};

/* Sets the file type for the audio recording.
Ex.) mp3, wav, ogg, etc.... */
AUAudioRecorder.prototype.setOutputFileType = function(fileType) {
	outputType = "audio/" + fileType + "; codecs=opus";
};

/************************
*
*       Accessors
*
*************************/

/* Returns whether or not the program has the user's permission to use the microphone. */
AUAudioRecorder.prototype.hasPermission = function() {
	if(this.permission == undefined) return false;
	return (this.permission == true) ? true : false;
};

/* Returns whether or not the audio will loop. */
AUAudioRecorder.prototype.isLooping = function() {
    if(audio != null && (typeof(audio) != null) && audio !== undefined) {
        if(audio.loop == true) { return true; } else { return false; }
    }
};

/* Returns whether or not the audio is currently playing. */
AUAudioRecorder.prototype.isPlaying = function() {
    if(audio != null && (typeof(audio) != null) && audio !== undefined) {
        if( (audio.currentTime == audio.duration && audio.loop == false) || (audio.currentTime == 0) || (AUAudioRecorder.prototype.isFinished())) {
            return false;
        } else {
            return true;
        }
    }
    return false;
};

/* Returns the audio object that contains the final recording. */
AUAudioRecorder.prototype.getRecording = function() {
    if(audio != null && (typeof(audio) != null) && audio !== undefined) { return audio; }
	return null;
};

/* Returns a Blob object, which can be used for file operations. */
AUAudioRecorder.prototype.getRecordingFile = function() {
    return theblob;
};

/* This returns the media stream from the web audio API. */
AUAudioRecorder.prototype.getStream = function() {
    if(mediaStream != null && (typeof(audio) != null) && audio !== undefined) { return mediaStream; }
	return null;
};

/* Returns the output file type. */
AUAudioRecorder.prototype.getOutputType = function() {
    if(outputType != null && (typeof(audio) != null) && audio !== undefined) { return outputType; }
    return null;
};

/* Returns whether or not the audio is finished playing. */
AUAudioRecorder.prototype.isFinished = function() {
	if(audio != null && (typeof(audio) != null) && audio !== undefined) { return audio.ended; }
	return null;
};<|endoftext|>


<commit_before>$(document).ready(function () {
    $('.collapsible').click(function () {
        $(this).parent().find('.collapse').collapse('toggle');
    });
});
<commit_msg>Switch to close folder icon when collapsing<commit_after>$(document).ready(function () {
    $('.collapsible').click(function () {
        var $btn = $(this);
        $btn.parent().find('.collapse').collapse('toggle');
        $btn.find('span').toggleClass('glyphicon-folder-open glyphicon-folder-close');
    });
});
<|endoftext|>


<commit_before>let _ = require('lodash');
let PouchDB = require('pouchdb');

module.exports = (db, search, config) => {
  db.paginate = (viewName, start, length, options) => {
    start = parseInt(start) || 0;
    length = parseInt(length) || 0;

    if (!options) options = {};

    var objs = [];
    var pagination = {
      previous: start - length,
      start: start + 1,
      end: null,
      length: length,
      next: null
    };
    if (pagination.previous < 0) {
      if (start <= 0)
        pagination.previous = null;
      else
        pagination.previous = 0;
    }

    if (typeof(options.include_docs) === 'undefined')
      options.include_docs = true;
    options = _.extend(options, {
      skip: start,
      limit: length + 1,
    });

    return db.query(viewName, options).then((_result) => {
      if (_result && _result.rows) {
        objs = _result.rows;
        if (objs.length > length) {
          objs.splice(length, objs.length - length);
          pagination.next = start + length;
        }
        objs = objs.map(row => options.include_docs ? row.doc :  row.value);
        pagination.end = start + objs.length;
      }

      return {
        list: objs,
        pagination: pagination
      };
    });
  };

  if (search) {
    search.paginate = async (searchTerm, type, start, length, sort) => {
      start = parseInt(start) || 0;
      length = parseInt(length) || 0;

      if (!sort) {
        sort = {
          column: '_score',
          desc: true
        }
      }

      let opts = {
        index: config.search.index,
        type: type,
        q: searchTerm.indexOf(':') >= 0 ? searchTerm : `_all:${searchTerm}`,
        from: start,
        size: length,
        sort: `${type}.${sort.column}:${sort.desc ? 'desc' : 'asc'}`
      };
      console.log(opts);
      let results = await search.search(opts);

      let p = {
        list: results.hits.hits.map(v => {
          v._source[type]._id = v._id;
          return v._source[type];
        }),
        pagination: {
          previous: start - length,
          start: start + 1,
          end: start + results.hits.hits.length,
          length: length,
          next: (results.hits.total > start + length) ? start + length : null
        }
      };
      if (p.pagination.previous < 0) {
        if (start <= 0)
          p.pagination.previous = null;
        else
          p.pagination.previous = 0;
      }
      return p;
    }
  }
};<commit_msg>Remove console.log<commit_after>let _ = require('lodash');
let PouchDB = require('pouchdb');

module.exports = (db, search, config) => {
  db.paginate = (viewName, start, length, options) => {
    start = parseInt(start) || 0;
    length = parseInt(length) || 0;

    if (!options) options = {};

    var objs = [];
    var pagination = {
      previous: start - length,
      start: start + 1,
      end: null,
      length: length,
      next: null
    };
    if (pagination.previous < 0) {
      if (start <= 0)
        pagination.previous = null;
      else
        pagination.previous = 0;
    }

    if (typeof(options.include_docs) === 'undefined')
      options.include_docs = true;
    options = _.extend(options, {
      skip: start,
      limit: length + 1,
    });

    return db.query(viewName, options).then((_result) => {
      if (_result && _result.rows) {
        objs = _result.rows;
        if (objs.length > length) {
          objs.splice(length, objs.length - length);
          pagination.next = start + length;
        }
        objs = objs.map(row => options.include_docs ? row.doc :  row.value);
        pagination.end = start + objs.length;
      }

      return {
        list: objs,
        pagination: pagination
      };
    });
  };

  if (search) {
    search.paginate = async (searchTerm, type, start, length, sort) => {
      start = parseInt(start) || 0;
      length = parseInt(length) || 0;

      if (!sort) {
        sort = {
          column: '_score',
          desc: true
        }
      }

      let opts = {
        index: config.search.index,
        type: type,
        q: searchTerm.indexOf(':') >= 0 ? searchTerm : `_all:${searchTerm}`,
        from: start,
        size: length,
        sort: `${type}.${sort.column}:${sort.desc ? 'desc' : 'asc'}`
      };
      let results = await search.search(opts);

      let p = {
        list: results.hits.hits.map(v => {
          v._source[type]._id = v._id;
          return v._source[type];
        }),
        pagination: {
          previous: start - length,
          start: start + 1,
          end: start + results.hits.hits.length,
          length: length,
          next: (results.hits.total > start + length) ? start + length : null
        }
      };
      if (p.pagination.previous < 0) {
        if (start <= 0)
          p.pagination.previous = null;
        else
          p.pagination.previous = 0;
      }
      return p;
    }
  }
};<|endoftext|>


<commit_before>module.exports = function(sails) {

	/**
	 * Module dependencies.
	 */

	var _ = require('lodash'),
		util = require('sails-util'),
		Hook = require('../../index');

	/**
	 * Expose hook definition
	 */

	return {

		defaults: {
			cors: {
				origin: '*',
				credentials: true,
				methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
				headers: 'content-type'
			}
		},

		initialize: function(cb) {

			sails.on('router:before', function () {

				// Make sure there's a universal OPTIONS route that just send back a 200
				sails.router.bind('options /*', sendHeaders(null, true));

				// If we're setting CORS on all routes by default, set up a universal route for it here.
				// CORS can still be turned off for specific routes by setting "cors:false"
				if (sails.config.cors.allRoutes === true) {
					sails.router.bind('/*', sendHeaders());
				}

				// Loop through all configured routes, looking for CORS options
				_.each(sails.config.routes, function(config, route) {

					if (!_.isUndefined(config.cors)) {

						// If cors is set to "false", clear the CORS headers for this route
						if (config.cors === false) {
							sails.router.bind(route, clearHeaders);
							return;
						}

						// If cors is set to "true", and we're not doing all routes by default, set
						// the CORS headers for this route using the default origin
						else if (config.cors === true && !sails.config.cors.allRoutes) {
							sails.router.bind(route, sendHeaders());
						}

						// Else if cors is set to a string, use that has the origin
						else if (typeof config.cors === "string") {
							sails.router.bind(route, sendHeaders({origin:config.cors}));
						}

						// Else if cors is an object, use that as the config
						else if (_.isPlainObject(config.cors)) {
							sails.router.bind(route, sendHeaders(config.cors));
						}

						// Otherwise throw a warning
						else {
							sails.log.warn("Invalid CORS settings for route "+route);
						}

					}

				});

        // Disable cross-origin socket requests by default for routes
        // where CORS is disabled.
        if (sails.config.cors.allRoutes === false) {
          sails.router.bind('/*', function(req, res, next) {

            // If this is a socket request...
            if (req.isSocket) {
              // If it's already been whitelisted via the sendHeaders function,
              // or it's not cross-origin, let it through
              if (!getOrigin(req.socket) || res.get('Access-Control-Allow-Origin')) {
                return next();
              }
              // Otherwise it's cross origin and NOT white-listed, so ist vorboten
              else {
                res.json(403, {error: 'Origin '+getOrigin(req.socket)+' not allowed for '+req.url});
              }
            }

            // If this is an HTTP request, just carry on.  If it's a request from a browser, the browser
            // will decide whether to handle the response based on the Access-Control-Allow-Origin
            // header (or lack thereof).
            else {
              return next();
            }

          });
        }

			});

			cb();

		}

	};

	function sendHeaders(routeCorsConfig, respond) {

		if (!routeCorsConfig) {
			routeCorsConfig = {};
		}
		return function(req, res, next) {

      // If this is a socket request, fake the origin header using the origin from the handshake
      if (req.isSocket) {
        req.headers = req.headers || {};
        req.headers.origin = getOrigin(req.socket);
      }

      // If we have an origin header...
			if (req.headers && req.headers.origin) {

				// Get the allowed origins
				var origins = (routeCorsConfig.origin || sails.config.cors.origin).split(',');

				// Match the origin of the request against the allowed origins
				var foundOrigin = false;
				_.every(origins, function(origin) {

					origin = origin.trim();
					// If we find a whitelisted origin, send the Access-Control-Allow-Origin header
					// to greenlight the request.
					if (origin == req.headers.origin || origin == "*") {
						res.set('Access-Control-Allow-Origin', req.headers.origin);
						foundOrigin = true;
						return false;
					}
					return true;
				});

				if (!foundOrigin) {

          // For socket requests, just reject CORS requests from bad origins, since the browser
          // won't do it for us
          if (req.isSocket) {
            return res.json(403, {error: 'Origin '+req.headers.origin+' not allowed for '+req.url})
          }

          // For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will
          // interpret as, "no way Jose."
					res.set('Access-Control-Allow-Origin', '');
				}

        // Determine whether or not to allow cookies to be passed cross-origin
				res.set('Access-Control-Allow-Credentials', routeCorsConfig.credentials || sails.config.cors.credentials);

        // Handle preflight requests
				if (req.method == "OPTIONS") {
					res.set('Access-Control-Allow-Methods', routeCorsConfig.methods || sails.config.cors.methods);
					res.set('Access-Control-Allow-Headers', routeCorsConfig.headers || sails.config.cors.headers);
				}

				// If it's really a cross-origin request, blank out the CSRF token.
				// The CSRF middleware won't check for the token on CORS requests.
				// Note that this won't blank the token for requests that have the
				// same domain but different ports or schemes, but that should be ok.
				if (req.headers.origin && !util.isSameOrigin(req)) {
					res.locals._csrf = null;
				}
			}

			if (respond) {
				res.send(200);
			} else {
				next();
			}

		};

	}

	function clearHeaders(req, res, next) {

		// Replace the CSRF token if required
		if (sails.config.csrf) {
			res.locals._csrf = req.csrfToken();
		}

		// If we can set headers (i.e. it's not a socket request), do so.
		if (res.set) {
			res.set('Access-Control-Allow-Origin', '');
			res.set('Access-Control-Allow-Credentials', '');
			res.set('Access-Control-Allow-Methods', '');
			res.set('Access-Control-Allow-Headers', '');
		}

		next();

	}

  /**
   * [getOrigin description]
   * @param  {[type]} socket [description]
   * @api private
   * @return {[type]}        [description]
   */
  function getOrigin(socket) {
    if (!(socket.handshake && socket.handshake.headers)) {
      return undefined;
    }
    else return socket.handshake.headers.origin;
  }

};
<commit_msg>Move default "OPTIONS" handler after code that sets headers for CORS requests Corrected handling of route-level CORS config by checking for keys rather than defaulting to Sails config if key was falsy Fixed code that replaces CSRF token in clearHeaders to check for new "protectionEnabled" config<commit_after>module.exports = function(sails) {

	/**
	 * Module dependencies.
	 */

	var _ = require('lodash'),
		util = require('sails-util'),
		Hook = require('../../index');

	/**
	 * Expose hook definition
	 */

	return {

		defaults: {
			cors: {
				origin: '*',
				credentials: true,
				methods: 'GET, POST, PUT, DELETE, OPTIONS, HEAD',
				headers: 'content-type'
			}
		},

		initialize: function(cb) {

			sails.on('router:before', function () {

				// If we're setting CORS on all routes by default, set up a universal route for it here.
				// CORS can still be turned off for specific routes by setting "cors:false"
				if (sails.config.cors.allRoutes === true) {
					sails.router.bind('/*', sendHeaders());
				}

				// Loop through all configured routes, looking for CORS options
				_.each(sails.config.routes, function(config, route) {

					if (!_.isUndefined(config.cors)) {

						// If cors is set to "false", clear the CORS headers for this route
						if (config.cors === false) {
							sails.router.bind(route, clearHeaders);
							return;
						}

						// If cors is set to "true", and we're not doing all routes by default, set
						// the CORS headers for this route using the default origin
						else if (config.cors === true && !sails.config.cors.allRoutes) {
							sails.router.bind(route, sendHeaders());
						}

						// Else if cors is set to a string, use that has the origin
						else if (typeof config.cors === "string") {
							sails.router.bind(route, sendHeaders({origin:config.cors}));
						}

						// Else if cors is an object, use that as the config
						else if (_.isPlainObject(config.cors)) {
							sails.router.bind(route, sendHeaders(config.cors));
						}

						// Otherwise throw a warning
						else {
							sails.log.warn("Invalid CORS settings for route "+route);
						}

					}

				});

        // Disable cross-origin socket requests by default for routes
        // where CORS is disabled.
        if (sails.config.cors.allRoutes === false) {
          sails.router.bind('/*', function(req, res, next) {

            // If this is a socket request...
            if (req.isSocket) {
              // If it's already been whitelisted via the sendHeaders function,
              // or it's not cross-origin, let it through
              if (!getOrigin(req.socket) || res.get('Access-Control-Allow-Origin')) {
                return next();
              }
              // Otherwise it's cross origin and NOT white-listed, so ist vorboten
              else {
                res.json(403, {error: 'Origin '+getOrigin(req.socket)+' not allowed for '+req.url});
              }
            }

            // If this is an HTTP request, just carry on.  If it's a request from a browser, the browser
            // will decide whether to handle the response based on the Access-Control-Allow-Origin
            // header (or lack thereof).
            else {
              return next();
            }

          });
        }

				// Make sure there's a blanket OPTIONS route that actually sends a response
				// to a preflight request, after the code above handles setting the appropriate headers
				sails.router.bind('options /*', function(req, res, next) {res.send(200);});

			});

			cb();

		}

	};

	function sendHeaders(routeCorsConfig) {

		if (!routeCorsConfig) {
			routeCorsConfig = {};
		}
		return function(req, res, next) {

      // If this is a socket request, fake the origin header using the origin from the handshake
      if (req.isSocket) {
        req.headers = req.headers || {};
        req.headers.origin = getOrigin(req.socket);
      }

      // If we have an origin header...
			if (req.headers && req.headers.origin) {

				// Get the allowed origins
				var origins = (routeCorsConfig.origin || sails.config.cors.origin).split(',');

				// Match the origin of the request against the allowed origins
				var foundOrigin = false;
				_.every(origins, function(origin) {

					origin = origin.trim();
					// If we find a whitelisted origin, send the Access-Control-Allow-Origin header
					// to greenlight the request.
					if (origin == req.headers.origin || origin == "*") {
						res.set('Access-Control-Allow-Origin', req.headers.origin);
						foundOrigin = true;
						return false;
					}
					return true;
				});

				if (!foundOrigin) {

          // For socket requests, just reject CORS requests from bad origins, since the browser
          // won't do it for us
          if (req.isSocket) {
            return res.json(403, {error: 'Origin '+req.headers.origin+' not allowed for '+req.url})
          }

          // For HTTP requests, set the Access-Control-Allow-Origin header to '', which the browser will
          // interpret as, "no way Jose."
					res.set('Access-Control-Allow-Origin', '');
				}

        // Determine whether or not to allow cookies to be passed cross-origin
				res.set('Access-Control-Allow-Credentials', !_.isUndefined(routeCorsConfig.credentials) ? routeCorsConfig.credentials : sails.config.cors.credentials);

        // Handle preflight requests
				if (req.method == "OPTIONS") {
					res.set('Access-Control-Allow-Methods', !_.isUndefined(routeCorsConfig.methods) ? routeCorsConfig.methods : sails.config.cors.methods);
					res.set('Access-Control-Allow-Headers', !_.isUndefined(routeCorsConfig.headers) ? routeCorsConfig.headers : sails.config.cors.headers);
				}

				// If it's really a cross-origin request, blank out the CSRF token.
				// The CSRF middleware won't check for the token on CORS requests.
				// Note that this won't blank the token for requests that have the
				// same domain but different ports or schemes, but that should be ok.
				if (req.headers.origin && !util.isSameOrigin(req)) {
					res.locals._csrf = null;
				}
			}

			next();

		};

	}

	function clearHeaders(req, res, next) {

		// Replace the CSRF token if required
		if (sails.config.csrf && sails.config.csrf.protectionEnabled) {
			res.locals._csrf = req.csrfToken();
		}

		// If we can set headers (i.e. it's not a socket request), do so.
		if (res.set) {
			res.set('Access-Control-Allow-Origin', '');
			res.set('Access-Control-Allow-Credentials', '');
			res.set('Access-Control-Allow-Methods', '');
			res.set('Access-Control-Allow-Headers', '');
		}

		next();

	}

  /**
   * [getOrigin description]
   * @param  {[type]} socket [description]
   * @api private
   * @return {[type]}        [description]
   */
  function getOrigin(socket) {
    if (!(socket.handshake && socket.handshake.headers)) {
      return undefined;
    }
    else return socket.handshake.headers.origin;
  }

};
<|endoftext|>


<commit_before>// Copyright 2010 WebDriver committers
// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.provide('bot.locators.linkText');
goog.provide('bot.locators.partialLinkText');

goog.require('bot');
goog.require('bot.dom');
goog.require('bot.locators.css');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.dom.DomHelper');

/**
 * Find an element by using the text value of a link
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @param {boolean} opt_isPartial Whether the link text needs to be matched
 *     only partially.
 * @return {Element} The first matching element found in the DOM, or null if no
 *     such element could be found.
 * @private
 */
bot.locators.linkText.single_ = function(target, root, opt_isPartial) {
  var elements = bot.locators.css.many('a', root);

  var element = goog.array.find(elements, function(element) {
    var text = bot.dom.getVisibleText(element);
    return (opt_isPartial && text.indexOf(target) != -1) || text == target;
  });
  return (/**@type{Element}*/element);
};

/**
 * Find many elements by using the value of the link text
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @param {boolean} opt_isPartial Whether the link text needs to be matched
 *     only partially.
 * @return {goog.array.ArrayLike} All matching elements, or an empty list.
 * @private
 */
bot.locators.linkText.many_ = function(target, root, opt_isPartial) {
  var elements = bot.locators.css.many('a', root);
  return goog.array.filter(elements, function(element) {
    var text = bot.dom.getVisibleText(element);
    return (opt_isPartial && text.indexOf(target) != -1) || text == target;
  });
};

/**
 * Find an element by using the text value of a link
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {Element} The first matching element found in the DOM, or null if no
 *     such element could be found.
 */
bot.locators.linkText.single = function(target, root) {
  return bot.locators.linkText.single_(target, root, false);
};

/**
 * Find many elements by using the value of the link text
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {goog.array.ArrayLike} All matching elements, or an empty list.
 */
bot.locators.linkText.many = function(target, root) {
  return bot.locators.linkText.many_(target, root, false);
};

/**
 * Find an element by using part of the text value of a link.
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {Element} The first matching element found in the DOM, or null if no
 *     such element could be found.
 */
bot.locators.partialLinkText.single = function(target, root) {
  return bot.locators.linkText.single_(target, root, true);
};

/**
 * Find many elements by using part of the value of the link text.
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {goog.array.ArrayLike} All matching elements, or an empty list.
 */
bot.locators.partialLinkText.many = function(target, root) {
  return bot.locators.linkText.many_(target, root, true);
};
<commit_msg>DanielWagnerHall: Fall back to xhtml-incompatible lookup if browser doesn't support CSS selectors.  This is a kind of ugly hack.<commit_after>// Copyright 2010 WebDriver committers
// Copyright 2010 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

goog.provide('bot.locators.linkText');
goog.provide('bot.locators.partialLinkText');

goog.require('bot');
goog.require('bot.dom');
goog.require('bot.locators.css');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.dom.DomHelper');

/**
 * Find an element by using the text value of a link
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @param {boolean} opt_isPartial Whether the link text needs to be matched
 *     only partially.
 * @return {Element} The first matching element found in the DOM, or null if no
 *     such element could be found.
 * @private
 */
bot.locators.linkText.single_ = function(target, root, opt_isPartial) {
  var elements;
  try {
    elements = bot.locators.css.many('a', root);
  } catch (e) {
    // Old versions of browsers don't support CSS. They won't have XHTML
    // support. Sorry.
    elements = goog.dom.getDomHelper(root).getElementsByTagNameAndClass(
        goog.dom.TagName.A, /*className=*/null, root);
  }

  var element = goog.array.find(elements, function(element) {
    var text = bot.dom.getVisibleText(element);
    return (opt_isPartial && text.indexOf(target) != -1) || text == target;
  });
  return (/**@type{Element}*/element);
};

/**
 * Find many elements by using the value of the link text
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @param {boolean} opt_isPartial Whether the link text needs to be matched
 *     only partially.
 * @return {goog.array.ArrayLike} All matching elements, or an empty list.
 * @private
 */
bot.locators.linkText.many_ = function(target, root, opt_isPartial) {
  var elements;
  try {
    elements = bot.locators.css.many('a', root);
  } catch (e) {
    // Old versions of browsers don't support CSS. They won't have XHTML
    // support. Sorry.
    elements = goog.dom.getDomHelper(root).getElementsByTagNameAndClass(
        goog.dom.TagName.A, /*className=*/null, root);
  }

  return goog.array.filter(elements, function(element) {
    var text = bot.dom.getVisibleText(element);
    return (opt_isPartial && text.indexOf(target) != -1) || text == target;
  });
};

/**
 * Find an element by using the text value of a link
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {Element} The first matching element found in the DOM, or null if no
 *     such element could be found.
 */
bot.locators.linkText.single = function(target, root) {
  return bot.locators.linkText.single_(target, root, false);
};

/**
 * Find many elements by using the value of the link text
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {goog.array.ArrayLike} All matching elements, or an empty list.
 */
bot.locators.linkText.many = function(target, root) {
  return bot.locators.linkText.many_(target, root, false);
};

/**
 * Find an element by using part of the text value of a link.
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {Element} The first matching element found in the DOM, or null if no
 *     such element could be found.
 */
bot.locators.partialLinkText.single = function(target, root) {
  return bot.locators.linkText.single_(target, root, true);
};

/**
 * Find many elements by using part of the value of the link text.
 * @param {string} target The link text to search for.
 * @param {!(Document|Element)} root The document or element to perform the
 *     search under.
 * @return {goog.array.ArrayLike} All matching elements, or an empty list.
 */
bot.locators.partialLinkText.many = function(target, root) {
  return bot.locators.linkText.many_(target, root, true);
};
<|endoftext|>


<commit_before>// Return the first not null-like value.
var coalesce = require('extant')

// Generate a unique, canonical string key from a JSON object.
var Keyify = require('keyify')

// Contextualized callbacks and event handlers.
var Operation = require('operation/variadic')

// Ever increasing serial integer with no maximum value.
var Monotonic = require('monotonic').asString

// Control-flow utilities.
var Signal = require('signal')
var cadence = require('cadence')

// Exceptions that you can catch by type.
var interrupt = require('interrupt').createInterrupter('destructible')

// Do nothing.
var noop = require('nop')

// Unique id for each instance of destructible.
var INSTANCE = '0'

// Uncatchable exception.
var panicIf = require('./panic').panicIf

function Destructible (key) {
    this.destroyed = false
    this.errors = []
    this.interrupts = []
    this.key = coalesce(key)
    this._destructors = {}
    this.waiting = []
    this.instance = INSTANCE = Monotonic.increment(INSTANCE, 0)
    this._destructing = new Signal
    this._destroyed = new Signal
    this._index = 0
    this._vargs = []
}

Destructible.prototype._destroy = function (key, error) {
    if (error != null) {
        this.errors.push(error)
        this.interrupts.push(interrupt('error', { key: key }, error))
    }
    if (!this.destroyed) {
        this._destroyedAt = Date.now()
        this._destructing.unlatch()
        var destructors = this._destructors
        this._destructors = {}
        for (var key in destructors) {
            try {
                destructors[key].call()
            } catch (error) {
                throw interrupt('destructor', error, {
                    destructible: this.key,
                    destructor: Keyify.parse(key)
                })
            }
        }
        this.destroyed = true
    }
}

Destructible.prototype._complete = function () {
    if (this.waiting.length == 0 && this._destroyed.open == null) {
        if (this.errors.length) {
            this._destroyed.unlatch(this.errors[0])
        } else {
            var vargs = [ null ]
            vargs = vargs.concat.apply(vargs, this._vargs)
            this._destroyed.unlatch.apply(this._destroyed, vargs)
        }
    }
}

Destructible.prototype.destroy = function (error) {
    this._destroy({ module: 'destructible', method: 'destroy' }, coalesce(error))
}

Destructible.prototype.markDestroyed = function (object, property) {
    this.addDestructor('markDestroyed', function () {
        object[coalesce(property, 'destroyed')] = true
    })
}

Destructible.prototype.addDestructor = function (key) {
    key = Keyify.stringify(key)
    var operation = Operation(Array.prototype.slice.call(arguments, 1))
    if (this.destroyed) {
        operation()
    } else {
        this._destructors[key] = operation
    }
}

Destructible.prototype.invokeDestructor = function (key) {
    key = Keyify.stringify(key)
    interrupt.assert(! this.destroyed, 'destroyed', this.errors[0], {
        destructible: this.key,
        destructor: key
    })
    var destructor = this._destructors[key]
    destructor()
    delete this._destructors[key]
}

Destructible.prototype.removeDestructor = function (key) {
    key = Keyify.stringify(key)
    delete this._destructors[key]
}

Destructible.prototype.getDestructors = function () {
    return Object.keys(this._destructors).map(function (key) {
        return Keyify.parse(key)
    })
}

Destructible.prototype._createOrthogonal = function (vargs) {
    return vargs.length ? Operation(vargs) : noop
}
Destructible.prototype._invokeOrthogonal = function (orthogonal, error) {
    orthogonal.apply(null, error == null ? [] : [ error ])
}

// TODO Sketch of what might be a common aspect of turning the corner, waiting
// for a start that never comes. You launch a stack using monitor or rescue and
// wait for it to be ready using a semaphore, but an error occurs so that the
// value is never ready.
Destructible.prototype.monitor = function (key) {
    var orthogonal = this._createOrthogonal(Array.prototype.slice.call(arguments, 1))
    var wait = { module: 'destructible', method: 'monitor', key: key }
    this.waiting.push(wait)
    var index = this._index++
    return Operation([ this, function (error) {
        this._invokeOrthogonal(orthogonal, error)
        this._vargs[index] = Array.prototype.slice.call(arguments, 1)
        this._destroy({ module: 'destructible', method: 'monitor', key: key }, coalesce(error))
        this.waiting.splice(this.waiting.indexOf(wait), 1)
        this._complete()
    } ])
}

Destructible.prototype.rescue = function (key) {
    var orthogonal = this._createOrthogonal(Array.prototype.slice.call(arguments, 1))
    var wait = { module: 'destructible', method: 'rescue', key: key }
    this.waiting.push(wait)
    return Operation([ this, function (error) {
        this._invokeOrthogonal(orthogonal, error)
        if (error != null) {
            this._destroy({ module: 'destructible', method: 'rescue', key: key }, error)
        }
        this.waiting.splice(this.waiting.indexOf(wait), 1)
        if (this.destroyed) {
            this._complete()
        }
    } ])
}

Destructible.prototype._completed = cadence(function (async, timeout) {
    async(function () {
        this._destructing.wait(async())
    }, function () {
        timeout -= (this._destroyedAt - Date.now())
        this._destroyed.wait(Math.max(timeout, 0), async())
    }, function () {
        panicIf(this._destroyed.open == null, 'hung', {
            destructible: this.key,
            waiting: this.waiting.slice(),
        }, { cause: coalesce(this.errors[0]) })
    })
})

Destructible.prototype.completed = function (timeout, callback) {
    var vargs = Array.prototype.slice.call(arguments)
    timeout = typeof vargs[0] == 'number' ? vargs.shift() : 30000
    this._completed(timeout, vargs.shift())
}

module.exports = Destructible
<commit_msg>Fix consume destructors as you go.<commit_after>// Return the first not null-like value.
var coalesce = require('extant')

// Generate a unique, canonical string key from a JSON object.
var Keyify = require('keyify')

// Contextualized callbacks and event handlers.
var Operation = require('operation/variadic')

// Ever increasing serial integer with no maximum value.
var Monotonic = require('monotonic').asString

// Control-flow utilities.
var Signal = require('signal')
var cadence = require('cadence')

// Exceptions that you can catch by type.
var interrupt = require('interrupt').createInterrupter('destructible')

// Do nothing.
var noop = require('nop')

// Unique id for each instance of destructible.
var INSTANCE = '0'

// Uncatchable exception.
var panicIf = require('./panic').panicIf

function Destructible (key) {
    this.destroyed = false
    this.errors = []
    this.interrupts = []
    this.key = coalesce(key)
    this._destructors = {}
    this.waiting = []
    this.instance = INSTANCE = Monotonic.increment(INSTANCE, 0)
    this._destructing = new Signal
    this._destroyed = new Signal
    this._index = 0
    this._vargs = []
}

Destructible.prototype._destroy = function (key, error) {
    if (error != null) {
        this.errors.push(error)
        this.interrupts.push(interrupt('error', { key: key }, error))
    }
    if (!this.destroyed) {
        this._destroyedAt = Date.now()
        this._destructing.unlatch()
        for (var key in this._destructors) {
            try {
                this._destructors[key].call()
            } catch (error) {
                throw interrupt('destructor', error, {
                    destructible: this.key,
                    destructor: Keyify.parse(key)
                })
            }
            delete this._destructors[key]
        }
        this.destroyed = true
    }
}

Destructible.prototype._complete = function () {
    if (this.waiting.length == 0 && this._destroyed.open == null) {
        if (this.errors.length) {
            this._destroyed.unlatch(this.errors[0])
        } else {
            var vargs = [ null ]
            vargs = vargs.concat.apply(vargs, this._vargs)
            this._destroyed.unlatch.apply(this._destroyed, vargs)
        }
    }
}

Destructible.prototype.destroy = function (error) {
    this._destroy({ module: 'destructible', method: 'destroy' }, coalesce(error))
}

Destructible.prototype.markDestroyed = function (object, property) {
    this.addDestructor('markDestroyed', function () {
        object[coalesce(property, 'destroyed')] = true
    })
}

Destructible.prototype.addDestructor = function (key) {
    key = Keyify.stringify(key)
    var operation = Operation(Array.prototype.slice.call(arguments, 1))
    if (this.destroyed) {
        operation()
    } else {
        this._destructors[key] = operation
    }
}

Destructible.prototype.invokeDestructor = function (key) {
    key = Keyify.stringify(key)
    interrupt.assert(! this.destroyed, 'destroyed', this.errors[0], {
        destructible: this.key,
        destructor: key
    })
    var destructor = this._destructors[key]
    destructor()
    delete this._destructors[key]
}

Destructible.prototype.removeDestructor = function (key) {
    key = Keyify.stringify(key)
    delete this._destructors[key]
}

Destructible.prototype.getDestructors = function () {
    return Object.keys(this._destructors).map(function (key) {
        return Keyify.parse(key)
    })
}

Destructible.prototype._createOrthogonal = function (vargs) {
    return vargs.length ? Operation(vargs) : noop
}
Destructible.prototype._invokeOrthogonal = function (orthogonal, error) {
    orthogonal.apply(null, error == null ? [] : [ error ])
}

// TODO Sketch of what might be a common aspect of turning the corner, waiting
// for a start that never comes. You launch a stack using monitor or rescue and
// wait for it to be ready using a semaphore, but an error occurs so that the
// value is never ready.
Destructible.prototype.monitor = function (key) {
    var orthogonal = this._createOrthogonal(Array.prototype.slice.call(arguments, 1))
    var wait = { module: 'destructible', method: 'monitor', key: key }
    this.waiting.push(wait)
    var index = this._index++
    return Operation([ this, function (error) {
        this._invokeOrthogonal(orthogonal, error)
        this._vargs[index] = Array.prototype.slice.call(arguments, 1)
        this._destroy({ module: 'destructible', method: 'monitor', key: key }, coalesce(error))
        this.waiting.splice(this.waiting.indexOf(wait), 1)
        this._complete()
    } ])
}

Destructible.prototype.rescue = function (key) {
    var orthogonal = this._createOrthogonal(Array.prototype.slice.call(arguments, 1))
    var wait = { module: 'destructible', method: 'rescue', key: key }
    this.waiting.push(wait)
    return Operation([ this, function (error) {
        this._invokeOrthogonal(orthogonal, error)
        if (error != null) {
            this._destroy({ module: 'destructible', method: 'rescue', key: key }, error)
        }
        this.waiting.splice(this.waiting.indexOf(wait), 1)
        if (this.destroyed) {
            this._complete()
        }
    } ])
}

Destructible.prototype._completed = cadence(function (async, timeout) {
    async(function () {
        this._destructing.wait(async())
    }, function () {
        timeout -= (this._destroyedAt - Date.now())
        this._destroyed.wait(Math.max(timeout, 0), async())
    }, function () {
        panicIf(this._destroyed.open == null, 'hung', {
            destructible: this.key,
            waiting: this.waiting.slice(),
        }, { cause: coalesce(this.errors[0]) })
    })
})

Destructible.prototype.completed = function (timeout, callback) {
    var vargs = Array.prototype.slice.call(arguments)
    timeout = typeof vargs[0] == 'number' ? vargs.shift() : 30000
    this._completed(timeout, vargs.shift())
}

module.exports = Destructible
<|endoftext|>


<commit_before>/*!
 * jquery-machine Plugin for jQuery
 *
 * Version 0.0.1
 *
 * Copyright 2011, Luca Ongaro
 * Licensed under the MIT license.
 *
 */

(function( $ ){
  "use strict";
  $.fn.machine = function(machine) {
    var $this = this,
        events = [],
        states = [],
        defaultState = "start",
        callMethodIfExisting = function(obj, method) {
          if(!!obj && typeof obj[method] === "function") {
            return obj[method].apply($this, Array.prototype.slice.call( arguments, 2));
          }
        };

    // populate states and event array, get default state
    for(var state in machine) {
      if (machine.hasOwnProperty(state)) {
        states.push(state);
        if(!!machine[state].defaultState) {
          defaultState = state;
        }
        machine[state].exits = machine[state].exits || {};
        for(var evt in machine[state].exits) {
          if (machine[state].exits.hasOwnProperty(evt)) {
            events.push(evt);
          }
        }
      }
    }
    events = $.unique(events);

    // Store state machine object
    $(this).data("machine", machine);

    // Enter default state
    callMethodIfExisting($(this).data("machine")[defaultState], "onEnter");
    $(this).data("state", defaultState);

    // Event handler
    $this.bind(events.join(" "), function(evt) {
      var machine = $(this).data("machine"),
          currentState = $(this).data("state"),
          nextState = machine[currentState].exits[evt.type];
      if (!!nextState) {
        callMethodIfExisting(machine[currentState], "onExit", evt);
        callMethodIfExisting(machine[nextState], "onEnter", evt);
        $(this).data("state", nextState);
      }
    });

    return $this;
  };

})(jQuery);<commit_msg>add possibility to specify a function to discriminate between different exit states for the same event in the same state<commit_after>/*!
 * jquery-machine Plugin for jQuery
 *
 * Version 0.0.1
 *
 * Copyright 2011, Luca Ongaro
 * Licensed under the MIT license.
 *
 */

(function( $ ){
  "use strict";
  $.fn.machine = function(machine) {
    var $this = this,
        events = [],
        states = [],
        defaultState = "start",
        callMethodIfExisting = function(obj, method) {
          if(!!obj && typeof obj[method] === "function") {
            return obj[method].apply($this, Array.prototype.slice.call( arguments, 2));
          }
        };

    // populate states and event array, get default state
    for(var state in machine) {
      if (machine.hasOwnProperty(state)) {
        states.push(state);
        if(!!machine[state].defaultState) {
          defaultState = state;
        }
        machine[state].exits = machine[state].exits || {};
        for(var evt in machine[state].exits) {
          if (machine[state].exits.hasOwnProperty(evt)) {
            events.push(evt);
          }
        }
      }
    }
    events = $.unique(events);

    // Store state machine object
    $(this).data("machine", machine);

    // Enter default state
    callMethodIfExisting($(this).data("machine")[defaultState], "onEnter");
    $(this).data("state", defaultState);

    // Event handler
    $this.bind(events.join(" "), function(evt) {
      var machine = $(this).data("machine"),
          currentState = $(this).data("state"),
          nextState = (typeof machine[currentState].exits[evt.type] === "function") ?
            machine[currentState].exits[evt.type](evt) :
            machine[currentState].exits[evt.type];
      if (!!nextState) {
        callMethodIfExisting(machine[currentState], "onExit", evt);
        callMethodIfExisting(machine[nextState], "onEnter", evt);
        $(this).data("state", nextState);
      }
    });

    return $this;
  };

})(jQuery);<|endoftext|>


<commit_before>importScripts("../../ext/Dexie.min.js");
importScripts("../../node_modules/lunr/lunr.min.js");
importScripts("../util/database.js");

//add bookmarks to the lunr index
var bookmarksIndex = lunr(function () {
	this.field('title', {
		boost: 5
	})
	this.field("body");
	this.field("url", {
		boost: 1
	})
	this.ref("id"); //url's are used as references
});

/* used to turn refs into bookmarks */

var bookmarksInMemory = {
	/* format is url: bookmarkObject */
}

db.bookmarks
	.each(function (bookmark) {

		bookmarksIndex.add({
			id: bookmark.url,
			title: bookmark.title || "",
			body: bookmark.text || "",
			url: bookmark.url,
		});

		bookmarksInMemory[bookmark.url] = {
			url: bookmark.url,
			title: bookmark.title,
			//we skip the text property, since it takes up a lot of memory and isn't used anywhere
			extraData: bookmark.extraData
		};

	});

onmessage = function (e) {
	var action = e.data.action;
	var pageData = e.data.data;
	var searchText = e.data.text && e.data.text.toLowerCase();

	if (action == "addBookmark") {

		db.bookmarks
			.add({
				url: pageData.url,
				title: pageData.title,
				text: pageData.text,
				extraData: pageData.extraData,
			});

		bookmarksIndex.add({
			id: pageData.url,
			title: pageData.title || "",
			body: pageData.text || "",
			url: pageData.url,
		});

		bookmarksInMemory[pageData.url] = pageData;
	}

	if (action == "deleteBookmark") {
		db.bookmarks.where("url").equals(pageData.url).delete();

		//mark the item as deleted, since lunr doesn't let us actually remove it from the index

		bookmarksInMemory[pageData.url].deleted = true;
	}

	if (action == "searchBookmarks") { //do a bookmarks search
		var result = bookmarksIndex.search(searchText);

		//return 5, sorted by relevancy

		result = result.sort(function (a, b) {
			return b.score - a.score
		}).splice(0, 5);

		//change data format

		for (var item in result) {
			var url = result[item].ref;
			bookmarksInMemory[url].score = result[item].score;

			result[item] = bookmarksInMemory[url];
			if (result[item].deleted) {
				delete result[item]
			}
		}
		postMessage({
			result: result,
			scope: "bookmarks",
			callback: e.data.callbackId,
		}); //send back to bookmarks.js
	}
}
<commit_msg>bug fixes<commit_after>importScripts("../../ext/Dexie.min.js");
importScripts("../../node_modules/lunr/lunr.min.js");
importScripts("../util/database.js");

//add bookmarks to the lunr index
var bookmarksIndex = lunr(function () {
	this.field('title', {
		boost: 5
	})
	this.field("body");
	this.field("url", {
		boost: 1
	})
	this.ref("id"); //url's are used as references
});

/* used to turn refs into bookmarks */

var bookmarksInMemory = {
	/* format is url: bookmarkObject */
}

db.bookmarks
	.each(function (bookmark) {

		bookmarksIndex.add({
			id: bookmark.url,
			title: bookmark.title || "",
			body: bookmark.text || "",
			url: bookmark.url,
		});

		bookmarksInMemory[bookmark.url] = {
			url: bookmark.url,
			title: bookmark.title,
			//we skip the text property, since it takes up a lot of memory and isn't used anywhere
			extraData: bookmark.extraData
		};

	});

onmessage = function (e) {
	var action = e.data.action;
	var pageData = e.data.data;
	var searchText = e.data.text && e.data.text.toLowerCase();

	if (action == "addBookmark") {

		db.bookmarks
			.add({
				url: pageData.url,
				title: pageData.title,
				text: pageData.text,
				extraData: pageData.extraData,
			});

		bookmarksIndex.add({
			id: pageData.url,
			title: pageData.title || "",
			body: pageData.text || "",
			url: pageData.url,
		});

		bookmarksInMemory[pageData.url] = pageData;
	}

	if (action == "deleteBookmark") {
		db.bookmarks.where("url").equals(pageData.url).delete();

		delete bookmarksInMemory[pageData.url];
	}

	if (action == "searchBookmarks") { //do a bookmarks search
		var results = bookmarksIndex.search(searchText);

		//return 5, sorted by relevancy

		results = results.sort(function (a, b) {
			return b.score - a.score
		}).splice(0, 5);

		//change data format

		for (var i = 0; i < results.length; i++) {
			var url = results[i].ref;

			//the item has been deleted
			if (!bookmarksInMemory[url]) {
				delete results[i];
				continue;
			}

			bookmarksInMemory[url].score = results[i].score;
			results[i] = bookmarksInMemory[url];
		}
		postMessage({
			result: results,
			scope: "bookmarks",
			callback: e.data.callbackId,
		}); //send back to bookmarks.js
	}
}
<|endoftext|>


<commit_before>angular.module('PetAppUI').controller('DashboardCtrl', function($scope, $http) {
    'use strict';

    $http.get('http://petapp-api.herokuapp.com/pets').success(function(response) {
        $scope.pets = response;
    });

});
<commit_msg>update dashboard ctrl to reflect serverurl constant<commit_after>angular.module('PetAppUI').controller('DashboardCtrl', function($scope, $http, ServerUrl) {
    'use strict';

    $http.get(ServerUrl + '/pets').success(function(response) {
        $scope.pets = response;
    });

    $http.get(ServerUrl).success(function(response) {
        $scope.user = response;
    });

});
<|endoftext|>


<commit_before>/**
* search trials
*
* @author Isaak Y Tecle <iyt2@cornell.edu>
*
*/

jQuery(document).ready(function(){

    var url = window.location.pathname;

    if (url.match(/solgs\/search\/trials\/trait\//) != null) {
	var traitId = jQuery("input[name='trait_id']").val();

	var urlStr = url.split(/\/+/);
	var protocolId = urlStr[7];
	jQuery('#genotyping_protocol_id').val(protocolId);

	url = '/solgs/search/result/populations/' + traitId + '/gp/' + protocolId;
	searchAllTrials(url);
    } else {
	url = '/solgs/search/trials/';
    }

  //  searchAllTrials(url);
});

function searchAllTrials(url, result) {

    jQuery("#all_trials_search_message").html('Searching for GS trials..').show();

    jQuery.ajax({
        type: 'POST',
        dataType: "json",
        url: url,
        data: {'show_result': result},
        cache: true,
        success: function(res) {

            jQuery("#all_trials_search_message").hide();

            listAllTrials(res.trials)
            var pagination = res.pagination;

            jQuery("#all_trials_search_message").hide();
	   jQuery("#all_trials_div").append(pagination);
        },
        error: function() {
            jQuery("#all_trials_search_message").html('Error occured fetching the first set of GS trials.').show();
        }

    });

    jQuery("#all_trials_div").on('click', "div.paginate_nav a", function(e) {
        var page = jQuery(this).attr('href');

        jQuery("#all_trials_div").empty();

        jQuery("#all_trials_search_message").html('Searching for more GS trials..').show();

        if (page) {
            jQuery.ajax({
                type: 'POST',
                dataType: "json",
                url: page,
                success: function(res) {
		    listAllTrials(res.trials)
                    var pagination = res.pagination;
                    jQuery("#all_trials_search_message").hide();
		    jQuery("#all_trials_div").append(pagination);
                },
                error: function() {
                    jQuery("#all_trials_search_message").html('Error occured fetching the next set of GS trials.').show();
                }
            });
        }

        return false;
    });

}

function listAllTrials (trials)  {

    if (trials) {
	var tableId = 'all_trials_table';
	var divId   = 'all_trials_div';

	var tableDetails = {
	    'divId'  : divId,
	    'tableId': tableId,
	    'data'   : trials
	};

	jQuery('#searched_trials_div').empty();
	jQuery('#all_trials_div').empty();

	displayTrainingPopulations(tableDetails);

    } else {
	jQuery("#all_trials_search_message").html('No trials to show.').show();
    }

}

function checkTrainingPopulation (popIds) {

    var protocolId = jQuery('#genotyping_protocol_id').val();

    jQuery.ajax({
        type: 'POST',
        dataType: 'json',
        url: '/solgs/check/training/population',
        data: {'population_ids' : popIds, 'genotyping_protocol_id': protocolId},
        success: function(response) {
            if (response.is_training_population) {
			jQuery("#searched_trials_message").hide();
			jQuery("#searched_trials_div").show();

			var divId   = 'searched_trials_div';
			var tableId = 'searched_trials_table';
			var data    = response.training_pop_data;

			var tableDetails = {
			    'divId'  : divId,
			    'tableId': tableId,
			    'data'   : data
			};

			displayTrainingPopulations(tableDetails);
                jQuery('#done_selecting_div').show();

            } else {
		jQuery("#searched_trials_message").html('
 Population ' + popId + ' can not be used as a training population.');
		jQuery("#search_all_training_pops").show();

		// jQuery("#searched_trials_message")
		// 	.delay(4000)
		// 	.fadeOut('slow', function () {
		// 	    searchAllTrials('/solgs/search/trials');
		// 	});
	    }
	},
	error: function(response) {
            jQuery("#searched_trials_message")
		.html('Error occured checking for if trial can be used as training population.');

	    jQuery("#searched_trials_message")
		.delay(4000)
		.fadeOut('slow', function () {
		    // searchAllTrials('/solgs/search/trials');
		});
        }

    });

}

jQuery(document).ready( function () {

    jQuery('#population_search_entry').keyup(function(e) {

	jQuery("#population_search_entry")
		.css('border', 'solid #96d3ec');

	jQuery("#form-feedback-search-trials")
	    .empty();

	if(e.keycode == 13) {

     	    jQuery('#search_training_pop').click();
    	}
    });

    jQuery('#search_training_pop').on('click', function () {

	var entry = jQuery('#population_search_entry').val();
	jQuery("#searched_trials_message").hide();

	if (entry) {

	    checkPopulationExists(entry);
	} else {
	    jQuery("#population_search_entry")
		.css('border', 'solid #FF0000');

	    jQuery("#form-feedback-search-trials")
		.text('Please enter trial name.');
	}
    });

});

jQuery(document).ready( function () {

    jQuery('#search_all_training_pops').on('click', function () {

	jQuery("#searched_trials_div").empty();
	jQuery("#all_trials_div").empty();
	var url = '/solgs/search/trials';
        var result = 'all';
	searchAllTrials(url, result);
    });

});

jQuery(document).ready( function () {
    jQuery("#color_tip").tooltip();
});

function checkPopulationExists (name) {
    jQuery("#searched_trials_message")
	.html("Checking if trial or training population " + name + " exists...please wait...")
	.show();

	jQuery("#all_trials_div").empty();

	jQuery.ajax({
            type: 'POST',
            dataType: 'json',
	    data: {'name': name},
            url: '/solgs/check/population/exists/',
            success: function(res) {

		if (res.population_ids) {

		    checkTrainingPopulation(res.population_ids);

		    jQuery('#searched_trials_message').html(
			'
Checking if the trial or population can be used
'
			    + 'as a training population...please wait...
');

		} else {
		    jQuery('#searched_trials_message')
			.html('
' + name + ' is not in the database.
');

		    jQuery("#searched_trials_message")
			.delay(4000)
			.fadeOut('slow', function () {
			   // searchAllTrials('/solgs/search/trials');
			});
		}
	    },
	    error: function(res) {
		jQuery("#searched_trials_message")
		    .html('Error occured checking if the training population exists.');

		jQuery("#searched_trials_message")
		    .delay(4000)
		    .fadeOut('slow', function () {
			// searchAllTrials('/solgs/search/trials');
		    });
            }
	});

}

function createTrialsTable (tableId) {

    var table = '
';
    table    += '

';
    table    += '	Trial	Description	Location	Year	More details	';
   // table    += '	';
    table    += '

';
    table    += '
';

    return table;

}

function displayTrainingPopulations (tableDetails) {

    var divId   = tableDetails.divId;
    var tableId = tableDetails.tableId;
    var data    = tableDetails.data;

    if (data) {

	var tableRows = jQuery('#' + tableId + ' tr').length;

	if (tableRows > 1) {
	    jQuery('#' + tableId).dataTable().fnAddData(data);
	} else {

	    var table = createTrialsTable(tableId);

	    jQuery('#' + divId).html(table).show();

	    jQuery('#' + tableId).dataTable({
                    'order'        : [[1, "desc"], [4, "desc"]],
		    'searching'    : true,
		    'ordering'     : true,
		    'processing'   : true,
		    'lengthChange' : false,
                    "bInfo"        : false,
                    "paging"       : false,
                    'oLanguage'    : {
		                     "sSearch": "Filter result by: "
		                    },
		    'data'         : data,
	    });
	}
    }

}
<commit_msg>tweak cols to order search results<commit_after>/**
* search trials
*
* @author Isaak Y Tecle <iyt2@cornell.edu>
*
*/

jQuery(document).ready(function(){

    var url = window.location.pathname;

    if (url.match(/solgs\/search\/trials\/trait\//) != null) {
	var traitId = jQuery("input[name='trait_id']").val();

	var urlStr = url.split(/\/+/);
	var protocolId = urlStr[7];
	jQuery('#genotyping_protocol_id').val(protocolId);

	url = '/solgs/search/result/populations/' + traitId + '/gp/' + protocolId;
	searchAllTrials(url);
    } else {
	url = '/solgs/search/trials/';
    }

  //  searchAllTrials(url);
});

function searchAllTrials(url, result) {

    jQuery("#all_trials_search_message").html('Searching for GS trials..').show();

    jQuery.ajax({
        type: 'POST',
        dataType: "json",
        url: url,
        data: {'show_result': result},
        cache: true,
        success: function(res) {

            jQuery("#all_trials_search_message").hide();

            listAllTrials(res.trials)
            var pagination = res.pagination;

            jQuery("#all_trials_search_message").hide();
	   jQuery("#all_trials_div").append(pagination);
        },
        error: function() {
            jQuery("#all_trials_search_message").html('Error occured fetching the first set of GS trials.').show();
        }

    });

    jQuery("#all_trials_div").on('click', "div.paginate_nav a", function(e) {
        var page = jQuery(this).attr('href');

        jQuery("#all_trials_div").empty();

        jQuery("#all_trials_search_message").html('Searching for more GS trials..').show();

        if (page) {
            jQuery.ajax({
                type: 'POST',
                dataType: "json",
                url: page,
                success: function(res) {
		    listAllTrials(res.trials)
                    var pagination = res.pagination;
                    jQuery("#all_trials_search_message").hide();
		    jQuery("#all_trials_div").append(pagination);
                },
                error: function() {
                    jQuery("#all_trials_search_message").html('Error occured fetching the next set of GS trials.').show();
                }
            });
        }

        return false;
    });

}

function listAllTrials (trials)  {

    if (trials) {
	var tableId = 'all_trials_table';
	var divId   = 'all_trials_div';

	var tableDetails = {
	    'divId'  : divId,
	    'tableId': tableId,
	    'data'   : trials
	};

	jQuery('#searched_trials_div').empty();
	jQuery('#all_trials_div').empty();

	displayTrainingPopulations(tableDetails);

    } else {
	jQuery("#all_trials_search_message").html('No trials to show.').show();
    }

}

function checkTrainingPopulation (popIds) {

    var protocolId = jQuery('#genotyping_protocol_id').val();

    jQuery.ajax({
        type: 'POST',
        dataType: 'json',
        url: '/solgs/check/training/population',
        data: {'population_ids' : popIds, 'genotyping_protocol_id': protocolId},
        success: function(response) {
            if (response.is_training_population) {
			jQuery("#searched_trials_message").hide();
			jQuery("#searched_trials_div").show();

			var divId   = 'searched_trials_div';
			var tableId = 'searched_trials_table';
			var data    = response.training_pop_data;

			var tableDetails = {
			    'divId'  : divId,
			    'tableId': tableId,
			    'data'   : data
			};

			displayTrainingPopulations(tableDetails);
                jQuery('#done_selecting_div').show();

            } else {
		jQuery("#searched_trials_message").html('
 Population ' + popId + ' can not be used as a training population.');
		jQuery("#search_all_training_pops").show();

		// jQuery("#searched_trials_message")
		// 	.delay(4000)
		// 	.fadeOut('slow', function () {
		// 	    searchAllTrials('/solgs/search/trials');
		// 	});
	    }
	},
	error: function(response) {
            jQuery("#searched_trials_message")
		.html('Error occured checking for if trial can be used as training population.');

	    jQuery("#searched_trials_message")
		.delay(4000)
		.fadeOut('slow', function () {
		    // searchAllTrials('/solgs/search/trials');
		});
        }

    });

}

jQuery(document).ready( function () {

    jQuery('#population_search_entry').keyup(function(e) {

	jQuery("#population_search_entry")
		.css('border', 'solid #96d3ec');

	jQuery("#form-feedback-search-trials")
	    .empty();

	if(e.keycode == 13) {

     	    jQuery('#search_training_pop').click();
    	}
    });

    jQuery('#search_training_pop').on('click', function () {

	var entry = jQuery('#population_search_entry').val();
	jQuery("#searched_trials_message").hide();

	if (entry) {

	    checkPopulationExists(entry);
	} else {
	    jQuery("#population_search_entry")
		.css('border', 'solid #FF0000');

	    jQuery("#form-feedback-search-trials")
		.text('Please enter trial name.');
	}
    });

});

jQuery(document).ready( function () {

    jQuery('#search_all_training_pops').on('click', function () {

	jQuery("#searched_trials_div").empty();
	jQuery("#all_trials_div").empty();
	var url = '/solgs/search/trials';
        var result = 'all';
	searchAllTrials(url, result);
    });

});

jQuery(document).ready( function () {
    jQuery("#color_tip").tooltip();
});

function checkPopulationExists (name) {
    jQuery("#searched_trials_message")
	.html("Checking if trial or training population " + name + " exists...please wait...")
	.show();

	jQuery("#all_trials_div").empty();

	jQuery.ajax({
            type: 'POST',
            dataType: 'json',
	    data: {'name': name},
            url: '/solgs/check/population/exists/',
            success: function(res) {

		if (res.population_ids) {

		    checkTrainingPopulation(res.population_ids);

		    jQuery('#searched_trials_message').html(
			'
Checking if the trial or population can be used
'
			    + 'as a training population...please wait...
');

		} else {
		    jQuery('#searched_trials_message')
			.html('
' + name + ' is not in the database.
');

		    jQuery("#searched_trials_message")
			.delay(4000)
			.fadeOut('slow', function () {
			   // searchAllTrials('/solgs/search/trials');
			});
		}
	    },
	    error: function(res) {
		jQuery("#searched_trials_message")
		    .html('Error occured checking if the training population exists.');

		jQuery("#searched_trials_message")
		    .delay(4000)
		    .fadeOut('slow', function () {
			// searchAllTrials('/solgs/search/trials');
		    });
            }
	});

}

function createTrialsTable (tableId) {

    var table = '
';
    table    += '

';
    table    += '	Trial	Description	Location	Year	More details	';
   // table    += '	';
    table    += '

';
    table    += '
';

    return table;

}

function displayTrainingPopulations (tableDetails) {

    var divId   = tableDetails.divId;
    var tableId = tableDetails.tableId;
    var data    = tableDetails.data;

    if (data) {

	var tableRows = jQuery('#' + tableId + ' tr').length;

	if (tableRows > 1) {
	    jQuery('#' + tableId).dataTable().fnAddData(data);
	} else {

	    var table = createTrialsTable(tableId);

	    jQuery('#' + divId).html(table).show();

	    jQuery('#' + tableId).dataTable({
                    'order'        : [[0, "desc"],  [2, "desc"], [3, "desc"]],
		    'searching'    : true,
		    'ordering'     : true,
		    'processing'   : true,
		    'lengthChange' : false,
                    "bInfo"        : false,
                    "paging"       : false,
                    'oLanguage'    : {
		                     "sSearch": "Filter result by: "
		                    },
		    'data'         : data,
	    });
	}
    }

}
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import reactMixin from 'react-mixin';
import autoBind from 'react-autobind';
import Reflux from 'reflux';
import {actions} from '../actions';
import {bem} from '../bem';
import {stores} from '../stores';
import mixins from '../mixins';
import assetUtils from 'js/assetUtils';
import DocumentTitle from 'react-document-title';
import SharingForm from './permissions/sharingForm';
import ProjectSettings from './modalForms/projectSettings';
import DataTable from './table';
import ProjectDownloads from './projectDownloads';
import {PROJECT_SETTINGS_CONTEXTS} from '../constants';
import FormMap from './map';
import RESTServices from './RESTServices';
import ui from '../ui';

export class FormSubScreens extends React.Component {
  constructor(props){
    super(props);
    this.state = {};
    autoBind(this);
  }
  componentDidMount () {
    this.listenTo(stores.asset, this.dmixAssetStoreChange);
    var uid = this.props.params.assetid || this.props.uid || this.props.params.uid;
    if (this.props.randdelay && uid) {
      window.setTimeout(()=>{
        actions.resources.loadAsset({id: uid});
      }, Math.random() * 3000);
    } else if (uid) {
      actions.resources.loadAsset({id: uid});
    }
  }
  render () {
    let permAccess = this.userCan('view_submissions', this.state) || this.userCan('partial_submissions', this.state);

    if (!this.state.permissions)
      return false;

    if (this.props.location.pathname == `/forms/${this.state.uid}/settings` &&
        !this.userCan('change_asset', this.state)) {
      return (<ui.AccessDeniedMessage/>);
    }

    if (this.props.location.pathname == `/forms/${this.state.uid}/settings/rest` && !permAccess) {
      return (<ui.AccessDeniedMessage/>);
    }

    //TODO:Remove owner only access to settings/media after we remove KC iframe: https://github.com/kobotoolbox/kpi/issues/2647#issuecomment-624301693
    if (this.props.location.pathname == `/forms/${this.state.uid}/settings/media` && !assetUtils.isSelfOwned(this.state)) {
      return (<ui.AccessDeniedMessage/>);
    }

    var iframeUrl = '';
    var report__base = '';
    var deployment__identifier = '';

    if (this.state.uid != undefined) {
      if (this.state.deployment__identifier != undefined) {
        deployment__identifier = this.state.deployment__identifier;
        report__base = deployment__identifier.replace('/forms/', '/reports/');
      }
      switch(this.props.location.pathname) {
        case `/forms/${this.state.uid}/data/report-legacy`:
          iframeUrl = report__base+'/digest.html';
          break;
        case `/forms/${this.state.uid}/data/table`:
          return <DataTable asset={this.state} />;
        case `/forms/${this.state.uid}/data/table-legacy`:
          iframeUrl = report__base+'/export.html';
          break;
        case `/forms/${this.state.uid}/data/gallery`:
          iframeUrl = deployment__identifier+'/photos';
          break;
        case `/forms/${this.state.uid}/data/map`:
          return <FormMap asset={this.state} />;
        case `/forms/${this.state.uid}/data/map/${this.props.params.viewby}`:
          return <FormMap asset={this.state} viewby={this.props.params.viewby}/>;
        case `/forms/${this.state.uid}/data/downloads`:
          return this.renderProjectDownloads();
        case `/forms/${this.state.uid}/settings`:
          return this.renderSettingsEditor();
        case `/forms/${this.state.uid}/settings/media`:
          iframeUrl = deployment__identifier+'/form_settings';
          break;
        case `/forms/${this.state.uid}/settings/sharing`:
          return this.renderSharing();
        case `/forms/${this.state.uid}/settings/rest`:
          return <RESTServices asset={this.state} />;
        case `/forms/${this.state.uid}/settings/rest/${this.props.params.hookUid}`:
          return <RESTServices asset={this.state} hookUid={this.props.params.hookUid}/>;
        case `/forms/${this.state.uid}/settings/kobocat`:
          iframeUrl = deployment__identifier+'/form_settings';
          break;
        case `/forms/${this.state.uid}/reset`:
          return this.renderReset();
      }
    }

    var docTitle = this.state.name || t('Untitled');

    return (
        <DocumentTitle title={`${docTitle} | KoboToolbox`}>
          <bem.FormView>
            <bem.FormView__cell m='iframe'>
              <iframe src={iframeUrl} />
            </bem.FormView__cell>
          </bem.FormView>
        </DocumentTitle>
      );
  }
  renderSettingsEditor() {
    var docTitle = this.state.name || t('Untitled');
    return (
        <DocumentTitle title={`${docTitle} | KoboToolbox`}>
          <bem.FormView m='form-settings'>
            <ProjectSettings
              context={PROJECT_SETTINGS_CONTEXTS.EXISTING}
              formAsset={this.state}
            />
          </bem.FormView>
        </DocumentTitle>
    );
  }
  renderProjectDownloads() {
    var docTitle = this.state.name || t('Untitled');
    return (
      <DocumentTitle title={`${docTitle} | KoboToolbox`}>
        <ProjectDownloads asset={this.state} />
      </DocumentTitle>
    );
  }
  renderSharing() {
    const uid = this.props.params.assetid || this.props.params.uid;
    return (
      <bem.FormView m='form-settings-sharing'>
        <SharingForm uid={uid} />
      </bem.FormView>
    );
  }
  renderReset() {
    return (
      <bem.Loading>
        <bem.Loading__inner>
          <i />
          {t('loading...')}
        </bem.Loading__inner>
      </bem.Loading>
    );
  }
}

reactMixin(FormSubScreens.prototype, Reflux.ListenerMixin);
reactMixin(FormSubScreens.prototype, mixins.dmix);
reactMixin(FormSubScreens.prototype, mixins.permissions);
reactMixin(FormSubScreens.prototype, mixins.contextRouter);

FormSubScreens.contextTypes = {
  router: PropTypes.object
};

export default FormSubScreens;
<commit_msg>Fix for 2944<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import reactMixin from 'react-mixin';
import autoBind from 'react-autobind';
import Reflux from 'reflux';
import {actions} from '../actions';
import {bem} from '../bem';
import {stores} from '../stores';
import mixins from '../mixins';
import assetUtils from 'js/assetUtils';
import DocumentTitle from 'react-document-title';
import SharingForm from './permissions/sharingForm';
import ProjectSettings from './modalForms/projectSettings';
import DataTable from './table';
import ProjectDownloads from './projectDownloads';
import {PROJECT_SETTINGS_CONTEXTS} from '../constants';
import FormMap from './map';
import RESTServices from './RESTServices';
import ui from '../ui';

export class FormSubScreens extends React.Component {
  constructor(props){
    super(props);
    this.state = {};
    autoBind(this);
  }
  componentDidMount () {
    this.listenTo(stores.asset, this.dmixAssetStoreChange);
    var uid = this.props.params.assetid || this.props.uid || this.props.params.uid;
    if (this.props.randdelay && uid) {
      window.setTimeout(()=>{
        actions.resources.loadAsset({id: uid});
      }, Math.random() * 3000);
    } else if (uid) {
      actions.resources.loadAsset({id: uid});
    }
  }
  render () {
    let permAccess = this.userCan('view_submissions', this.state) || this.userCan('partial_submissions', this.state);

    if (!this.state.permissions)
      return false;

    if ((this.props.location.pathname == `/forms/${this.state.uid}/settings` || this.props.location.pathname == `/forms/${this.state.uid}/settings/sharing`) &&
        // TODO: Once "Manage Project" permission is added, remove "Edit Form" access here
        !this.userCan('change_asset', this.state)) {
      return (<ui.AccessDeniedMessage/>);
    }

    if (this.props.location.pathname == `/forms/${this.state.uid}/settings/rest` && !permAccess) {
      return (<ui.AccessDeniedMessage/>);
    }

    //TODO:Remove owner only access to settings/media after we remove KC iframe: https://github.com/kobotoolbox/kpi/issues/2647#issuecomment-624301693
    if (this.props.location.pathname == `/forms/${this.state.uid}/settings/media` && !assetUtils.isSelfOwned(this.state)) {
      return (<ui.AccessDeniedMessage/>);
    }

    var iframeUrl = '';
    var report__base = '';
    var deployment__identifier = '';

    if (this.state.uid != undefined) {
      if (this.state.deployment__identifier != undefined) {
        deployment__identifier = this.state.deployment__identifier;
        report__base = deployment__identifier.replace('/forms/', '/reports/');
      }
      switch(this.props.location.pathname) {
        case `/forms/${this.state.uid}/data/report-legacy`:
          iframeUrl = report__base+'/digest.html';
          break;
        case `/forms/${this.state.uid}/data/table`:
          return <DataTable asset={this.state} />;
        case `/forms/${this.state.uid}/data/table-legacy`:
          iframeUrl = report__base+'/export.html';
          break;
        case `/forms/${this.state.uid}/data/gallery`:
          iframeUrl = deployment__identifier+'/photos';
          break;
        case `/forms/${this.state.uid}/data/map`:
          return <FormMap asset={this.state} />;
        case `/forms/${this.state.uid}/data/map/${this.props.params.viewby}`:
          return <FormMap asset={this.state} viewby={this.props.params.viewby}/>;
        case `/forms/${this.state.uid}/data/downloads`:
          return this.renderProjectDownloads();
        case `/forms/${this.state.uid}/settings`:
          return this.renderSettingsEditor();
        case `/forms/${this.state.uid}/settings/media`:
          iframeUrl = deployment__identifier+'/form_settings';
          break;
        case `/forms/${this.state.uid}/settings/sharing`:
          return this.renderSharing();
        case `/forms/${this.state.uid}/settings/rest`:
          return <RESTServices asset={this.state} />;
        case `/forms/${this.state.uid}/settings/rest/${this.props.params.hookUid}`:
          return <RESTServices asset={this.state} hookUid={this.props.params.hookUid}/>;
        case `/forms/${this.state.uid}/settings/kobocat`:
          iframeUrl = deployment__identifier+'/form_settings';
          break;
        case `/forms/${this.state.uid}/reset`:
          return this.renderReset();
      }
    }

    var docTitle = this.state.name || t('Untitled');

    return (
        <DocumentTitle title={`${docTitle} | KoboToolbox`}>
          <bem.FormView>
            <bem.FormView__cell m='iframe'>
              <iframe src={iframeUrl} />
            </bem.FormView__cell>
          </bem.FormView>
        </DocumentTitle>
      );
  }
  renderSettingsEditor() {
    var docTitle = this.state.name || t('Untitled');
    return (
        <DocumentTitle title={`${docTitle} | KoboToolbox`}>
          <bem.FormView m='form-settings'>
            <ProjectSettings
              context={PROJECT_SETTINGS_CONTEXTS.EXISTING}
              formAsset={this.state}
            />
          </bem.FormView>
        </DocumentTitle>
    );
  }
  renderProjectDownloads() {
    var docTitle = this.state.name || t('Untitled');
    return (
      <DocumentTitle title={`${docTitle} | KoboToolbox`}>
        <ProjectDownloads asset={this.state} />
      </DocumentTitle>
    );
  }
  renderSharing() {
    const uid = this.props.params.assetid || this.props.params.uid;
    return (
      <bem.FormView m='form-settings-sharing'>
        <SharingForm uid={uid} />
      </bem.FormView>
    );
  }
  renderReset() {
    return (
      <bem.Loading>
        <bem.Loading__inner>
          <i />
          {t('loading...')}
        </bem.Loading__inner>
      </bem.Loading>
    );
  }
}

reactMixin(FormSubScreens.prototype, Reflux.ListenerMixin);
reactMixin(FormSubScreens.prototype, mixins.dmix);
reactMixin(FormSubScreens.prototype, mixins.permissions);
reactMixin(FormSubScreens.prototype, mixins.contextRouter);

FormSubScreens.contextTypes = {
  router: PropTypes.object
};

export default FormSubScreens;
<|endoftext|>


<commit_before>'use strict';

/* Directives */

angular.module('sfAdmin.directives', ["jsonRpc", "sfAdmin.filters"])
.directive("requireEqual", function() {
	return {
		restrict: "A",
		require: "ngModel",
		scope: {
			requireEqual: "=",
		},
		// Basic idea is it's a directive to do validation, used like this:
		// <input type="password" ng-model="record.password"/>
		// <input type="password" ng-model="record.confirmPassword" require-equal="record.password"/>
		link: function(scope, elem, attrs, ngModelCtrl) {
			// If for some reason we're getting called early, when ngModelCtrl
			// is not yet available, then do nothing.
			if (!ngModelCtrl) return;
			ngModelCtrl.$parsers.unshift(function(newValue) {
				if (newValue == scope.requireEqual) {
					ngModelCtrl.$setValidity("match", true);
				} else {
					ngModelCtrl.$setValidity("match", false);
				}
			});
		},
	};
})
.directive('focusMe', ['$timeout', '$parse', function($timeout, $parse) {
	// This directive's code is from http://stackoverflow.com/questions/14833326/how-to-set-focus-in-angularjs
	return {
		//scope: true,   // optionally create a child scope
		link: function(scope, element, attrs) {
			var model = $parse(attrs.focusMe);
			scope.$watch(model, function(value) {
				console.log('value=',value);
				if(value === true) {
					$timeout(function() {
						element[0].focus();
					});
				}
			});
			// to address @blesh's comment, set attribute value to 'false'
			// on blur event:
			element.bind('blur', function() {
				console.log('blur');
				scope.$apply(model.assign(scope, false));
			});
		}
	};
}]);
;
<commit_msg>remove console log<commit_after>'use strict';

/* Directives */

angular.module('sfAdmin.directives', ["jsonRpc", "sfAdmin.filters"])
.directive("requireEqual", function() {
	return {
		restrict: "A",
		require: "ngModel",
		scope: {
			requireEqual: "=",
		},
		// Basic idea is it's a directive to do validation, used like this:
		// <input type="password" ng-model="record.password"/>
		// <input type="password" ng-model="record.confirmPassword" require-equal="record.password"/>
		link: function(scope, elem, attrs, ngModelCtrl) {
			// If for some reason we're getting called early, when ngModelCtrl
			// is not yet available, then do nothing.
			if (!ngModelCtrl) return;
			ngModelCtrl.$parsers.unshift(function(newValue) {
				if (newValue == scope.requireEqual) {
					ngModelCtrl.$setValidity("match", true);
				} else {
					ngModelCtrl.$setValidity("match", false);
				}
			});
		},
	};
})
.directive('focusMe', ['$timeout', '$parse', function($timeout, $parse) {
	// This directive's code is from http://stackoverflow.com/questions/14833326/how-to-set-focus-in-angularjs
	return {
		//scope: true,   // optionally create a child scope
		link: function(scope, element, attrs) {
			var model = $parse(attrs.focusMe);
			scope.$watch(model, function(value) {
				if(value === true) {
					$timeout(function() {
						element[0].focus();
					});
				}
			});
			// to address @blesh's comment, set attribute value to 'false'
			// on blur event:
			element.bind('blur', function() {
				console.log('blur');
				scope.$apply(model.assign(scope, false));
			});
		}
	};
}]);
;
<|endoftext|>