<commit_before>var app = require('../../src/app');
var request = require('supertest')(app);
var async = require('async');
var status = require('http-status-codes');

var chai = require('chai');
var expect = chai.expect;

var utils = require('./testUtils');
var testScouts = require('./testScouts');

describe.only('Class sizes', function () {
  var badges, events;
  var generatedUsers, generatedScouts, generatedOfferings;
  var scoutId;
  var registrationIds = [];
  var badId = '123456789012345678901234';

  before(function (done) {
    utils.dropDb(done);
  });

  beforeEach(function (done) {
    utils.dropTable(['Event', 'Offering', 'Badge', 'Assignment', 'Registration'], done);
  });

  before(function (done) {
    this.timeout(10000);
    utils.generateTokens(['admin', 'teacher', 'coordinator'], function (err, generatedTokens) {
      if (err) return done(err);
      generatedUsers = generatedTokens;
      return done();
    });
  });

  beforeEach(function (done) {
    utils.createBadges(generatedUsers.admin.token, function (err, items) {
      if (err) return done(err);
      badges = items;
      return done();
    });
  });

  beforeEach(function (done) {
    utils.createEvents(generatedUsers.admin.token, function (err, items) {

      if (err) return done(err);
      events = items;
      return done();
    });
  });

  beforeEach(function (done) {
    utils.createScoutsForUser(generatedUsers.coordinator, testScouts(5), generatedUsers.coordinator.token, function (err, scouts) {
      if (err) return done(err);
      generatedScouts = scouts;
      return done();
    });
  });

  beforeEach(function (done) {
    async.forEachOfSeries(generatedScouts, function (scout, index, cb) {
        request.post('/api/scouts/' + scout.id + '/registrations')
          .set('Authorization', generatedUsers.coordinator.token)
          .send({
            event_id: events[0].id
          })
          .expect(status.CREATED)
          .end(function (err, res) {
            if (err) return done(err);
            registrationIds.push(res.body.registration.id);
            return cb();
          });
    }, function (err) {
      done(err);
    });
  });

  after(function (done) {
    utils.dropDb(done);
  });

  describe('when offerings do not exist', function () {
    var postData;

    beforeEach(function () {
      postData = {
        badge_id: badges[1].id,
        offering: {
          duration: 1,
          periods: [1, 2, 3],
          price: '10.00',
          requirements: ['1', '2', '3a', '3b']
        }
      };
    });

    it('should default to 20 as the size limit', function (done) {
      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.CREATED)
        .end(function (err, res) {
          if (err) return done(err);
          var event = res.body.event;
          expect(event.offerings).to.have.lengthOf(1);
          expect(event.offerings[0].details.size_limit).to.equal(20);
          return done();
        });
    });

    it('should accept an input for class size', function (done) {
      postData.offering.size_limit = 30;

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.CREATED)
        .end(function (err, res) {
          if (err) return done(err);
          var event = res.body.event;
          expect(event.offerings).to.have.lengthOf(1);
          expect(event.offerings[0].details.size_limit).to.equal(30);
          return done();
        });
    });

    it('should not allow a negative class size', function (done) {
      postData.offering.size_limit = -1;

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.BAD_REQUEST, done);
    });

    it('should expect a number', function (done) {
      postData.offering.size_limit = 'hello';

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.BAD_REQUEST, done);
    });
  });

  describe('when an offering exists', function () {
    var offering, assignmentData;

    beforeEach(function (done) {
      var postData = {
        badge_id: badges[1].id,
        offering: {
          duration: 1,
          periods: [1, 2, 3],
          price: '10.00',
          requirements: ['1', '2', '3a', '3b'],
          size_limit: 1
        }
      };

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.CREATED)
        .end(function (err, res) {
          if (err) return done(err);
          var event = res.body.event;
          offering = event.offerings[0];
          return done();
        });
    });

    beforeEach(function () {
      assignmentData = {
        periods: [1],
        offering: offering.details.id
      };
    });

    it('should allow joining if under the limit for a period', function (done) {
      request.post('/api/scouts/' + generatedScouts[0].id + '/registrations/' + registrationIds[0] + '/assignments')
        .set('Authorization', generatedUsers.teacher.token)
        .send(assignmentData)
        .expect(status.CREATED, done);
    });

    it('should allow joining multiple periods under the limit', function (done) {
      async.series([
        function (cb) {
          request.post('/api/scouts/' + generatedScouts[0].id + '/registrations/' + registrationIds[0] + '/assignments')
            .set('Authorization', generatedUsers.teacher.token)
            .send(assignmentData)
            .expect(status.CREATED, cb);
        },
        function (cb) {
          assignmentData.periods = [2];

          request.post('/api/scouts/' + generatedScouts[1].id + '/registrations/' + registrationIds[1] + '/assignments')
            .set('Authorization', generatedUsers.teacher.token)
            .send(assignmentData)
            .expect(status.CREATED, cb);
        }
      ], done);
    });
  });
});
<commit_msg>Test for expected limit behavior when adding assignments<commit_after>var app = require('../../src/app');
var request = require('supertest')(app);
var async = require('async');
var status = require('http-status-codes');

var chai = require('chai');
var expect = chai.expect;

var utils = require('./testUtils');
var testScouts = require('./testScouts');

describe.only('Class sizes', function () {
  var badges, events;
  var generatedUsers, generatedScouts, generatedOfferings;
  var scoutId;
  var registrationIds = [];
  var badId = '123456789012345678901234';

  before(function (done) {
    utils.dropDb(done);
  });

  beforeEach(function (done) {
    utils.dropTable(['Event', 'Offering', 'Badge', 'Assignment', 'Registration'], done);
  });

  before(function (done) {
    this.timeout(10000);
    utils.generateTokens(['admin', 'teacher', 'coordinator'], function (err, generatedTokens) {
      if (err) return done(err);
      generatedUsers = generatedTokens;
      return done();
    });
  });

  beforeEach(function (done) {
    utils.createBadges(generatedUsers.admin.token, function (err, items) {
      if (err) return done(err);
      badges = items;
      return done();
    });
  });

  beforeEach(function (done) {
    utils.createEvents(generatedUsers.admin.token, function (err, items) {

      if (err) return done(err);
      events = items;
      return done();
    });
  });

  beforeEach(function (done) {
    utils.createScoutsForUser(generatedUsers.coordinator, testScouts(5), generatedUsers.coordinator.token, function (err, scouts) {
      if (err) return done(err);
      generatedScouts = scouts;
      return done();
    });
  });

  beforeEach(function (done) {
    async.forEachOfSeries(generatedScouts, function (scout, index, cb) {
        request.post('/api/scouts/' + scout.id + '/registrations')
          .set('Authorization', generatedUsers.coordinator.token)
          .send({
            event_id: events[0].id
          })
          .expect(status.CREATED)
          .end(function (err, res) {
            if (err) return done(err);
            registrationIds.push(res.body.registration.id);
            return cb();
          });
    }, function (err) {
      done(err);
    });
  });

  after(function (done) {
    utils.dropDb(done);
  });

  describe('when offerings do not exist', function () {
    var postData;

    beforeEach(function () {
      postData = {
        badge_id: badges[1].id,
        offering: {
          duration: 1,
          periods: [1, 2, 3],
          price: '10.00',
          requirements: ['1', '2', '3a', '3b']
        }
      };
    });

    it('should default to 20 as the size limit', function (done) {
      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.CREATED)
        .end(function (err, res) {
          if (err) return done(err);
          var event = res.body.event;
          expect(event.offerings).to.have.lengthOf(1);
          expect(event.offerings[0].details.size_limit).to.equal(20);
          return done();
        });
    });

    it('should accept an input for class size', function (done) {
      postData.offering.size_limit = 30;

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.CREATED)
        .end(function (err, res) {
          if (err) return done(err);
          var event = res.body.event;
          expect(event.offerings).to.have.lengthOf(1);
          expect(event.offerings[0].details.size_limit).to.equal(30);
          return done();
        });
    });

    it('should not allow a negative class size', function (done) {
      postData.offering.size_limit = -1;

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.BAD_REQUEST, done);
    });

    it('should expect a number', function (done) {
      postData.offering.size_limit = 'hello';

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.BAD_REQUEST, done);
    });
  });

  describe('when an offering exists', function () {
    var offering, assignmentData;

    beforeEach(function (done) {
      var postData = {
        badge_id: badges[1].id,
        offering: {
          duration: 1,
          periods: [1, 2, 3],
          price: '10.00',
          requirements: ['1', '2', '3a', '3b'],
          size_limit: 1
        }
      };

      request.post('/api/events/' + events[0].id + '/badges')
        .set('Authorization', generatedUsers.admin.token)
        .send(postData)
        .expect(status.CREATED)
        .end(function (err, res) {
          if (err) return done(err);
          var event = res.body.event;
          offering = event.offerings[0];
          return done();
        });
    });

    beforeEach(function () {
      assignmentData = {
        periods: [1],
        offering: offering.details.id
      };
    });

    it('should allow joining if under the limit for a period', function (done) {
      request.post('/api/scouts/' + generatedScouts[0].id + '/registrations/' + registrationIds[0] + '/assignments')
        .set('Authorization', generatedUsers.teacher.token)
        .send(assignmentData)
        .expect(status.CREATED, done);
    });

    it('should allow joining multiple periods under the limit', function (done) {
      async.series([
        function (cb) {
          request.post('/api/scouts/' + generatedScouts[0].id + '/registrations/' + registrationIds[0] + '/assignments')
            .set('Authorization', generatedUsers.teacher.token)
            .send(assignmentData)
            .expect(status.CREATED, cb);
        },
        function (cb) {
          assignmentData.periods = [2];

          request.post('/api/scouts/' + generatedScouts[1].id + '/registrations/' + registrationIds[1] + '/assignments')
            .set('Authorization', generatedUsers.teacher.token)
            .send(assignmentData)
            .expect(status.CREATED, cb);
        }
      ], done);
    });

    it('should not allow creating an assignment over the limit', function (done) {
      async.series([
        function (cb) {
          request.post('/api/scouts/' + generatedScouts[0].id + '/registrations/' + registrationIds[0] + '/assignments')
            .set('Authorization', generatedUsers.teacher.token)
            .send(assignmentData)
            .expect(status.CREATED, cb);
        },
        function (cb) {
          request.post('/api/scouts/' + generatedScouts[1].id + '/registrations/' + registrationIds[1] + '/assignments')
            .set('Authorization', generatedUsers.teacher.token)
            .send(assignmentData)
            .expect(status.BAD_REQUEST, cb);
        }
      ], done);
    });
  });
});
<|endoftext|>


