<commit_before>/*
 * dependencies: jquery, backbonejs, underscorejs, window.sliMpd.router
 */
(function() {
    "use strict";

    var $ = window.jQuery,
        _ = window._;
    window.sliMpd = $.extend(true, window.sliMpd, {
        modules : {}
    });
    window.sliMpd.modules.AbstractView = window.Backbone.View.extend({

        rendered : false,

        initialize : function(options) {
            window.Backbone.View.prototype.initialize.call(this, options);
            _.bindAll.apply(_, [this].concat(_.functions(this)));
        },

        render : function() {
        	// only render page once (to prevent multiple click listeners)
            if (this.rendered) {
                return;
            }

            $('a.ajax-link', this.$el).off('click', this.genericClickListener).on('click', this.genericClickListener);
            $('.ajax-rqst', this.$el).off('click', this.ajaxRequestClickListener).on('click', this.ajaxRequestClickListener);
            $('.player-ctrl', this.$el).off('click', this.playerCtrlClickListener).on('click', this.playerCtrlClickListener);
            $('.ajax-partial', this.$el).off('click', this.ajaxPartialClickListener).on('click', this.ajaxPartialClickListener);
            $('.trigger-modal', this.$el).off('click', this.triggerModalClickListener).on('click', this.triggerModalClickListener);
            //$('*[data-toggle="lightbox"]', this.$el).off('click', this.triggerLightboxClickListener).on('click', this.triggerLightboxClickListener);

            // TODO: whats best practice to toggle playermode triggered by any element? @see app.js:'.playerModeToggle a'-Eventbinding
            $('.playerModeToggleTrigger', this.$el).off('click', this.playerModeToggleTriggerListener).on('click', this.playerModeToggleTriggerListener);

		    /* display selected value in dropdown instead of dropdown-label */
			var that = this;
		    $('.dropdown-label', that.$el).each(function(index, item){
		    	$(item).find('.btn:first-child').html(
		    		$('*[data-sortkey="'+ $(item, that.$el).attr('data-activesorting')+'"]', that.$el).html()
		    	);
		    });

		    $('.ajax-form', this.$el).on('submit', function(e) {
				e.preventDefault();
				var url = $(this).attr('action') + '?' + $(this).serialize();
				console.log(url);
				window.sliMpd.router.navigate(url, {
					trigger : true
				});

				//that.searchfield.autocomplete('close');
			});

		    $('.dropdown-toggle', this.$el).dropdown();
		    $('.toggle-tooltip', this.$el).tooltip();
  			$('[data-toggle="popover"]', this.$el).popover();

		    /* route /maintainance/albumdebug */
		    $('.inline-tab-nav a', this.$el).click(function (e) {
		        e.preventDefault();
		        $(this).tab('show');
		    });
		    $('.grid', this.$el).sortable({
		        tolerance: 'pointer',
		        revert: 'invalid',
		        placeholder: 'span2 well placeholder tile',
		        forceHelperSize: true
		    });

		    $('object.svg-ajax-object', that.$el).each(function(index, item){
		    	console.log('FOUND: object.svg-ajax-object');
		    	var obj = item;
			    $.ajax({
	    			url: $(obj).attr('data-svgurl')
	    		}).retry({
	    			times: 10,
	    			timeout: 3000
	    		}).then(function(response){
	    			$(obj).attr('data', $(obj).attr('data-svgurl'));
	  			});
	  		});

            window.Backbone.View.prototype.render.call(this);
            this.rendered = true;
        },

        remove : function() {
            $('a.ajax-link', this.$el).off('click', this.genericClickListener);
            $('.player-ctrl', this.$el).off('click', this.playerCtrlClickListener);

            window.Backbone.View.prototype.remove.call(this);
        },

        genericClickListener : function(e) {
            e.preventDefault();
        	var $el = $(e.currentTarget);
            window.sliMpd.router.navigate($el.attr('href'), {
                trigger : true
            });
        },

        playerCtrlClickListener : function(e) {
            e.preventDefault();
        	var $el = $(e.currentTarget);
        	if(typeof $el.attr('data-player') == 'undefined') {
        		console.log('ERROR: missing player-item. exiting...');
        		return;
        	}
			try {
		        var item = JSON.parse($el.attr('data-player'));
		        window.sliMpd.currentPlayer.process(item);
		    } catch(e) {
		    	//console.log(e + ' in data-player attribute');
			}
		},

		ajaxPartialClickListener : function(e) {
       		e.preventDefault();
        	var $el = $(e.currentTarget);
        	if(typeof $el.attr('data-ajaxtarget') == 'undefined') {
        		console.log('ERROR: data-ajaxtarget. exiting...');
        		return;
        	}
        	var that = this;
        	$.ajax({
				url: window.sliMpd.setGetParameter($el.attr('href'), 'nosurrounding', '1')
			}).done(function(response) {
				$($el.attr('data-ajaxtarget')).html(response);
				that.rendered = false;
				that.render();
			});
		},

		ajaxRequestClickListener : function(e) {
			e.preventDefault();
        	var $el = $(e.currentTarget);
        	$.ajax({
				url: window.sliMpd.setGetParameter($el.attr('data-href'), 'nosurrounding', '1')
			}).done(function(response) {
				window.sliMpd.checkNotify(response);
			});
		},

       	triggerModalClickListener : function(e) {
       		e.preventDefault();
       		var $el = $(e.currentTarget);
	        $.ajax({
				url: $el.attr('data-href')
			}).done(function(response){
				window.sliMpd.modal.renderModalContent(response);
			});
       	},

       	/*
       	// FIXME: why does this not work?
       	// @see: app.js:document.ready()
       	triggerLightboxClickListener : function(e) {
       		event.preventDefault();
			return $(this).ekkoLightbox({
				always_show_close: true,
				type: 'image'
			});
		},
        */
        // TODO: whats best practice to toggle playermode triggered by any element? @see app.js:'.playerModeToggle a'-Eventbinding
        playerModeToggleTriggerListener : function(e) {
       		e.preventDefault();
       		$('.playerModeToggle a').trigger('click');
       	},

        process : function(e) {
           //
        },

    });

})();<commit_msg>dropped eventlisteners in AbstractView.js::remove()<commit_after>/*
 * dependencies: jquery, backbonejs, underscorejs, window.sliMpd.router
 */
(function() {
    "use strict";

    var $ = window.jQuery,
        _ = window._;
    window.sliMpd = $.extend(true, window.sliMpd, {
        modules : {}
    });
    window.sliMpd.modules.AbstractView = window.Backbone.View.extend({

        rendered : false,

        initialize : function(options) {
            window.Backbone.View.prototype.initialize.call(this, options);
            _.bindAll.apply(_, [this].concat(_.functions(this)));
        },

        render : function() {
        	// only render page once (to prevent multiple click listeners)
            if (this.rendered) {
                return;
            }

            $('a.ajax-link', this.$el).off('click', this.genericClickListener).on('click', this.genericClickListener);
            $('.ajax-rqst', this.$el).off('click', this.ajaxRequestClickListener).on('click', this.ajaxRequestClickListener);
            $('.player-ctrl', this.$el).off('click', this.playerCtrlClickListener).on('click', this.playerCtrlClickListener);
            $('.ajax-partial', this.$el).off('click', this.ajaxPartialClickListener).on('click', this.ajaxPartialClickListener);
            $('.trigger-modal', this.$el).off('click', this.triggerModalClickListener).on('click', this.triggerModalClickListener);
            //$('*[data-toggle="lightbox"]', this.$el).off('click', this.triggerLightboxClickListener).on('click', this.triggerLightboxClickListener);

            // TODO: whats best practice to toggle playermode triggered by any element? @see app.js:'.playerModeToggle a'-Eventbinding
            $('.playerModeToggleTrigger', this.$el).off('click', this.playerModeToggleTriggerListener).on('click', this.playerModeToggleTriggerListener);

		    /* display selected value in dropdown instead of dropdown-label */
			var that = this;
		    $('.dropdown-label', that.$el).each(function(index, item){
		    	$(item).find('.btn:first-child').html(
		    		$('*[data-sortkey="'+ $(item, that.$el).attr('data-activesorting')+'"]', that.$el).html()
		    	);
		    });

		    $('.ajax-form', this.$el).on('submit', function(e) {
				e.preventDefault();
				var url = $(this).attr('action') + '?' + $(this).serialize();
				console.log(url);
				window.sliMpd.router.navigate(url, {
					trigger : true
				});

				//that.searchfield.autocomplete('close');
			});

		    $('.dropdown-toggle', this.$el).dropdown();
		    $('.toggle-tooltip', this.$el).tooltip();
  			$('[data-toggle="popover"]', this.$el).popover();

		    /* route /maintainance/albumdebug */
		    $('.inline-tab-nav a', this.$el).click(function (e) {
		        e.preventDefault();
		        $(this).tab('show');
		    });
		    $('.grid', this.$el).sortable({
		        tolerance: 'pointer',
		        revert: 'invalid',
		        placeholder: 'span2 well placeholder tile',
		        forceHelperSize: true
		    });

		    $('object.svg-ajax-object', that.$el).each(function(index, item){
		    	console.log('FOUND: object.svg-ajax-object');
		    	var obj = item;
			    $.ajax({
	    			url: $(obj).attr('data-svgurl')
	    		}).retry({
	    			times: 10,
	    			timeout: 3000
	    		}).then(function(response){
	    			$(obj).attr('data', $(obj).attr('data-svgurl'));
	  			});
	  		});

            window.Backbone.View.prototype.render.call(this);
            this.rendered = true;
        },

        remove : function() {
            $('a.ajax-link', this.$el).off('click', this.genericClickListener);
            $('.ajax-rqst', this.$el).off('click', this.ajaxRequestClickListener);
            $('.player-ctrl', this.$el).off('click', this.playerCtrlClickListener);
            $('.ajax-partial', this.$el).off('click', this.ajaxPartialClickListener);
            $('.trigger-modal', this.$el).off('click', this.triggerModalClickListener);
            $('.playerModeToggleTrigger', this.$el).off('click', this.playerModeToggleTriggerListener);

            window.Backbone.View.prototype.remove.call(this);
        },

        genericClickListener : function(e) {
            e.preventDefault();
        	var $el = $(e.currentTarget);
            window.sliMpd.router.navigate($el.attr('href'), {
                trigger : true
            });
        },

        playerCtrlClickListener : function(e) {
            e.preventDefault();
        	var $el = $(e.currentTarget);
        	if(typeof $el.attr('data-player') == 'undefined') {
        		console.log('ERROR: missing player-item. exiting...');
        		return;
        	}
			try {
		        var item = JSON.parse($el.attr('data-player'));
		        window.sliMpd.currentPlayer.process(item);
		    } catch(e) {
		    	//console.log(e + ' in data-player attribute');
			}
		},

		ajaxPartialClickListener : function(e) {
       		e.preventDefault();
        	var $el = $(e.currentTarget);
        	if(typeof $el.attr('data-ajaxtarget') == 'undefined') {
        		console.log('ERROR: data-ajaxtarget. exiting...');
        		return;
        	}
        	var that = this;
        	$.ajax({
				url: window.sliMpd.setGetParameter($el.attr('href'), 'nosurrounding', '1')
			}).done(function(response) {
				$($el.attr('data-ajaxtarget')).html(response);
				that.rendered = false;
				that.render();
			});
		},

		ajaxRequestClickListener : function(e) {
			e.preventDefault();
        	var $el = $(e.currentTarget);
        	$.ajax({
				url: window.sliMpd.setGetParameter($el.attr('data-href'), 'nosurrounding', '1')
			}).done(function(response) {
				window.sliMpd.checkNotify(response);
			});
		},

       	triggerModalClickListener : function(e) {
       		e.preventDefault();
       		var $el = $(e.currentTarget);
	        $.ajax({
				url: $el.attr('data-href')
			}).done(function(response){
				window.sliMpd.modal.renderModalContent(response);
			});
       	},

       	/*
       	// FIXME: why does this not work?
       	// @see: app.js:document.ready()
       	triggerLightboxClickListener : function(e) {
       		event.preventDefault();
			return $(this).ekkoLightbox({
				always_show_close: true,
				type: 'image'
			});
		},
        */
        // TODO: whats best practice to toggle playermode triggered by any element? @see app.js:'.playerModeToggle a'-Eventbinding
        playerModeToggleTriggerListener : function(e) {
       		e.preventDefault();
       		$('.playerModeToggle a').trigger('click');
       	},

        process : function(e) {
           //
        },

    });

})();<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var util = require('util');
var Class = require('../../util/class');
var Statement = require('./statement');
var FieldString = require('../condition/field');

