<commit_before>/* Any copyright is dedicated to the Public Domain.
 * https://creativecommons.org/publicdomain/zero/1.0/ */

/* eslint-env mocha */

'use strict';

const assert = require('assert');
const helpers = require('../lib/helpers.js');

describe('upgradeToHttps()', () => {
  describe('CDNs', () => {
    it('Known', () => {
      const knownHttpsUrl = helpers.upgradeToHttps('https://code.jquery.com/script.js');
      assert.equal(knownHttpsUrl, 'https://code.jquery.com/script.js');
      const knownHttpUrl = helpers.upgradeToHttps('http://code.jquery.com/script.js');
      assert.equal(knownHttpUrl, 'https://code.jquery.com/script.js');
    });

    it('Unknown', () => {
      const unknownHttpsUrl = helpers.upgradeToHttps('https://example.com/script.js');
      assert.equal(unknownHttpsUrl, 'https://example.com/script.js');
      const unknownHttpUrl = helpers.upgradeToHttps('http://example.com/script.js');
      assert.equal(unknownHttpUrl, 'http://example.com/script.js');
    });
  });

  describe('URLs', () => {
    it('Schemeless', () => {
      const schemelessUnknownUrl = helpers.upgradeToHttps('example.com/script.js');
      assert.equal(schemelessUnknownUrl, 'http://example.com/script.js');
      const schemelessKnownUrl = helpers.upgradeToHttps('code.jquery.com/script.js');
      assert.equal(schemelessKnownUrl, 'https://code.jquery.com/script.js');
    });

    it('Relative', () => {
      const relativeUnknownUrl = helpers.upgradeToHttps('//example.com/script.js');
      assert.equal(relativeUnknownUrl, 'https://example.com/script.js');
      const relativeKnownUrl = helpers.upgradeToHttps('//code.jquery.com/script.js');
      assert.equal(relativeKnownUrl, 'https://code.jquery.com/script.js');
    });
  });

  describe('Invalid URLs', () => {
    it('Invalid scheme', () => {
      const ftpScheme = helpers.upgradeToHttps('ftp://example.com/script.js');
      assert.strictEqual(ftpScheme, false);
    });

    it('Bare hostname', () => {
      const bareHostname = helpers.upgradeToHttps('foobar');
      assert.equal(bareHostname, 'http://foobar/');
    });
  });
});

describe('eligibility()', () => {
  describe('Eligible', () => {
    it('CORS', () => {
      const allGood = { headers: { 'access-control-allow-origin': '*' } };
      const result = helpers.eligibility(allGood);
      assert.deepEqual(result, []);
    });
  });

  describe('Non-eligible', () => {
    it('non-CORS', () => {
      const nonCORS = { headers: { dnt: '1' } };
      const result = helpers.eligibility(nonCORS);
      assert.deepEqual(result, ['non-cors']);
    });
  });
});

describe('shuffleArray()', () => {
  describe('Array Shuffling', () => {
    it('preserves length', () => {
      const a = ['a', 'b', 'c', 'd'];
      const result = helpers.shuffleArray(a);
      assert.equal(result.length, a.length);
    });

    it('returns all elements', () => {
      const a = ['a', 'b'];
      const result = helpers.shuffleArray(a);
      assert.strictEqual(result[0] === 'a' || result[1] === 'a', true);
      assert.strictEqual(result[0] === 'b' || result[1] === 'b', true);
    });

    it('clones the array', () => {
      const a = ['a'];
      const result = helpers.shuffleArray(a);
      a[0] = 'b';
      assert.strictEqual(result[0], 'a');
    });
  });
});

describe('guessResourceType()', () => {
  describe('Matching', () => {
    describe('Content-type', () => {
      it('js', () => {
        const jsCt1 = helpers.guessResourceType({ ct: 'text/javascript' });
        assert.deepEqual(jsCt1, 'js');
        const jsCt2 = helpers.guessResourceType({ ct: 'application/javascript' });
        assert.deepEqual(jsCt2, 'js');
        const jsCt3 = helpers.guessResourceType({ ct: 'application/x-javascript' });
        assert.deepEqual(jsCt3, 'js');
      });

      it('css', () => {
        const cssCt1 = helpers.guessResourceType({ ct: 'text/css' });
        assert.deepEqual(cssCt1, 'css');
      });

      it('.forbidden', () => {
        const forbiddenCt1 = helpers.guessResourceType({ ct: 'text/plain' });
        assert.deepEqual(forbiddenCt1, '.forbidden');
        const forbiddenCt2 = helpers.guessResourceType({ ct: 'text/xml' });
        assert.deepEqual(forbiddenCt2, '.forbidden');
        const forbiddenCt3 = helpers.guessResourceType({ ct: 'application/octet-stream' });
        assert.deepEqual(forbiddenCt3, '.forbidden');
        const forbiddenCt4 = helpers.guessResourceType({ ct: 'application/xml' });
        assert.deepEqual(forbiddenCt4, '.forbidden');
      });
    });

    describe('Extension', () => {
      it('js', () => {
        const jsUrl1 = helpers.guessResourceType({ url: 'https://example.com/file.min.js' });
        assert.deepEqual(jsUrl1, 'js');
      });

      it('css', () => {
        const cssUrl1 = helpers.guessResourceType({ url: 'http://example.com/file.css' });
        assert.deepEqual(cssUrl1, 'css');
        const cssUrl2 = helpers.guessResourceType({ url: 'http://example.com/STYLES.CSS' });
        assert.deepEqual(cssUrl2, 'css');
      });

      it('URL parameters', () => {
        const urlWithQuery = helpers.guessResourceType({ url: 'http://example.com/file.css?v=1.0.2' });
        assert.deepEqual(urlWithQuery, 'css');
        const urlWithHash = helpers.guessResourceType({ url: 'http://example.com/file.css#v=1.0.2' });
        assert.deepEqual(urlWithHash, 'css');
      });

      // The internal label ".forbidden" must never be detected as a file ext
      it('NOT .forbidden', () => {
        const forbiddenUrl1 = helpers.guessResourceType({ url: 'http://example.com/file.forbidden' });
        assert.deepEqual(forbiddenUrl1, null);
        const forbiddenUrl2 = helpers.guessResourceType({ url: 'http://example.com/file..forbidden' });
        assert.deepEqual(forbiddenUrl2, null);
      });
    });
  });

  describe('Fallback', () => {
    it('Invalid content-type', () => {
      const pdfCt1 = helpers.guessResourceType({
        ct: 'invalid/type',
        url: 'http://example.com'
      });
      assert.deepEqual(pdfCt1, null);
    });

    it('Invalid extension', () => {
      const jsUrl2 = helpers.guessResourceType({ url: 'https://example.com/file.ZZZ' });
      assert.deepEqual(jsUrl2, null);
    });

    it('Missing extension', () => {
      const jsUrl3 = helpers.guessResourceType({ url: 'https://example.com/file' });
      assert.deepEqual(jsUrl3, null);
    });

    it('Empty path', () => {
      const jsUrl4 = helpers.guessResourceType({ url: 'https://example.com' });
      assert.deepEqual(jsUrl4, null);
    });
  });

  describe('Match precedence', () => {
    it('Content-type over extension', () => {
      const cssUrl2 = helpers.guessResourceType({
        ct: 'text/css',
        url: 'https://example.com/file.min.js'
      });
      assert.deepEqual(cssUrl2, 'css');
    });
  });
});