<commit_before>var UNDEFINED = {}

function lz(list) {
  this.fn = []
  this.i = 0
  this.len = list.length

  this.list = list

  if (!(this instanceof lz)) {
    return new lz(list)
  }
}

lz.prototype.valueOf = function () {
  if (this._value) {
    return this._value
  }

  return this._value = this.all()
}

lz.prototype.next = function () {
  var item = this.list[this.i++]
  if (this.i > this.len) return UNDEFINED
  for (var j = 0; j < this.fn.length; j += 1) {
    item = this.fn[j](item)
  }
  return item
}

lz.prototype.filter = function (f) {
  var _ = this
  this.fn.push(function (x) {
    if (f(x) === true) return x
    else return _.next()
  })
  return this
}

lz.prototype.map = function (f) {
  this.fn.push(function (x) { return f(x) })
  return this
}

lz.prototype.head = function () {
  var item
  return (item = this.next()) === UNDEFINED ? null : item
}

//lz.prototype.foldl
//lz.prototype.foldr
//lz.prototype.each ?
//lz.prototype.any
//lz.prototype.some
//lz.prototype.init
//lz.prototype.tail
//lz.prototype.last
//lz.prototype.drop
//lz.prototype.has
//lz.prototype.takeWhile
//lz.prototype.dropWhile
//lz.prototype.reverse

//lz utils, not lazy but whatever. include lz.memoize, lz.flatten, etc.

lz.prototype.take = function (n) {
  var results = []
  var item
  while (n > 0) {
    item = this.next()
    if (item === UNDEFINED) break
    results.push(item)
    n -= 1
  }
  return results
}

lz.prototype.all = function () {
  return this.take(this.len)
}

lz.range = function (start, end) {
  var i = new lz([])
  i.len = end
  i._next = i.next
  i.next = function () {
    this.list.push(this.i + start)
    return i._next()
  }
  return i
}

lz.cycle = function (list) {
  var z = new lz(list)
  z._next = z.next
  z.next = function () {
    if (this.i === this.len) {
      this.i = 0
    }
    return this._next()
  }
  return z
}

lz.zipWith = function (fn, list1, list2) {
  var z = new lz([])

  if (!(list1 instanceof lz) && !(list2 instanceof lz)) {
    z.next = function () {
      return fn(list1[this.i], list2[this.i++])
    }
    return z
  } else {
    if (!(list1 instanceof lz)) list1 = lz(list1)
    if (!(list2 instanceof lz)) list2 = lz(list2)
    z.len = list1.len > list2.len ? list1.len : list2.len
    z._next = z.next
    z.next = function () {
      this.list.push(fn(list1.next(), list2.next()))
      return this._next()
    }
    return z
  }
}

module.exports = lz
<commit_msg>Fixes zipWith (fast) && renames .len to .length<commit_after>var UNDEFINED = {}

function lz(list) {
  this.fn = []
  this.i = 0
  this.length = list.length

  this.list = list

  if (!(this instanceof lz)) {
    return new lz(list)
  }
}

lz.prototype.valueOf = function () {
  if (this._value) {
    return this._value
  }

  return this._value = this.all()
}

lz.prototype.next = function () {
  var item = this.list[this.i++]
  if (this.i > this.length) return UNDEFINED
  for (var j = 0; j < this.fn.length; j += 1) {
    item = this.fn[j](item)
  }
  return item
}

lz.prototype.filter = function (f) {
  var _ = this
  this.fn.push(function (x) {
    if (f(x) === true) return x
    else return _.next()
  })
  return this
}

lz.prototype.map = function (f) {
  this.fn.push(function (x) { return f(x) })
  return this
}

lz.prototype.head = function () {
  var item
  return (item = this.next()) === UNDEFINED ? null : item
}

//lz.prototype.foldl
//lz.prototype.foldr
//lz.prototype.each ?
//lz.prototype.any
//lz.prototype.some
//lz.prototype.init
//lz.prototype.tail
//lz.prototype.last
//lz.prototype.drop
//lz.prototype.has
//lz.prototype.takeWhile
//lz.prototype.dropWhile
//lz.prototype.reverse

//lz utils, not lazy but whatever. include lz.memoize, lz.flatten, etc.

lz.prototype.take = function (n) {
  var results = []
  var item
  while (n > 0) {
    item = this.next()
    if (item === UNDEFINED) break
    results.push(item)
    n -= 1
  }
  return results
}

lz.prototype.all = function () {
  return this.take(this.length)
}

lz.prototype.zipWith = function (fn, list) {
  return lz.zipWith(fn, list, this.list)
}

lz.range = function (start, end) {
  var i = new lz([])
  i.length = end
  i._next = i.next
  i.next = function () {
    this.list.push(this.i + start)
    return i._next()
  }
  return i
}

lz.cycle = function (list) {
  var z = new lz(list)
  var length = list.length
  z.length = Infinity
  z._next = z.next
  z.next = function () {
    if (this.i === length) {
      this.i = 0
    }
    return this._next()
  }
  return z
}

lz.zipWith = function (fn, list1, list2) {
  var z = new lz([])
  z.length = list1.length < list2.length ? list1.length : list2.length

  if (!(list1 instanceof lz) && !(list2 instanceof lz)) {
    z.next = function () {
      if (this.i >= this.length) return UNDEFINED
      return fn(list1[this.i], list2[this.i++])
    }
    return z
  } else {
    if (!(list1 instanceof lz)) list1 = lz(list1)
    if (!(list2 instanceof lz)) list2 = lz(list2)
    z._next = z.next
    z.next = function () {
      this.list.push(fn(list1.next(), list2.next()))
      return this._next()
    }
    return z
  }
}

module.exports = lz
<|endoftext|>


<commit_before>/*! ======================================================================================

Copyright (c) 2015 Måns Beckman  http://www.spatialillusions.com
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

------------------------------------------------------------------------------------------

For updates and more information go to http://www.spatialillusions.com

======================================================================================= */
'use strict';

var MS = new function(){
  this._colorModes	= {};
  this._dashArrays = {
    pending: "4,4",
    anticipated: "8,12",
    feintDummy: "8,8"
  };
  this._hqStafLength = 100;
  this._iconCache = {}; // A cache of icn to speed stuff up...
  this._iconParts = [];
  this._labelCache = {}; // A cache of label overrides to speed stuff up...
  this._labelOverrides = {};
  this._letterSIDCicons = [];
  this._markerParts = [];
  this._numberSIDCicons = [];
  this._STD2525 = true;
  this._svgNS = "http://www.w3.org/2000/svg";

  this.autoSVG = true;
  this.version = '0.6.0';

  if (typeof console === 'object') {
    console.log('milsymbol.js ' + this.version + ' - Copyright (c) 2017 Måns Beckman  http://www.spatialillusions.com');
  }
  if (typeof parseXML === 'undefined') {
    window.parseXML = function (s,doc) {
      doc = doc || document;
      var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
      return doc.adoptNode(doc2.documentElement);
    };
  }
};

MS.addIconParts = function(parts) {
  if (typeof parts === 'function') {
    this._iconParts = this._iconParts.concat(parts);
  }
};
MS.addLetterLabelOverrides = function(parts){
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('letter')) this._labelOverrides['letter'] = [];
      this._labelOverrides['letter'] = this._labelOverrides['letter'].concat(parts);
    }
};
MS.addLetterSIDCicons = function(parts){
  if (typeof parts === 'function') {
    this._letterSIDCicons = this._letterSIDCicons.concat(parts);
  }
};
MS.addMarkerParts = function(parts) {
  if (typeof parts === 'function') {
    MS.setMarkerParts(MS.getMarkerParts().concat(parts));
  }
};
MS.addNumberLabelOverrides = function(parts){
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('number')) this._labelOverrides['number'] = [];
      this._labelOverrides['number'] = this._labelOverrides['number'].concat(parts);
    }
};
MS.addNumberSIDCicons = function(parts){
  if (typeof parts === 'function') {
    this._numberSIDCicons = this._numberSIDCicons.concat(parts);
  }
};
MS.bbox = require('./ms/bbox.js');
MS.buildingBlock = function(pre,post,bbox) {
  if ( pre.length == 1 && Array.isArray(pre[0]) ) pre = pre[0];
  if ( post.length == 1 && Array.isArray(post[0]) ) post = post[0];
  return {pre: pre, post: post, bbox: bbox};
};
MS.colorMode = function(civilian,friend,hostile,neutral,unknown) {
  var o = {};
  o.Civilian = civilian;
  o.Friend 	= friend;
  o.Hostile = hostile;
  o.Neutral = neutral;
  o.Unknown = unknown;
  return o;
};
MS.getColorMode = function(mode) {
  var c = this._colorModes[mode];
  // TODO call MS.colorMode instead.
  var o = {};
  o.Hostile = c.Hostile;
  o.Friend = c.Friend;
  o.Neutral = c.Neutral;
  o.Unknown = c.Unknown;
  o.Civilian = c.Civilian;
  return o;
};
MS.getDashArrays = function() {
  return this._dashArrays;
};
MS.getHqStafLength = function() {
  return this._hqStafLength;
};
MS.getMarkerParts = function() {
  return this._markerParts.slice(0);
};
MS.outline = function(geom,outline,stroke,color){
  if(Array.isArray(geom)){
    var clone = [];
    for(var i in geom){
      clone.push(MS.outline(geom[i],outline,stroke,color));
    }
  }else{
    var clone = {};
    for (var key in geom){
      if(['fill','fillopacity'].indexOf(key) == -1){
        clone[key] = geom[key];
      }
    }
    if(geom.type == 'translate' || geom.type == 'rotate'  || geom.type == 'scale'){
      clone.draw = [];
      for (var draw in geom.draw){
        clone.draw.push(MS.outline(geom.draw[draw],outline,stroke,color));
      }
    }else{
      clone.strokewidth = clone.stroke != false ? (Number(clone.strokewidth||stroke) + 2*outline) : 2*outline;
      clone.stroke = color;
      clone.fill = false;
      clone.linecap = 'round';
    }
  }
  return clone;
};
MS.rotate = function(angle, instruction){
  return {type:'rotate',degree:angle,x:100,y:100,draw:[instruction]};
};
MS.scale = function(factor, instruction){
  return {type:'translate',x:(100-factor*100),y:(100-factor*100),draw:[{type:'scale',factor:factor,draw:[instruction]}]};
};
MS.setColorMode = function(mode,colorMode) {
  this._colorModes[mode] = {};
  this._colorModes[mode].Hostile 	= colorMode.Hostile;
  this._colorModes[mode].Friend 	= colorMode.Friend;
  this._colorModes[mode].Neutral 	= colorMode.Neutral;
  this._colorModes[mode].Unknown 	= colorMode.Unknown;
  this._colorModes[mode].Civilian = colorMode.Civilian;
  return this._colorModes[mode];
};
MS.setDashArrays = function(pending,anticipated,feintDummy) {
  this._dashArrays.pending = pending;
  this._dashArrays.anticipated = anticipated;
  this._dashArrays.feintDummy = feintDummy;
  return this._dashArrays;
};
MS.setHqStafLength = function(len) {
  this._hqStafLength = len;
  return this._hqStafLength;
};
MS.setMarkerParts = function(parts) {
  this._markerParts = parts;
};
MS.setStandard = require('./ms/setstandard.js');
MS.translate = function(x, y, instruction){
  return {type:'translate',x:x,y:y,draw:[instruction]};
};