/**
 * Documentation forthcoming.
 *
 * Just for building conditions.
 *
 * @since 1.0
 * @public
 * @constructor
 * @param {Grammar} grammar The grammar to use when building phrases.
 */
var Phrasing = Class.extend(/** @lends Phrasing# */{
  init: function (grammar, translator) {
    this._super();
    this._grammar = grammar;
    this._translator = translator;
  },

  /**
   * Documentation forthcoming.
   *
   * @since 1.0
   * @public
   * @method
   * @return {Fragment} The where fragment.
   */
  where: function(condition) {
    return this._grammar.join([
      'WHERE', ' ', condition.build(this._grammar, this._translator)]);
  },

  /**
   * Documentation forthcoming.
   *
   * @since 1.0
   * @public
   * @method
   * @return {Fragment} The join fragment.
   */
  join: function(join) {
    var quote = this._grammar.field.bind(this._grammar);
    var fragments = [join.type.toUpperCase(), ' JOIN ', quote(join.table)];
    if (join.condition) {
      fragments.push(' ON ', join.condition.build(
        this._grammar,
        this._translator));
    }
    return this._grammar.join(fragments);
  },

  /**
   * Documentation forthcoming.
   *
   * @since 1.0
   * @public
   * @method
   * @param {String|Array} data.columns The columns to select. This will be a string,
   * `*` when the request is for all columns. Otherwise, it will be an array of
   * strings representing the column names. The strings may be qualified with the
   * table name, in which case they would use a dot to separate the field from
   * the column. For example, `articles.title` would refer to the `title` column
   * of the `articles` table.
   * @return {Statement} The select statement.
   */
  select: function(data) {
    var tables = data.tables;
    var columns = data.columns;
    var joins = data.joins;
    var where = data.where;
    var quote = this._grammar.field.bind(this._grammar);
    var quotedColumns = columns === '*' ? [columns] : columns.map(quote);
    var delimitedColumns = this._grammar.delimit(quotedColumns);
    var delimitedTables = this._grammar.delimit(tables.map(quote));
    var fragments = [].concat(['SELECT '],
      delimitedColumns, [' FROM '], delimitedTables);

    if (where) { fragments.push(' ', this.where(where)); }

    joins.forEach(function(join) {
      fragments.push(' ', this.join(join));
    }, this);

    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  insert: function(data) {
    var table = data.table;
    var quoteField = this._grammar.field.bind(this._grammar);
    var quoteValue = this._grammar.value.bind(this._grammar);

    var columns = _(data.values)
      .map(_.keys)
      .flatten()
      .uniq()
      .value();

    var valueGroups = data.values.map(function(value) {
      var values = columns.map(function(col) {
        return value[col];
      })
      .map(function(value) {
        return value instanceof FieldString.__class__ ?
          quoteField(value) :
          quoteValue(value);
      });
      values = this._grammar.delimit(values);
      values = this._grammar.join(values);
      values = this._grammar.group(values);
      values = this._grammar.join(values);
      return values;
    }, this);

    valueGroups = this._grammar.delimit(valueGroups);
    valueGroups = this._grammar.join(valueGroups);
    columns = this._grammar.delimit(columns.map(quoteField));
    columns = this._grammar.group(this._grammar.join(columns));
    var fragments = [].concat(['INSERT INTO '], [quoteField(table)],
      [' '], columns, [' VALUES '], valueGroups);
    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  delete: function(data) {
    var table = data.table;
    var table = data.table;
    var where = data.where;
    var quote = this._grammar.field.bind(this._grammar);
    var fragments = [].concat(['DELETE FROM '],
      quote(table));

    if (where) { fragments.push(' ', this.where(where)); }

    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  createTable: function(data) {
    var options = data.options;
    var quoteField = this._grammar.field.bind(this._grammar);
    var columns = data.columns.map(function(column) {
      var type = this._translator.type(column.type, column.typeOptions);
      return util.format('%s %s', quoteField(column.name), type);
    }, this);
    var delimitedColumns = this._grammar.delimit(columns);
    var joinedColumns = this._grammar.join(delimitedColumns);
    var groupedColumns = this._grammar.group(joinedColumns);
    var fragments = ['CREATE TABLE '];
    if (options.ifNotExists) {
      fragments.push('IF NOT EXISTS ');
    }
    fragments.push(util.format('%s ', quoteField(data.name)));
    fragments = fragments.concat(groupedColumns);
    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  dropTable: function(data) {
    var options = data.options;
    var quoteField = this._grammar.field.bind(this._grammar);
    var fragments = ['DROP TABLE '];
    if (options.ifExists) {
      fragments.push('IF EXISTS ');
    }
    fragments.push(quoteField(data.name));
    return Statement.create(this._grammar.join(fragments));
  }
});

module.exports = Phrasing.reopenClass({ __name__: 'Phrasing' });
<commit_msg>Removed duplicate line.<commit_after>'use strict';

var _ = require('lodash');
var util = require('util');
var Class = require('../../util/class');
var Statement = require('./statement');
var FieldString = require('../condition/field');

/**
 * Documentation forthcoming.
 *
 * Just for building conditions.
 *
 * @since 1.0
 * @public
 * @constructor
 * @param {Grammar} grammar The grammar to use when building phrases.
 */
var Phrasing = Class.extend(/** @lends Phrasing# */{
  init: function (grammar, translator) {
    this._super();
    this._grammar = grammar;
    this._translator = translator;
  },

  /**
   * Documentation forthcoming.
   *
   * @since 1.0
   * @public
   * @method
   * @return {Fragment} The where fragment.
   */
  where: function(condition) {
    return this._grammar.join([
      'WHERE', ' ', condition.build(this._grammar, this._translator)]);
  },

  /**
   * Documentation forthcoming.
   *
   * @since 1.0
   * @public
   * @method
   * @return {Fragment} The join fragment.
   */
  join: function(join) {
    var quote = this._grammar.field.bind(this._grammar);
    var fragments = [join.type.toUpperCase(), ' JOIN ', quote(join.table)];
    if (join.condition) {
      fragments.push(' ON ', join.condition.build(
        this._grammar,
        this._translator));
    }
    return this._grammar.join(fragments);
  },

  /**
   * Documentation forthcoming.
   *
   * @since 1.0
   * @public
   * @method
   * @param {String|Array} data.columns The columns to select. This will be a string,
   * `*` when the request is for all columns. Otherwise, it will be an array of
   * strings representing the column names. The strings may be qualified with the
   * table name, in which case they would use a dot to separate the field from
   * the column. For example, `articles.title` would refer to the `title` column
   * of the `articles` table.
   * @return {Statement} The select statement.
   */
  select: function(data) {
    var tables = data.tables;
    var columns = data.columns;
    var joins = data.joins;
    var where = data.where;
    var quote = this._grammar.field.bind(this._grammar);
    var quotedColumns = columns === '*' ? [columns] : columns.map(quote);
    var delimitedColumns = this._grammar.delimit(quotedColumns);
    var delimitedTables = this._grammar.delimit(tables.map(quote));
    var fragments = [].concat(['SELECT '],
      delimitedColumns, [' FROM '], delimitedTables);

    if (where) { fragments.push(' ', this.where(where)); }

    joins.forEach(function(join) {
      fragments.push(' ', this.join(join));
    }, this);

    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  insert: function(data) {
    var table = data.table;
    var quoteField = this._grammar.field.bind(this._grammar);
    var quoteValue = this._grammar.value.bind(this._grammar);

    var columns = _(data.values)
      .map(_.keys)
      .flatten()
      .uniq()
      .value();

    var valueGroups = data.values.map(function(value) {
      var values = columns.map(function(col) {
        return value[col];
      })
      .map(function(value) {
        return value instanceof FieldString.__class__ ?
          quoteField(value) :
          quoteValue(value);
      });
      values = this._grammar.delimit(values);
      values = this._grammar.join(values);
      values = this._grammar.group(values);
      values = this._grammar.join(values);
      return values;
    }, this);

    valueGroups = this._grammar.delimit(valueGroups);
    valueGroups = this._grammar.join(valueGroups);
    columns = this._grammar.delimit(columns.map(quoteField));
    columns = this._grammar.group(this._grammar.join(columns));
    var fragments = [].concat(['INSERT INTO '], [quoteField(table)],
      [' '], columns, [' VALUES '], valueGroups);
    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  delete: function(data) {
    var table = data.table;
    var where = data.where;
    var quote = this._grammar.field.bind(this._grammar);
    var fragments = [].concat(['DELETE FROM '],
      quote(table));

    if (where) { fragments.push(' ', this.where(where)); }

    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  createTable: function(data) {
    var options = data.options;
    var quoteField = this._grammar.field.bind(this._grammar);
    var columns = data.columns.map(function(column) {
      var type = this._translator.type(column.type, column.typeOptions);
      return util.format('%s %s', quoteField(column.name), type);
    }, this);
    var delimitedColumns = this._grammar.delimit(columns);
    var joinedColumns = this._grammar.join(delimitedColumns);
    var groupedColumns = this._grammar.group(joinedColumns);
    var fragments = ['CREATE TABLE '];
    if (options.ifNotExists) {
      fragments.push('IF NOT EXISTS ');
    }
    fragments.push(util.format('%s ', quoteField(data.name)));
    fragments = fragments.concat(groupedColumns);
    return Statement.create(this._grammar.join(fragments));
  },

  /**
   * Documentation forthcoming.
   */
  dropTable: function(data) {
    var options = data.options;
    var quoteField = this._grammar.field.bind(this._grammar);
    var fragments = ['DROP TABLE '];
    if (options.ifExists) {
      fragments.push('IF EXISTS ');
    }
    fragments.push(quoteField(data.name));
    return Statement.create(this._grammar.join(fragments));
  }
});

module.exports = Phrasing.reopenClass({ __name__: 'Phrasing' });
<|endoftext|>


<commit_before>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

function is_external() {
	return typeof window !== "undefined";
}

//Cache electron so require doesn't get rewritten
const ld = is_external() ? require("electron").remote.require : require;
const electronWindow = is_external() ? require("electron").remote.getCurrentWindow() : null;

export default {
	load: function (library) {
		return ld(library);
	},
	close: function() {
		if (electronWindow) {
			electronWindow.close();
		} else {
			process.exit(0);
		}
	},
	is_external: is_external
};
<commit_msg>Cache electron reference<commit_after>/* Copyright (c) Royal Holloway, University of London | Contact Blake Loring (blake@parsed.uk), Duncan Mitchell (Duncan.Mitchell.2015@rhul.ac.uk), or Johannes Kinder (johannes.kinder@rhul.ac.uk) for details or support | LICENSE.md for license details */

function is_external() {
	return typeof window !== "undefined";
}

function calectron() {
  if (!window._ELC) {
    window._ELC = require("electron");
  }
  return window._ELC;
}

//Cache electron so require doesn't get rewritten
const ld = is_external() ? calectron().remote.require : require;
const electronWindow = is_external() ? calectron().remote.getCurrentWindow() : null;

export default {
	load: function (library) {
		return ld(library);
	},
	close: function() {
		if (electronWindow) {
			electronWindow.close();
		} else {
			process.exit(0);
		}
	},
	is_external: is_external
};
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

define(function(require, exports, module) {

/**
 * 'eval' command
 */
var evalCommandSpec = {
  name: 'eval',
  params: [
    {
      name: 'javascript',
      type: 'javascript',
      description: 'Script to evaluate'
    }
  ],
  returnType: 'html',
  description: 'Call \'eval\' on some JavaScript',
  exec: function(args, context) {
    var resultPrefix = 'Result for \'' + args.javascript + '\': ';
    try {
      var result = eval(args.javascript);

      if (result === null) {
        return resultPrefix + 'null.';
      }

      if (result === undefined) {
        return resultPrefix + 'undefined.';
      }

      if (typeof result === 'function') {
        return resultPrefix +
          (result + '').replace(/\n/g, '
').replace(/ /g, '&#160');
      }

      return resultPrefix + result;
    } catch (e) {
      return 'Error: ' + e.message;
    }
  }
};

/**
 * Arm window.alert with metadata
 */
var alert = {
  name: 'alert',
  description: 'Show an alert dialog',
  params: [
    {
      name: 'message',
      type: 'string',
      description: 'Message to display'
    }
  ],
  exec: function(args, context) {
    window.alert(args.message);
  }
};

/**
 * 'echo' command
 */
var echo = {
  name: 'echo',
  description: 'Show a message',
  params: [
    {
      name: 'message',
      type: 'string',
      description: 'Message to output'
    }
  ],
  returnType: 'string',
  exec: function echo(args, context) {
    return args.message;
  }
};

var gcli = require('gcli/index');

exports.startup = function() {
  gcli.addCommand(evalCommandSpec);
  gcli.addCommand(echo);
  gcli.addCommand(alert);
};

exports.shutdown = function() {
  gcli.removeCommand(evalCommandSpec);
  gcli.removeCommand(echo);
  gcli.removeCommand(alert);
};

});
<commit_msg>Bug 678152 (part) - Shorten message so it doesn't wrap in popup dialog<commit_after>/*
 * Copyright 2009-2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE.txt or:
 * http://opensource.org/licenses/BSD-3-Clause
 */

define(function(require, exports, module) {

/**
 * 'eval' command
 */
var evalCommandSpec = {
  name: 'eval',
  params: [
    {
      name: 'javascript',
      type: 'javascript',
      description: 'Script to evaluate'
    }
  ],
  returnType: 'html',
  description: 'Call \'eval\' on some JavaScript',
  exec: function(args, context) {
    var resultPrefix = 'Result for \'' + args.javascript + '\': ';
    try {
      var result = eval(args.javascript);

      if (result === null) {
        return resultPrefix + 'null.';
      }

      if (result === undefined) {
        return resultPrefix + 'undefined.';
      }

      if (typeof result === 'function') {
        return resultPrefix +
          (result + '').replace(/\n/g, '
').replace(/ /g, '&#160');
      }

      return resultPrefix + result;
    } catch (e) {
      return 'Error: ' + e.message;
    }
  }
};

/**
 * Arm window.alert with metadata
 */
var alert = {
  name: 'alert',
  description: 'Show an alert dialog',
  params: [
    {
      name: 'message',
      type: 'string',
      description: 'Message to display'
    }
  ],
  exec: function(args, context) {
    window.alert(args.message);
  }
};

/**
 * 'echo' command
 */
var echo = {
  name: 'echo',
  description: 'Show a message',
  params: [
    {
      name: 'message',
      type: 'string',
      description: 'Message'
    }
  ],
  returnType: 'string',
  exec: function echo(args, context) {
    return args.message;
  }
};

var gcli = require('gcli/index');

exports.startup = function() {
  gcli.addCommand(evalCommandSpec);
  gcli.addCommand(echo);
  gcli.addCommand(alert);
};

exports.shutdown = function() {
  gcli.removeCommand(evalCommandSpec);
  gcli.removeCommand(echo);
  gcli.removeCommand(alert);
};

});
<|endoftext|>


<commit_before>'use strict';

// MODULES //

var tape = require( 'tape' );
var isfinite = require( '@stdlib/math/base/utils/is-finite' );
var isnan = require( '@stdlib/math/base/utils/is-nan' );
var abs = require( '@stdlib/math/base/special/abs' );
var PINF = require( '@stdlib/math/constants/float64-pinf' );
var gammainc = require( './../lib' );

// FIXTURES //

var expected1;
var expected2;
var expected3;
var expected4;
var fixtures;
var x;
var s;
var v;
var i;

fixtures = JSON.parse( require( './fixtures/cpp/output.json').program_message );

x = fixtures.x;
s = fixtures.s;

expected1 = fixtures.lower_regularized;
for ( i = 0; i < expected1.length; i++ ) {
	v = expected1[ i ];
	if ( v === 'Inf' ) {
		expected1[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected1[ i ] = NaN;
	}
}
expected2 = fixtures.upper_regularized;
for ( i = 0; i < expected2.length; i++ ) {
	v = expected2[ i ];
	if ( v === 'Inf' ) {
		expected2[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected2[ i ] = NaN;
	}
}
expected3 = fixtures.lower_unregularized;
for ( i = 0; i < expected3.length; i++ ) {
	v = expected3[ i ];
	if ( v === 'Inf' ) {
		expected3[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected3[ i ] = NaN;
	}
}
expected4 = fixtures.upper_unregularized;
for ( i = 0; i < expected4.length; i++ ) {
	v = expected4[ i ];
	if ( v === 'Inf' ) {
		expected4[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected4[ i ] = NaN;
	}
}

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.strictEqual( typeof gammainc, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function returns `NaN` if provided a `NaN`', function test( t ) {
	var val;

	val = gammainc( NaN, 2 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	val = gammainc( 4, NaN );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	t.end();
});

tape( 'the function returns NaN if provided x < 0 or s <= 0', function test( t ) {
	var val;

	// Case: x < 0
	val = gammainc( -0.1, 2 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	// Case: s = 0
	val = gammainc( 0.1, 0 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	// Case: s < 0
	val = gammainc( 0.1, -2 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	t.end();
});

tape( 'the function returns 0 for the lower incomplete gamma function when the first argument is zero', function test( t ) {
	var val;
	var s;
	for ( s = 1; s < 10; s++ ) {
		val = gammainc( 0, s );
		t.ok( val === 0, 'returns 0' );
	}
	t.end();
});

tape( 'the function correctly evaluates the lower incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ] );

		b1 = isfinite( actual );
		b2 = isfinite( expected1[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected1[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 ) {
			delta = abs( actual - expected1[ i ] );
			tol = 2e-14 * expected1[ i ];
			t.ok( delta <= tol, 'returned result is within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected1[ i ] + '.' );
		}
	}
	t.end();
});

tape( 'the function correctly evaluates the upper incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ], true, true );

		b1 = isfinite( actual );
		b2 = isfinite( expected2[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected2[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 ) {
			delta = abs( actual - expected2[ i ] );
			tol = 9e-15 * expected2[ i ];
			t.ok( delta <= tol, 'within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected2[ i ] + '.' );
		}
	}
	t.end();
});

tape( 'the function correctly evaluates the unregularized lower incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ], false, false );

		b1 = isfinite( actual );
		b2 = isfinite( expected3[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected3[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 ) {
			delta = abs( actual - expected3[ i ] );
			tol = 3e-14 * expected3[ i ];
			t.ok( delta <= tol, 'within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected3[ i ] + '.' );
		}
	}
	t.end();
});

tape( 'the function correctly evaluates the unregularized upper incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ], false, true );

		b1 = isfinite( actual );
		b2 = isfinite( expected4[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected4[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 ) {
			delta = abs( actual - expected4[ i ] );
			tol = 3e-14 * expected4[ i ];
			t.ok( delta <= tol, 'within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected4[ i ] + '.' );
		}
	}
	t.end();
});
<commit_msg>Update tests to check if expected value is NaN<commit_after>'use strict';

// MODULES //

var tape = require( 'tape' );
var isfinite = require( '@stdlib/math/base/utils/is-finite' );
var isnan = require( '@stdlib/math/base/utils/is-nan' );
var abs = require( '@stdlib/math/base/special/abs' );
var PINF = require( '@stdlib/math/constants/float64-pinf' );
var gammainc = require( './../lib' );

// FIXTURES //

var expected1;
var expected2;
var expected3;
var expected4;
var fixtures;
var x;
var s;
var v;
var i;

fixtures = JSON.parse( require( './fixtures/cpp/output.json').program_message );

x = fixtures.x;
s = fixtures.s;

expected1 = fixtures.lower_regularized;
for ( i = 0; i < expected1.length; i++ ) {
	v = expected1[ i ];
	if ( v === 'Inf' ) {
		expected1[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected1[ i ] = NaN;
	}
}
expected2 = fixtures.upper_regularized;
for ( i = 0; i < expected2.length; i++ ) {
	v = expected2[ i ];
	if ( v === 'Inf' ) {
		expected2[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected2[ i ] = NaN;
	}
}
expected3 = fixtures.lower_unregularized;
for ( i = 0; i < expected3.length; i++ ) {
	v = expected3[ i ];
	if ( v === 'Inf' ) {
		expected3[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected3[ i ] = NaN;
	}
}
expected4 = fixtures.upper_unregularized;
for ( i = 0; i < expected4.length; i++ ) {
	v = expected4[ i ];
	if ( v === 'Inf' ) {
		expected4[ i ] = PINF;
	}
	else if ( v === 'NaN' ) {
		expected4[ i ] = NaN;
	}
}

// TESTS //

tape( 'main export is a function', function test( t ) {
	t.ok( true, __filename );
	t.strictEqual( typeof gammainc, 'function', 'main export is a function' );
	t.end();
});

tape( 'the function returns `NaN` if provided a `NaN`', function test( t ) {
	var val;

	val = gammainc( NaN, 2 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	val = gammainc( 4, NaN );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	t.end();
});

tape( 'the function returns NaN if provided x < 0 or s <= 0', function test( t ) {
	var val;

	// Case: x < 0
	val = gammainc( -0.1, 2 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	// Case: s = 0
	val = gammainc( 0.1, 0 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	// Case: s < 0
	val = gammainc( 0.1, -2 );
	t.strictEqual( isnan( val ), true, 'returns NaN' );

	t.end();
});

tape( 'the function returns 0 for the lower incomplete gamma function when the first argument is zero', function test( t ) {
	var val;
	var s;
	for ( s = 1; s < 10; s++ ) {
		val = gammainc( 0, s );
		t.ok( val === 0, 'returns 0' );
	}
	t.end();
});

tape( 'the function correctly evaluates the lower incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ] );

		b1 = isfinite( actual );
		b2 = isfinite( expected1[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected1[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 || !b2 ) {
			delta = abs( actual - expected1[ i ] );
			tol = 2e-14 * expected1[ i ];
			t.ok( delta <= tol, 'returned result is within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected1[ i ] + '.' );
		}
	}
	t.end();
});

tape( 'the function correctly evaluates the upper incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ], true, true );

		b1 = isfinite( actual );
		b2 = isfinite( expected2[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected2[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 || !b2 ) {
			delta = abs( actual - expected2[ i ] );
			tol = 9e-15 * expected2[ i ];
			t.ok( delta <= tol, 'within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected2[ i ] + '.' );
		}
	}
	t.end();
});

tape( 'the function correctly evaluates the unregularized lower incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ], false, false );

		b1 = isfinite( actual );
		b2 = isfinite( expected3[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected3[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 || !b2 ) {
			delta = abs( actual - expected3[ i ] );
			tol = 3e-14 * expected3[ i ];
			t.ok( delta <= tol, 'within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected3[ i ] + '.' );
		}
	}
	t.end();
});

tape( 'the function correctly evaluates the unregularized upper incomplete gamma function', function test( t ) {
	var actual;
	var delta;
	var tol;
	var b1;
	var b2;
	var i;
	for ( i = 0; i < x.length; i++ ) {
		actual = gammainc( x[ i ], s[ i ], false, true );

		b1 = isfinite( actual );
		b2 = isfinite( expected4[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b2) ? 'finite' : 'not finite' ) );

		b1 = isnan( actual );
		b2 = isnan( expected4[ i ] );
		t.equal( b1, b2, 'returned result is ' + ( (b1) ? '' : 'not' ) + ' NaN' );
		if ( !b1 || !b2 ) {
			delta = abs( actual - expected4[ i ] );
			tol = 3e-14 * expected4[ i ];
			t.ok( delta <= tol, 'within tolerance. x: '+x[i]+', s: '+s[i]+' actual: ' + actual + '; expected: ' + expected4[ i ] + '.' );
		}
	}
	t.end();
});
<|endoftext|>


<commit_before>var searchFilter = $('#search-filter').val();
var pageLen = $('#page-len').val();
var dateRange = $('#date-range').val();

function failedAjaxCall() {
    'use strict';
    $('#table-loading').remove();
}

function countFailCallback() {
    'use strict';
    JSBase.replaceContentByClass('.count-badge', '∞');
}

function batchCountElements(data) {
    'use strict';
    var localData = data.result,
        len = localData.length,
        i = 0,
        j = 0,
        batchElements = 4,
        jobName = '',
        queriesLen = len * 4,
        batchQueries = new Array(queriesLen),
        errorReason = 'Batch count failed',
        deferredAjaxCall = null,
        ajaxData = null;

    if (len > 0) {
        for (i; i < queriesLen; i += batchElements) {
            j = i;
            jobName = localData[i / batchElements].job;

            // Get successful defconfig count.
            batchQueries[i] = {
                'method': 'GET',
                'operation_id': '#defconf-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=PASS&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get failed defconfig count.
            batchQueries[j + 1] = {
                'method': 'GET',
                'operation_id': '#defconf-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=FAIL&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get successful boot reports count.
            batchQueries[j + 2] = {
                'method': 'GET',
                'operation_id': '#boot-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=PASS&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get failed boot reports count.
            batchQueries[j + 3] = {
                'method': 'GET',
                'operation_id': '#boot-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=FAIL&date_range=' + dateRange +
                    '&job=' + jobName
            };
        }

        ajaxData = JSON.stringify({
            'batch': batchQueries
        });
        deferredAjaxCall = JSBase.createDeferredCall(
            '/_ajax/batch',
            'POST',
            ajaxData,
            null,
            countFailCallback,
            errorReason,
            {'Content-Type': 'application/json'},
            'batch-failed'
        );

        $.when(deferredAjaxCall).done(function(data) {
            var batchData = data.result,
                batchLen = batchData.length,
                batchResult = null,
                idx = 0;

            if (batchLen > 0) {
                for (idx; idx < batchLen; idx++) {
                    batchResult = batchData[idx].result[0];
                    $(batchData[idx].operation_id).empty().append(
                        batchResult.count);
                }
            }
        });
    }
}

function createJobsTable(data) {
    'use strict';

    var localData = data.result,
        table = $('#jobstable').dataTable({
        'dom': '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"' +
            '<"length-menu"l>>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4 col-lg-offset-2"f>' +
            'r' +
            '<"col-xs-12 col-sm-12 col-md-12 col-lg-12"t>>' +
            '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"i>' +
            '<"col-xs-12 col-sm-12 col-md-6 col-lg-6"p>>',
        'language': {
            'lengthMenu': '_MENU_ jobs per page',
            'zeroRecords': '
No jobs to display.
',
            'search': '
' +
                '' +
                '_INPUT_
'
        },
        'initComplete': function() {
            $('#table-loading').remove();
            $('#table-div').fadeIn('slow', 'linear');

            var api = this.api();

            pageLen = Number(pageLen);
            if (isNaN(pageLen)) {
                pageLen = 25;
            }

            api.page.len(pageLen).draw();

            if (searchFilter !== null && searchFilter.length > 0) {
                api.search(searchFilter, true).draw();
            }
        },
        'lengthMenu': [25, 50, 75, 100],
        'deferRender': true,
        'ordering': true,
        'processing': true,
        'stateDuration': -1,
        'stateSave': true,
        'order': [3, 'desc'],
        'search': {
            'regex': true
        },
        'data': localData,
        'columns': [
            {
                'data': 'job',
                'title': 'Tree ‐ Branch',
                'type': 'string',
                'render': function(data, type, object) {
                    return '' + data + ' ‐ ' +
                        object.git_branch + '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Build Status',
                'type': 'String',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Boot Status',
                'type': 'string',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'created_on',
                'title': 'Date',
                'type': 'date',
                'render': function(data) {
                    var created = new Date(data.$date);
                    return created.getCustomISODate();
                }
            },
            {
                'data': 'status',
                'title': 'Status',
                'type': 'string',
                'className': 'pull-center',
                'render': function(data) {
                    var displ;
                    switch (data) {
                        case 'BUILD':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'PASS':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'FAIL':
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                        default:
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                    }
                    return displ;
                }
            },
            {
                'data': 'job',
                'title': '',
                'searchable': false,
                'orderable': false,
                'width': '30px',
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '';
                }
            }
        ]
    });

    $(document).on('click', '#jobstable tbody tr', function() {
        var tableData = table.fnGetData(this);
        if (tableData) {
            window.location = '/job/' + tableData.job + '/';
        }
    });

    $('#search-area > .input-sm').attr('placeholder', 'Filter the results');
    $('.input-sm').keyup(function(key) {
        // Remove focus from input when Esc is pressed.
        if (key.keyCode === 27) {
            $(this).blur();
        }
    });

    return data;
}

function updateJobsPage(data) {
    'use strict';
    // Simple function needed to wrap another deferred call.
    // Create the table, then update it with the batch count operation.
    $.when(createJobsTable(data)).done(batchCountElements);
}

$(document).ready(function() {
    'use strict';

    $('#li-job').addClass('active');
    $('#table-div').hide();

    var errorReason = 'Job data call failed',
        deferredAjaxCall = null,
        ajaxData = null;

    ajaxData = {
        'aggregate': 'job',
        'sort': 'created_on',
        'sort_order': -1,
        'date_range': $('#date-range').val(),
        'field': [
            'job', 'created_on', 'status', 'git_branch'
        ]
    };
    deferredAjaxCall = JSBase.createDeferredCall(
        '/_ajax/job',
        'GET',
        ajaxData,
        null,
        failedAjaxCall,
        errorReason,
        null,
        'failed-job'
    );

    $.when(deferredAjaxCall).done(updateJobsPage);
});
<commit_msg>Fix jslint errors.<commit_after>var searchFilter = $('#search-filter').val();
var pageLen = $('#page-len').val();
var dateRange = $('#date-range').val();

function failedAjaxCall() {
    'use strict';
    $('#table-loading').remove();
}

function countFailCallback() {
    'use strict';
    JSBase.replaceContentByClass('.count-badge', '∞');
}

function batchCountElements(data) {
    'use strict';
    var localData = data.result,
        len = localData.length,
        i = 0,
        j = 0,
        batchElements = 4,
        jobName = '',
        queriesLen = len * 4,
        batchQueries = new Array(queriesLen),
        errorReason = 'Batch count failed',
        deferredAjaxCall = null,
        ajaxData = null;

    if (len > 0) {
        for (i; i < queriesLen; i += batchElements) {
            j = i;
            jobName = localData[i / batchElements].job;

            // Get successful defconfig count.
            batchQueries[i] = {
                'method': 'GET',
                'operation_id': '#defconf-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=PASS&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get failed defconfig count.
            batchQueries[j + 1] = {
                'method': 'GET',
                'operation_id': '#defconf-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'defconfig',
                'query': 'status=FAIL&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get successful boot reports count.
            batchQueries[j + 2] = {
                'method': 'GET',
                'operation_id': '#boot-success-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=PASS&date_range=' + dateRange +
                    '&job=' + jobName
            };

            // Get failed boot reports count.
            batchQueries[j + 3] = {
                'method': 'GET',
                'operation_id': '#boot-fail-count-' + jobName,
                'collection': 'count',
                'document_id': 'boot',
                'query': 'status=FAIL&date_range=' + dateRange +
                    '&job=' + jobName
            };
        }

        ajaxData = JSON.stringify({
            'batch': batchQueries
        });
        deferredAjaxCall = JSBase.createDeferredCall(
            '/_ajax/batch',
            'POST',
            ajaxData,
            null,
            countFailCallback,
            errorReason,
            {'Content-Type': 'application/json'},
            'batch-failed'
        );

        $.when(deferredAjaxCall).done(function(data) {
            var batchData = data.result,
                batchLen = batchData.length,
                batchResult = null,
                idx = 0;

            if (batchLen > 0) {
                for (idx; idx < batchLen; idx = idx + 1) {
                    batchResult = batchData[idx].result[0];
                    $(batchData[idx].operation_id).empty().append(
                        batchResult.count);
                }
            }
        });
    }
}

function createJobsTable(data) {
    'use strict';

    var localData = data.result,
        table = $('#jobstable').dataTable({
        'dom': '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"' +
            '<"length-menu"l>>' +
            '<"col-xs-12 col-sm-12 col-md-4 col-lg-4 col-lg-offset-2"f>' +
            'r' +
            '<"col-xs-12 col-sm-12 col-md-12 col-lg-12"t>>' +
            '<"row"<"col-xs-12 col-sm-12 col-md-6 col-lg-6"i>' +
            '<"col-xs-12 col-sm-12 col-md-6 col-lg-6"p>>',
        'language': {
            'lengthMenu': '_MENU_ jobs per page',
            'zeroRecords': '
No jobs to display.
',
            'search': '
' +
                '' +
                '_INPUT_
'
        },
        'initComplete': function() {
            $('#table-loading').remove();
            $('#table-div').fadeIn('slow', 'linear');

            var api = this.api();

            pageLen = Number(pageLen);
            if (isNaN(pageLen)) {
                pageLen = 25;
            }

            api.page.len(pageLen).draw();

            if (searchFilter !== null && searchFilter.length > 0) {
                api.search(searchFilter, true).draw();
            }
        },
        'lengthMenu': [25, 50, 75, 100],
        'deferRender': true,
        'ordering': true,
        'processing': true,
        'stateDuration': -1,
        'stateSave': true,
        'order': [3, 'desc'],
        'search': {
            'regex': true
        },
        'data': localData,
        'columns': [
            {
                'data': 'job',
                'title': 'Tree ‐ Branch',
                'type': 'string',
                'render': function(data, type, object) {
                    return '' + data + ' ‐ ' +
                        object.git_branch + '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Build Status',
                'type': 'String',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'job',
                'title': '' +
                    'Boot Status',
                'type': 'string',
                'searchable': false,
                'orderable': false,
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '' +
                        '';
                }
            },
            {
                'data': 'created_on',
                'title': 'Date',
                'type': 'date',
                'render': function(data) {
                    var created = new Date(data.$date);
                    return created.getCustomISODate();
                }
            },
            {
                'data': 'status',
                'title': 'Status',
                'type': 'string',
                'className': 'pull-center',
                'render': function(data) {
                    var displ;
                    switch (data) {
                        case 'BUILD':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'PASS':
                            displ = '' +
                                '' +
                                '';
                            break;
                        case 'FAIL':
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                        default:
                            displ = '' +
                                '' +
                                '' +
                                '';
                            break;
                    }
                    return displ;
                }
            },
            {
                'data': 'job',
                'title': '',
                'searchable': false,
                'orderable': false,
                'width': '30px',
                'className': 'pull-center',
                'render': function(data) {
                    return '' +
                        '' +
                        '';
                }
            }
        ]
    });

    $(document).on('click', '#jobstable tbody tr', function() {
        var tableData = table.fnGetData(this);
        if (tableData) {
            window.location = '/job/' + tableData.job + '/';
        }
    });

    $('#search-area > .input-sm').attr('placeholder', 'Filter the results');
    $('.input-sm').keyup(function(key) {
        // Remove focus from input when Esc is pressed.
        if (key.keyCode === 27) {
            $(this).blur();
        }
    });

    return data;
}

function updateJobsPage(data) {
    'use strict';
    // Simple function needed to wrap another deferred call.
    // Create the table, then update it with the batch count operation.
    $.when(createJobsTable(data)).done(batchCountElements);
}

$(document).ready(function() {
    'use strict';

    $('#li-job').addClass('active');
    $('#table-div').hide();

    var errorReason = 'Job data call failed',
        deferredAjaxCall = null,
        ajaxData = null;

    ajaxData = {
        'aggregate': 'job',
        'sort': 'created_on',
        'sort_order': -1,
        'date_range': $('#date-range').val(),
        'field': [
            'job', 'created_on', 'status', 'git_branch'
        ]
    };
    deferredAjaxCall = JSBase.createDeferredCall(
        '/_ajax/job',
        'GET',
        ajaxData,
        null,
        failedAjaxCall,
        errorReason,
        null,
        'failed-job'
    );

    $.when(deferredAjaxCall).done(updateJobsPage);
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */

CLASS({
  name: 'QIssueCreateView',
  package: 'foam.apps.quickbug.ui',
  extendsModel: 'foam.ui.DetailView',

  requires: [
    'foam.ui.ActionButton',
    'AutocompleteView',
    'foam.apps.quickbug.LabelAutocompleteView',
    'foam.apps.quickbug.StatusAutocompleteView',
    'TextFieldView',
    'foam.apps.quickbug.ui.GriddedStringArrayView'
  ],

  imports: [
    'issueDAO',
    'browser'
  ],

  properties: [
    {
      name: 'model',
      factory: function() { return this.X.QIssue; }
    },
    {
      model_: 'BooleanProperty',
      name: 'saving',
      defaultValue: false
    },
    { name: 'errorView', factory: function() { return this.TextFieldView.create({ mode: 'read-only' }); } },
  ],

  actions: [
    {
      name: 'save',
      label: 'Create',
      isEnabled: function() { return ! this.saving },
      action: function() {
        var self = this;
        this.saving = true;
        this.errorView.data = "";
        this.issueDAO.put(this.data, {
          put: function(obj) {
            self.saving = false;
            self.browser.location.createMode = false;
            self.browser.location.id = obj.id;
          },
          error: function() {
            self.saving = false;
            self.errorView.data = "Error creating issue.";
          }
        });
      }
    },
    {
      name: 'discard',
      label: 'Discard',
      isEnabled: function() { return ! this.saving },
      action: function() {
        this.browser.location.createMode = false;
      }
    },
  ],

  templates: [
    function toHTML() {/*
      <div class="issueCreateView" id="<%= this.id %>">

      Create Issue

Summary:	$$summary

Description:	$$description

Status:
        <% var Y = this.Y.sub(); Y.registerModel(this.StatusAutocompleteView, 'AutocompleteView'); %>
        $$status{ X: Y }

Owner:	$$owner

Cc:	$$cc

Labels:
        <% Y = this.Y.sub(); Y.registerModel(this.LabelAutocompleteView, 'AutocompleteView'); %>
        $$labels{ X: Y, model_: 'foam.apps.quickbug.ui.GriddedStringArrayView' }

      <%= this.ActionButton.create({ action: this.model_.SAVE,    data: this }) %>
      <%= this.ActionButton.create({ action: this.model_.DISCARD, data: this }) %>
      %%errorView

    */}
  ]
});
<commit_msg>Fix QIssueCreateView requires<commit_after>/**
 * @license
 * Copyright 2015 Google Inc. All Rights Reserved.
 *
 * 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.
 */

CLASS({
  name: 'QIssueCreateView',
  package: 'foam.apps.quickbug.ui',
  extendsModel: 'foam.ui.DetailView',

  requires: [
    'foam.ui.ActionButton',
    'AutocompleteView',
    'foam.apps.quickbug.ui.LabelAutocompleteView',
    'foam.apps.quickbug.ui.StatusAutocompleteView',
    'TextFieldView',
    'foam.apps.quickbug.ui.GriddedStringArrayView'
  ],

  imports: [
    'issueDAO',
    'browser'
  ],

  properties: [
    {
      name: 'model',
      factory: function() { return this.X.QIssue; }
    },
    {
      model_: 'BooleanProperty',
      name: 'saving',
      defaultValue: false
    },
    { name: 'errorView', factory: function() { return this.TextFieldView.create({ mode: 'read-only' }); } },
  ],

  actions: [
    {
      name: 'save',
      label: 'Create',
      isEnabled: function() { return ! this.saving },
      action: function() {
        var self = this;
        this.saving = true;
        this.errorView.data = "";
        this.issueDAO.put(this.data, {
          put: function(obj) {
            self.saving = false;
            self.browser.location.createMode = false;
            self.browser.location.id = obj.id;
          },
          error: function() {
            self.saving = false;
            self.errorView.data = "Error creating issue.";
          }
        });
      }
    },
    {
      name: 'discard',
      label: 'Discard',
      isEnabled: function() { return ! this.saving },
      action: function() {
        this.browser.location.createMode = false;
      }
    },
  ],

  templates: [
    function toHTML() {/*
      <div class="issueCreateView" id="<%= this.id %>">

      Create Issue

Summary:	$$summary

Description:	$$description

Status:
        <% var Y = this.Y.sub(); Y.registerModel(this.StatusAutocompleteView, 'AutocompleteView'); %>
        $$status{ X: Y }

Owner:	$$owner

Cc:	$$cc

Labels:
        <% Y = this.Y.sub(); Y.registerModel(this.LabelAutocompleteView, 'AutocompleteView'); %>
        $$labels{ X: Y, model_: 'foam.apps.quickbug.ui.GriddedStringArrayView' }

      <%= this.ActionButton.create({ action: this.model_.SAVE,    data: this }) %>
      <%= this.ActionButton.create({ action: this.model_.DISCARD, data: this }) %>
      %%errorView

    */}
  ]
});
<|endoftext|>


<commit_before>/*! Respond.js v1.4.0: min/max-width media query polyfill. (c) Scott Jehl. MIT Lic. j.mp/respondjs  */
(function( w ){

	"use strict";

	//exposed namespace
	var respond = {};
	w.respond = respond;

	//define update even in native-mq-supporting browsers, to avoid errors
	respond.update = function(){};

	//define ajax obj
	var requestQueue = [];

  // attempt to use XMLHttpRequest, if not use XDomainRequest
  var ajax = function( url, callback ) {
    try {
        var xhr = getXMLHttpRequest();
        xhr.open('GET', url, true);
        xhr.send();

        xhr.onreadystatechange = new function() {
            if (xhr.readyState === 4) {
              callback(xhr.responseText);
            }
        };
     } catch (e) {
        if ( window.XDomainRequest ) {
          var xdr = new XDomainRequest();
          xdr.open('get', url);
          xdr.onload = function() {
            callback(xdr.responseText);
          };
          xdr.onerror = function() {
            return false; // xdr load fail
          };
          xdr.send();
        }
     }
  };

	//expose for testing
	respond.ajax = ajax;
	respond.queue = requestQueue;

	// expose for testing
	respond.regex = {
		media: /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,
		keyframes: /@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,
		urls: /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,
		findStyles: /@media *([^\{]+)\{([\S\s]+?)$/,
		only: /(only\s+)?([a-zA-Z]+)\s?/,
		minw: /\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,
		maxw: /\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/
	};

	//expose media query support flag for external use
	respond.mediaQueriesSupported = w.matchMedia && w.matchMedia( "only all" ) !== null && w.matchMedia( "only all" ).matches;

	//if media queries are supported, exit here
	if( respond.mediaQueriesSupported ){
		return;
	}

	//define vars
	var doc = w.document,
		docElem = doc.documentElement,
		mediastyles = [],
		rules = [],
		appendedEls = [],
		parsedSheets = {},
		resizeThrottle = 30,
		head = doc.getElementsByTagName( "head" )[0] || docElem,
		base = doc.getElementsByTagName( "base" )[0],
		links = head.getElementsByTagName( "link" ),

		lastCall,
		resizeDefer,

		//cached container for 1em value, populated the first time it's needed
		eminpx,

		// returns the value of 1em in pixels
		getEmValue = function() {
			var ret,
				div = doc.createElement('div'),
				body = doc.body,
				originalHTMLFontSize = docElem.style.fontSize,
				originalBodyFontSize = body && body.style.fontSize,
				fakeUsed = false;

			div.style.cssText = "position:absolute;font-size:1em;width:1em";

			if( !body ){
				body = fakeUsed = doc.createElement( "body" );
				body.style.background = "none";
			}

			// 1em in a media query is the value of the default font size of the browser
			// reset docElem and body to ensure the correct value is returned
			docElem.style.fontSize = "100%";
			body.style.fontSize = "100%";

			body.appendChild( div );

			if( fakeUsed ){
				docElem.insertBefore( body, docElem.firstChild );
			}

			ret = div.offsetWidth;

			if( fakeUsed ){
				docElem.removeChild( body );
			}
			else {
				body.removeChild( div );
			}

			// restore the original values
			docElem.style.fontSize = originalHTMLFontSize;
			if( originalBodyFontSize ) {
				body.style.fontSize = originalBodyFontSize;
			}

			//also update eminpx before returning
			ret = eminpx = parseFloat(ret);

			return ret;
		},

		//enable/disable styles
		applyMedia = function( fromResize ){
			var name = "clientWidth",
				docElemProp = docElem[ name ],
				currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
				styleBlocks	= {},
				lastLink = links[ links.length-1 ],
				now = (new Date()).getTime();

			//throttle resize calls
			if( fromResize && lastCall && now - lastCall < resizeThrottle ){
				w.clearTimeout( resizeDefer );
				resizeDefer = w.setTimeout( applyMedia, resizeThrottle );
				return;
			}
			else {
				lastCall = now;
			}

			for( var i in mediastyles ){
				if( mediastyles.hasOwnProperty( i ) ){
					var thisstyle = mediastyles[ i ],
						min = thisstyle.minw,
						max = thisstyle.maxw,
						minnull = min === null,
						maxnull = max === null,
						em = "em";

					if( !!min ){
						min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
					}
					if( !!max ){
						max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 );
					}

					// if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true
					if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){
						if( !styleBlocks[ thisstyle.media ] ){
							styleBlocks[ thisstyle.media ] = [];
						}
						styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
					}
				}
			}

			//remove any existing respond style element(s)
			for( var j in appendedEls ){
				if( appendedEls.hasOwnProperty( j ) ){
					if( appendedEls[ j ] && appendedEls[ j ].parentNode === head ){
						head.removeChild( appendedEls[ j ] );
					}
				}
			}
			appendedEls.length = 0;

			//inject active styles, grouped by media type
			for( var k in styleBlocks ){
				if( styleBlocks.hasOwnProperty( k ) ){
					var ss = doc.createElement( "style" ),
						css = styleBlocks[ k ].join( "\n" );

					ss.type = "text/css";
					ss.media = k;

					//originally, ss was appended to a documentFragment and sheets were appended in bulk.
					//this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one!
					head.insertBefore( ss, lastLink.nextSibling );

					if ( ss.styleSheet ){
						ss.styleSheet.cssText = css;
					}
					else {
						ss.appendChild( doc.createTextNode( css ) );
					}

					//push to appendedEls to track for later removal
					appendedEls.push( ss );
				}
			}
		},
		//find media blocks in css text, convert to style blocks
		translate = function( styles, href, media ){
			var qs = styles.replace( respond.regex.keyframes, '' ).match( respond.regex.media ),
				ql = qs && qs.length || 0;

			//try to get CSS path
			href = href.substring( 0, href.lastIndexOf( "/" ) );

			var repUrls = function( css ){
					return css.replace( respond.regex.urls, "$1" + href + "$2$3" );
				},
				useMedia = !ql && media;

			//if path exists, tack on trailing slash
			if( href.length ){ href += "/"; }

			//if no internal queries exist, but media attr does, use that
			//note: this currently lacks support for situations where a media attr is specified on a link AND
				//its associated stylesheet has internal CSS media queries.
				//In those cases, the media attribute will currently be ignored.
			if( useMedia ){
				ql = 1;
			}

			for( var i = 0; i < ql; i++ ){
				var fullq, thisq, eachq, eql;

				//media attr
				if( useMedia ){
					fullq = media;
					rules.push( repUrls( styles ) );
				}
				//parse for styles
				else{
					fullq = qs[ i ].match( respond.regex.findStyles ) && RegExp.$1;
					rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
				}

				eachq = fullq.split( "," );
				eql = eachq.length;

				for( var j = 0; j < eql; j++ ){
					thisq = eachq[ j ];
					mediastyles.push( {
						media : thisq.split( "(" )[ 0 ].match( respond.regex.only ) && RegExp.$2 || "all",
						rules : rules.length - 1,
						hasquery : thisq.indexOf("(") > -1,
						minw : thisq.match( respond.regex.minw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ),
						maxw : thisq.match( respond.regex.maxw ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" )
					} );
				}
			}

			applyMedia();
		},

		//recurse through request queue, get css text
		makeRequests = function(){
			if( requestQueue.length ){
				var thisRequest = requestQueue.shift();

				ajax( thisRequest.href, function( styles ){
					translate( styles, thisRequest.href, thisRequest.media );
					parsedSheets[ thisRequest.href ] = true;

					// by wrapping recursive function call in setTimeout
					// we prevent "Stack overflow" error in IE7
					w.setTimeout(function(){ makeRequests(); },0);
				} );
			}
		},

		//loop stylesheets, send text content to translate
		ripCSS = function(){

			for( var i = 0; i < links.length; i++ ){
				var sheet = links[ i ],
				href = sheet.href,
				media = sheet.media,
				isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";

				//only links plz and prevent re-parsing
				if( !!href && isCSS && !parsedSheets[ href ] ){
					// selectivizr exposes css through the rawCssText expando
					if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
						translate( sheet.styleSheet.rawCssText, href, media );
						parsedSheets[ href ] = true;
					} else {
							// IE7 doesn't handle urls that start with '//' for ajax request
							// manually add in the protocol
							if ( href.substring(0,2) === "//" ) { href = w.location.protocol + href; }
							requestQueue.push( {
								href: href,
								media: media
							} );
					}
				}
			}
			makeRequests();
		};

	//translate CSS
	ripCSS();

	//expose update for re-running respond later on
	respond.update = ripCSS;

	//expose getEmValue
	respond.getEmValue = getEmValue;

	//adjust on resize
	function callMedia(){
		applyMedia( true );
	}

	if( w.addEventListener ){
		w.addEventListener( "resize", callMedia, false );
	}
	else if( w.attachEvent ){
		w.attachEvent( "onresize", callMedia );
	}
})(this);
<commit_msg>Remove unused Respond fork.<commit_after><|endoftext|>


<commit_before>'use babel'

import * as _ from 'lodash'
import * as helpers from './language-helpers'
import * as path from 'path'
import childProcess from 'child_process'
import * as likelySubtags from './likely-subtags'
import { Disposable, CompositeDisposable } from 'atom'
import Spell from './spell'

export default class DictionaryProvider extends Disposable {

  constructor () {
    super(() => {
      this.disposables.dispose()
      this.checkers = new Map()
    })
    this.disposables = new CompositeDisposable()
    this.checkers = new Map()
    this.dictionaries = new Map()
    atom.config.onDidChange('linter-spell.spellPath', () => {
      this.checkers = new Map()
      this.updateDictionaries()
    })
    this.provider = {
      name: 'Ispell dictionary',
      languages: this.getAvailableLanguages(),
      checkRange: (textEditor, languages, range) => {
        const checker = this.getChecker(languages)
        if (!checker) return []
        return checker.getMisspellings(textEditor, range)
          .then(misspellings => _.map(misspellings,
            misspelling => {
              const word = textEditor.getTextInBufferRange(misspelling.range)
              const upperCase = word.toLowerCase() !== word

              const result = {
                range: misspelling.range,
                suggestions: misspelling.suggestions,
                actions: [{
                  title: 'Ignore',
                  apply: () => checker.ignoreWord(word, false)
                }]
              }

              if (upperCase) {
                result.actions.push({
                  title: 'Ignore (case sensitive)',
                  apply: () => checker.ignoreWord(word, true)
                })
              }

              result.actions.push({
                title: 'Add to personal dictionary',
                apply: () => checker.addWord(word, false)
              })

              if (upperCase) {
                result.actions.push({
                  title: 'Add to personal dictionary (case sensitive)',
                  apply: () => checker.addWord(word, true)
                })
              }

              return result
            }))
      },
      checkWord: (textEditor, languages, range) => {
        const checker = this.getChecker(languages)
        if (!checker) return { isWord: false }
        const word = textEditor.getTextInBufferRange(range)
        return checker.getMisspellings(textEditor, range)
          .then(misspellings => (misspellings.length === 0)
            ? { isWord: true }
            : {
              isWord: false,
              suggestions: misspellings[0].suggestions,
              actions: [{
                title: 'Add to personal dictionary',
                apply: () => checker.addWord(word, false)
              }, {
                title: 'Add to personal dictionary (case sensitive)',
                apply: () => checker.addWord(word, true)
              }, {
                title: 'Ignore',
                apply: () => checker.ignoreWord(word, false)
              }, {
                title: 'Ignore (case sensitive)',
                apply: () => checker.ignoreWord(word, true)
              }]
            })
      }
    }
    this.updateDictionaries()
  }

  provideDictionary () {
    return this.provider
  }

  getAvailableLanguages () {
    let l = []
    for (const lang of this.dictionaries.keys()) {
      l.push(lang.replace(/-\*/g, ''))
    }
    l.sort()
    return l
  }

  getChecker (languages) {
    let id = languages.join()
    if (this.checkers.has(id)) return this.checkers.get(id)

    let checker = new Spell(languages)
    this.disposables.add(checker)
    this.checkers.set(id, checker)
    checker.onError(err => {
      console.error(err)
      if (this.checkers.has(id)) {
        this.checkers.delete(id)
        atom.notifications.addError(
          'Spell Checker Communication Error',
          { detail: `Unable to communicate with spell checker. Please verify your settings of linter-spell.\n${err}` })
      }
    })
    return checker
  }

  maximizeRank (tag) {
    let rank = 0
    let value
    for (const entry of this.dictionaries.entries()) {
      const newRank = helpers.rankRange(entry[0], tag)
      if (newRank > rank) {
        rank = newRank
        value = entry
      }
    }
    return value
  }

  resolve (languages, notify) {
    let d = []
    for (const language of languages) {
      const fallback = likelySubtags[language]
      let dict = this.maximizeRank(language)
      if (fallback) dict = dict || this.maximizeRank(fallback)
      if (dict) {
        d.push(dict)
      } else if (notify) {
        atom.notifications.addWarning(
          'Missing Dictionary', {
            detail: `Unable to find a dictionary for language ${language}${fallback ? ' with fallback ' + fallback : ''}.`
          })
      }
    }
    return d
  }

  resolveDictionaries (languages) {
    return _.map(this.resolve(languages, true), entry => entry[1])
  }

  resolveLanguages (languages) {
    return _.map(this.resolve(languages, false), entry => entry[0].replace(/-\*/g, ''))
  }

  addDictionary (name) {
    const lang = helpers.parseRange(name)
    if (lang !== '*' && (!this.dictionaries.has(lang) || name < this.dictionaries.get(lang))) {
      this.dictionaries.set(lang, name)
    }
  }

  async updateDictionaries () {
    const spellPath = atom.config.get('linter-spell.spellPath')
    const ispell = path.parse(spellPath).name.toLowerCase()
    let output = ''
    this.dictionaries.clear()
    switch (ispell) {
      case 'aspell':
        output = childProcess.spawnSync(spellPath, ['dicts'], { encoding: 'utf8' })
        for (const line of output.stdout.split(/[\r\n]+/g)) {
          this.addDictionary(line)
        }
        break
      case 'hunspell':
        output = childProcess.spawnSync(spellPath, ['-D'], { encoding: 'utf8', input: '' })
        let save = false
        for (const line of output.stderr.split(/[\r\n]+/g)) {
          if (line.match(/\s-d.*:$/)) {
            save = true
          } else if (line.match(/:$/)) {
            save = false
          } else if (save) {
            this.addDictionary(path.basename(line))
          }
        }
        break
    }
    this.provider.languages = this.getAvailableLanguages()
//    this.emitter.emit('change-languages', null)
  }

}
<commit_msg>Add guard for dictionary request<commit_after>'use babel'

import * as _ from 'lodash'
import * as helpers from './language-helpers'
import * as path from 'path'
import childProcess from 'child_process'
import * as likelySubtags from './likely-subtags'
import { Disposable, CompositeDisposable } from 'atom'
import Spell from './spell'

export default class DictionaryProvider extends Disposable {

  constructor () {
    super(() => {
      this.disposables.dispose()
      this.checkers = new Map()
    })
    this.disposables = new CompositeDisposable()
    this.checkers = new Map()
    this.dictionaries = new Map()
    atom.config.onDidChange('linter-spell.spellPath', () => {
      this.checkers = new Map()
      this.updateDictionaries()
    })
    this.provider = {
      name: 'Ispell dictionary',
      languages: this.getAvailableLanguages(),
      checkRange: (textEditor, languages, range) => {
        const checker = this.getChecker(languages)
        if (!checker) return []
        return checker.getMisspellings(textEditor, range)
          .then(misspellings => _.map(misspellings,
            misspelling => {
              const word = textEditor.getTextInBufferRange(misspelling.range)
              const upperCase = word.toLowerCase() !== word

              const result = {
                range: misspelling.range,
                suggestions: misspelling.suggestions,
                actions: [{
                  title: 'Ignore',
                  apply: () => checker.ignoreWord(word, false)
                }]
              }

              if (upperCase) {
                result.actions.push({
                  title: 'Ignore (case sensitive)',
                  apply: () => checker.ignoreWord(word, true)
                })
              }

              result.actions.push({
                title: 'Add to personal dictionary',
                apply: () => checker.addWord(word, false)
              })

              if (upperCase) {
                result.actions.push({
                  title: 'Add to personal dictionary (case sensitive)',
                  apply: () => checker.addWord(word, true)
                })
              }

              return result
            }))
      },
      checkWord: (textEditor, languages, range) => {
        const checker = this.getChecker(languages)
        if (!checker) return { isWord: false }
        const word = textEditor.getTextInBufferRange(range)
        return checker.getMisspellings(textEditor, range)
          .then(misspellings => (misspellings.length === 0)
            ? { isWord: true }
            : {
              isWord: false,
              suggestions: misspellings[0].suggestions,
              actions: [{
                title: 'Add to personal dictionary',
                apply: () => checker.addWord(word, false)
              }, {
                title: 'Add to personal dictionary (case sensitive)',
                apply: () => checker.addWord(word, true)
              }, {
                title: 'Ignore',
                apply: () => checker.ignoreWord(word, false)
              }, {
                title: 'Ignore (case sensitive)',
                apply: () => checker.ignoreWord(word, true)
              }]
            })
      }
    }
    this.updateDictionaries()
  }

  provideDictionary () {
    return this.provider
  }

  getAvailableLanguages () {
    let l = []
    for (const lang of this.dictionaries.keys()) {
      l.push(lang.replace(/-\*/g, ''))
    }
    l.sort()
    return l
  }

  getChecker (languages) {
    let id = languages.join()
    if (this.checkers.has(id)) return this.checkers.get(id)

    let checker = new Spell(languages)
    this.disposables.add(checker)
    this.checkers.set(id, checker)
    checker.onError(err => {
      console.error(err)
      if (this.checkers.has(id)) {
        this.checkers.delete(id)
        atom.notifications.addError(
          'Spell Checker Communication Error',
          { detail: `Unable to communicate with spell checker. Please verify your settings of linter-spell.\n${err}` })
      }
    })
    return checker
  }

  maximizeRank (tag) {
    let rank = 0
    let value
    for (const entry of this.dictionaries.entries()) {
      const newRank = helpers.rankRange(entry[0], tag)
      if (newRank > rank) {
        rank = newRank
        value = entry
      }
    }
    return value
  }

  resolve (languages, notify) {
    let d = []
    for (const language of languages) {
      const fallback = likelySubtags[language]
      let dict = this.maximizeRank(language)
      if (fallback) dict = dict || this.maximizeRank(fallback)
      if (dict) {
        d.push(dict)
      } else if (notify) {
        atom.notifications.addWarning(
          'Missing Dictionary', {
            detail: `Unable to find a dictionary for language ${language}${fallback ? ' with fallback ' + fallback : ''}.`
          })
      }
    }
    return d
  }

  resolveDictionaries (languages) {
    return _.map(this.resolve(languages, true), entry => entry[1])
  }

  resolveLanguages (languages) {
    return _.map(this.resolve(languages, false), entry => entry[0].replace(/-\*/g, ''))
  }

  addDictionary (name) {
    const lang = helpers.parseRange(name)
    if (lang !== '*' && (!this.dictionaries.has(lang) || name < this.dictionaries.get(lang))) {
      this.dictionaries.set(lang, name)
    }
  }

  async updateDictionaries () {
    const spellPath = atom.config.get('linter-spell.spellPath')
    const ispell = path.parse(spellPath).name.toLowerCase()
    let output = ''
    this.dictionaries.clear()
    switch (ispell) {
      case 'aspell':
        output = childProcess.spawnSync(spellPath, ['dicts'], { encoding: 'utf8' })
        if (output.status !== 0) {
          atom.notifications.addError('linter-spell: Dictionary request failed', { description: `Call to aspell failed with a code of ${output.status}.` })
        }
        if (output.stdout) {
          for (const line of output.stdout.split(/[\r\n]+/g)) {
            this.addDictionary(line)
          }
        }
        break
      case 'hunspell':
        output = childProcess.spawnSync(spellPath, ['-D'], { encoding: 'utf8', input: '' })
        if (output.status !== 0) {
          atom.notifications.addError('linter-spell: Dictionary request failed', { description: `Call to hunspell failed with a code of ${output.status}.` })
        }
        if (output.stderr) {
          let save = false
          for (const line of output.stderr.split(/[\r\n]+/g)) {
            if (line.match(/\s-d.*:$/)) {
              save = true
            } else if (line.match(/:$/)) {
              save = false
            } else if (save) {
              this.addDictionary(path.basename(line))
            }
          }
        }
        break
    }
    this.provider.languages = this.getAvailableLanguages()
//    this.emitter.emit('change-languages', null)
  }

}
<|endoftext|>


<commit_before>// Copyright 2002-2015, University of Colorado Boulder

/**
 * This grunt task iterates over all of the license.json files and reports any images or audio that have any of the following
 * problems:
 *
 * missing-license.json    The resource file has no associated license.json file
 * incompatible-license    Known to be from an unapproved source outside of PhET
 * not-annotated           There is a license.json file but the asset is not in there
 * missing-file            There is an entry in the license.json but no corresponding file
 *
 * This can be run from any simulation directory with `grunt create-image-and-audio-license-report` and it reports for
 * all directories (not just the simulation at hand).
 *
 * Note that this program relies on numerous heuristics for determining the output, such as allowed entries that
 * determine if a file originates from PhET.
 *
 * See https://github.com/phetsims/tasks/issues/274
 *
 * @author Sam Reid
 */

/**
 * @param grunt the grunt instance
 */
module.exports = function( grunt ) {
  // The following comment permits node-specific globals (such as process.cwd()) to pass jshint
  /* jslint node: true */
  'use strict';

  // modules
  var getLicenseInfo = require( '../../../chipper/js/grunt/getLicenseInfo' );

  // constants
  var ACTIVE_REPOS_FILENAME = 'chipper/data/active-repos';  // The relative path to the list of active repos

  // Start in the github checkout dir (above one of the sibling directories)
  var directory = process.cwd();
  var rootdir = directory + '/../';

  // Iterate over all active-repos
  var repos = grunt.file.read( rootdir + '/' + ACTIVE_REPOS_FILENAME ).trim();
  var reposByLine = repos.split( /\r?\n/ );

  /**
   * Create a fast report based on the license.json files for the specified repository and directory (images or audio)
   * @param {string} repo - the name of the repository, such as 'balancing-act'
   * @param {string} directory - the name of the directory to search such as 'images'
   * @private
   */
  var reportForDirectory = function( repo, directory ) {

    var searchDir = rootdir + repo + '/' + directory;

    // Not all projects have an audio/ directory
    if ( grunt.file.exists( searchDir ) ) {

      // Iterate over all images and audio directories recursively
      grunt.file.recurse( searchDir, function( abspath, rootdir, subdir, filename ) {

        // Some files don't need to be attributed in the license.json
        if ( abspath.indexOf( 'README.md' ) < 0 &&
             filename.indexOf( 'license.json' ) !== 0 ) {

          // Classify the resource
          var result = getLicenseInfo( abspath, abspath );

          // Report if it is a problem
          if ( result.isProblematic === true ) {
            grunt.log.writeln( 'incompatible-license: ' + repo + '/' + directory + '/' + filename );
          }
        }

        // Now iterate through the license.json entries and see which are missing files
        // This helps to identify stale entries in the license.json files.
        if ( filename === 'license.json' ) {

          var file = grunt.file.read( abspath, 'utf8' );
          var json = JSON.parse( file );

          // For each key in the json file, make sure that file exists in the directory
          for ( var key in json ) {
            if ( json.hasOwnProperty( key ) ) {
              var resourceFilename = searchDir + '/' + key;
              var exists = grunt.file.exists( resourceFilename );
              if ( !exists ) {
                grunt.log.writeln( 'missing-file: ' + repo + '/' + directory + '/' + key );
              }
            }
          }
        }
      } );
    }
  };
  for ( var i = 0; i < reposByLine.length; i++ ) {
    reportForDirectory( reposByLine[ i ], 'images' );
    reportForDirectory( reposByLine[ i ], 'audio' );
  }
};<commit_msg>#198 assert that the repo exists<commit_after>// Copyright 2002-2015, University of Colorado Boulder

/**
 * This grunt task iterates over all of the license.json files and reports any images or audio that have any of the following
 * problems:
 *
 * missing-license.json    The resource file has no associated license.json file
 * incompatible-license    Known to be from an unapproved source outside of PhET
 * not-annotated           There is a license.json file but the asset is not in there
 * missing-file            There is an entry in the license.json but no corresponding file
 *
 * This can be run from any simulation directory with `grunt create-image-and-audio-license-report` and it reports for
 * all directories (not just the simulation at hand).
 *
 * Note that this program relies on numerous heuristics for determining the output, such as allowed entries that
 * determine if a file originates from PhET.
 *
 * See https://github.com/phetsims/tasks/issues/274
 *
 * @author Sam Reid
 */

var assert = require( 'assert' );

/**
 * @param grunt the grunt instance
 */
module.exports = function( grunt ) {
  // The following comment permits node-specific globals (such as process.cwd()) to pass jshint
  /* jslint node: true */
  'use strict';

  // modules
  var getLicenseInfo = require( '../../../chipper/js/grunt/getLicenseInfo' );

  // constants
  var ACTIVE_REPOS_FILENAME = 'chipper/data/active-repos';  // The relative path to the list of active repos

  // Start in the github checkout dir (above one of the sibling directories)
  var directory = process.cwd();
  var rootdir = directory + '/../';

  // Iterate over all active-repos
  var repos = grunt.file.read( rootdir + '/' + ACTIVE_REPOS_FILENAME ).trim();
  var reposByLine = repos.split( /\r?\n/ );

  /**
   * Create a fast report based on the license.json files for the specified repository and directory (images or audio)
   * @param {string} repo - the name of the repository, such as 'balancing-act'
   * @param {string} directory - the name of the directory to search such as 'images'
   * @private
   */
  var reportForDirectory = function( repo, directory ) {

    assert( grunt.file.exists( repo ), 'missing required repo: ' + repo );

    var searchDir = rootdir + repo + '/' + directory;

    // Not all projects have an audio/ directory
    if ( grunt.file.exists( searchDir ) ) {

      // Iterate over all images and audio directories recursively
      grunt.file.recurse( searchDir, function( abspath, rootdir, subdir, filename ) {

        // Some files don't need to be attributed in the license.json
        if ( abspath.indexOf( 'README.md' ) < 0 &&
             filename.indexOf( 'license.json' ) !== 0 ) {

          // Classify the resource
          var result = getLicenseInfo( abspath, abspath );

          // Report if it is a problem
          if ( result.isProblematic === true ) {
            grunt.log.writeln( 'incompatible-license: ' + repo + '/' + directory + '/' + filename );
          }
        }

        // Now iterate through the license.json entries and see which are missing files
        // This helps to identify stale entries in the license.json files.
        if ( filename === 'license.json' ) {

          var file = grunt.file.read( abspath, 'utf8' );
          var json = JSON.parse( file );

          // For each key in the json file, make sure that file exists in the directory
          for ( var key in json ) {
            if ( json.hasOwnProperty( key ) ) {
              var resourceFilename = searchDir + '/' + key;
              var exists = grunt.file.exists( resourceFilename );
              if ( !exists ) {
                grunt.log.writeln( 'missing-file: ' + repo + '/' + directory + '/' + key );
              }
            }
          }
        }
      } );
    }
  };
  for ( var i = 0; i < reposByLine.length; i++ ) {
    reportForDirectory( reposByLine[ i ], 'images' );
    reportForDirectory( reposByLine[ i ], 'audio' );
  }
};<|endoftext|>