// Ideally we should find a way to test this without using the network
describe('generate()', () => {
  (((result) => {
    const resource = {
      url: 'https://code.jquery.com/jquery-1.11.2.min.js',
      algorithms: ['sha384']
    };
    const expect = {
      success: true,
      status: 200,
      url: 'https://code.jquery.com/jquery-1.11.2.min.js',
      type: 'js',
      integrity: 'sha384-Pn+PczAsODRZ2PiGg0IheRROpP7lXO1NTIjiPo6cca8TliBvaeil42fobhzvZd74',
      eligibility: []
    };

    before((done) => {
      helpers.generate(resource, (data) => {
        result = data;
        done();
      });
    });

    it('js', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const resource = {
      url: 'https://code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css',
      algorithms: ['sha384']
    };
    const expect = {
      success: true,
      status: 200,
      url: 'https://code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css',
      type: 'css',
      integrity: 'sha384-w/LBTbFO0P4C3wi1uA2RpBjIEBMRuH15ue80rElDXquOVM6x7Cw3nsOqy7vSBid9',
      eligibility: []
    };

    before((done) => {
      helpers.generate(resource, (data) => {
        result = data;
        done();
      });
    });

    it('css', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const resource = {
      url: 'https://code.jquery.com/jquery-1.11.2-notfound.min.js',
      algorithms: ['sha384']
    };
    const expect = {
      success: false,
      status: 404
    };

    before((done) => {
      helpers.generate(resource, (data) => {
        result = data;
        done();
      });
    });

    it('404', () => {
      assert.deepEqual(result, expect);
    });
  }))();
});

// Ideally we should find a way to test this without using the network
describe('generateElement()', () => {
  (((result) => {
    const url = 'https://www.google-analytics.com/ga.js';
    const expect = 'Error: this resource is not eligible for integrity checks. See https://enable-cors.org/server.html';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('non-CORS', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css';
    const expect = '<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css" integrity="sha384-w/LBTbFO0P4C3wi1uA2RpBjIEBMRuH15ue80rElDXquOVM6x7Cw3nsOqy7vSBid9" crossorigin="anonymous">';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('css', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'code.jquery.com/jquery-1.11.2.min.js';
    const expect = '<script src="https://code.jquery.com/jquery-1.11.2.min.js" integrity="sha384-Pn+PczAsODRZ2PiGg0IheRROpP7lXO1NTIjiPo6cca8TliBvaeil42fobhzvZd74" crossorigin="anonymous"></script>';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('js', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'https://code.jquery.com/jquery-1.11.2-notfound.min.js';
    const expect = 'Error: fetching the resource returned a 404 error code.';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('404', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'ftp://code.jquery.com/jquery-1.11.2.min.js';
    const expect = 'Error: fetching the resource returned an unexpected error.';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('bad scheme', () => {
      assert.deepEqual(result, expect);
    });
  }))();
});
<commit_msg>Add a test with http in generateElement().<commit_after>/* Any copyright is dedicated to the Public Domain.
 * https://creativecommons.org/publicdomain/zero/1.0/ */

/* eslint-env mocha */

'use strict';

const assert = require('assert');
const helpers = require('../lib/helpers.js');

describe('upgradeToHttps()', () => {
  describe('CDNs', () => {
    it('Known', () => {
      const knownHttpsUrl = helpers.upgradeToHttps('https://code.jquery.com/script.js');
      assert.equal(knownHttpsUrl, 'https://code.jquery.com/script.js');
      const knownHttpUrl = helpers.upgradeToHttps('http://code.jquery.com/script.js');
      assert.equal(knownHttpUrl, 'https://code.jquery.com/script.js');
    });

    it('Unknown', () => {
      const unknownHttpsUrl = helpers.upgradeToHttps('https://example.com/script.js');
      assert.equal(unknownHttpsUrl, 'https://example.com/script.js');
      const unknownHttpUrl = helpers.upgradeToHttps('http://example.com/script.js');
      assert.equal(unknownHttpUrl, 'http://example.com/script.js');
    });
  });

  describe('URLs', () => {
    it('Schemeless', () => {
      const schemelessUnknownUrl = helpers.upgradeToHttps('example.com/script.js');
      assert.equal(schemelessUnknownUrl, 'http://example.com/script.js');
      const schemelessKnownUrl = helpers.upgradeToHttps('code.jquery.com/script.js');
      assert.equal(schemelessKnownUrl, 'https://code.jquery.com/script.js');
    });

    it('Relative', () => {
      const relativeUnknownUrl = helpers.upgradeToHttps('//example.com/script.js');
      assert.equal(relativeUnknownUrl, 'https://example.com/script.js');
      const relativeKnownUrl = helpers.upgradeToHttps('//code.jquery.com/script.js');
      assert.equal(relativeKnownUrl, 'https://code.jquery.com/script.js');
    });
  });

  describe('Invalid URLs', () => {
    it('Invalid scheme', () => {
      const ftpScheme = helpers.upgradeToHttps('ftp://example.com/script.js');
      assert.strictEqual(ftpScheme, false);
    });

    it('Bare hostname', () => {
      const bareHostname = helpers.upgradeToHttps('foobar');
      assert.equal(bareHostname, 'http://foobar/');
    });
  });
});

describe('eligibility()', () => {
  describe('Eligible', () => {
    it('CORS', () => {
      const allGood = { headers: { 'access-control-allow-origin': '*' } };
      const result = helpers.eligibility(allGood);
      assert.deepEqual(result, []);
    });
  });

  describe('Non-eligible', () => {
    it('non-CORS', () => {
      const nonCORS = { headers: { dnt: '1' } };
      const result = helpers.eligibility(nonCORS);
      assert.deepEqual(result, ['non-cors']);
    });
  });
});

describe('shuffleArray()', () => {
  describe('Array Shuffling', () => {
    it('preserves length', () => {
      const a = ['a', 'b', 'c', 'd'];
      const result = helpers.shuffleArray(a);
      assert.equal(result.length, a.length);
    });

    it('returns all elements', () => {
      const a = ['a', 'b'];
      const result = helpers.shuffleArray(a);
      assert.strictEqual(result[0] === 'a' || result[1] === 'a', true);
      assert.strictEqual(result[0] === 'b' || result[1] === 'b', true);
    });

    it('clones the array', () => {
      const a = ['a'];
      const result = helpers.shuffleArray(a);
      a[0] = 'b';
      assert.strictEqual(result[0], 'a');
    });
  });
});

describe('guessResourceType()', () => {
  describe('Matching', () => {
    describe('Content-type', () => {
      it('js', () => {
        const jsCt1 = helpers.guessResourceType({ ct: 'text/javascript' });
        assert.deepEqual(jsCt1, 'js');
        const jsCt2 = helpers.guessResourceType({ ct: 'application/javascript' });
        assert.deepEqual(jsCt2, 'js');
        const jsCt3 = helpers.guessResourceType({ ct: 'application/x-javascript' });
        assert.deepEqual(jsCt3, 'js');
      });

      it('css', () => {
        const cssCt1 = helpers.guessResourceType({ ct: 'text/css' });
        assert.deepEqual(cssCt1, 'css');
      });

      it('.forbidden', () => {
        const forbiddenCt1 = helpers.guessResourceType({ ct: 'text/plain' });
        assert.deepEqual(forbiddenCt1, '.forbidden');
        const forbiddenCt2 = helpers.guessResourceType({ ct: 'text/xml' });
        assert.deepEqual(forbiddenCt2, '.forbidden');
        const forbiddenCt3 = helpers.guessResourceType({ ct: 'application/octet-stream' });
        assert.deepEqual(forbiddenCt3, '.forbidden');
        const forbiddenCt4 = helpers.guessResourceType({ ct: 'application/xml' });
        assert.deepEqual(forbiddenCt4, '.forbidden');
      });
    });

    describe('Extension', () => {
      it('js', () => {
        const jsUrl1 = helpers.guessResourceType({ url: 'https://example.com/file.min.js' });
        assert.deepEqual(jsUrl1, 'js');
      });

      it('css', () => {
        const cssUrl1 = helpers.guessResourceType({ url: 'http://example.com/file.css' });
        assert.deepEqual(cssUrl1, 'css');
        const cssUrl2 = helpers.guessResourceType({ url: 'http://example.com/STYLES.CSS' });
        assert.deepEqual(cssUrl2, 'css');
      });

      it('URL parameters', () => {
        const urlWithQuery = helpers.guessResourceType({ url: 'http://example.com/file.css?v=1.0.2' });
        assert.deepEqual(urlWithQuery, 'css');
        const urlWithHash = helpers.guessResourceType({ url: 'http://example.com/file.css#v=1.0.2' });
        assert.deepEqual(urlWithHash, 'css');
      });

      // The internal label ".forbidden" must never be detected as a file ext
      it('NOT .forbidden', () => {
        const forbiddenUrl1 = helpers.guessResourceType({ url: 'http://example.com/file.forbidden' });
        assert.deepEqual(forbiddenUrl1, null);
        const forbiddenUrl2 = helpers.guessResourceType({ url: 'http://example.com/file..forbidden' });
        assert.deepEqual(forbiddenUrl2, null);
      });
    });
  });

  describe('Fallback', () => {
    it('Invalid content-type', () => {
      const pdfCt1 = helpers.guessResourceType({
        ct: 'invalid/type',
        url: 'http://example.com'
      });
      assert.deepEqual(pdfCt1, null);
    });

    it('Invalid extension', () => {
      const jsUrl2 = helpers.guessResourceType({ url: 'https://example.com/file.ZZZ' });
      assert.deepEqual(jsUrl2, null);
    });

    it('Missing extension', () => {
      const jsUrl3 = helpers.guessResourceType({ url: 'https://example.com/file' });
      assert.deepEqual(jsUrl3, null);
    });

    it('Empty path', () => {
      const jsUrl4 = helpers.guessResourceType({ url: 'https://example.com' });
      assert.deepEqual(jsUrl4, null);
    });
  });

  describe('Match precedence', () => {
    it('Content-type over extension', () => {
      const cssUrl2 = helpers.guessResourceType({
        ct: 'text/css',
        url: 'https://example.com/file.min.js'
      });
      assert.deepEqual(cssUrl2, 'css');
    });
  });
});

// Ideally we should find a way to test this without using the network
describe('generate()', () => {
  (((result) => {
    const resource = {
      url: 'https://code.jquery.com/jquery-1.11.2.min.js',
      algorithms: ['sha384']
    };
    const expect = {
      success: true,
      status: 200,
      url: 'https://code.jquery.com/jquery-1.11.2.min.js',
      type: 'js',
      integrity: 'sha384-Pn+PczAsODRZ2PiGg0IheRROpP7lXO1NTIjiPo6cca8TliBvaeil42fobhzvZd74',
      eligibility: []
    };

    before((done) => {
      helpers.generate(resource, (data) => {
        result = data;
        done();
      });
    });

    it('js', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const resource = {
      url: 'https://code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css',
      algorithms: ['sha384']
    };
    const expect = {
      success: true,
      status: 200,
      url: 'https://code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css',
      type: 'css',
      integrity: 'sha384-w/LBTbFO0P4C3wi1uA2RpBjIEBMRuH15ue80rElDXquOVM6x7Cw3nsOqy7vSBid9',
      eligibility: []
    };

    before((done) => {
      helpers.generate(resource, (data) => {
        result = data;
        done();
      });
    });

    it('css', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const resource = {
      url: 'https://code.jquery.com/jquery-1.11.2-notfound.min.js',
      algorithms: ['sha384']
    };
    const expect = {
      success: false,
      status: 404
    };

    before((done) => {
      helpers.generate(resource, (data) => {
        result = data;
        done();
      });
    });

    it('404', () => {
      assert.deepEqual(result, expect);
    });
  }))();
});

// Ideally we should find a way to test this without using the network
describe('generateElement()', () => {
  (((result) => {
    const url = 'https://www.google-analytics.com/ga.js';
    const expect = 'Error: this resource is not eligible for integrity checks. See https://enable-cors.org/server.html';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('non-CORS', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css';
    const expect = '<link rel="stylesheet" href="https://code.jquery.com/ui/1.11.3/themes/black-tie/jquery-ui.css" integrity="sha384-w/LBTbFO0P4C3wi1uA2RpBjIEBMRuH15ue80rElDXquOVM6x7Cw3nsOqy7vSBid9" crossorigin="anonymous">';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('css', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'http://cdn.ckeditor.com/4.9.2/standard/ckeditor.js';
    const expect = '<script src="http://cdn.ckeditor.com/4.9.2/standard/ckeditor.js" integrity="sha384-5z5Xzy2KLn1l/Q0rWj1TYy+VXyLHqWrwDKCCLG++mTDqiJr4uRbP9f37MKAm4ca8" crossorigin="anonymous"></script>';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('css (http)', () => {
      assert.strictEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'code.jquery.com/jquery-1.11.2.min.js';
    const expect = '<script src="https://code.jquery.com/jquery-1.11.2.min.js" integrity="sha384-Pn+PczAsODRZ2PiGg0IheRROpP7lXO1NTIjiPo6cca8TliBvaeil42fobhzvZd74" crossorigin="anonymous"></script>';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('js', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'https://code.jquery.com/jquery-1.11.2-notfound.min.js';
    const expect = 'Error: fetching the resource returned a 404 error code.';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('404', () => {
      assert.deepEqual(result, expect);
    });
  }))();

  (((result) => {
    const url = 'ftp://code.jquery.com/jquery-1.11.2.min.js';
    const expect = 'Error: fetching the resource returned an unexpected error.';

    before((done) => {
      helpers.generateElement(url, 'sha384', (data) => {
        result = data;
        done();
      });
    });

    it('bad scheme', () => {
      assert.deepEqual(result, expect);
    });
  }))();
});
<|endoftext|>


<commit_before>Readium.Views.ViewerApplicationView = Backbone.View.extend({
	el: 'body',

	uiVisible: false,

	initialize: function() {
		this.model.on("change:full_screen", this.toggleFullscreen, this);
		this.model.on("change:current_theme", this.renderTheme, this);

		this.optionsPresenter = new Readium.Models.OptionsPresenter({
			book: this.model
		});
		this.optionsView = new Readium.Views.OptionsView({model: this.optionsPresenter});
		this.optionsView.render();

		// the little overlay
		this.navWidget = new Readium.Views.NavWidgetView({model: _book});
		this.navWidget.render();

		// the top bar
		this.toolbar = new Readium.Views.ToolbarView({model: _book});
		this.toolbar.render();

		// the table of contents
		this.model.on("change:has_toc", this.init_toc, this);

		this.addGlobalEventHandlers();

	},

	toggleFullscreen: function() {
		if(this.model.get("full_screen")) {
			document.documentElement.webkitRequestFullScreen();
		}
		else {
			document.webkitCancelFullScreen();
		}
	},

	addGlobalEventHandlers: function() {
		var book = this.model;
		window.onresize = function(event) {
			book.trigger("repagination_event");
		}

		$(document).keydown(function(e) {
			if(e.which == 39) {
				book.nextPage();
			}

			if(e.which == 37) {
				book.prevPage();
			}
		});
	},

	render: function() {
		// right now we dont do anything but
		// convention is to return this from render
		this.renderTheme();
		return this;
	},

	renderTheme: function() {
		var theme = this.model.get("current_theme");
		this.$el.toggleClass("default-theme", "default-theme" === theme);
		this.$el.toggleClass("night-theme", "night-theme" === theme);
		this.$el.toggleClass("parchment-theme", "parchment-theme" === theme);
		this.$el.toggleClass("ballard-theme", "ballard-theme" === theme);
		this.$el.toggleClass("vancouver-theme", "vancouver-theme" === theme);

		this.$("#readium-book-view-el").toggleClass("default-theme", "default-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("night-theme", "night-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("parchment-theme", "parchment-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("ballard-theme", "ballard-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("vancouver-theme", "vancouver-theme" === theme);
	},

	init_toc: function() {
		if( this.model.get("has_toc") ) {
			var toc_item = this.model.getToc();
			this.toc = toc_item.TocView();
			toc_item.fetch();

		}
	},

	events: {
		"click #prev-page-button": 		function() { this.model.prevPage() },
		"click #next-page-button": 		function() { this.model.nextPage() }
  	},
});<commit_msg>toggle page turn buttons<commit_after>Readium.Views.ViewerApplicationView = Backbone.View.extend({
	el: 'body',

	uiVisible: false,

	initialize: function() {
		this.model.on("change:full_screen", this.toggleFullscreen, this);
		this.model.on("change:current_theme", this.renderTheme, this);
		this.model.on("change:toolbar_visible", this.renderPageButtons, this);

		this.optionsPresenter = new Readium.Models.OptionsPresenter({
			book: this.model
		});
		this.optionsView = new Readium.Views.OptionsView({model: this.optionsPresenter});
		this.optionsView.render();

		// the little overlay
		this.navWidget = new Readium.Views.NavWidgetView({model: _book});
		this.navWidget.render();

		// the top bar
		this.toolbar = new Readium.Views.ToolbarView({model: _book});
		this.toolbar.render();

		// the table of contents
		this.model.on("change:has_toc", this.init_toc, this);

		this.addGlobalEventHandlers();

	},

	toggleFullscreen: function() {
		if(this.model.get("full_screen")) {
			document.documentElement.webkitRequestFullScreen();
		}
		else {
			document.webkitCancelFullScreen();
		}
	},

	addGlobalEventHandlers: function() {
		var book = this.model;
		window.onresize = function(event) {
			book.trigger("repagination_event");
		}

		$(document).keydown(function(e) {
			if(e.which == 39) {
				book.nextPage();
			}

			if(e.which == 37) {
				book.prevPage();
			}
		});
	},

	render: function() {
		// right now we dont do anything but
		// convention is to return this from render
		this.renderTheme();
		this.renderPageButtons();
		return this;
	},

	renderPageButtons: function() {
		var vis = this.model.get("toolbar_visible");
		this.$("#prev-page-button").toggle(vis);
		this.$("#next-page-button").toggle(vis);
		return this;
	},

	renderTheme: function() {
		var theme = this.model.get("current_theme");
		this.$el.toggleClass("default-theme", "default-theme" === theme);
		this.$el.toggleClass("night-theme", "night-theme" === theme);
		this.$el.toggleClass("parchment-theme", "parchment-theme" === theme);
		this.$el.toggleClass("ballard-theme", "ballard-theme" === theme);
		this.$el.toggleClass("vancouver-theme", "vancouver-theme" === theme);

		this.$("#readium-book-view-el").toggleClass("default-theme", "default-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("night-theme", "night-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("parchment-theme", "parchment-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("ballard-theme", "ballard-theme" === theme);
		this.$("#readium-book-view-el").toggleClass("vancouver-theme", "vancouver-theme" === theme);
	},

	init_toc: function() {
		if( this.model.get("has_toc") ) {
			var toc_item = this.model.getToc();
			this.toc = toc_item.TocView();
			toc_item.fetch();

		}
	},

	events: {
		"click #prev-page-button": 		function() { this.model.prevPage() },
		"click #next-page-button": 		function() { this.model.nextPage() }
  	},
});<|endoftext|>


<commit_before>/*
  Copyright 2008-2011 Jamie Hoover.
  Licensed per the terms of the Apache License v2.0. See Readme.md for details.
*/

/*globals QUnit, $versions, describe, before, after, given, it, assert*/

/*jshint bitwise: true, browser: true, curly: true, eqeqeq: true, forin: true, immed: true, indent: 2, jquery: true, maxerr: 3, newcap: true, noarg: true, noempty: true, nomen: true, nonew: true, onevar: true, plusplus: true, regexp: true, strict: true, undef: true, white: true*/

var
  jQueryVersions = ['1.7.1', '1.7', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6', '1.5.2', '1.5.1', '1.5', '1.4.4', '1.4.3'],
  environment = decodeURI((new RegExp('environment' + '=' + '(.+?)(&|$)').exec(location.search) || [null])[1]),
  theme = decodeURI((new RegExp('theme' + '=' + '(.+?)(&|$)').exec(location.search) || [null])[1]),
  scriptPath;

if (environment === 'production') {
  scriptPath = '../jquery.ninjaui.min.js';
} else {
  environment = 'development';
  jQueryVersions = jQueryVersions[0];
  scriptPath = '../src/ninjaui.js';
}

QUnit.config.hidepassed = true;
QUnit.config.reorder = true;
QUnit.specify.globalApi = true;

$versions(jQueryVersions).load(scriptPath).execute(function ($, jQuery, version) {
  'use strict';

  if ($.inArray(theme, ['dojo']) > -1) {
    $('<link/>', {
      rel: 'stylesheet',
      href: '../themes/ninjaui.theme.' + theme + '.css'
    }).appendTo('head');
    $('body').addClass('nui-' + theme);
  }

  var
    $examples = $('

jQuery ' + version + ' Examples (' + environment + ')

').appendTo('body'),
    $example = $('
');

  QUnit.specify('Ninja User Interface', function () {
    describe('jQuery ' + version, function () {

      describe('Infrastructure', function () {
        it('should load jQuery ' + version, function () {
          assert($.fn.jquery).equals(version);
        });

        it('should load Ninja UI', function () {
          assert($.ninja).isDefined();
        });

        if (environment !== 'production') {
          it('should return development Ninja UI version if environment is not production', function () {
            assert($.ninja.version()).equals('development');
          });
        }
      });

      describe('$.ninja.autocomplete()', function () {

        var $autocomplete = $.ninja.autocomplete({
          placeholder: 'United States Cities'
        }).source(function (event) {
          $.ajax({
            url: 'http://ws.geonames.org/searchJSON',
            dataType: 'jsonp',
            data: {
              country: 'US',
              featureClass: 'P',
              fuzzy: 0,
              maxRows: 10,
              q: event.query
            },
            success: function (data) {
              $autocomplete.list({
                choices: $.map(data.geonames, function (item) {
                  return {
                    html: item.name + ', ' + item.adminName1,
                    value: item.name + ', ' + item.adminCode1
                  };
                }),
                query: event.query
              });
            },
            error: function (request, status, message) {
              $.error(message);
            }
          });
        });

        $examples.append('
$.ninja.autocomplete()
', $example.clone().append($autocomplete));

      });

      describe('$.ninja.button()', function () {
        var $toggleSelect, $toggleDisable,
        $button = $.ninja.button({
          html: 'Button'
        }).disable(function () {
          $toggleSelect.attr({
            disabled: 'disabled'
          });
        }).enable(function () {
          $toggleSelect.attr({
            disabled: false
          });
        }).select(function () {
          $toggleSelect.attr({
            checked: 'checked'
          });
        }).deselect(function () {
          $toggleSelect.attr({
            checked: false
          });
        }),
        $buttonSelected = $.ninja.button({
          css: {
            'margin-right': '16px'
          },
          html: 'Selected Button',
          select: true
        }),
        $buttonDisabled = $.ninja.button({
          html: 'Disabled Button',
          disable: true
        });

        $toggleSelect = $('<input/>', {
          type: 'checkbox'
        }).change(function () {
          if ($toggleSelect.attr('checked')) {
            $button.select();
          } else {
            $button.deselect();
          }
        });

        $toggleDisable = $('<input/>', {
          type: 'checkbox'
        }).change(function () {
          if ($toggleDisable.attr('checked')) {
            $button.disable();
          } else {
            $button.enable();
          }
        });

        $examples.append('
$.ninja.button()
', $example.clone().append($button, ' ', $toggleSelect, ' Select ', $toggleDisable, ' Disable', '

', $buttonSelected, ' ', $buttonDisabled));

        it('should have button class', function () {
          assert($button.hasClass('nui-btn')).isTrue();
        });

        it('should accept css overrides on creation', function () {
          assert($buttonSelected.css('margin-right')).equals('16px');
          // Note that different browsers are not consistent in how they deal with invalid styles.
          // Note also that values given and values returned do not always match, such as 1em returning 16px
        });

        it('should accept html content on creation', function () {
          assert($buttonSelected.html()).equals('Selected Button');
        });

        it('should have class of nui-slc when select is true', function () {
          assert($buttonSelected.hasClass('nui-slc')).isTrue();
        });

        it('should have class of nui-dsb when disable is true', function () {
          assert($buttonDisabled.hasClass('nui-dsb')).isTrue();
        });
      });

      describe('$.ninja.dialog()', function () {
        var
          $toggleDialog,
          $dialog = $.ninja.dialog({
            html: '
This is HTML inside the dialog.
'
          }).attach(function () {
            $toggleDialog.attr({
              checked: 'checked'
            });
          }).detach(function () {
            $toggleDialog.attr({
              checked: false
            });
          });
        $toggleDialog = $('<input/>', {
          type: 'checkbox'
        }).change(function () {
          if ($toggleDialog.attr('checked')) {
            $dialog.attach();
          } else {
            $dialog.detach();
          }
        });
        $examples.append('
$.ninja.dialog()
', $example.clone().append($toggleDialog, ' Attach Dialog'));
      });

      describe('$.ninja.drawer()', function () {

        var $drawer, $drawerSelect;

        $drawer = $.ninja.drawer({
          html: '
This is HTML inside the drawer.
',
          title: 'Drawer'
        });

        $drawerSelect = $.ninja.drawer({
          css: {
            width: '360px'
          },
          html: '
This is HTML inside the drawer.
',
          select: true,
          title: 'Selected Drawer'
        });

        $examples.append('
$.ninja.drawer()
', $example.clone().append($drawer, '
', $drawerSelect));

        it('should have drawer class', function () {
          assert($drawer.hasClass('nui-drw')).isTrue();
        });

        it('should accept css overrides on creation', function () {
          assert($drawerSelect.css('width')).equals('360px');
          // Note that different browsers are not consistent in how they deal with invalid styles.
          // Note also that values given and values returned do not always match, such as 1em returning 16px
        });

        it('should accept html content on creation', function () {
          assert($drawer.find('.nui-try').html()).equals('
This is HTML inside the drawer.
');
        });

        it('should have a right arrow before selecting', function () {
          assert($drawer.find('.nui-btn .nui-icn').attr('aria-label')).equals('arrow-right');
        });

        it('should have a down arrow after selecting', function () {
          assert($drawerSelect.find('.nui-btn .nui-icn').attr('aria-label')).equals('arrow-down');
        });

      });

      describe('$(\'#object\').ninja().hint()', function () {
        var
          $buttonHint = $.ninja.button({
            html: 'Hint'
          }).hint({
            html: '
This is HTML inside the hint.
'
          });
        $examples.append('
$.ninja.x.hint() or $(\'#foo\').ninja().hint()
', $example.clone().append($buttonHint));
      });

      describe('$.ninja.icon()', function () {

        $examples.append('
$.ninja.icon()
');

        var
          iconNames = ['spin', 'stop', 'yield', 'go', 'x', '-', '+', 'camera', 'arrow-down', 'arrow-right', 'home', 'email', 'search', 'star', 'X'],
          $exampleIcons = $example.clone().appendTo($examples);

        $.each(iconNames, function (i, iconName) {
          var $exampleIcon, $icon;
          if (iconName === 'stop') {
            $icon = $.ninja.icon({
              css: {
                fill: '#c00',
                margin: '5em',
                stroke: '#c00'
              },
              name: iconName
            });
          } else if (iconName === 'yield') {
            $icon = $.ninja.icon({
              css: {
                fill: 'goldenrod',
                stroke: 'goldenrod'
              },
              name: iconName
            });
          } else if (iconName === 'go') {
            $icon = $.ninja.icon({
              css: {
                fill: 'green',
                stroke: 'green'
              },
              name: iconName
            });
          } else {
            $icon = $.ninja.icon({
              name: iconName
            });
          }
          $exampleIcon = $('', {
            'class': 'ninjaui-example-icon'
          }).append($icon, ' ', iconName).appendTo($exampleIcons);

          it('should have icon class', function () {
            if ($.inArray(version, ['1.5.2', '1.5.1', '1.5', '1.4.4', '1.4.3']) === -1) {
              // can't test these due to a bug in these jQuery versions
              assert($icon.attr('class')).equals('nui-icn');
            }
          });

          it('should have aria label', function () {
            assert($icon.attr('aria-label')).equals(iconName);
          });

          it('should have image role', function () {
            assert($icon.attr('role')).equals('img');
          });

          it('should have icon title', function () {
            assert($('title', $icon).text()).equals(iconName);
          });

          it('should accept css overrides on creation', function () {
            if (iconName === 'stop') {
              assert($icon.find('g').attr('style')).equals('fill: #cc0000; margin-top: 5em; margin-right: 5em; margin-bottom: 5em; margin-left: 5em; stroke: #cc0000; ');
            } else if (iconName === 'warn') {
              assert($icon.find('g').attr('style')).equals('fill: #daa520; stroke: #daa520; ');
            } else if (iconName === 'go') {
              assert($icon.find('g').attr('style')).equals('fill: #008000; stroke: #008000; ');
            }
          });
        });

      });

      describe('$.ninja.menu()', function () {
        var
          $message = $(''),
          please = function () {
            $message.html(':( Try again.');
          },
          $menu = $.ninja.menu({
            choices: [
              {
                html: '
Mo
',
                select: function () {
                  $message.html('Oh, a wise guy eh?');
                }
              },
              {
                html: '
Larry
',
                select: function () {
                  $message.html('Cut it out, ya puddinhead!');
                }
              },
              {
                html: '
Curly
',
                select: function () {
                  $message.html('Hey, Mo!');
                }
              },
              { spacer: true },
              {
                html: '
Shemp
',
                select: function () {
                  please();
                }
              },
              {
                html: '
Joe
',
                select: function () {
                  please();
                }
              },
              {
                html: '
Curly Joe
',
                select: function () {
                  please();
                }
              }
            ],
            html: 'Menu'
          });

        $examples.append('
$.ninja.menu()
', $example.clone().append($menu, ' ', $message));
      });

      describe('$.ninja.rating()', function () {
        var
          $message = $(''),
          $rating = $.ninja.rating({
            average: 3
          }).select(function (event) {
            $message.html('New rating: ' + event.stars + ' stars');
          });
        $examples.append('
$.ninja.rating()
', $example.clone().append($rating, ' ', $message));
      });

      describe('$.ninja.slider()', function () {
        var
          poorly = function () {
            var foo = 'bar';
          },
          $slider = $.ninja.slider({
            choices: [
              {
                html: '0 dB',
                select: function (event) {
                  poorly();
                }
              },
              { html: '10 dB' },
              { html: '20-30 dB' },
              { html: '40-60 dB' },
              { html: '60 dB' },
              { html: '60-80 dB' },
              { html: '78 dB' },
              { html: '80-90 dB' },
              { html: '100 dB' },
              { html: '120 dB' },
              { html: '130 dB' },
              { html: '150 dB' },
              { html: '168 dB' }
            ],
            slot: 3,
            title: 'Volume'
          });

        $examples.append('
$.ninja.slider()
', $example.clone().append($slider));
      });

      describe('$.ninja.tabs()', function () {
        var
          $message = $(''),
          poorly = function () {
            $message.html('You have chosen... poorly.');
          },
          $tabs = $.ninja.tabs({
            choices: [
              {
                html: '
Gold Tab
',
                select: function () {
                  poorly();
                }
              },
              {
                html: '
Silver Tab
',
                select: function () {
                  poorly();
                }
              },
              {
                html: '
Wood Tab
',
                select: function () {
                  $message.html('You have chosen... wisely.');
                }
              }
            ]
          });

        $examples.append('
$.ninja.tabs()
', $example.clone().append($tabs, ' ', $message));
      });
/* */

    });
  });
});
<commit_msg>Change css tests to pixel-based margins rather than other (browser-munged) properties, then use the .css() function to get at them. Lastly the 'warn' icon is now 'yield' so make sure we actually test it.<commit_after>/*
  Copyright 2008-2011 Jamie Hoover.
  Licensed per the terms of the Apache License v2.0. See Readme.md for details.
*/

/*globals QUnit, $versions, describe, before, after, given, it, assert*/

/*jshint bitwise: true, browser: true, curly: true, eqeqeq: true, forin: true, immed: true, indent: 2, jquery: true, maxerr: 3, newcap: true, noarg: true, noempty: true, nomen: true, nonew: true, onevar: true, plusplus: true, regexp: true, strict: true, undef: true, white: true*/

var
  jQueryVersions = ['1.7.1', '1.7', '1.6.4', '1.6.3', '1.6.2', '1.6.1', '1.6', '1.5.2', '1.5.1', '1.5', '1.4.4', '1.4.3'],
  environment = decodeURI((new RegExp('environment' + '=' + '(.+?)(&|$)').exec(location.search) || [null])[1]),
  theme = decodeURI((new RegExp('theme' + '=' + '(.+?)(&|$)').exec(location.search) || [null])[1]),
  scriptPath;

if (environment === 'production') {
  scriptPath = '../jquery.ninjaui.min.js';
} else {
  environment = 'development';
  jQueryVersions = jQueryVersions[0];
  scriptPath = '../src/ninjaui.js';
}

QUnit.config.hidepassed = true;
QUnit.config.reorder = true;
QUnit.specify.globalApi = true;

$versions(jQueryVersions).load(scriptPath).execute(function ($, jQuery, version) {
  'use strict';

  if ($.inArray(theme, ['dojo']) > -1) {
    $('<link/>', {
      rel: 'stylesheet',
      href: '../themes/ninjaui.theme.' + theme + '.css'
    }).appendTo('head');
    $('body').addClass('nui-' + theme);
  }

  var
    $examples = $('

jQuery ' + version + ' Examples (' + environment + ')

').appendTo('body'),
    $example = $('
');

  QUnit.specify('Ninja User Interface', function () {
    describe('jQuery ' + version, function () {

      describe('Infrastructure', function () {
        it('should load jQuery ' + version, function () {
          assert($.fn.jquery).equals(version);
        });

        it('should load Ninja UI', function () {
          assert($.ninja).isDefined();
        });

        if (environment !== 'production') {
          it('should return development Ninja UI version if environment is not production', function () {
            assert($.ninja.version()).equals('development');
          });
        }
      });

      describe('$.ninja.autocomplete()', function () {

        var $autocomplete = $.ninja.autocomplete({
          placeholder: 'United States Cities'
        }).source(function (event) {
          $.ajax({
            url: 'http://ws.geonames.org/searchJSON',
            dataType: 'jsonp',
            data: {
              country: 'US',
              featureClass: 'P',
              fuzzy: 0,
              maxRows: 10,
              q: event.query
            },
            success: function (data) {
              $autocomplete.list({
                choices: $.map(data.geonames, function (item) {
                  return {
                    html: item.name + ', ' + item.adminName1,
                    value: item.name + ', ' + item.adminCode1
                  };
                }),
                query: event.query
              });
            },
            error: function (request, status, message) {
              $.error(message);
            }
          });
        });

        $examples.append('
$.ninja.autocomplete()
', $example.clone().append($autocomplete));

      });

      describe('$.ninja.button()', function () {
        var $toggleSelect, $toggleDisable,
        $button = $.ninja.button({
          html: 'Button'
        }).disable(function () {
          $toggleSelect.attr({
            disabled: 'disabled'
          });
        }).enable(function () {
          $toggleSelect.attr({
            disabled: false
          });
        }).select(function () {
          $toggleSelect.attr({
            checked: 'checked'
          });
        }).deselect(function () {
          $toggleSelect.attr({
            checked: false
          });
        }),
        $buttonSelected = $.ninja.button({
          css: {
            'margin-right': '16px'
          },
          html: 'Selected Button',
          select: true
        }),
        $buttonDisabled = $.ninja.button({
          html: 'Disabled Button',
          disable: true
        });

        $toggleSelect = $('<input/>', {
          type: 'checkbox'
        }).change(function () {
          if ($toggleSelect.attr('checked')) {
            $button.select();
          } else {
            $button.deselect();
          }
        });

        $toggleDisable = $('<input/>', {
          type: 'checkbox'
        }).change(function () {
          if ($toggleDisable.attr('checked')) {
            $button.disable();
          } else {
            $button.enable();
          }
        });

        $examples.append('
$.ninja.button()
', $example.clone().append($button, ' ', $toggleSelect, ' Select ', $toggleDisable, ' Disable', '

', $buttonSelected, ' ', $buttonDisabled));

        it('should have button class', function () {
          assert($button.hasClass('nui-btn')).isTrue();
        });

        it('should accept css overrides on creation', function () {
          assert($buttonSelected.css('margin-right')).equals('16px');
          // Note that different browsers are not consistent in how they deal with invalid styles.
          // Note also that values given and values returned do not always match, such as 1em returning 16px
        });

        it('should accept html content on creation', function () {
          assert($buttonSelected.html()).equals('Selected Button');
        });

        it('should have class of nui-slc when select is true', function () {
          assert($buttonSelected.hasClass('nui-slc')).isTrue();
        });

        it('should have class of nui-dsb when disable is true', function () {
          assert($buttonDisabled.hasClass('nui-dsb')).isTrue();
        });
      });

      describe('$.ninja.dialog()', function () {
        var
          $toggleDialog,
          $dialog = $.ninja.dialog({
            html: '
This is HTML inside the dialog.
'
          }).attach(function () {
            $toggleDialog.attr({
              checked: 'checked'
            });
          }).detach(function () {
            $toggleDialog.attr({
              checked: false
            });
          });
        $toggleDialog = $('<input/>', {
          type: 'checkbox'
        }).change(function () {
          if ($toggleDialog.attr('checked')) {
            $dialog.attach();
          } else {
            $dialog.detach();
          }
        });
        $examples.append('
$.ninja.dialog()
', $example.clone().append($toggleDialog, ' Attach Dialog'));
      });

      describe('$.ninja.drawer()', function () {

        var $drawer, $drawerSelect;

        $drawer = $.ninja.drawer({
          html: '
This is HTML inside the drawer.
',
          title: 'Drawer'
        });

        $drawerSelect = $.ninja.drawer({
          css: {
            width: '360px'
          },
          html: '
This is HTML inside the drawer.
',
          select: true,
          title: 'Selected Drawer'
        });

        $examples.append('
$.ninja.drawer()
', $example.clone().append($drawer, '
', $drawerSelect));

        it('should have drawer class', function () {
          assert($drawer.hasClass('nui-drw')).isTrue();
        });

        it('should accept css overrides on creation', function () {
          assert($drawerSelect.css('width')).equals('360px');
          // Note that different browsers are not consistent in how they deal with invalid styles.
          // Note also that values given and values returned do not always match, such as 1em returning 16px
        });

        it('should accept html content on creation', function () {
          assert($drawer.find('.nui-try').html()).equals('
This is HTML inside the drawer.
');
        });

        it('should have a right arrow before selecting', function () {
          assert($drawer.find('.nui-btn .nui-icn').attr('aria-label')).equals('arrow-right');
        });

        it('should have a down arrow after selecting', function () {
          assert($drawerSelect.find('.nui-btn .nui-icn').attr('aria-label')).equals('arrow-down');
        });

      });

      describe('$(\'#object\').ninja().hint()', function () {
        var
          $buttonHint = $.ninja.button({
            html: 'Hint'
          }).hint({
            html: '
This is HTML inside the hint.
'
          });
        $examples.append('
$.ninja.x.hint() or $(\'#foo\').ninja().hint()
', $example.clone().append($buttonHint));
      });

      describe('$.ninja.icon()', function () {

        $examples.append('
$.ninja.icon()
');

        var
          iconNames = ['spin', 'stop', 'yield', 'go', 'x', '-', '+', 'camera', 'arrow-down', 'arrow-right', 'home', 'email', 'search', 'star', 'X'],
          $exampleIcons = $example.clone().appendTo($examples);

        $.each(iconNames, function (i, iconName) {
          var $exampleIcon, $icon;
          if (iconName === 'stop') {
            $icon = $.ninja.icon({
              css: {
                margin: '80px'
              },
              name: iconName
            });
          } else if (iconName === 'yield') {
            $icon = $.ninja.icon({
              css: {
                margin: '96px'
              },
              name: iconName
            });
          } else if (iconName === 'go') {
            $icon = $.ninja.icon({
              css: {
                margin: '64px'
              },
              name: iconName
            });
          } else {
            $icon = $.ninja.icon({
              name: iconName
            });
          }
          $exampleIcon = $('', {
            'class': 'ninjaui-example-icon'
          }).append($icon, ' ', iconName).appendTo($exampleIcons);

          it('should have icon class', function () {
            if ($.inArray(version, ['1.5.2', '1.5.1', '1.5', '1.4.4', '1.4.3']) === -1) {
              // can't test these due to a bug in these jQuery versions
              assert($icon.attr('class')).equals('nui-icn');
            }
          });

          it('should have aria label', function () {
            assert($icon.attr('aria-label')).equals(iconName);
          });

          it('should have image role', function () {
            assert($icon.attr('role')).equals('img');
          });

          it('should have icon title', function () {
            assert($('title', $icon).text()).equals(iconName);
          });

          it('should accept css overrides on creation', function () {
            if (iconName === 'stop') {
              assert($icon.find('g').css('margin-top')).equals('80px');
            } else if (iconName === 'yield') {
              assert($icon.find('g').css('margin-top')).equals('96px');
            } else if (iconName === 'go') {
              assert($icon.find('g').css('margin-top')).equals('64px');
            }
          });
        });

      });

      describe('$.ninja.menu()', function () {
        var
          $message = $(''),
          please = function () {
            $message.html(':( Try again.');
          },
          $menu = $.ninja.menu({
            choices: [
              {
                html: '
Mo
',
                select: function () {
                  $message.html('Oh, a wise guy eh?');
                }
              },
              {
                html: '
Larry
',
                select: function () {
                  $message.html('Cut it out, ya puddinhead!');
                }
              },
              {
                html: '
Curly
',
                select: function () {
                  $message.html('Hey, Mo!');
                }
              },
              { spacer: true },
              {
                html: '
Shemp
',
                select: function () {
                  please();
                }
              },
              {
                html: '
Joe
',
                select: function () {
                  please();
                }
              },
              {
                html: '
Curly Joe
',
                select: function () {
                  please();
                }
              }
            ],
            html: 'Menu'
          });

        $examples.append('
$.ninja.menu()
', $example.clone().append($menu, ' ', $message));
      });

      describe('$.ninja.rating()', function () {
        var
          $message = $(''),
          $rating = $.ninja.rating({
            average: 3
          }).select(function (event) {
            $message.html('New rating: ' + event.stars + ' stars');
          });
        $examples.append('
$.ninja.rating()
', $example.clone().append($rating, ' ', $message));
      });

      describe('$.ninja.slider()', function () {
        var
          poorly = function () {
            var foo = 'bar';
          },
          $slider = $.ninja.slider({
            choices: [
              {
                html: '0 dB',
                select: function (event) {
                  poorly();
                }
              },
              { html: '10 dB' },
              { html: '20-30 dB' },
              { html: '40-60 dB' },
              { html: '60 dB' },
              { html: '60-80 dB' },
              { html: '78 dB' },
              { html: '80-90 dB' },
              { html: '100 dB' },
              { html: '120 dB' },
              { html: '130 dB' },
              { html: '150 dB' },
              { html: '168 dB' }
            ],
            slot: 3,
            title: 'Volume'
          });

        $examples.append('
$.ninja.slider()
', $example.clone().append($slider));
      });

      describe('$.ninja.tabs()', function () {
        var
          $message = $(''),
          poorly = function () {
            $message.html('You have chosen... poorly.');
          },
          $tabs = $.ninja.tabs({
            choices: [
              {
                html: '
Gold Tab
',
                select: function () {
                  poorly();
                }
              },
              {
                html: '
Silver Tab
',
                select: function () {
                  poorly();
                }
              },
              {
                html: '
Wood Tab
',
                select: function () {
                  $message.html('You have chosen... wisely.');
                }
              }
            ]
          });

        $examples.append('
$.ninja.tabs()
', $example.clone().append($tabs, ' ', $message));
      });
/* */

    });
  });
});
<|endoftext|>


<commit_before>test('options.yml', function () {

var paragraph = "Some paragraph\nwith a linebreak.";

// =[ 1 ]=  By default, inline linebreaks will be converted to html linebreaks  =======
equal(textile.convert(paragraph), "
Some paragraph
\nwith a linebreak.
");
equal(textile.convert(paragraph, {breaks:false}), "
Some paragraph\nwith a linebreak.
");

});
<commit_msg>Options test is not converted from yml.<commit_after>test('jstextile options', function () {

var paragraph = "Some paragraph\nwith a linebreak.";

// =[ 1 ]=  By default, inline linebreaks will be converted to html linebreaks  =======
equal(textile.convert(paragraph), "
Some paragraph
\nwith a linebreak.
");
equal(textile.convert(paragraph, {breaks:false}), "
Some paragraph\nwith a linebreak.
");

});
<|endoftext|>


<commit_before>'use strict';

var path = require('path'),
    assert = require('yeoman-generator').assert,
    helpers = require('yeoman-generator').test;

describe('starterkit:package-dependencies', function() {

    before(function(done) {
        helpers.run(path.join(__dirname, '../generators/app'))
            .inDir(path.join(__dirname, './.tmp'))
            .withOptions({
                skipInstall: true
            })
            .on('end', done);
    });

    it('should contain necessary dependencies', function() {
        [
            'browser-sync',
            'gulp',
            'gulp-autoprefixer',
            'gulp-beautify',
            'gulp-concat',
            'gulp-cssimport',
            'gulp-imagemin',
            'gulp-notify',
            'gulp-plumber',
            'gulp-rename',
            'gulp-uglify',
            'vinyl-ftp'
        ].forEach(function(dependency) {
            assert.fileContent('package.json', dependency);
        });
    });

    before(function(done) {
        helpers.run(path.join(__dirname, '../generators/app'))
            .inDir(path.join(__dirname, './.tmp'))
            .withOptions({
                skipInstall: true
            })
            .withPrompts({
                useBabel: true,
                useFlexboxgrid: true
            })
            .on('end', done);
    });

    it('should contain additional dependencies', function() {
        [
            'gulp-babel',
            'flexboxgrid'
        ].forEach(function(dependency) {
            assert.fileContent('package.json', dependency);
        });
    });
});
<commit_msg>added mocha tests<commit_after>'use strict';

var path = require('path'),
    assert = require('yeoman-generator').assert,
    helpers = require('yeoman-generator').test;

describe('starterkit:package-dependencies', function() {

    before(function(done) {
        helpers.run(path.join(__dirname, '../generators/app'))
            .inDir(path.join(__dirname, './.tmp'))
            .withOptions({
                skipInstall: true
            })
            .on('end', done);
    });

    it('should contain necessary dependencies', function() {
        [
            'browser-sync',
            'gulp',
            'gulp-autoprefixer',
            'gulp-beautify',
            'gulp-concat',
            'gulp-cssimport',
            'gulp-imagemin',
            'gulp-notify',
            'gulp-plumber',
            'gulp-rename',
            'gulp-uglify',
            'vinyl-ftp'
        ].forEach(function(dependency) {
            assert.fileContent('package.json', dependency);
        });
    });

    before(function(done) {
        helpers.run(path.join(__dirname, '../generators/app'))
            .inDir(path.join(__dirname, './.tmp'))
            .withOptions({
                skipInstall: true
            })
            .withPrompts({
                useBabel: true
            })
            .on('end', done);
    });

    it('should contain additional dependencies', function() {
        [
            'gulp-babel'
        ].forEach(function(dependency) {
            assert.fileContent('package.json', dependency);
        });
    });
});
<|endoftext|>


<commit_before>const system = require('system');

/* eslint-disable no-console */
/* globals phantom:false */

if (system.args.length !== 2) {
	console.log('Usage: phantom.js <URL>');
	phantom.exit(1);
}

const page = require('webpage').create();
phantom.onError = page.onError = function(err) {
	console.log(err);
	phantom.exit(1);
};

page.open(system.args[1], function(status) {
	if (status !== 'success') {
		console.log('Cannot load the page');
		phantom.exit(1);
	}
});
<commit_msg>PhantomJS: exit on successful load.<commit_after>const system = require('system');

/* eslint-disable no-console */
/* globals phantom:false */

if (system.args.length !== 2) {
	console.log('Usage: phantom.js <URL>');
	phantom.exit(1);
}

const page = require('webpage').create();
phantom.onError = page.onError = function(err) {
	console.log(err);
	phantom.exit(1);
};

page.open(system.args[1], function(status) {
	if (status !== 'success') {
		console.log('Cannot load the page');
		phantom.exit(1);
	}
	phantom.exit(0);
});
<|endoftext|>


<commit_before>const system = require('system');

// To make a screenshot: https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js
// phantomjs rasterize.js http://localhost:6060/ output.png

/* eslint-disable no-console, no-multi-assign */
/* globals phantom:false */

if (system.args.length !== 2) {
	console.log('Usage: phantom.js <URL>');
	phantom.exit(1);
}

const page = require('webpage').create();
phantom.onError = page.onError = function(err) {
	console.log('PhantomJS error:', err.errorString);
	phantom.exit(1);
};

page.onResourceError = page.onResourceTimeout = function(err) {
	console.log('PhantomJS cannot load resource:', err.url, '-', err.errorString);
};

page.onConsoleMessage = function(msg) {
	console.log('PhantomJS:', msg);
};

page.viewportSize = { width: 1024, height: 768 };

page.open(system.args[1], function(status) {
	if (status !== 'success') {
		console.log('PhantomJS: Cannot load the page');
		phantom.exit(1);
	}
	phantom.exit(0);
});
<commit_msg>Test: Ignore failures when loading placebeard.it<commit_after>const system = require('system');

// To make a screenshot: https://github.com/ariya/phantomjs/blob/master/examples/rasterize.js
// phantomjs rasterize.js http://localhost:6060/ output.png

/* eslint-disable no-console, no-multi-assign */
/* globals phantom:false */

if (system.args.length !== 2) {
	console.log('Usage: phantom.js <URL>');
	phantom.exit(1);
}

const page = require('webpage').create();
phantom.onError = page.onError = function(err) {
	console.log('PhantomJS error:', err.errorString);
	phantom.exit(1);
};

page.onResourceError = page.onResourceTimeout = function(err) {
	if (err.url.startsWith('http://placebeard.it/')) {
		return;
	}

	console.log('PhantomJS cannot load resource:', err.url, '-', err.errorString);
};

page.onConsoleMessage = function(msg) {
	console.log('PhantomJS:', msg);
};

page.viewportSize = { width: 1024, height: 768 };

page.open(system.args[1], function(status) {
	if (status !== 'success') {
		console.log('PhantomJS: Cannot load the page');
		phantom.exit(1);
	}
	phantom.exit(0);
});
<|endoftext|>


<commit_before>
var sl = require('..');

var list = [
    { id: 1, name: 'Adam', age: 800 },
    { id: 2, name: 'Eve', age: 600 },
    { id: 3, name: 'Abel', age: 500 },
    { id: 4, name: 'Caine', age: 400 }
];

exports['project name'] = function (test) {
    var result = sl.project(list, ['name']);

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (var k = 0; k < list.length; k++) {
        test.equal(result[k].name, list[k].name);
        test.equal(Object.keys(result[k]).length, 1);
    }
}

exports['project only name'] = function (test) {
    var result = sl.project(list, 'name');

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (var k = 0; k < list.length; k++) {
        test.equal(result[k].name, list[k].name);
        test.equal(Object.keys(result[k]).length, 1);
    }
}

exports['project id and name'] = function (test) {
    var result = sl.project(list, ['id', 'name']);

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (var k = 0; k < list.length; k++) {
        test.equal(result[k].id, list[k].id);
        test.equal(result[k].name, list[k].name);
        test.equal(Object.keys(result[k]).length, 2);
    }
}

exports['project id and name with rename'] = function (test) {
    var result = sl.project(list, { id: 'id2', name: 'name2' });

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (var k = 0; k < list.length; k++) {
        test.equal(result[k].id2, list[k].id);
        test.equal(result[k].name2, list[k].name);
        test.equal(Object.keys(result[k]).length, 2);
    }
}

<commit_msg>Refactor project tests<commit_after>
const sl = require('..');

const list = [
    { id: 1, name: 'Adam', age: 800 },
    { id: 2, name: 'Eve', age: 600 },
    { id: 3, name: 'Abel', age: 500 },
    { id: 4, name: 'Caine', age: 400 }
];

exports['project name'] = function (test) {
    const result = sl.project(list, ['name']);

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (let k = 0; k < list.length; k++) {
        test.equal(result[k].name, list[k].name);
        test.equal(Object.keys(result[k]).length, 1);
    }
}

exports['project only name'] = function (test) {
    const result = sl.project(list, 'name');

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (let k = 0; k < list.length; k++) {
        test.equal(result[k].name, list[k].name);
        test.equal(Object.keys(result[k]).length, 1);
    }
}

exports['project id and name'] = function (test) {
    const result = sl.project(list, ['id', 'name']);

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (let k = 0; k < list.length; k++) {
        test.equal(result[k].id, list[k].id);
        test.equal(result[k].name, list[k].name);
        test.equal(Object.keys(result[k]).length, 2);
    }
}

exports['project id and name with rename'] = function (test) {
    const result = sl.project(list, { id: 'id2', name: 'name2' });

    test.ok(result);
    test.ok(Array.isArray(result));
    test.equal(result.length, list.length);

    for (let k = 0; k < list.length; k++) {
        test.equal(result[k].id2, list[k].id);
        test.equal(result[k].name2, list[k].name);
        test.equal(Object.keys(result[k]).length, 2);
    }
}

<|endoftext|>


<commit_before>var logger = require('../lib/logger')
  , session = require('../lib/app');

var ui = require('../lib/ui/ui');

ui.init();

ui.cmd(["debug", 2]);

session.users = {
    '92837105728491852': {
        persona_state: "offline",
        player_name: "Gabe Newell",
        game_name: ""
    },
    '90864320871438724': {
        persona_state: "ingame",
        player_name: "Robin Walker",
        game_name: "Age of Empires II HD Edition"
    },
    '93087430280872349': {
        persona_state: "online",
        player_name: "IceFrog",
        game_name: ""
    },
    '92934987123508759': {
        persona_state: "online",
        player_name: "The Pink Cookie",
        game_name: ""
    },
    '93402347985239844': {
        persona_state: "ingame",
        player_name: "Axel Gembe",
        game_name: "Board Game Simulator"
    },
};

session.friends = [
    '92837105728491852',
    '90864320871438724',
    '93087430280872349'
];

session.clans = {
    '8294721957374875': {
        clan_name: "Steam Chat",
        user_count: 5,
        user_list: 5,
        members: {
            '92837105728491852': "owner",
            '90864320871438724': "officer",
            '93087430280872349': "moderator",
            '92934987123508759': "member",
            '93402347985239844': "nobody"
        }
    }
};

setTimeout(() => {
    ui.userwin.updateFriend();
    ui.steam.emit(
        'message',
        "92837105728491852",
        "Gabe Newell",
        "online",
        "ping"
    );
}, 500);

setTimeout(() => {
    ui.userwin.updateGroup('8294721957374875');
}, 2000);
<commit_msg>Set session.connected to true to enable further testing<commit_after>var logger = require('../lib/logger')
  , session = require('../lib/app');

var ui = require('../lib/ui/ui');

ui.init();

ui.cmd(["debug", 2]);

session.users = {
    '92837105728491852': {
        persona_state: "offline",
        player_name: "Gabe Newell",
        game_name: ""
    },
    '90864320871438724': {
        persona_state: "ingame",
        player_name: "Robin Walker",
        game_name: "Age of Empires II HD Edition"
    },
    '93087430280872349': {
        persona_state: "online",
        player_name: "IceFrog",
        game_name: ""
    },
    '92934987123508759': {
        persona_state: "online",
        player_name: "The Pink Cookie",
        game_name: ""
    },
    '93402347985239844': {
        persona_state: "ingame",
        player_name: "Axel Gembe",
        game_name: "Board Game Simulator"
    },
};

session.friends = [
    '92837105728491852',
    '90864320871438724',
    '93087430280872349'
];

session.clans = {
    '8294721957374875': {
        clan_name: "Steam Chat",
        user_count: 5,
        user_list: 5,
        members: {
            '92837105728491852': "owner",
            '90864320871438724': "officer",
            '93087430280872349': "moderator",
            '92934987123508759': "member",
            '93402347985239844': "nobody"
        }
    }
};

session.connected = true;

setTimeout(() => {
    ui.userwin.updateFriend();
    ui.steam.emit(
        'message',
        "92837105728491852",
        "Gabe Newell",
        "online",
        "ping"
    );
}, 500);

setTimeout(() => {
    ui.userwin.updateGroup('8294721957374875');
}, 2000);
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

const defaultProps = {
	onClick: function () {},
	className: 'btn',
	url: null,
};

const propTypes = {
	children: PropTypes.node.isRequired,
};

class Component extends React.Component {

	constructor(props) {
		super(props);
	}

	handleClick() {
		return this.props.onClick();
	}

	render() {
		let className = this.props.className;
		let url = false;

		if (this.props.url) {
			if (this.props.url !== '#') {
				url = true;
			}

			if (!url) {
				return ({this.props.children});
			}

			return ({this.props.children});
		}

		return (
			<button onClick={() => this.handleClick()} className={className} dangerouslySetInnerHTML={{ __html: this.props.html }}>
				{this.props.children}
			</button>
		);
	}

}

Component.displayName = 'PopupAction';
Component.propTypes = propTypes;
Component.defaultProps = defaultProps;

export default Component;
<commit_msg>Update ActionButton.js<commit_after>import React from 'react';
import PropTypes from 'prop-types';

const defaultProps = {
	onClick: function () {},
	className: 'btn',
	url: null,
};

const propTypes = {
	children: PropTypes.node.isRequired,
};

class Component extends React.Component {

	constructor(props) {
		super(props);
	}

	handleClick() {
		return this.props.onClick();
	}

	render() {
		let className = this.props.className;
		let url = false;

		if (this.props.url) {
			if (this.props.url !== '#') {
				url = true;
			}

			if (!url) {
				return ({this.props.children});
			}

			return ({this.props.children});
		}

		return (
			<button onClick={() => this.handleClick()} className={className} dangerouslySetInnerHTML={{ __html: 'html
html' }}>
				{'text'}
			</button>
		);
	}

}

Component.displayName = 'PopupAction';
Component.propTypes = propTypes;
Component.defaultProps = defaultProps;

export default Component;
<|endoftext|>


<commit_before>import React, {Component} from 'react'
import {Link} from 'react-router-dom'
import RaisedButton from 'material-ui/RaisedButton'

export default class Home extends Component {
  render() {
    return (

        Home. Not Protected. Anyone can see this.

        <Link to="/login">
          <RaisedButton label="Login" primary={true}/>
        </Link>
        <Link to="/register">
          <RaisedButton label="Registration" primary={true} />
        </Link>

    )
  }
}<commit_msg>cleaned up<commit_after>import React, {Component} from 'react'

export default class Gameadmin extends Component {
  render() {
    return (

        Gameadmin

    )
  }
}<|endoftext|>


<commit_before>(function(exports){
    exports.features = [];
    var featureRunner = {
        enqueue : function(feature){
            exports.features.push(feature);
        }
    };

    function Feature(featureDescription){
        function Scenario(scenarioDescription, options){
            var self = this;
            options = options || {};
            this.description = scenarioDescription;
            this.steps = [];
            this.addStep = function(){
              this.steps.push({
                description : arguments[1],
                fullDescription : arguments[0] + '  ' + arguments[1],
                arguments : Array.prototype.splice.call(arguments, 2)
              });
            };

            this.given = function(){
                this.addStep.apply(this, ['Given'].concat(Array.prototype.slice.call(arguments, 0)));

                self.and = function(){
                  this.addStep.apply(this, ['And'].concat(Array.prototype.slice.call(arguments, 0)));
                  return self;
                };

                return self;
            };
            this.when = function(){
                self.addStep.apply(this, ['When'].concat(Array.prototype.slice.call(arguments, 0)));

                self.and = function(){
                  self.addStep.apply(this, ['And'].concat(Array.prototype.slice.call(arguments, 0)));
                  return self;
                };

                return self;
            };
            this.then = function(){
                self.addStep.apply(this, ['Then'].concat(Array.prototype.slice.call(arguments, 0)));

                self.and = function(){
                  self.addStep.apply(this, ['And'].concat(Array.prototype.slice.call(arguments, 0)));
                  return self;
                };

                return self;
            };

            // could add this.and as a default - but at least this way you don't get and until you use given, when or then
            this.isOnly = options.only === true ? true : false;
            this.never = options.not === true ? true : false;
        }
        Scenario.prototype = this;
        var self = this;

        self.not = {
            scenario : function(){
                return self.scenario.apply(self, Array.prototype.slice.call(arguments, 0).concat({ not : true}));
            }
        };

        self.only = {
            scenario : function(){
                return self.scenario.apply(self, Array.prototype.slice.call(arguments, 0).concat({ only : true}));
            }
        };

        this.description = featureDescription;
        this.scenarios = [];
        exports.scenario = this.scenario = function(scenarioDescription, callback){
            var scenario = new Scenario(scenarioDescription, callback);
            self.scenarios.push(scenario);
            return scenario;
        };
    }
    function feature(featureDescription, callback){
        var f = new Feature(featureDescription, callback);
        featureRunner.enqueue(f);
        return f;
    }

    exports.steps = [];

    function FeatureSteps(featurePattern, callback){
        this.pattern = new RegExp(featurePattern);
        this.beforeSteps = [];
        this.afterSteps = [];
        this.steps = [];
        this.given = this.when = this.then = function(pattern, definition){
            this.steps.push({pattern : new RegExp('^' + pattern + '$'), definition : definition});
            return this;
        };
        this.before = function(definition){
            this.beforeSteps.push(definition);
            return this;
        };

        this.after = function(definition){
            this.afterSteps.push(definition);
            return this;
        };

        if (callback){
            callback.call(this);
        }
    }

    exports.feature = feature;
    exports.featureSteps = function(featurePattern, callback){
        var featureSteps = new FeatureSteps(featurePattern, callback);
        exports.steps.push(featureSteps);
        return featureSteps;
    };
}(typeof window !== 'undefined' ? window : module.exports));<commit_msg>Add support of TableArgs<commit_after>(function(exports){
    exports.features = [];
    var featureRunner = {
        enqueue : function(feature){
            exports.features.push(feature);
        }
    };

    function Feature(featureDescription){
        function Scenario(scenarioDescription, options){
            var self = this;
            options = options || {};
            this.description = scenarioDescription;
            this.steps = [];
			this.addStep = function(){
			  var args = Array.prototype.splice.call(arguments, 2);
              this.steps.push({
                description : arguments[1],
                fullDescription : arguments[0] + '  ' + arguments[1] + ' ' + JSON.stringify(args),
                arguments : args
              });
            };

            this.given = function(){
                this.addStep.apply(this, ['Given'].concat(Array.prototype.slice.call(arguments, 0)));

                self.and = function(){
                  this.addStep.apply(this, ['And'].concat(Array.prototype.slice.call(arguments, 0)));
                  return self;
                };

                return self;
            };
            this.when = function(){
                self.addStep.apply(this, ['When'].concat(Array.prototype.slice.call(arguments, 0)));

                self.and = function(){
                  self.addStep.apply(this, ['And'].concat(Array.prototype.slice.call(arguments, 0)));
                  return self;
                };

                return self;
            };
            this.then = function(){
                self.addStep.apply(this, ['Then'].concat(Array.prototype.slice.call(arguments, 0)));

                self.and = function(){
                  self.addStep.apply(this, ['And'].concat(Array.prototype.slice.call(arguments, 0)));
                  return self;
                };

                return self;
            };

            // could add this.and as a default - but at least this way you don't get and until you use given, when or then
            this.isOnly = options.only === true ? true : false;
            this.never = options.not === true ? true : false;
        }
        Scenario.prototype = this;
        var self = this;

        self.not = {
            scenario : function(){
                return self.scenario.apply(self, Array.prototype.slice.call(arguments, 0).concat({ not : true}));
            }
        };

        self.only = {
            scenario : function(){
                return self.scenario.apply(self, Array.prototype.slice.call(arguments, 0).concat({ only : true}));
            }
        };

        this.description = featureDescription;
        this.scenarios = [];
        exports.scenario = this.scenario = function(scenarioDescription, callback){
            var scenario = new Scenario(scenarioDescription, callback);
            self.scenarios.push(scenario);
            return scenario;
        };
    }
    function feature(featureDescription, callback){
        var f = new Feature(featureDescription, callback);
        featureRunner.enqueue(f);
        return f;
    }

    exports.steps = [];

    function FeatureSteps(featurePattern, callback){
        this.pattern = new RegExp(featurePattern);
        this.beforeSteps = [];
        this.afterSteps = [];
        this.steps = [];
        this.given = this.when = this.then = function(pattern, definition){
            this.steps.push({pattern : new RegExp('^' + pattern + '$'), definition : definition});
            return this;
        };
        this.before = function(definition){
            this.beforeSteps.push(definition);
            return this;
        };

        this.after = function(definition){
            this.afterSteps.push(definition);
            return this;
        };

        if (callback){
            callback.call(this);
        }
    }

    exports.feature = feature;
    exports.featureSteps = function(featurePattern, callback){
        var featureSteps = new FeatureSteps(featurePattern, callback);
        exports.steps.push(featureSteps);
        return featureSteps;
    };
}(typeof window !== 'undefined' ? window : module.exports));<|endoftext|>