// For backward compability
MS.bboxMax = function(box1,box2){
	return box1.merge(box2);
};

module.exports = MS;
<commit_msg>Update copyright in license to 2017<commit_after>/*! ======================================================================================

Copyright (c) 2017 Måns Beckman  http://www.spatialillusions.com
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the <organization> nor the
      names of its contributors may be used to endorse or promote products
      derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

------------------------------------------------------------------------------------------

For updates and more information go to http://www.spatialillusions.com

======================================================================================= */
'use strict';

var MS = new function(){
  this._colorModes	= {};
  this._dashArrays = {
    pending: "4,4",
    anticipated: "8,12",
    feintDummy: "8,8"
  };
  this._hqStafLength = 100;
  this._iconCache = {}; // A cache of icn to speed stuff up...
  this._iconParts = [];
  this._labelCache = {}; // A cache of label overrides to speed stuff up...
  this._labelOverrides = {};
  this._letterSIDCicons = [];
  this._markerParts = [];
  this._numberSIDCicons = [];
  this._STD2525 = true;
  this._svgNS = "http://www.w3.org/2000/svg";

  this.autoSVG = true;
  this.version = '0.6.0';

  if (typeof console === 'object') {
    console.log('milsymbol.js ' + this.version + ' - Copyright (c) 2017 Måns Beckman  http://www.spatialillusions.com');
  }
  if (typeof parseXML === 'undefined') {
    window.parseXML = function (s,doc) {
      doc = doc || document;
      var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
      return doc.adoptNode(doc2.documentElement);
    };
  }
};

MS.addIconParts = function(parts) {
  if (typeof parts === 'function') {
    this._iconParts = this._iconParts.concat(parts);
  }
};
MS.addLetterLabelOverrides = function(parts){
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('letter')) this._labelOverrides['letter'] = [];
      this._labelOverrides['letter'] = this._labelOverrides['letter'].concat(parts);
    }
};
MS.addLetterSIDCicons = function(parts){
  if (typeof parts === 'function') {
    this._letterSIDCicons = this._letterSIDCicons.concat(parts);
  }
};
MS.addMarkerParts = function(parts) {
  if (typeof parts === 'function') {
    MS.setMarkerParts(MS.getMarkerParts().concat(parts));
  }
};
MS.addNumberLabelOverrides = function(parts){
  if (typeof parts === 'function') {
    if (!this._labelOverrides.hasOwnProperty('number')) this._labelOverrides['number'] = [];
      this._labelOverrides['number'] = this._labelOverrides['number'].concat(parts);
    }
};
MS.addNumberSIDCicons = function(parts){
  if (typeof parts === 'function') {
    this._numberSIDCicons = this._numberSIDCicons.concat(parts);
  }
};
MS.bbox = require('./ms/bbox.js');
MS.buildingBlock = function(pre,post,bbox) {
  if ( pre.length == 1 && Array.isArray(pre[0]) ) pre = pre[0];
  if ( post.length == 1 && Array.isArray(post[0]) ) post = post[0];
  return {pre: pre, post: post, bbox: bbox};
};
MS.colorMode = function(civilian,friend,hostile,neutral,unknown) {
  var o = {};
  o.Civilian = civilian;
  o.Friend 	= friend;
  o.Hostile = hostile;
  o.Neutral = neutral;
  o.Unknown = unknown;
  return o;
};
MS.getColorMode = function(mode) {
  var c = this._colorModes[mode];
  // TODO call MS.colorMode instead.
  var o = {};
  o.Hostile = c.Hostile;
  o.Friend = c.Friend;
  o.Neutral = c.Neutral;
  o.Unknown = c.Unknown;
  o.Civilian = c.Civilian;
  return o;
};
MS.getDashArrays = function() {
  return this._dashArrays;
};
MS.getHqStafLength = function() {
  return this._hqStafLength;
};
MS.getMarkerParts = function() {
  return this._markerParts.slice(0);
};
MS.outline = function(geom,outline,stroke,color){
  if(Array.isArray(geom)){
    var clone = [];
    for(var i in geom){
      clone.push(MS.outline(geom[i],outline,stroke,color));
    }
  }else{
    var clone = {};
    for (var key in geom){
      if(['fill','fillopacity'].indexOf(key) == -1){
        clone[key] = geom[key];
      }
    }
    if(geom.type == 'translate' || geom.type == 'rotate'  || geom.type == 'scale'){
      clone.draw = [];
      for (var draw in geom.draw){
        clone.draw.push(MS.outline(geom.draw[draw],outline,stroke,color));
      }
    }else{
      clone.strokewidth = clone.stroke != false ? (Number(clone.strokewidth||stroke) + 2*outline) : 2*outline;
      clone.stroke = color;
      clone.fill = false;
      clone.linecap = 'round';
    }
  }
  return clone;
};
MS.rotate = function(angle, instruction){
  return {type:'rotate',degree:angle,x:100,y:100,draw:[instruction]};
};
MS.scale = function(factor, instruction){
  return {type:'translate',x:(100-factor*100),y:(100-factor*100),draw:[{type:'scale',factor:factor,draw:[instruction]}]};
};
MS.setColorMode = function(mode,colorMode) {
  this._colorModes[mode] = {};
  this._colorModes[mode].Hostile 	= colorMode.Hostile;
  this._colorModes[mode].Friend 	= colorMode.Friend;
  this._colorModes[mode].Neutral 	= colorMode.Neutral;
  this._colorModes[mode].Unknown 	= colorMode.Unknown;
  this._colorModes[mode].Civilian = colorMode.Civilian;
  return this._colorModes[mode];
};
MS.setDashArrays = function(pending,anticipated,feintDummy) {
  this._dashArrays.pending = pending;
  this._dashArrays.anticipated = anticipated;
  this._dashArrays.feintDummy = feintDummy;
  return this._dashArrays;
};
MS.setHqStafLength = function(len) {
  this._hqStafLength = len;
  return this._hqStafLength;
};
MS.setMarkerParts = function(parts) {
  this._markerParts = parts;
};
MS.setStandard = require('./ms/setstandard.js');
MS.translate = function(x, y, instruction){
  return {type:'translate',x:x,y:y,draw:[instruction]};
};

// For backward compability
MS.bboxMax = function(box1,box2){
	return box1.merge(box2);
};

module.exports = MS;
<|endoftext|>


<commit_before>var ContentManager = {
    init: function() {
        $(document).on('click', 'a.js-nav', function() {
            History.pushState({}, $(this).text(), $(this).attr('href'));
            return false;
        });

        History.Adapter.bind(
            window,
            'statechange',
            ContentManager.onStateChange
        );

        // Trigger initial app state.
        window.location.pathname == '/'
            ? History.pushState({}, '', $('html').data('default-path'))
            : History.Adapter.trigger(window, 'statechange');
    },

    // Handles content manipulation on state change.
    onStateChange: function() {
        var state = History.getState();
        var $app = $('#app');
        var initialLoad = $app.is(':hidden');

        $('#appnavbar a.js-nav.currentpage').removeClass('currentpage');
        $('#appnavbar a[href="' + window.location.pathname + '"]')
            .addClass('currentpage');

        if (initialLoad) {
            $app.delay(100).fadeIn(500, function() {
                $('#headerwrapper').slideDown(350, function() {
                    $('#header').slideDown(350);
                });
            });

            // Don't load new content if there's already content present.
            if ($('#no-content').length === 0) {
                return;
            }
        }

        ContentManager.loadNewContent(state.url, null, initialLoad);
    },

    // Loads new content into the application content container.
    loadNewContent: function(path, data, skipFadeout) {
        var $content = $('.content');
        var $contentwrapper = $('#contentwrapper');

        var fadeoutPromise = $.Deferred(function(deferred) {
            $content.css('height', $content.height() + 'px');
            if (skipFadeout) {
                $contentwrapper.hide();
                $content.addClass('loading');
                deferred.resolve();
            } else {
                $contentwrapper.fadeOut(150, function() {
                    $content.addClass('loading');
                    deferred.resolve();
                });
            }
        }).promise();

        var fetchPromise = $.ajax({
            type: data ? 'POST' : 'GET',
            url: path,
            data: data
        }).promise();

        $.when(fetchPromise, fadeoutPromise)
            .done(function(responseData) {
                var markup = responseData[0];
                $('title').html(markup.match(/<title>(.*?)<\/title>/)[1]);
                $('#capsule').replaceWith($('#capsule', $(markup)));

                $contentwrapper.css({
                    'visibility':'hidden',
                    'display': 'block'
                });
                var height = $contentwrapper.height();
                $contentwrapper.css({
                    'visibility':'',
                    'display': 'none'
                });

                $content.animate({height: height}, 500, function() {
                    $content.removeClass('loading');
                    $contentwrapper.fadeIn(150, function() {
                        $content.css('height','');
                    });
                });
            })
            .fail(Error.show);
    },

    // Prepares the UI upon login/logout.
    onLoginLogout: function(redirect, fadetime) {
        var $container = $('#container');
        var fadeout = $.Deferred(function(deferred) {
            $container.fadeOut(150, function() {
                deferred.resolve();
            });
        });

        $.when($.get(redirect), fadeout).done(function(data) {
            $('#appcontainer').replaceWith($('#appcontainer', $(data[0])));
            $container.fadeIn(fadetime, function() {
                History.pushState({}, '', redirect);
            });
        });
    }
};

$(function() {
    ContentManager.init();
});
<commit_msg>Fixed bug that the previous bug fix introduced.<commit_after>var ContentManager = {
    init: function() {
        $(document).on('click', 'a.js-nav', function() {
            History.pushState({}, $(this).text(), $(this).attr('href'));
            return false;
        });

        History.Adapter.bind(
            window,
            'statechange',
            ContentManager.onStateChange
        );

        // Trigger initial app state.
        window.location.pathname == '/'
            ? History.pushState({}, '', $('html').data('default-path'))
            : History.Adapter.trigger(window, 'statechange');
    },

    // Handles content manipulation on state change.
    onStateChange: function() {
        var state = History.getState();
        var $app = $('#app');
        var initialLoad = $app.is(':hidden');

        $('#appnavbar a.js-nav.currentpage').removeClass('currentpage');
        $('#appnavbar a[href="' + window.location.pathname + '"]')
            .addClass('currentpage');

        if (initialLoad) {
            $app.delay(100).fadeIn(500, function() {
                $('#headerwrapper').slideDown(350, function() {
                    $('#header').slideDown(350);
                });
            });

            // Don't load new content if there's already content present.
            if (!document.getElementById('no-content')) {
                return;
            }
        }

        ContentManager.loadNewContent(state.url, null, initialLoad);
    },

    // Loads new content into the application content container.
    loadNewContent: function(path, data, skipFadeout) {
        var $content = $('.content');
        var $contentwrapper = $('#contentwrapper');

        var fadeoutPromise = $.Deferred(function(deferred) {
            $content.css('height', $content.height() + 'px');
            if (skipFadeout) {
                $contentwrapper.hide();
                $content.addClass('loading');
                deferred.resolve();
            } else {
                $contentwrapper.fadeOut(150, function() {
                    $content.addClass('loading');
                    deferred.resolve();
                });
            }
        }).promise();

        var fetchPromise = $.ajax({
            type: data ? 'POST' : 'GET',
            url: path,
            data: data
        }).promise();

        $.when(fetchPromise, fadeoutPromise)
            .done(function(responseData) {
                var markup = responseData[0];
                $('title').html(markup.match(/<title>(.*?)<\/title>/)[1]);
                $('#capsule').replaceWith($('#capsule', $(markup)));

                $contentwrapper.css({
                    'visibility':'hidden',
                    'display': 'block'
                });
                var height = $contentwrapper.height();
                $contentwrapper.css({
                    'visibility':'',
                    'display': 'none'
                });

                $content.animate({height: height}, 500, function() {
                    $content.removeClass('loading');
                    $contentwrapper.fadeIn(150, function() {
                        $content.css('height','');
                    });
                });
            })
            .fail(Error.show);
    },

    // Prepares the UI upon login/logout.
    onLoginLogout: function(redirect, fadetime) {
        var $container = $('#container');
        var fadeout = $.Deferred(function(deferred) {
            $container.fadeOut(150, function() {
                deferred.resolve();
            });
        });

        $.when($.get(redirect), fadeout).done(function(data) {
            $('#appcontainer').replaceWith($('#appcontainer', $(data[0])));
            $container.fadeIn(fadetime, function() {
                History.pushState({}, '', redirect);
            });
        });
    }
};

$(function() {
    ContentManager.init();
});
<|endoftext|>


<commit_before>/*
 * Common classes / functions for Selenium RC format.
 */

var subScriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
subScriptLoader.loadSubScript('chrome://selenium-ide/content/formats/formatCommandOnlyAdapter.js', this);

function formatHeader(testCase) {
    var className = testCase.getTitle();
	if (!className) {
		className = "NewTest";
	}

	var formatLocal = testCase.formatLocal(this.name);
	methodName = testMethodName(className.replace(/Test$/, "").replace(/^Test/, "").
								replace(/^[A-Z]/, function(str) { return str.toLowerCase(); }));
	var header = (options.getHeader ? options.getHeader() : options.header).
		replace(/\$\{className\}/g, className).
		replace(/\$\{methodName\}/g, methodName).
		replace(/\$\{baseURL\}/g, testCase.getBaseURL()).
		replace(/\$\{([a-zA-Z0-9_]+)\}/g, function(str, name) { return options[name]; });
	this.lastIndent = indents(parseInt(options.initialIndents, 10));
	formatLocal.header = header;
	return formatLocal.header;
}

function formatFooter(testCase) {
	var formatLocal = testCase.formatLocal(this.name);
	formatLocal.footer = options.footer;
	return formatLocal.footer;
}

function indents(num) {
	function repeat(c, n) {
		var str = "";
		for (var i = 0; i < n; i++) {
			str += c;
		}
		return str;
	}

    try {
    	var indent = options.indent;
    	if ('tab' == indent) {
    		return repeat("\t", num);
    	} else {
    		return repeat(" ", num * parseInt(options.indent, 10));
    	}
    } catch (error) {
        return repeat(" ", 0);
    }
}

function capitalize(string) {
	return string.replace(/^[a-z]/, function(str) { return str.toUpperCase(); });
}

function underscore(text) {
	return text.replace(/[A-Z]/g, function(str) {
			return '_' + str.toLowerCase();
		});
}

function notOperator() {
	return "!";
}

function logicalAnd(conditions) {
    return conditions.join(" && ");
}

function equals(e1, e2) {
	return new Equals(e1, e2);
}

function Equals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
}

Equals.prototype.invert = function() {
	return new NotEquals(this.e1, this.e2);
};

function NotEquals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
	this.negative = true;
}

NotEquals.prototype.invert = function() {
	return new Equals(this.e1, this.e2);
};

function RegexpMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
}

RegexpMatch.prototype.invert = function() {
	return new RegexpNotMatch(this.pattern, this.expression);
};

RegexpMatch.prototype.assert = function() {
	return assertTrue(this.toString());
};

RegexpMatch.prototype.verify = function() {
	return verifyTrue(this.toString());
};

function RegexpNotMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
	this.negative = true;
}

RegexpNotMatch.prototype.invert = function() {
	return new RegexpMatch(this.pattern, this.expression);
};

RegexpNotMatch.prototype.toString = function() {
	return notOperator() + RegexpMatch.prototype.toString.call(this);
};

RegexpNotMatch.prototype.assert = function() {
	return assertFalse(this.invert());
};

RegexpNotMatch.prototype.verify = function() {
	return verifyFalse(this.invert());
};

function seleniumEquals(type, pattern, expression) {
	if (type == 'String[]') {
		return seleniumEquals('String', pattern.replace(/\\,/g, ',') , joinExpression(expression));
	} else if (type == 'String' && pattern.match(/^regexp:/)) {
		return new RegexpMatch(pattern.substring(7), expression);
	} else if (type == 'String' && pattern.match(/^regex:/)) {
		return new RegexpMatch(pattern.substring(6), expression);
	} else if (type == 'String' && (pattern.match(/^glob:/) || pattern.match(/[\*\?]/))) {
		pattern = pattern.replace(/^glob:/, '');
		pattern = pattern.replace(/([\]\[\\\{\}\$\(\).])/g, "\\$1");
		pattern = pattern.replace(/\?/g, "[\\s\\S]");
		pattern = pattern.replace(/\*/g, "[\\s\\S]*");
		return new RegexpMatch("^" + pattern + "$", expression);
	} else {
		pattern = pattern.replace(/^exact:/, '');
		return new Equals(xlateValue(type, pattern), expression);
	}
}

function xlateArgument(value) {
	value = value.replace(/^\s+/, '');
	value = value.replace(/\s+$/, '');
	var r;
	var r2;
	var parts = [];
	if ((r = /^javascript\{([\d\D]*)\}$/.exec(value))) {
		var js = r[1];
		var prefix = "";
		while ((r2 = /storedVars\['(.*?)'\]/.exec(js))) {
			parts.push(string(prefix + js.substring(0, r2.index) + "'"));
			parts.push(variableName(r2[1]));
			js = js.substring(r2.index + r2[0].length);
			prefix = "'";
		}
		parts.push(string(prefix + js));
		return new CallSelenium("getEval", [concatString(parts)]);
	} else if ((r = /\$\{/.exec(value))) {
		var regexp = /\$\{(.*?)\}/g;
		var lastIndex = 0;
		while (r2 = regexp.exec(value)) {
		    if (this.declaredVars && this.declaredVars[r2[1]]) {
    			if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(variableName(r2[1]));
    			lastIndex = regexp.lastIndex;
    		} else if (r2[1] == "nbsp") {
    		    if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(nonBreakingSpace());
    			lastIndex = regexp.lastIndex;
    		}
		}
		if (lastIndex < value.length) {
			parts.push(string(value.substring(lastIndex, value.length)));
		}
		return concatString(parts);
	} else {
		return string(value);
	}
}

function addDeclaredVar(variable) {
	if (this.declaredVars == null) {
		this.declaredVars = {};
	}
	this.declaredVars[variable] = true;
}

function newVariable(prefix, index) {
	if (index == null) index = 1;
	if (this.declaredVars && this.declaredVars[prefix + index]) {
		return newVariable(prefix, index + 1);
	} else {
		addDeclaredVar(prefix + index);
		return prefix + index;
	}
}

function variableName(value) {
	return value;
}

function concatString(array) {
	return array.join(" + ");
}

function string(value) {
	if (value != null) {
		//value = value.replace(/^\s+/, '');
		//value = value.replace(/\s+$/, '');
		value = value.replace(/\\/g, '\\\\');
		value = value.replace(/\"/g, '\\"');
		value = value.replace(/\r/g, '\\r');
		value = value.replace(/\n/g, '\\n');
		return '"' + value + '"';
	} else {
		return '""';
	}
}

function CallSelenium(message, args) {
	this.message = message;
	if (args) {
		this.args = args;
	} else {
		this.args = [];
	}
}

CallSelenium.prototype.invert = function() {
	var call = new CallSelenium(this.message);
	call.args = this.args;
	call.negative = !this.negative;
	return call;
};

function xlateArrayElement(value) {
	return value.replace(/\\(.)/g, "$1");
}

function parseArray(value) {
	var start = 0;
	var list = [];
	for (var i = 0; i < value.length; i++) {
		if (value.charAt(i) == ',') {
			list.push(xlateArrayElement(value.substring(start, i)));
			start = i + 1;
		} else if (value.charAt(i) == '\\') {
			i++;
		}
	}
	list.push(xlateArrayElement(value.substring(start, value.length)));
	return list;
}

function xlateValue(type, value) {
	if (type == 'String[]') {
		return array(parseArray(value));
	} else {
		return xlateArgument(value);
	}
}

function formatCommand(command) {
	var line = null;
	if (command.type == 'command') {
		var def = command.getDefinition();
		if (def && def.isAccessor) {
			var call = new CallSelenium(def.name);
			for (var i = 0; i < def.params.length; i++) {
				call.args.push(xlateArgument(command.getParameterAt(i)));
			}
			var extraArg = command.getParameterAt(def.params.length);
			if (def.name.match(/^is/)) { // isXXX
				if (command.command.match(/^assert/) ||
					(this.assertOrVerifyFailureOnNext && command.command.match(/^verify/))) {
					line = (def.negative ? assertFalse : assertTrue)(call);
				} else if (command.command.match(/^verify/)) {
					line = (def.negative ? verifyFalse : verifyTrue)(call);
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable('boolean', extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					line = waitFor(def.negative ? call.invert() : call);
				}
			} else { // getXXX
				if (command.command.match(/^(verify|assert)/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
					line = eq[method]();
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable(def.returnType, extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					line = waitFor(eq);
				}
			}
		} else if (this.pause && 'pause' == command.command) {
			line = pause(command.target);
		} else if (this.echo && 'echo' == command.command) {
			line = echo(command.target);
		} else if ('store' == command.command) {
			addDeclaredVar(command.value);
			line = statement(assignToVariable('String', command.value, xlateArgument(command.target)));
		} else if (command.command.match(/^(assert|verify)Selected$/)) {
			var optionLocator = command.value;
			var flavor = 'Label';
			var value = optionLocator;
			var r = /^(index|label|value|id)=(.*)$/.exec(optionLocator);
			if (r) {
				flavor = r[1].replace(/^[a-z]/, function(str) { return str.toUpperCase() });
				value = r[2];
			}
			var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
			var call = new CallSelenium("getSelected" + flavor);
			call.args.push(xlateArgument(command.target));
			var eq = seleniumEquals('String', value, call);
			line = statement(eq[method]());
		} else if (def) {
			if (def.name.match(/^(assert|verify)(Error|Failure)OnNext$/)) {
				this.assertOrVerifyFailureOnNext = true;
				this.assertFailureOnNext = def.name.match(/^assert/);
				this.verifyFailureOnNext = def.name.match(/^verify/);
			} else {
				var call = new CallSelenium(def.name);
                if ("open" == def.name && options.urlSuffix && !command.target.match(/^\w+:\/\//)) {
                    // urlSuffix is used to translate core-based test
                    call.args.push(xlateArgument(options.urlSuffix + command.target));
                } else {
                    for (var i = 0; i < def.params.length; i++) {
                        call.args.push(xlateArgument(command.getParameterAt(i)));
                    }
                }
				line = statement(call, command);
			}
		} else {
			this.log.info("unknown command: <" + command.command + ">");
			// TODO
			var call = new CallSelenium(command.command);
			if ((command.target != null && command.target.length > 0)
				|| (command.value != null && command.value.length > 0)) {
				call.args.push(string(command.target));
				if (command.value != null && command.value.length > 0) {
					call.args.push(string(command.value));
				}
			}
			line = formatComment(new Comment(statement(call)));
		}
	}
	if (line && this.assertOrVerifyFailureOnNext) {
		line = assertOrVerifyFailure(line, this.assertFailureOnNext);
		this.assertOrVerifyFailureOnNext = false;
		this.assertFailureOnNext = false;
		this.verifyFailureOnNext = false;
	}
	return line;
}

this.remoteControl = true;
this.playable = false;

<commit_msg>AdamGoucher - formats can now customize how set* is handled locally<commit_after>/*
 * Common classes / functions for Selenium RC format.
 */

var subScriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
subScriptLoader.loadSubScript('chrome://selenium-ide/content/formats/formatCommandOnlyAdapter.js', this);

function formatHeader(testCase) {
    var className = testCase.getTitle();
	if (!className) {
		className = "NewTest";
	}

	var formatLocal = testCase.formatLocal(this.name);
	methodName = testMethodName(className.replace(/Test$/, "").replace(/^Test/, "").
								replace(/^[A-Z]/, function(str) { return str.toLowerCase(); }));
	var header = (options.getHeader ? options.getHeader() : options.header).
		replace(/\$\{className\}/g, className).
		replace(/\$\{methodName\}/g, methodName).
		replace(/\$\{baseURL\}/g, testCase.getBaseURL()).
		replace(/\$\{([a-zA-Z0-9_]+)\}/g, function(str, name) { return options[name]; });
	this.lastIndent = indents(parseInt(options.initialIndents, 10));
	formatLocal.header = header;
	return formatLocal.header;
}

function formatFooter(testCase) {
	var formatLocal = testCase.formatLocal(this.name);
	formatLocal.footer = options.footer;
	return formatLocal.footer;
}

function indents(num) {
	function repeat(c, n) {
		var str = "";
		for (var i = 0; i < n; i++) {
			str += c;
		}
		return str;
	}

    try {
    	var indent = options.indent;
    	if ('tab' == indent) {
    		return repeat("\t", num);
    	} else {
    		return repeat(" ", num * parseInt(options.indent, 10));
    	}
    } catch (error) {
        return repeat(" ", 0);
    }
}

function capitalize(string) {
	return string.replace(/^[a-z]/, function(str) { return str.toUpperCase(); });
}

function underscore(text) {
	return text.replace(/[A-Z]/g, function(str) {
			return '_' + str.toLowerCase();
		});
}

function notOperator() {
	return "!";
}

function logicalAnd(conditions) {
    return conditions.join(" && ");
}

function equals(e1, e2) {
	return new Equals(e1, e2);
}

function Equals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
}

Equals.prototype.invert = function() {
	return new NotEquals(this.e1, this.e2);
};

function NotEquals(e1, e2) {
	this.e1 = e1;
	this.e2 = e2;
	this.negative = true;
}

NotEquals.prototype.invert = function() {
	return new Equals(this.e1, this.e2);
};

function RegexpMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
}

RegexpMatch.prototype.invert = function() {
	return new RegexpNotMatch(this.pattern, this.expression);
};

RegexpMatch.prototype.assert = function() {
	return assertTrue(this.toString());
};

RegexpMatch.prototype.verify = function() {
	return verifyTrue(this.toString());
};

function RegexpNotMatch(pattern, expression) {
	this.pattern = pattern;
	this.expression = expression;
	this.negative = true;
}

RegexpNotMatch.prototype.invert = function() {
	return new RegexpMatch(this.pattern, this.expression);
};

RegexpNotMatch.prototype.toString = function() {
	return notOperator() + RegexpMatch.prototype.toString.call(this);
};

RegexpNotMatch.prototype.assert = function() {
	return assertFalse(this.invert());
};

RegexpNotMatch.prototype.verify = function() {
	return verifyFalse(this.invert());
};

function seleniumEquals(type, pattern, expression) {
	if (type == 'String[]') {
		return seleniumEquals('String', pattern.replace(/\\,/g, ',') , joinExpression(expression));
	} else if (type == 'String' && pattern.match(/^regexp:/)) {
		return new RegexpMatch(pattern.substring(7), expression);
	} else if (type == 'String' && pattern.match(/^regex:/)) {
		return new RegexpMatch(pattern.substring(6), expression);
	} else if (type == 'String' && (pattern.match(/^glob:/) || pattern.match(/[\*\?]/))) {
		pattern = pattern.replace(/^glob:/, '');
		pattern = pattern.replace(/([\]\[\\\{\}\$\(\).])/g, "\\$1");
		pattern = pattern.replace(/\?/g, "[\\s\\S]");
		pattern = pattern.replace(/\*/g, "[\\s\\S]*");
		return new RegexpMatch("^" + pattern + "$", expression);
	} else {
		pattern = pattern.replace(/^exact:/, '');
		return new Equals(xlateValue(type, pattern), expression);
	}
}

function xlateArgument(value) {
	value = value.replace(/^\s+/, '');
	value = value.replace(/\s+$/, '');
	var r;
	var r2;
	var parts = [];
	if ((r = /^javascript\{([\d\D]*)\}$/.exec(value))) {
		var js = r[1];
		var prefix = "";
		while ((r2 = /storedVars\['(.*?)'\]/.exec(js))) {
			parts.push(string(prefix + js.substring(0, r2.index) + "'"));
			parts.push(variableName(r2[1]));
			js = js.substring(r2.index + r2[0].length);
			prefix = "'";
		}
		parts.push(string(prefix + js));
		return new CallSelenium("getEval", [concatString(parts)]);
	} else if ((r = /\$\{/.exec(value))) {
		var regexp = /\$\{(.*?)\}/g;
		var lastIndex = 0;
		while (r2 = regexp.exec(value)) {
		    if (this.declaredVars && this.declaredVars[r2[1]]) {
    			if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(variableName(r2[1]));
    			lastIndex = regexp.lastIndex;
    		} else if (r2[1] == "nbsp") {
    		    if (r2.index - lastIndex > 0) {
    				parts.push(string(value.substring(lastIndex, r2.index)));
    			}
    			parts.push(nonBreakingSpace());
    			lastIndex = regexp.lastIndex;
    		}
		}
		if (lastIndex < value.length) {
			parts.push(string(value.substring(lastIndex, value.length)));
		}
		return concatString(parts);
	} else {
		return string(value);
	}
}

function addDeclaredVar(variable) {
	if (this.declaredVars == null) {
		this.declaredVars = {};
	}
	this.declaredVars[variable] = true;
}

function newVariable(prefix, index) {
	if (index == null) index = 1;
	if (this.declaredVars && this.declaredVars[prefix + index]) {
		return newVariable(prefix, index + 1);
	} else {
		addDeclaredVar(prefix + index);
		return prefix + index;
	}
}

function variableName(value) {
	return value;
}

function concatString(array) {
	return array.join(" + ");
}

function string(value) {
	if (value != null) {
		//value = value.replace(/^\s+/, '');
		//value = value.replace(/\s+$/, '');
		value = value.replace(/\\/g, '\\\\');
		value = value.replace(/\"/g, '\\"');
		value = value.replace(/\r/g, '\\r');
		value = value.replace(/\n/g, '\\n');
		return '"' + value + '"';
	} else {
		return '""';
	}
}

function CallSelenium(message, args) {
	this.message = message;
	if (args) {
		this.args = args;
	} else {
		this.args = [];
	}
}

CallSelenium.prototype.invert = function() {
	var call = new CallSelenium(this.message);
	call.args = this.args;
	call.negative = !this.negative;
	return call;
};

function xlateArrayElement(value) {
	return value.replace(/\\(.)/g, "$1");
}

function parseArray(value) {
	var start = 0;
	var list = [];
	for (var i = 0; i < value.length; i++) {
		if (value.charAt(i) == ',') {
			list.push(xlateArrayElement(value.substring(start, i)));
			start = i + 1;
		} else if (value.charAt(i) == '\\') {
			i++;
		}
	}
	list.push(xlateArrayElement(value.substring(start, value.length)));
	return list;
}

function xlateValue(type, value) {
	if (type == 'String[]') {
		return array(parseArray(value));
	} else {
		return xlateArgument(value);
	}
}

function formatCommand(command) {
	var line = null;
	if (command.type == 'command') {
		var def = command.getDefinition();
		if (def && def.isAccessor) {
			var call = new CallSelenium(def.name);
			for (var i = 0; i < def.params.length; i++) {
				call.args.push(xlateArgument(command.getParameterAt(i)));
			}
			var extraArg = command.getParameterAt(def.params.length);
			if (def.name.match(/^is/)) { // isXXX
				if (command.command.match(/^assert/) ||
					(this.assertOrVerifyFailureOnNext && command.command.match(/^verify/))) {
					line = (def.negative ? assertFalse : assertTrue)(call);
				} else if (command.command.match(/^verify/)) {
					line = (def.negative ? verifyFalse : verifyTrue)(call);
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable('boolean', extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					line = waitFor(def.negative ? call.invert() : call);
				}
			} else { // getXXX
				if (command.command.match(/^(verify|assert)/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
					line = eq[method]();
				} else if (command.command.match(/^store/)) {
					addDeclaredVar(extraArg);
					line = statement(assignToVariable(def.returnType, extraArg, call));
				} else if (command.command.match(/^waitFor/)) {
					var eq = seleniumEquals(def.returnType, extraArg, call);
					if (def.negative) eq = eq.invert();
					line = waitFor(eq);
				}
			}
		} else if (this.pause && 'pause' == command.command) {
			line = pause(command.target);
		} else if (this.echo && 'echo' == command.command) {
			line = echo(command.target);
		} else if ('store' == command.command) {
			addDeclaredVar(command.value);
			line = statement(assignToVariable('String', command.value, xlateArgument(command.target)));
	    } else if (this.set && command.command.match(/^set/)) {
	        line = set(command.command, command.target);
		} else if (command.command.match(/^(assert|verify)Selected$/)) {
			var optionLocator = command.value;
			var flavor = 'Label';
			var value = optionLocator;
			var r = /^(index|label|value|id)=(.*)$/.exec(optionLocator);
			if (r) {
				flavor = r[1].replace(/^[a-z]/, function(str) { return str.toUpperCase() });
				value = r[2];
			}
			var method = (!this.assertOrVerifyFailureOnNext && command.command.match(/^verify/)) ? 'verify' : 'assert';
			var call = new CallSelenium("getSelected" + flavor);
			call.args.push(xlateArgument(command.target));
			var eq = seleniumEquals('String', value, call);
			line = statement(eq[method]());
		} else if (def) {
			if (def.name.match(/^(assert|verify)(Error|Failure)OnNext$/)) {
				this.assertOrVerifyFailureOnNext = true;
				this.assertFailureOnNext = def.name.match(/^assert/);
				this.verifyFailureOnNext = def.name.match(/^verify/);
			} else {
				var call = new CallSelenium(def.name);
                if ("open" == def.name && options.urlSuffix && !command.target.match(/^\w+:\/\//)) {
                    // urlSuffix is used to translate core-based test
                    call.args.push(xlateArgument(options.urlSuffix + command.target));
                } else {
                    for (var i = 0; i < def.params.length; i++) {
                        call.args.push(xlateArgument(command.getParameterAt(i)));
                    }
                }
				line = statement(call, command);
			}
		} else {
			this.log.info("unknown command: <" + command.command + ">");
			// TODO
			var call = new CallSelenium(command.command);
			if ((command.target != null && command.target.length > 0)
				|| (command.value != null && command.value.length > 0)) {
				call.args.push(string(command.target));
				if (command.value != null && command.value.length > 0) {
					call.args.push(string(command.value));
				}
			}
			line = formatComment(new Comment(statement(call)));
		}
	}
	if (line && this.assertOrVerifyFailureOnNext) {
		line = assertOrVerifyFailure(line, this.assertFailureOnNext);
		this.assertOrVerifyFailureOnNext = false;
		this.assertFailureOnNext = false;
		this.verifyFailureOnNext = false;
	}
	return line;
}

this.remoteControl = true;
this.playable = false;

<|endoftext|>


<commit_before>if (typeof VIE === 'undefined') {
    VIE = {};
}

VIE.ContainerManager = {
    models: {},
    views: {},

    /**
     * @private
     */
    _getContainerProperties: function(element, emptyValues) {
        var containerProperties = {};

        jQuery.each(jQuery('[property]', element), function(index, objectProperty) {
            var objectProperty = jQuery(objectProperty);
            var propertyName = objectProperty.attr('property');

            if (emptyValues) {
                containerProperties[propertyName] = '';
                return true;
            }

            containerProperties[propertyName] = objectProperty.html();
        });

        return containerProperties;
    },

    /**
     * @private
     */
    _getContainerValue: function(element, propertyName) {
        var element = jQuery(element);

        if (typeof element.attr(propertyName) !== 'undefined')
        {
            // Direct match with container
            return element.attr(propertyName);
        }
        return element.find('[' + propertyName + ']').attr(propertyName);
    },

    getContainerIdentifier: function(element) {
        return VIE.ContainerManager._getContainerValue(element, 'about');
    },

    cloneContainer: function(element) {
        var element = jQuery(element).clone(false);

        if (typeof element.attr('about') !== 'undefined')
        {
            // Direct match with container
            element.attr('about', '');
        }
        element.find('[about]').attr('about', '');
        element.find('[property]').html('');

        return element;
    },

    getViewForContainer: function(element) {
        var element = jQuery(element);
        var type = VIE.ContainerManager._getContainerValue(element, 'typeof');

        if (typeof VIE.ContainerManager.views[type] !== 'undefined') {
            // We already have a view for this type
            return VIE.ContainerManager.views[type];
        }

        var viewProperties = {};
        viewProperties.initialize = function() {
            _.bindAll(this, 'render');
            this.model.bind('change', this.render);
            this.model.view = this;
        };
        viewProperties.tagName = element.get(0).nodeName;
        viewProperties.make = function(tagName, attributes, content) {
            return VIE.ContainerManager.cloneContainer(element);
        };
        viewProperties.render = function() {
            var model = this.model;
            jQuery('[property]', this.el).each(function(index, propertyElement) {
                var propertyElement = jQuery(propertyElement);
                var property = propertyElement.attr('property');
                propertyElement.html(model.get(property));
            });
            return this;
        };

        VIE.ContainerManager.views[type] = Backbone.View.extend(viewProperties);

        return VIE.ContainerManager.views[type];
    },

    getModelForContainer: function(element) {
        var type = VIE.ContainerManager._getContainerValue(element, 'typeof');

        if (typeof VIE.ContainerManager.models[type] !== 'undefined') {
            // We already have a model for this type
            return VIE.ContainerManager.models[type];
        }

        // Parse the relevant properties from DOM
        var modelPropertiesFromRdf = VIE.ContainerManager._getContainerProperties(element, true);
        var modelProperties = jQuery.extend({}, modelPropertiesFromRdf);

        modelProperties.type = type;

        modelProperties.initialize = function() {
            var modelInstance = this;
            var populateProperties = {};
            jQuery.each(modelPropertiesFromRdf, function(propName, propValue) {

                if (!modelInstance.get(propName)) {
                    populateProperties[propName] = modelInstance.getPlaceholder(propName);
                }

            });

            if (!jQuery.isEmptyObject(populateProperties)) {
                modelInstance.set(populateProperties);
            }
        };

        VIE.ContainerManager.findAdditionalModelProperties(element, modelProperties);

        VIE.ContainerManager.models[type] = Backbone.Model.extend(modelProperties);

        return VIE.ContainerManager.models[type];
    },

    /**
     * Override this to seek additional properties from the element to include to the model
     */
    findAdditionalModelProperties: function(element, properties) {
    },

    /**
     * Override this to seek additional properties from the element to include to the instance
     */
    findAdditionalInstanceProperties: function(element, properties) {
    },

    getInstanceForContainer: function(element) {
        var model = VIE.ContainerManager.getModelForContainer(element);
        var properties = VIE.ContainerManager._getContainerProperties(element, false);
        var view = VIE.ContainerManager.getViewForContainer(element);

        properties.id = VIE.ContainerManager._getContainerValue(element, 'about');

        VIE.ContainerManager.findAdditionalInstanceProperties(element, properties);

        var modelInstance = new model(properties);
        modelInstance.view = new view({model: modelInstance, el: element});

        return modelInstance;
    }
};
<commit_msg>Store instances in the ContainerManager<commit_after>if (typeof VIE === 'undefined') {
    VIE = {};
}

VIE.ContainerManager = {
    models: {},
    views: {},
	instances: [],

    /**
     * @private
     */
    _getContainerProperties: function(element, emptyValues) {
        var containerProperties = {};

        jQuery.each(jQuery('[property]', element), function(index, objectProperty) {
            var objectProperty = jQuery(objectProperty);
            var propertyName = objectProperty.attr('property');

            if (emptyValues) {
                containerProperties[propertyName] = '';
                return true;
            }

            containerProperties[propertyName] = objectProperty.html();
        });

        return containerProperties;
    },

    /**
     * @private
     */
    _getContainerValue: function(element, propertyName) {
        var element = jQuery(element);

        if (typeof element.attr(propertyName) !== 'undefined')
        {
            // Direct match with container
            return element.attr(propertyName);
        }
        return element.find('[' + propertyName + ']').attr(propertyName);
    },

    getContainerIdentifier: function(element) {
        return VIE.ContainerManager._getContainerValue(element, 'about');
    },

    cloneContainer: function(element) {
        var element = jQuery(element).clone(false);

        if (typeof element.attr('about') !== 'undefined')
        {
            // Direct match with container
            element.attr('about', '');
        }
        element.find('[about]').attr('about', '');
        element.find('[property]').html('');

        return element;
    },

    getViewForContainer: function(element) {
        var element = jQuery(element);
        var type = VIE.ContainerManager._getContainerValue(element, 'typeof');

        if (typeof VIE.ContainerManager.views[type] !== 'undefined') {
            // We already have a view for this type
            return VIE.ContainerManager.views[type];
        }

        var viewProperties = {};
        viewProperties.initialize = function() {
            _.bindAll(this, 'render');
            this.model.bind('change', this.render);
            this.model.view = this;
        };
        viewProperties.tagName = element.get(0).nodeName;
        viewProperties.make = function(tagName, attributes, content) {
            return VIE.ContainerManager.cloneContainer(element);
        };
        viewProperties.render = function() {
            var model = this.model;
            jQuery('[property]', this.el).each(function(index, propertyElement) {
                var propertyElement = jQuery(propertyElement);
                var property = propertyElement.attr('property');
                propertyElement.html(model.get(property));
            });
            return this;
        };

        VIE.ContainerManager.views[type] = Backbone.View.extend(viewProperties);

        return VIE.ContainerManager.views[type];
    },

    getModelForContainer: function(element) {
        var type = VIE.ContainerManager._getContainerValue(element, 'typeof');

        if (typeof VIE.ContainerManager.models[type] !== 'undefined') {
            // We already have a model for this type
            return VIE.ContainerManager.models[type];
        }

        // Parse the relevant properties from DOM
        var modelPropertiesFromRdf = VIE.ContainerManager._getContainerProperties(element, true);
        var modelProperties = jQuery.extend({}, modelPropertiesFromRdf);

        modelProperties.type = type;

        modelProperties.initialize = function() {
            var modelInstance = this;
            var populateProperties = {};
            jQuery.each(modelPropertiesFromRdf, function(propName, propValue) {

                if (!modelInstance.get(propName)) {
                    populateProperties[propName] = modelInstance.getPlaceholder(propName);
                }

            });

            if (!jQuery.isEmptyObject(populateProperties)) {
                modelInstance.set(populateProperties);
            }
        };

        VIE.ContainerManager.findAdditionalModelProperties(element, modelProperties);

        VIE.ContainerManager.models[type] = Backbone.Model.extend(modelProperties);

        return VIE.ContainerManager.models[type];
    },

    /**
     * Override this to seek additional properties from the element to include to the model
     */
    findAdditionalModelProperties: function(element, properties) {
    },

    /**
     * Override this to seek additional properties from the element to include to the instance
     */
    findAdditionalInstanceProperties: function(element, properties) {
    },

    getInstanceForContainer: function(element) {
        var model = VIE.ContainerManager.getModelForContainer(element);
        var properties = VIE.ContainerManager._getContainerProperties(element, false);
        var view = VIE.ContainerManager.getViewForContainer(element);

        properties.id = VIE.ContainerManager._getContainerValue(element, 'about');

        VIE.ContainerManager.findAdditionalInstanceProperties(element, properties);

        var modelInstance = new model(properties);
        modelInstance.view = new view({model: modelInstance, el: element});

		VIE.ContainerManager.instances.push(modelInstance);

        return modelInstance;
    },

	cleanup: function() {
		VIE.ContainerManager.instances = [];
	}
};
<|endoftext|>


<commit_before>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

/* eslint-disable max-len */
/* global getParamsFromSelectors:false, inlineAjaxForm:false, updateHtml:false */

(function(global) {
    'use strict';

    $(document).ready(function() {
        setupActionLinks();
        setupAjaxForms();
        setupConfirmPopup();
        setupMathJax();
        setupSelectAllNone();
        setupAnchorLinks();
    });

    global.getParamsFromSelectors = function getParamsFromSelectors() {
        var fieldParams = {};
        _.each(arguments, function(selector) {
            $(selector).each(function() {
                if (!(this.name in fieldParams)) {
                    fieldParams[this.name] = [];
                }
                fieldParams[this.name].push($(this).val());
            });
        });
        return fieldParams;
    };

    global.getFormParams = function getFormParams($form) {
        return getParamsFromSelectors($form.find('input[type=text]:not(:disabled), input[type=hidden]:not(:disabled), \
                                                  input:checked:not(:disabled), textarea:not(:disabled), \
                                                  select:not(:disabled)'));
    };

    function setupSelectAllNone() {
        $('body').on('click', '[data-select-all]', function() {
            var selector = $(this).data('select-all');
            $(selector).filter(':not(:checked)').prop('checked', true).trigger('change');
        });

        $('body').on('click', '[data-select-none]', function() {
            var selector = $(this).data('select-none');
            $(selector).filter(':checked').prop('checked', false).trigger('change');
        });
    }

    function setupConfirmPopup() {
        $('body').on('click', '[data-confirm]:not(button[data-href]):not(input:button[data-href]):not(a[data-method][data-href]):not(a[data-ajax-dialog][data-href])', function() {
            var $this = $(this);

            function performAction() {
                var evt = $.Event('indico:confirmed');
                $this.trigger(evt);

                // Handle custom code
                if (evt.isDefaultPrevented()) {
                    return;
                }

                if ($this.is('form')) {
                    $this.submit();
                } else {
                    window.location = $this.attr('href');
                }
            }

            var evtBefore = $.Event('indico:beforeConfirmed');
            $this.trigger(evtBefore);

            if (evtBefore.isDefaultPrevented()) {
                performAction();
            } else {
                confirmPrompt($(this).data('confirm'), $(this).data('title')).then(performAction);
            }

            return false;
        });
    }

    function setupActionLinks() {
        var selectors = [
            'button[data-href][data-method]', 'input:button[data-href][data-method]', 'a[data-href][data-method]',
            'button[data-href][data-ajax-dialog]', 'input:button[data-href][data-ajax-dialog]', 'a[data-href][data-ajax-dialog]',
            'button[data-content][data-ajax-dialog]', 'input:button[data-content][data-ajax-dialog]', 'a[data-content][data-ajax-dialog]'
        ];
        $('body').on('click', selectors.join(', '), function(e) {
            e.preventDefault();
            var $this = $(this);
            if ($this.hasClass('disabled')) {
                return;
            }
            var url = $this.data('href');
            var method = ($this.data('method') || 'GET').toUpperCase();
            var params = $this.data('params') || {};
            var paramsSelector = $this.data('params-selector');
            var update = $this.data('update');
            var ajax = $this.data('ajax') !== undefined;
            var highlightUpdate = $this.data('highlight-update') !== undefined;
            var dialog = $this.data('ajax-dialog') !== undefined;
            var reload = $this.data('reload-after');
            var content = $this.data('content');

            if (!$.isPlainObject(params)) {
                throw new Error('Invalid params. Must be valid JSON if set.');
            }

            if (paramsSelector) {
                params = $.extend({}, getParamsFromSelectors(paramsSelector), params);
            }

            function execute() {
                var evt = $.Event('indico:confirmed');
                $this.trigger(evt);

                // Handle custom code
                if (evt.isDefaultPrevented()) {
                    return;
                }

                // Handle AJAX dialog
                if (dialog) {
                    var closeButton = $this.data('close-button');
                    ajaxDialog({
                        trigger: $this,
                        url: url,
                        method: method,
                        data: params,
                        content: $(content).html(),
                        title: $this.data('title'),
                        subtitle: $this.data('subtitle'),
                        closeButton: closeButton === undefined ? false : (closeButton || true),
                        dialogClasses: $this.data('dialog-classes'),
                        hidePageHeader: $this.data('hide-page-header') !== undefined,
                        confirmCloseUnsaved: $this.data('confirm-close-unsaved') !== undefined,
                        onClose: function(data, customData) {
                            if (data) {
                                handleFlashes(data, true, $this);
                                if (update) {
                                    updateHtml(update, data, false, highlightUpdate);
                                } else if (reload !== undefined && reload !== 'customData') {
                                    IndicoUI.Dialogs.Util.progress();
                                    location.reload();
                                }
                            } else if (reload === 'customData' && customData) {
                                IndicoUI.Dialogs.Util.progress();
                                location.reload();
                            }
                        }
                    });
                    return;
                }

                // Handle html update or reload
                if (ajax || update || reload !== undefined) {
                    $.ajax({
                        method: method,
                        url: url,
                        data: params,
                        error: handleAjaxError,
                        complete: IndicoUI.Dialogs.Util.progress(),
                        success: function(data) {
                            var successEvt = $.Event('declarative:success');
                            $this.trigger(successEvt, [data]);
                            if (successEvt.isDefaultPrevented()) {
                                return;
                            }
                            if (update) {
                                handleFlashes(data, true, $this);
                                updateHtml(update, data, false, highlightUpdate);
                            } else if (reload !== undefined) {
                                IndicoUI.Dialogs.Util.progress();
                                location.reload();
                            }
                        }
                    });
                    return;
                }

                // Handle normal GET/POST
                if (method === 'GET') {
                    location.href = build_url(url, params);
                } else if (method === 'POST') {
                    var form = $('<form>', {
                        action: url,
                        method: method
                    });
                    form.append($('<input>', {type: 'hidden', name: 'csrf_token', value: $('#csrf-token').attr('content')}));
                    $.each(params, function(key, value) {
                        form.append($('<input>', {type: 'hidden', name: key, value: value}));
                    });
                    form.appendTo('body').submit();
                }
            }

            var promptMsg = $this.data('confirm');
            var confirmed;
            if (!promptMsg) {
                confirmed = $.Deferred().resolve();
            } else {
                confirmed = confirmPrompt(promptMsg, $(this).data('title') || $T('Confirm action'));
            }
            confirmed.then(execute);
        });
    }

    function setupAjaxForms() {
        function _getOptions($elem, extra) {
            var updateOpts = $elem.data('update');
            return $.extend({
                context: $elem,
                formContainer: $elem.data('form-container'),
                confirmCloseUnsaved: $elem.data('confirm-close-unsaved') !== undefined,
                update: updateOpts ? {
                    element: $elem.data('update'),
                    replace: $elem.data('replace-update') !== undefined,
                    highlight: $elem.data('highlight-update') !== undefined
                } : null
            }, extra);
        }

        function _handleClick(evt) {
            evt.preventDefault();
            var $this = $(this);
            if ($this.hasClass('disabled')) {
                return;
            }

            inlineAjaxForm(_getOptions($this, {
                load: {
                    url: $this.data('href')
                },
                scrollToForm: $this.data('scroll-to-form') !== undefined
            }));

            function toggleDisabled(disabled) {
                if ($this.data('hide-trigger') !== undefined) {
                    $this.toggle(!disabled);
                }
                if ($this.is('a')) {
                    $this.toggleClass('disabled', disabled);
                } else {
                    $this.prop('disabled', disabled);
                }
            }

            $this.on('ajaxForm:show', function() {
                toggleDisabled(true);
            }).on('ajaxForm:hide', function() {
                toggleDisabled(false);
            });
        }

        function _handleHtmlUpdate($elem) {
            $elem.find('form[data-ajax-form]').each(function() {
                var $this = $(this);
                inlineAjaxForm(_getOptions($this, {
                    load: null,
                    initiallyHidden: $this.data('initially-hidden') !== undefined
                }));
            });
        }

        $('body').on('click', 'button[data-ajax-form], a[data-ajax-form]', _handleClick);
        $('body').on('indico:htmlUpdated', function(evt) {
            _handleHtmlUpdate($(evt.target));
        });
        _handleHtmlUpdate($('body'));
    }

    function setupMathJax() {
        var $elems = $('.js-mathjax');
        if ($elems.length) {
            $elems.mathJax();
        }
    }

    function setupAnchorLinks() {
        $('[data-anchor]').each(function() {
            var $elem = $(this);
            var fragment = $elem.data('anchor');
            $('<a>', {
                class: 'anchor-link',
                href: '#' + fragment,
                title: $T.gettext('Direct link to this item')
            }).html('¶').appendTo($elem);
        });
    }
})(window);
<commit_msg>Support data-replace-update in declarative ajax<commit_after>/* This file is part of Indico.
 * Copyright (C) 2002 - 2016 European Organization for Nuclear Research (CERN).
 *
 * Indico is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 *
 * Indico is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Indico; if not, see <http://www.gnu.org/licenses/>.
 */

/* eslint-disable max-len */
/* global getParamsFromSelectors:false, inlineAjaxForm:false, updateHtml:false */

(function(global) {
    'use strict';

    $(document).ready(function() {
        setupActionLinks();
        setupAjaxForms();
        setupConfirmPopup();
        setupMathJax();
        setupSelectAllNone();
        setupAnchorLinks();
    });

    global.getParamsFromSelectors = function getParamsFromSelectors() {
        var fieldParams = {};
        _.each(arguments, function(selector) {
            $(selector).each(function() {
                if (!(this.name in fieldParams)) {
                    fieldParams[this.name] = [];
                }
                fieldParams[this.name].push($(this).val());
            });
        });
        return fieldParams;
    };

    global.getFormParams = function getFormParams($form) {
        return getParamsFromSelectors($form.find('input[type=text]:not(:disabled), input[type=hidden]:not(:disabled), \
                                                  input:checked:not(:disabled), textarea:not(:disabled), \
                                                  select:not(:disabled)'));
    };

    function setupSelectAllNone() {
        $('body').on('click', '[data-select-all]', function() {
            var selector = $(this).data('select-all');
            $(selector).filter(':not(:checked)').prop('checked', true).trigger('change');
        });

        $('body').on('click', '[data-select-none]', function() {
            var selector = $(this).data('select-none');
            $(selector).filter(':checked').prop('checked', false).trigger('change');
        });
    }

    function setupConfirmPopup() {
        $('body').on('click', '[data-confirm]:not(button[data-href]):not(input:button[data-href]):not(a[data-method][data-href]):not(a[data-ajax-dialog][data-href])', function() {
            var $this = $(this);

            function performAction() {
                var evt = $.Event('indico:confirmed');
                $this.trigger(evt);

                // Handle custom code
                if (evt.isDefaultPrevented()) {
                    return;
                }

                if ($this.is('form')) {
                    $this.submit();
                } else {
                    window.location = $this.attr('href');
                }
            }

            var evtBefore = $.Event('indico:beforeConfirmed');
            $this.trigger(evtBefore);

            if (evtBefore.isDefaultPrevented()) {
                performAction();
            } else {
                confirmPrompt($(this).data('confirm'), $(this).data('title')).then(performAction);
            }

            return false;
        });
    }

    function setupActionLinks() {
        var selectors = [
            'button[data-href][data-method]', 'input:button[data-href][data-method]', 'a[data-href][data-method]',
            'button[data-href][data-ajax-dialog]', 'input:button[data-href][data-ajax-dialog]', 'a[data-href][data-ajax-dialog]',
            'button[data-content][data-ajax-dialog]', 'input:button[data-content][data-ajax-dialog]', 'a[data-content][data-ajax-dialog]'
        ];
        $('body').on('click', selectors.join(', '), function(e) {
            e.preventDefault();
            var $this = $(this);
            if ($this.hasClass('disabled')) {
                return;
            }
            var url = $this.data('href');
            var method = ($this.data('method') || 'GET').toUpperCase();
            var params = $this.data('params') || {};
            var paramsSelector = $this.data('params-selector');
            var update = $this.data('update');
            var ajax = $this.data('ajax') !== undefined;
            var replaceUpdate = $this.data('replace-update') !== undefined;
            var highlightUpdate = $this.data('highlight-update') !== undefined;
            var dialog = $this.data('ajax-dialog') !== undefined;
            var reload = $this.data('reload-after');
            var content = $this.data('content');

            if (!$.isPlainObject(params)) {
                throw new Error('Invalid params. Must be valid JSON if set.');
            }

            if (paramsSelector) {
                params = $.extend({}, getParamsFromSelectors(paramsSelector), params);
            }

            function execute() {
                var evt = $.Event('indico:confirmed');
                $this.trigger(evt);

                // Handle custom code
                if (evt.isDefaultPrevented()) {
                    return;
                }

                // Handle AJAX dialog
                if (dialog) {
                    var closeButton = $this.data('close-button');
                    ajaxDialog({
                        trigger: $this,
                        url: url,
                        method: method,
                        data: params,
                        content: $(content).html(),
                        title: $this.data('title'),
                        subtitle: $this.data('subtitle'),
                        closeButton: closeButton === undefined ? false : (closeButton || true),
                        dialogClasses: $this.data('dialog-classes'),
                        hidePageHeader: $this.data('hide-page-header') !== undefined,
                        confirmCloseUnsaved: $this.data('confirm-close-unsaved') !== undefined,
                        onClose: function(data, customData) {
                            if (data) {
                                handleFlashes(data, true, $this);
                                if (update) {
                                    updateHtml(update, data, replaceUpdate, highlightUpdate);
                                } else if (reload !== undefined && reload !== 'customData') {
                                    IndicoUI.Dialogs.Util.progress();
                                    location.reload();
                                }
                            } else if (reload === 'customData' && customData) {
                                IndicoUI.Dialogs.Util.progress();
                                location.reload();
                            }
                        }
                    });
                    return;
                }

                // Handle html update or reload
                if (ajax || update || reload !== undefined) {
                    $.ajax({
                        method: method,
                        url: url,
                        data: params,
                        error: handleAjaxError,
                        complete: IndicoUI.Dialogs.Util.progress(),
                        success: function(data) {
                            var successEvt = $.Event('declarative:success');
                            $this.trigger(successEvt, [data]);
                            if (successEvt.isDefaultPrevented()) {
                                return;
                            }
                            if (update) {
                                handleFlashes(data, true, $this);
                                updateHtml(update, data, replaceUpdate, highlightUpdate);
                            } else if (reload !== undefined) {
                                IndicoUI.Dialogs.Util.progress();
                                location.reload();
                            }
                        }
                    });
                    return;
                }

                // Handle normal GET/POST
                if (method === 'GET') {
                    location.href = build_url(url, params);
                } else if (method === 'POST') {
                    var form = $('<form>', {
                        action: url,
                        method: method
                    });
                    form.append($('<input>', {type: 'hidden', name: 'csrf_token', value: $('#csrf-token').attr('content')}));
                    $.each(params, function(key, value) {
                        form.append($('<input>', {type: 'hidden', name: key, value: value}));
                    });
                    form.appendTo('body').submit();
                }
            }

            var promptMsg = $this.data('confirm');
            var confirmed;
            if (!promptMsg) {
                confirmed = $.Deferred().resolve();
            } else {
                confirmed = confirmPrompt(promptMsg, $(this).data('title') || $T('Confirm action'));
            }
            confirmed.then(execute);
        });
    }

    function setupAjaxForms() {
        function _getOptions($elem, extra) {
            var updateOpts = $elem.data('update');
            return $.extend({
                context: $elem,
                formContainer: $elem.data('form-container'),
                confirmCloseUnsaved: $elem.data('confirm-close-unsaved') !== undefined,
                update: updateOpts ? {
                    element: $elem.data('update'),
                    replace: $elem.data('replace-update') !== undefined,
                    highlight: $elem.data('highlight-update') !== undefined
                } : null
            }, extra);
        }

        function _handleClick(evt) {
            evt.preventDefault();
            var $this = $(this);
            if ($this.hasClass('disabled')) {
                return;
            }

            inlineAjaxForm(_getOptions($this, {
                load: {
                    url: $this.data('href')
                },
                scrollToForm: $this.data('scroll-to-form') !== undefined
            }));

            function toggleDisabled(disabled) {
                if ($this.data('hide-trigger') !== undefined) {
                    $this.toggle(!disabled);
                }
                if ($this.is('a')) {
                    $this.toggleClass('disabled', disabled);
                } else {
                    $this.prop('disabled', disabled);
                }
            }

            $this.on('ajaxForm:show', function() {
                toggleDisabled(true);
            }).on('ajaxForm:hide', function() {
                toggleDisabled(false);
            });
        }

        function _handleHtmlUpdate($elem) {
            $elem.find('form[data-ajax-form]').each(function() {
                var $this = $(this);
                inlineAjaxForm(_getOptions($this, {
                    load: null,
                    initiallyHidden: $this.data('initially-hidden') !== undefined
                }));
            });
        }

        $('body').on('click', 'button[data-ajax-form], a[data-ajax-form]', _handleClick);
        $('body').on('indico:htmlUpdated', function(evt) {
            _handleHtmlUpdate($(evt.target));
        });
        _handleHtmlUpdate($('body'));
    }

    function setupMathJax() {
        var $elems = $('.js-mathjax');
        if ($elems.length) {
            $elems.mathJax();
        }
    }

    function setupAnchorLinks() {
        $('[data-anchor]').each(function() {
            var $elem = $(this);
            var fragment = $elem.data('anchor');
            $('<a>', {
                class: 'anchor-link',
                href: '#' + fragment,
                title: $T.gettext('Direct link to this item')
            }).html('¶').appendTo($elem);
        });
    }
})(window);
<|endoftext|>


<commit_before>// @flow
import React from 'react'
import {WebView} from 'react-native'

import type {StoryType} from './types'

export default function NewsItemView({story}: {story: StoryType}) {
  const content = `

${story.title[0]}

    ${story['content:encoded'][0]}
  `
  return (
    <WebView source={{html: content}} />
  )
}
<commit_msg>fix Mess not using content:encoded for stories<commit_after>// @flow
import React from 'react'
import {WebView} from 'react-native'

import type {StoryType} from './types'

export default function NewsItemView({story}: {story: StoryType}) {
  const content = `

${story.title[0]}

    ${(story['content:encoded'] || story['description'])[0]}
  `
  return (
    <WebView source={{html: content}} />
  )
}
<|endoftext|>