<commit_before>/*
This file is part of the Juju GUI, which lets users view and manage Juju
environments within a graphical interface (https://launchpad.net/juju-gui).
Copyright (C) 2012-2013 Canonical Ltd.

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License version 3, as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
General Public License for more details.

You should have received a copy of the GNU Affero General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

'use strict';

describe('service module annotations', function() {
  var db, juju, models, utils, viewContainer, views, Y, serviceModule;
  var called, location;

  before(function(done) {
    Y = YUI(GlobalConfig).use([
      'juju-gui',
      'juju-models',
      'juju-tests-utils',
      'juju-views',
      'node',
      'node-event-simulate'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      utils = Y.namespace('juju-tests.utils');
      views = Y.namespace('juju.views');
      done();
    });
  });

  beforeEach(function() {
    viewContainer = utils.makeContainer();
    db = new models.Database();
    called = false;
    location =
        { 'gui-x': 0,
          'gui-y': 0};
    var env = {
      update_annotations: function(name, type, data) {
        called = true;
        location['gui-x'] = data['gui-x'];
        location['gui-y'] = data['gui-y'];},
      get: function() {}};
    var view = new views.environment(
        { container: viewContainer,
          db: db,
          env: env});
    view.render();
    view.rendered();
    serviceModule = view.topo.modules.ServiceModule;
    serviceModule.set('useTransitions', false);
  });

  afterEach(function() {
    if (viewContainer) {
      viewContainer.remove(true);
    }
  });

  // Test the drag end handler.
  it('should set location annotations on service block drag end',
     function() {
       var d =
           { id: 'wordpress',
             inDrag: true,
             x: 100.1,
             y: 200.2};
       serviceModule.dragend(d, serviceModule);
       assert.isTrue(called);
       location['gui-x'].should.equal(100.1);
       location['gui-y'].should.equal(200.2);
     });

  it('should not set annotations on drag end if building a relation',
     function() {
       var d =
           { id: 'wordpress',
             x: 100.1,
             y: 200.2};
       var topo = serviceModule.get('component');
       topo.buildingRelation = true;
       serviceModule.dragend(d, serviceModule);
       assert.isFalse(called);
       location['gui-x'].should.equal(0);
       location['gui-y'].should.equal(0);
     });
});

describe('service module events', function() {
  var db, charm, fakeStore, juju, models, serviceModule, topo, utils,
      view, viewContainer, views, Y;

  before(function(done) {
    Y = YUI(GlobalConfig).use(['node',
      'juju-tests-utils',
      'juju-landscape',
      'juju-models',
      'juju-views',
      'juju-gui',
      'node-event-simulate',
      'slider'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      views = Y.namespace('juju.views');
      utils = Y.namespace('juju-tests.utils');
      done();
    });
  });

  beforeEach(function() {
    fakeStore = new Y.juju.charmworld.APIv2({});
    fakeStore.iconpath = function() {
      return 'charm icon url';
    };
    viewContainer = utils.makeContainer('content');
    var charmData = utils.loadFixture('data/haproxy-api-response.json', true);
    charm = new models.Charm(charmData.charm);
    db = new models.Database();
    db.services.add({id: 'haproxy', charm: 'cs:precise/haproxy-18'});
    db.charms.add(charm);
    view = new views.environment({
      container: viewContainer,
      db: db,
      env: {
        update_annotations: function() {},
        get: function() {}
      },
      nsRouter: {
        url: function() { return; }
      },
      store: fakeStore
    });
    view.render();
    view.rendered();
    topo = view.topo;
    serviceModule = topo.modules.ServiceModule;
  });

  afterEach(function() {
    if (viewContainer) {
      viewContainer.remove(true);
    }

    fakeStore.destroy();
    charm.destroy();
    db.destroy();
    topo.destroy();
    view.destroy();
  });

  it('should show the service menu', function() {
    var box = topo.service_boxes.haproxy;
    var menu = viewContainer.one('#service-menu');
    assert.isFalse(menu.hasClass('active'));
    serviceModule.showServiceMenu(box);
    assert(menu.hasClass('active'));
    // Check no-op.
    serviceModule.showServiceMenu(box);
    assert(menu.hasClass('active'));
  });

  it('should hide the service menu',
     function() {
       var box = topo.service_boxes.haproxy;
       var menu = viewContainer.one('#service-menu');
       serviceModule.showServiceMenu(box);
       assert(menu.hasClass('active'));
       serviceModule.hideServiceMenu();
       assert.isFalse(menu.hasClass('active'));
       // Check no-op.
       serviceModule.hideServiceMenu();
       assert.isFalse(menu.hasClass('active'));
     });

  // Click the provided service so that the service menu is shown.
  // Return the service menu.
  var clickService = function(service) {
    // Monkeypatch to avoid the click event handler bailing out early.
    topo.service_boxes.haproxy.containsPoint = function() {
      return true;
    };
    // Click the service.
    service.simulate('click');
    return viewContainer.one('#service-menu');
  };

  it('should not show the service menu after the service is double-clicked',
     function() {
       var service = viewContainer.one('.service');
       var menu = clickService(service);

       // Ideally the browser would not send the click event right away...
       assert(menu.hasClass('active'));
       service.simulate('dblclick');
       assert.isFalse(menu.hasClass('active'));
     });

  it('should handle touch/click events properly', function() {
    var service = viewContainer.one('.service');
    var menu = viewContainer.one('#service-menu');
    assert.isFalse(menu.hasClass('active'));
    serviceModule._touchstartServiceTap({
      currentTarget: service,
      touches: [{PageX: 0, PageY: 0}]
    }, topo);
    // Touch events should also fire click events, which will be ignored.
    // Fire one manually here.
    clickService(service);
    assert(menu.hasClass('active'));
  });

  it('must not process service clicks after a dragend', function() {
    // Test the work-around that prevents serviceClick from doing its work if
    // called after dragend.  Behaviour-driven testing via a tool such as
    // Selenium will add more coverage.
    var topo = view.topo;
    var called = false;
    var d =
        { id: 'wordpress',
          containsPoint: function() { return true; }
        };
    serviceModule.fake = function() { called = true; };
    serviceModule.set('currentServiceClickAction', 'fake');
    topo.ignoreServiceClick = true;
    serviceModule.serviceClick(d, serviceModule);
    assert.isFalse(called);
    // The flag is reset when encountered and ignored.
    assert.isFalse(topo.ignoreServiceClick);
  });

  it('should show only visible services', function() {
    var haproxy = db.services.getById('haproxy'); // Added in beforeEach.
    db.services.add([
      {id: 'rails', life: 'dying'},
      {id: 'mysql', life: 'dead'}
    ]);
    var django = db.services.add({id: 'django'});
    var wordpress = db.services.add({
      id: 'wordpress',
      life: 'dying',
      aggregated_status: {error: 42}
    });
    serviceModule.update();
    var boxes = topo.service_boxes;
    // There are five services in total.
    assert.strictEqual(5, db.services.size(), 'total');
    // But only three of those are actually displayed.
    assert.strictEqual(3, Y.Object.size(boxes), 'displayed');
    // And they are the visible ones.
    assert.deepPropertyVal(boxes, 'haproxy.model', haproxy);
    assert.deepPropertyVal(boxes, 'django.model', django);
    // Service wordpress is displayed because it has units in an error state.
    assert.deepPropertyVal(boxes, 'wordpress.model', wordpress);
  });

  it('should deploy a service on charm token drop events', function(done) {
    var localContainer = utils.makeContainer(),
        src = '/juju-ui/assets/svgs/service_health_mask.svg',
        preventCount = 0,
        fakeEventObject = {
          halt: function() {
            preventCount += 1;
          },
          _event: {
            dataTransfer: {
              getData: function(name) {
                return JSON.stringify({
                  data: '{"id": "cs:foo/bar-1"}',
                  dataType: 'token-drag-and-drop',
                  iconSrc: src
                });
              }
            },
            target: {},
            clientX: 155,
            clientY: 153
          }
        };

    var eventHandle = Y.on('initiateDeploy', function(charm, ghostAttributes) {
      eventHandle.detach();
      // After the translation and calculations the above x and y coords should
      // place the element at 320, 392
      assert.deepEqual(ghostAttributes, {
        coordinates: [320, 392],
        icon: src
      });
      // Make sure that the drag and drop was properly prevented.
      assert.equal(preventCount, 1);
      done();
    });
    serviceModule.set('component', topo);
    serviceModule.canvasDropHandler(fakeEventObject);
  });

  it('should deploy a bundle on bundle token drop events', function(done) {
    var localContainer = utils.makeContainer(),
        src = '/juju-ui/assets/svgs/service_health_mask.svg',
        preventCount = 0,
        fakeEventObject = {
          halt: function() {
            preventCount += 1;
          },
          _event: {
            dataTransfer: {
              getData: function(name) {
                return JSON.stringify({
                  data: '{"basket_name": "foo", "data": "BUNDLE DATA"}',
                  dataType: 'token-drag-and-drop',
                  iconSrc: src
                });
              }
            },
            target: {},
            clientX: 155,
            clientY: 153
          }
        };

    view.topo.set('env', {deployerImport: function(deployerData) {
      assert.include(deployerData, 'BUNDLE DATA');
      done();
    }});
    serviceModule.set('component', view.topo);
    serviceModule.canvasDropHandler(fakeEventObject);
  });
});
<commit_msg>fix lint<commit_after>/*
This file is part of the Juju GUI, which lets users view and manage Juju
environments within a graphical interface (https://launchpad.net/juju-gui).
Copyright (C) 2012-2013 Canonical Ltd.

This program is free software: you can redistribute it and/or modify it under
the terms of the GNU Affero General Public License version 3, as published by
the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranties of MERCHANTABILITY,
SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero
General Public License for more details.

You should have received a copy of the GNU Affero General Public License along
with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

'use strict';

describe('service module annotations', function() {
  var db, juju, models, utils, viewContainer, views, Y, serviceModule;
  var called, location;

  before(function(done) {
    Y = YUI(GlobalConfig).use([
      'juju-gui',
      'juju-models',
      'juju-tests-utils',
      'juju-views',
      'node',
      'node-event-simulate'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      utils = Y.namespace('juju-tests.utils');
      views = Y.namespace('juju.views');
      done();
    });
  });

  beforeEach(function() {
    viewContainer = utils.makeContainer();
    db = new models.Database();
    called = false;
    location =
        { 'gui-x': 0,
          'gui-y': 0};
    var env = {
      update_annotations: function(name, type, data) {
        called = true;
        location['gui-x'] = data['gui-x'];
        location['gui-y'] = data['gui-y'];},
      get: function() {}};
    var view = new views.environment(
        { container: viewContainer,
          db: db,
          env: env});
    view.render();
    view.rendered();
    serviceModule = view.topo.modules.ServiceModule;
    serviceModule.set('useTransitions', false);
  });

  afterEach(function() {
    if (viewContainer) {
      viewContainer.remove(true);
    }
  });

  // Test the drag end handler.
  it('should set location annotations on service block drag end',
     function() {
       var d =
           { id: 'wordpress',
             inDrag: true,
             x: 100.1,
             y: 200.2};
       serviceModule.dragend(d, serviceModule);
       assert.isTrue(called);
       location['gui-x'].should.equal(100.1);
       location['gui-y'].should.equal(200.2);
     });

  it('should not set annotations on drag end if building a relation',
     function() {
       var d =
           { id: 'wordpress',
             x: 100.1,
             y: 200.2};
       var topo = serviceModule.get('component');
       topo.buildingRelation = true;
       serviceModule.dragend(d, serviceModule);
       assert.isFalse(called);
       location['gui-x'].should.equal(0);
       location['gui-y'].should.equal(0);
     });
});

describe('service module events', function() {
  var db, charm, fakeStore, juju, models, serviceModule, topo, utils,
      view, viewContainer, views, Y;

  before(function(done) {
    Y = YUI(GlobalConfig).use(['node',
      'juju-tests-utils',
      'juju-landscape',
      'juju-models',
      'juju-views',
      'juju-gui',
      'node-event-simulate',
      'slider'],
    function(Y) {
      juju = Y.namespace('juju');
      models = Y.namespace('juju.models');
      views = Y.namespace('juju.views');
      utils = Y.namespace('juju-tests.utils');
      done();
    });
  });

  beforeEach(function() {
    fakeStore = new Y.juju.charmworld.APIv2({});
    fakeStore.iconpath = function() {
      return 'charm icon url';
    };
    viewContainer = utils.makeContainer('content');
    var charmData = utils.loadFixture('data/haproxy-api-response.json', true);
    charm = new models.Charm(charmData.charm);
    db = new models.Database();
    db.services.add({id: 'haproxy', charm: 'cs:precise/haproxy-18'});
    db.charms.add(charm);
    view = new views.environment({
      container: viewContainer,
      db: db,
      env: {
        update_annotations: function() {},
        get: function() {}
      },
      nsRouter: {
        url: function() { return; }
      },
      store: fakeStore
    });
    view.render();
    view.rendered();
    topo = view.topo;
    serviceModule = topo.modules.ServiceModule;
  });

  afterEach(function() {
    if (viewContainer) {
      viewContainer.remove(true);
    }

    fakeStore.destroy();
    charm.destroy();
    db.destroy();
    topo.destroy();
    view.destroy();
  });

  it('should show the service menu', function() {
    var box = topo.service_boxes.haproxy;
    var menu = viewContainer.one('#service-menu');
    assert.isFalse(menu.hasClass('active'));
    serviceModule.showServiceMenu(box);
    assert(menu.hasClass('active'));
    // Check no-op.
    serviceModule.showServiceMenu(box);
    assert(menu.hasClass('active'));
  });

  it('should hide the service menu',
     function() {
       var box = topo.service_boxes.haproxy;
       var menu = viewContainer.one('#service-menu');
       serviceModule.showServiceMenu(box);
       assert(menu.hasClass('active'));
       serviceModule.hideServiceMenu();
       assert.isFalse(menu.hasClass('active'));
       // Check no-op.
       serviceModule.hideServiceMenu();
       assert.isFalse(menu.hasClass('active'));
     });

  // Click the provided service so that the service menu is shown.
  // Return the service menu.
  var clickService = function(service) {
    // Monkeypatch to avoid the click event handler bailing out early.
    topo.service_boxes.haproxy.containsPoint = function() {
      return true;
    };
    // Click the service.
    service.simulate('click');
    return viewContainer.one('#service-menu');
  };

  it('should not show the service menu after the service is double-clicked',
     function() {
       var service = viewContainer.one('.service');
       var menu = clickService(service);

       // Ideally the browser would not send the click event right away...
       assert(menu.hasClass('active'));
       service.simulate('dblclick');
       assert.isFalse(menu.hasClass('active'));
     });

  it('should handle touch/click events properly', function() {
    var service = viewContainer.one('.service');
    var menu = viewContainer.one('#service-menu');
    assert.isFalse(menu.hasClass('active'));
    serviceModule._touchstartServiceTap({
      currentTarget: service,
      touches: [{PageX: 0, PageY: 0}]
    }, topo);
    // Touch events should also fire click events, which will be ignored.
    // Fire one manually here.
    clickService(service);
    assert(menu.hasClass('active'));
  });

  it('must not process service clicks after a dragend', function() {
    // Test the work-around that prevents serviceClick from doing its work if
    // called after dragend.  Behaviour-driven testing via a tool such as
    // Selenium will add more coverage.
    var topo = view.topo;
    var called = false;
    var d =
        { id: 'wordpress',
          containsPoint: function() { return true; }
        };
    serviceModule.fake = function() { called = true; };
    serviceModule.set('currentServiceClickAction', 'fake');
    topo.ignoreServiceClick = true;
    serviceModule.serviceClick(d, serviceModule);
    assert.isFalse(called);
    // The flag is reset when encountered and ignored.
    assert.isFalse(topo.ignoreServiceClick);
  });

  it('should show only visible services', function() {
    var haproxy = db.services.getById('haproxy'); // Added in beforeEach.
    db.services.add([
      {id: 'rails', life: 'dying'},
      {id: 'mysql', life: 'dead'}
    ]);
    var django = db.services.add({id: 'django'});
    var wordpress = db.services.add({
      id: 'wordpress',
      life: 'dying',
      aggregated_status: {error: 42}
    });
    serviceModule.update();
    var boxes = topo.service_boxes;
    // There are five services in total.
    assert.strictEqual(5, db.services.size(), 'total');
    // But only three of those are actually displayed.
    assert.strictEqual(3, Y.Object.size(boxes), 'displayed');
    // And they are the visible ones.
    assert.deepPropertyVal(boxes, 'haproxy.model', haproxy);
    assert.deepPropertyVal(boxes, 'django.model', django);
    // Service wordpress is displayed because it has units in an error state.
    assert.deepPropertyVal(boxes, 'wordpress.model', wordpress);
  });

  it('should deploy a service on charm token drop events', function(done) {
    var src = '/juju-ui/assets/svgs/service_health_mask.svg',
        preventCount = 0,
        fakeEventObject = {
          halt: function() {
            preventCount += 1;
          },
          _event: {
            dataTransfer: {
              getData: function(name) {
                return JSON.stringify({
                  data: '{"id": "cs:foo/bar-1"}',
                  dataType: 'token-drag-and-drop',
                  iconSrc: src
                });
              }
            },
            target: {},
            clientX: 155,
            clientY: 153
          }
        };

    var eventHandle = Y.on('initiateDeploy', function(charm, ghostAttributes) {
      eventHandle.detach();
      // After the translation and calculations the above x and y coords should
      // place the element at 320, 392
      assert.deepEqual(ghostAttributes, {
        coordinates: [320, 392],
        icon: src
      });
      // Make sure that the drag and drop was properly prevented.
      assert.equal(preventCount, 1);
      done();
    });
    serviceModule.set('component', topo);
    serviceModule.canvasDropHandler(fakeEventObject);
  });

  it('should deploy a bundle on bundle token drop events', function(done) {
    var src = '/juju-ui/assets/svgs/service_health_mask.svg',
        preventCount = 0,
        fakeEventObject = {
          halt: function() {
            preventCount += 1;
          },
          _event: {
            dataTransfer: {
              getData: function(name) {
                return JSON.stringify({
                  data: '{"basket_name": "foo", "data": "BUNDLE DATA"}',
                  dataType: 'token-drag-and-drop',
                  iconSrc: src
                });
              }
            },
            target: {},
            clientX: 155,
            clientY: 153
          }
        };

    view.topo.set('env', {deployerImport: function(deployerData) {
      assert.include(deployerData, 'BUNDLE DATA');
      done();
    }});
    serviceModule.set('component', view.topo);
    serviceModule.canvasDropHandler(fakeEventObject);
  });
});
<|endoftext|>


<commit_before>delete global.window;

import fs from 'fs';
import path from 'path';

import * as Redux from 'redux';
import cheerio from 'cheerio';
import {expect} from 'chai';

import Requerio from '../../src/requerio';

const html = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'index.html'), 'utf8');
const $ = global.$ = cheerio.load(html);

const timeout = 100;

const $organisms = {
  'window': null,
  'document': null,
  'html': null,
  'body': null,
  '#main': null,
  '.main__section': null,
  '.main__section--0': null,
  '.main__section--1': null
};
$.prototype.addExtensibility = function () {
  console.log('extensibility added! (jk)'); // eslint-disable-line no-console
};
$.prototype.handleExtensibility = function () {
  console.log('extensibility handled! (jk)'); // eslint-disable-line no-console
};
$.prototype.removeExtensibility = function () {
  console.log('extensibility removed! (jk)'); // eslint-disable-line no-console
};
function customReducer(state, action) {
  switch (action.method) {
    case 'addExtensibility':
      state.extensible = true;
      state[action.args[0]] = action.args[1];
      break;

    case 'handleExtensibility':
      state.handle = () => {};
      break;

    case 'removeExtensibility':
      state.extensible = false;
      break;
  }

  return state;
}
const customMiddleware = () => next => action => {
  switch (action.method) {
    case 'deferExtensibility': {
      console.log('extensibility deferred! (jk)'); // eslint-disable-line no-console

      const startTime = Date.now();
      action.promise = new Promise((resolve) => {
        setTimeout(() => {
          action.$org.dispatchAction('addExtensibility', ['elapsed', Date.now() - startTime]);
          resolve();
        }, timeout);
      });

      return next(action);
    }

    default: {
      return next(action);
    }
  }
};

const requerio = new Requerio($, Redux, $organisms, customReducer, Redux.applyMiddleware(customMiddleware));
requerio.init();

describe('Requerio', function () {
  describe('extensibility', function () {
    it('should accept a custom reducer', function () {
      const $org = requerio.$orgs['#main'];
      $org.dispatchAction('addExtensibility');
      const state = $org.getState();

      expect(state.extensible).to.equal(true);
    });

    it('should handle an incorrect state property type in a custom reducer', function () {
      const $org = requerio.$orgs['#main'];
      $org.dispatchAction('handleExtensibility');
      const state = $org.getState();

      expect(state.handle).to.be.undefined;
    });

    it('should accept custom middleware', function (done) {
      const $org = requerio.$orgs['#main'];
      $org.dispatchAction('removeExtensibility');
      const stateBefore = $org.getState();

      $org.dispatchAction('deferExtensibility').promise.then(() => {
        const stateAfter = $org.getState();

        expect(stateBefore.extensible).to.equal(false);
        expect(stateAfter.extensible).to.equal(true);
        expect(stateAfter.elapsed).to.be.a('number');
        expect(stateAfter.elapsed).to.be.above(timeout);
        done();
      });
    });
  });
});
<commit_msg>more accurate test<commit_after>delete global.window;

import fs from 'fs';
import path from 'path';

import * as Redux from 'redux';
import cheerio from 'cheerio';
import {expect} from 'chai';

import Requerio from '../../src/requerio';

const html = fs.readFileSync(path.join(__dirname, '..', 'fixtures', 'index.html'), 'utf8');
const $ = global.$ = cheerio.load(html);

const timeout = 100;

const $organisms = {
  'window': null,
  'document': null,
  'html': null,
  'body': null,
  '#main': null,
  '.main__section': null,
  '.main__section--0': null,
  '.main__section--1': null
};
$.prototype.addExtensibility = function () {
  console.log('extensibility added! (jk)'); // eslint-disable-line no-console
};
$.prototype.handleExtensibility = function () {
  console.log('extensibility handled! (jk)'); // eslint-disable-line no-console
};
$.prototype.removeExtensibility = function () {
  console.log('extensibility removed! (jk)'); // eslint-disable-line no-console
};
function customReducer(state, action) {
  switch (action.method) {
    case 'addExtensibility':
      state.extensible = true;
      state[action.args[0]] = action.args[1];
      break;

    case 'handleExtensibility':
      state.handle = () => {};
      break;

    case 'removeExtensibility':
      state.extensible = false;
      break;
  }

  return state;
}
const customMiddleware = () => next => action => {
  switch (action.method) {
    case 'deferExtensibility': {
      console.log('extensibility deferred! (jk)'); // eslint-disable-line no-console

      const startTime = Date.now();
      action.promise = new Promise((resolve) => {
        setTimeout(() => {
          action.$org.dispatchAction('addExtensibility', ['elapsed', Date.now() - startTime]);
          resolve();
        }, timeout);
      });

      return next(action);
    }

    default: {
      return next(action);
    }
  }
};

const requerio = new Requerio($, Redux, $organisms, customReducer, Redux.applyMiddleware(customMiddleware));
requerio.init();

describe('Requerio', function () {
  describe('extensibility', function () {
    it('should accept a custom reducer', function () {
      const $org = requerio.$orgs['#main'];
      $org.dispatchAction('addExtensibility');
      const state = $org.getState();

      expect(state.extensible).to.equal(true);
    });

    it('should handle an incorrect state property type in a custom reducer', function () {
      const $org = requerio.$orgs['#main'];
      $org.dispatchAction('handleExtensibility');
      const state = $org.getState();

      expect(state.handle).to.be.undefined;
    });

    it('should accept custom middleware', function (done) {
      const $org = requerio.$orgs['#main'];
      $org.dispatchAction('removeExtensibility');
      const stateBefore = $org.getState();

      $org.dispatchAction('deferExtensibility').promise.then(() => {
        const stateAfter = $org.getState();

        expect(stateBefore.extensible).to.equal(false);
        expect(stateAfter.extensible).to.equal(true);
        expect(stateAfter.elapsed).to.be.a('number');
        expect(stateAfter.elapsed).to.not.be.below(timeout);
        done();
      });
    });
  });
});
<|endoftext|>


<commit_before>(function() {
  function fetchPreview(url) {

    $('#host').hide("blind", {  }, 150, function() {
      $('#loading').show("blind", { }, 150);
      $.ajax({
        url: url.url + '.html' + url.parameters,
        success: function(data) {
          $("#host").html(data);

          $('#loading').hide("blind", { }, 150, function() {
            $('#host').show("blind", { }, 150);

          });
        },
        error: function(xhr, status, errorThrown) {
          $("#host").html('
Oops!

There was a problem with your request:
' + status + '');

          $('#loading').hide("blind", { }, 150, function() {
            $('#host').show("blind", { }, 150);

          });
        }
      });
    });
  }

  function openHelp(helpId) {
    var $dialog = $('

')
    .html(help[helpId].details)
    .dialog({
      autoOpen: false,
      title: help[helpId].title,
      show: 'drop',
      hide: 'drop'
    });
    $dialog.dialog('open');
  }

  function renderSettings() {
    var style = '';
    if(viewModel.chosenStyle() === 'yes') {
      style="styled"
    } else {
      style='unstyled'
    };

    if(viewModel.chosenStartDate() != '') {
      start = ", after " + viewModel.chosenStartDate()
    } else {
      start = ""
    };

    if(viewModel.chosenEndDate() != '') {
      end = ", before " + viewModel.chosenEndDate()
    } else {
      end = ""
    };

    $('#settings').html(viewModel.chosenLimit().label + ' ' +
        viewModel.chosenCollection() + start + end + ', in ' +
        viewModel.chosenFormat() + ' format ' +  style + '');
  }

  /* Clipboard from http://code.google.com/p/zeroclipboard/ */
  function initializeClipboard() {
    var clip = null;

    clip = new ZeroClipboard.Client();
    clip.setHandCursor( true );

    // clip.addEventListener('load', function (client) {
    //   //alert("Flash movie loaded and ready.");
    // });
    //
    clip.addEventListener('mouseOver', function (client) {
      clip.setText( $('#embed').val() );
    });
    clip.addEventListener('complete', function (client, text) {
      $('#embed').effect("highlight", {}, 1500);

    });
    clip.glue( 'd_clip_button', 'd_clip_container' );

  }

  // Initialization

  $( function() {
    ko.applyBindings(viewModel);

    viewModel.url = ko.dependentObservable( function() {
      var apiVersion = $('body').attr('data-api-version');
      var baseUri = "api/" + apiVersion + "/" + $('#group').attr('value');
      var groupUrl = window.location.toString().replace(/builder(.*)/,baseUri);
      var latestUrl = groupUrl + "/" + this.chosenCollection().toLowerCase() + "/" + this.chosenLimit().label;
      var latestParams = '?uri=' + $("#uri").attr("value") + '&formatting=' +
        this.chosenFormat() + '&style=' + this.chosenStyle() + '&start=' +
        this.chosenStartDate() + '&end=' + this.chosenEndDate();

      // Refresh Display
      fetchPreview({url: latestUrl, parameters: latestParams});
      renderSettings();
      // Update TextArea
      var script = '


<commit_before>/* @flow */
/* eslint-env mocha */

const EventEmitter = require('events')
const sinon = require('sinon')
const { FetchError } = require('electron-fetch')

const Prep = require('../../../core/prep')
const { Remote } = require('../../../core/remote')

const configHelpers = require('../../support/helpers/config')
const pouchHelpers = require('../../support/helpers/pouch')
const {
  deleteAll,
  createTheCouchdbFolder
} = require('../../support/helpers/cozy')

/*::
import type { Metadata } from '../../../core/metadata'
import type { RemoteDoc, JsonApiDoc } from '../../../core/remote/document'
*/

describe('Remote', function() {
  before('instanciate config', configHelpers.createConfig)
  before('register OAuth client', configHelpers.registerClient)
  before('instanciate pouch', pouchHelpers.createDatabase)
  before('instanciate remote', function() {
    this.prep = sinon.createStubInstance(Prep)
    this.events = new EventEmitter()
    this.remote = new Remote(this)
  })
  beforeEach(deleteAll)
  beforeEach(createTheCouchdbFolder)
  after('clean pouch', pouchHelpers.cleanDatabase)
  after('clean config directory', configHelpers.cleanConfig)

  describe('offline management', () => {
    it('The remote can be started when offline ', async function() {
      let fetchStub = sinon
        .stub(global, 'fetch')
        .rejects(new FetchError('net::ERR_INTERNET_DISCONNECTED'))
      let eventsSpy = sinon.spy(this.events, 'emit')
      await this.remote.start().started
      eventsSpy.should.have.been.calledWith('offline')
      fetchStub.restore()
      // skip waiting for HEARTBEAT
      await this.remote.watcher.watch()
      eventsSpy.should.have.been.calledWith('online')
      eventsSpy.restore()
    }).timeout(120000)
  })
})
<commit_msg>test/unit/remote/offline: Set Prep's config<commit_after>/* @flow */
/* eslint-env mocha */

const EventEmitter = require('events')
const sinon = require('sinon')
const { FetchError } = require('electron-fetch')

const Prep = require('../../../core/prep')
const { Remote } = require('../../../core/remote')

const configHelpers = require('../../support/helpers/config')
const pouchHelpers = require('../../support/helpers/pouch')
const {
  deleteAll,
  createTheCouchdbFolder
} = require('../../support/helpers/cozy')

/*::
import type { Metadata } from '../../../core/metadata'
import type { RemoteDoc, JsonApiDoc } from '../../../core/remote/document'
*/

describe('Remote', function() {
  before('instanciate config', configHelpers.createConfig)
  before('register OAuth client', configHelpers.registerClient)
  before('instanciate pouch', pouchHelpers.createDatabase)
  before('instanciate remote', function() {
    this.prep = sinon.createStubInstance(Prep)
    this.prep.config = this.config
    this.events = new EventEmitter()
    this.remote = new Remote(this)
  })
  beforeEach(deleteAll)
  beforeEach(createTheCouchdbFolder)
  after('clean pouch', pouchHelpers.cleanDatabase)
  after('clean config directory', configHelpers.cleanConfig)

  describe('offline management', () => {
    it('The remote can be started when offline ', async function() {
      let fetchStub = sinon
        .stub(global, 'fetch')
        .rejects(new FetchError('net::ERR_INTERNET_DISCONNECTED'))
      let eventsSpy = sinon.spy(this.events, 'emit')
      await this.remote.start().started
      eventsSpy.should.have.been.calledWith('offline')
      fetchStub.restore()
      // skip waiting for HEARTBEAT
      await this.remote.watcher.watch()
      eventsSpy.should.have.been.calledWith('online')
      eventsSpy.restore()
    }).timeout(120000)
  })
})
<|endoftext|>


<commit_before>enyo.kind({
	name: "Deimos",
	classes: "enyo-unselectable onyx",
	published: {
		edited: false
	},
	components: [
		{kind: "DragAvatar", components: [
			{tag: "img", src: "$deimos/images/icon.png", style: "width: 24px; height: 24px;"}
		]},
		{kind: "FittableRows", classes: "enyo-fit", components: [
			{kind: "onyx.Toolbar", layoutKind: "FittableColumnsLayout", Xstyle: "margin: 0 10px;", name: "toolbar", components: [
				{name: "docLabel", content: "Deimos"},
				{kind: "onyx.PickerDecorator", components: [
					{name: "kindButton", kind: "onyx.PickerButton"}, //this uses the defaultKind property of PickerDecorator to inherit from PickerButton
					{name: "kindPicker", kind: "onyx.Picker", onChange: "kindSelected", components: [
					]}
				]},
				{fit: true},
				{kind: "onyx.Button", content: "Code Editor", ontap: "closeDesignerAction"}
			]},
			{name: "body", fit: true, classes: "deimos_panel_body",kind: "FittableColumns", components: [
				{name: "left", classes:"ares_deimos_left", kind: "Palette", ondragstart: "dragStart"},
				{name: "middle", fit: true, kind: "FittableRows",components: [
					{kind: "Designer", fit: true, onChange: "designerChange", onSelect: "designerSelect", ondragstart: "dragStart", onDesignRendered: "designRendered"},
				]},
				{name: "right", classes:"ares_deimos_right", kind: "FittableRows", components: [
					{kind: "FittableColumns", components: [
						{name:"upButton", kind: "onyx.Button", content: "Up", ontap: "upAction"},
						{name:"downButton", kind: "onyx.Button", content: "Down", ontap: "downAction"},
						{name:"deleteButton", kind: "onyx.Button", content: "Delete", classes: "btn-danger",  ontap: "deleteAction"}
					]},
					{kind: "ComponentView", classes: "deimos_panel ares_deimos_componentView", onSelect: "componentViewSelect", ondrop: "componentViewDrop"},
					{kind: "Inspector", fit: true, classes: "deimos_panel", onModify: "inspectorModify"}
				]}
			]}
		]}
	],
	handlers: {
		ondrag: "drag",
		ondragfinish: "dragFinish"
	},
	events: {
		onCloseDesigner: "",
		onDesignerUpdate: ""
	},
	kinds: null,
	create: function() {
		this.inherited(arguments);
		this.kinds=[];
		this.index=null;
	},
	/**
	 * Loads the first kind passed thru the data parameter
	 * @param data contains kinds declaration (enyo.kind format)
	 *   and project information such as the analyzer output
	 *   for all the .js files of the project and for enyo/onyx.
	 * @public
	 */
	load: function(data) {
		var what = data.kinds;
		var maxLen = 0;
		this.kinds = what;
		this.$.kindPicker.destroyClientControls();
		for (var i = 0; i < what.length; i++) {
			var k = what[i];
			this.$.kindPicker.createComponent({
				content: k.name,
				index: i,
				active: (i==0)
			});
			maxLen = Math.max(k.name.length, maxLen);
		}
		//this.index=0; //this is set in KindSelected
		this.$.kindButton.applyStyle("width", (maxLen+2) + "em");
		this.$.kindPicker.render();
		this.setEdited(false);

		// Pass the project information (analyzer output, ...) to the inspector
		this.$.inspector.setProjectData(data.projectData);
		this.$.inspector.setFileIndexer(data.fileIndexer);
	},
	kindSelected: function(inSender, inEvent) {
		/* FIXME
		 * Strange: this function is always called twice for each change
		 * If we return true, it is called only once
		 * but the PickerButton is not rendered correctly.
		 */
		var index = inSender.getSelected().index;
		var kind = this.kinds[index];

		if (index !== this.index) {

			if (this.index !== null && this.getEdited()) {
				// save changes when switching kinds
				var modified = this.$.designer.getComponents();
				this.kinds[this.index].components = modified;
				this.kinds[this.index].content = this.$.designer.save();
				this.sendUpdateToAres();
			}

			this.$.inspector.inspect(null);
			this.$.designer.load(kind);
			this.refreshComponentView();
		}

		this.index=index;
		this.$.kindButton.setContent(kind.name);
		this.$.toolbar.reflow();
		return true; // Stop the propagation of the event
	},
	refreshInspector: function() {
		enyo.job("inspect", enyo.bind(this, function() {
			this.$.inspector.inspect(this.$.designer.selection);
		}), 200);
	},
	refreshComponentView: function() {
		this.$.componentView.visualize(this.$.designer.$.sandbox, this.$.designer.$.model);
		this.$.componentView.select(this.$.designer.selection);
	},
	designerChange: function(inSender) {
		this.refreshComponentView();
		this.refreshInspector();
		this.setEdited(true);
		//TODO: Is it "worth it" to send all intermediate updates to the editor?
		this.sendUpdateToAres();
		return true; // Stop the propagation of the event
	},
	designerSelect: function(inSender, inEvent) {
		var c = inSender.selection;
		this.refreshInspector();
		this.$.componentView.select(c);
		this.enableDisableButtons(c);
		return true; // Stop the propagation of the event
	},
	componentViewSelect: function(inSender) {
		var c = inSender.selection;
		this.$.designer.select(c);
		this.refreshInspector();
		this.enableDisableButtons(c);
		return true; // Stop the propagation of the event
	},
	inspectorModify: function() {
		this.refreshComponentView();
		this.$.designer.refresh();
		this.setEdited(true);
		//TODO: Is it "worth it" to send all intermediate updates to the editor?
		this.sendUpdateToAres();
		return true; // Stop the propagation of the event
	},
	componentViewDrop: function(inSender, inEvent) {
		return this.$.designer.drop(inSender, inEvent);
	},
	dragStart: function(inSender, inEvent) {
		return true; // Stop the propagation of the event
	},
	drag: function(inSender, inEvent) {
		if (inEvent.dragInfo) {
			this.$.dragAvatar.drag(inEvent);
			return true; // Stop the propagation of the event
		}
	},
	dragFinish: function(inSender, inEvent) {
		if (inEvent.dragInfo) {
			inEvent.preventTap();
			this.$.dragAvatar.hide();
			//this.refreshInspector();
			return true; // Stop the propagation of the event
		}
	},
	prepareDesignerUpdate: function() {
		if (this.index !== null) {
			// Get the last modifications
			this.kinds[this.index].content = this.$.designer.save();

			// Prepare the data for the code editor
			var event = {docHasChanged: this.getEdited(), contents: []};
			for(var i = 0 ; i < this.kinds.length ; i++ ) {
				event.contents[i] = this.kinds[i].content;
			}
			return event;
		}
	},
	closeDesignerAction: function(inSender, inEvent) {
		// Prepare the data for the code editor
		var event = this.prepareDesignerUpdate();
		this.$.inspector.setProjectData(null);
		this.doCloseDesigner(event);
		return true; // Stop the propagation of the event
	},
	// When the designer finishes rendering, re-build the components view
	// TODO: Build this from the Model, not by trawling the view hierarchy...
	designRendered: function() {
		this.refreshComponentView();
		return true; // Stop the propagation of the event
	},
	saveComplete: function() {
		this.setEdited(false);
	},
	upAction: function(inSender, inEvent) {
		this.$.designer.upAction(inSender, inEvent);
	},
	downAction: function(inSender, inEvent) {
		this.$.designer.downAction(inSender, inEvent);
	},
	deleteAction: function(inSender, inEvent) {
		this.$.designer.deleteAction(inSender, inEvent);
	},
	enableDisableButtons: function(control) {
		var disabled = this.$.designer.isRootControl(control);
		this.$.upButton.setDisabled(disabled);
		this.$.downButton.setDisabled(disabled);
		this.$.deleteButton.setDisabled(disabled);
	},
	editedChanged: function() {
		// Note: This doesn't look like it does anything, because we send updates to the document to Ares immediately, so a doc is
		// only "edited" for a few ms. I left this in here because I was tracking down some cases where the state stayed "edited"
		if (this.edited) {
			this.$.docLabel.setContent("Deimos *");
		} else {
			this.$.docLabel.setContent("Deimos");
		}
	},
	sendUpdateToAres: function() {
		this.doDesignerUpdate(this.prepareDesignerUpdate());
		this.setEdited(false);
	}
});

<commit_msg>Always reload kinds into designer when load() is called<commit_after>enyo.kind({
	name: "Deimos",
	classes: "enyo-unselectable onyx",
	published: {
		edited: false
	},
	components: [
		{kind: "DragAvatar", components: [
			{tag: "img", src: "$deimos/images/icon.png", style: "width: 24px; height: 24px;"}
		]},
		{kind: "FittableRows", classes: "enyo-fit", components: [
			{kind: "onyx.Toolbar", layoutKind: "FittableColumnsLayout", Xstyle: "margin: 0 10px;", name: "toolbar", components: [
				{name: "docLabel", content: "Deimos"},
				{kind: "onyx.PickerDecorator", components: [
					{name: "kindButton", kind: "onyx.PickerButton"}, //this uses the defaultKind property of PickerDecorator to inherit from PickerButton
					{name: "kindPicker", kind: "onyx.Picker", onChange: "kindSelected", components: [
					]}
				]},
				{fit: true},
				{kind: "onyx.Button", content: "Code Editor", ontap: "closeDesignerAction"}
			]},
			{name: "body", fit: true, classes: "deimos_panel_body",kind: "FittableColumns", components: [
				{name: "left", classes:"ares_deimos_left", kind: "Palette", ondragstart: "dragStart"},
				{name: "middle", fit: true, kind: "FittableRows",components: [
					{kind: "Designer", fit: true, onChange: "designerChange", onSelect: "designerSelect", ondragstart: "dragStart", onDesignRendered: "designRendered"},
				]},
				{name: "right", classes:"ares_deimos_right", kind: "FittableRows", components: [
					{kind: "FittableColumns", components: [
						{name:"upButton", kind: "onyx.Button", content: "Up", ontap: "upAction"},
						{name:"downButton", kind: "onyx.Button", content: "Down", ontap: "downAction"},
						{name:"deleteButton", kind: "onyx.Button", content: "Delete", classes: "btn-danger",  ontap: "deleteAction"}
					]},
					{kind: "ComponentView", classes: "deimos_panel ares_deimos_componentView", onSelect: "componentViewSelect", ondrop: "componentViewDrop"},
					{kind: "Inspector", fit: true, classes: "deimos_panel", onModify: "inspectorModify"}
				]}
			]}
		]}
	],
	handlers: {
		ondrag: "drag",
		ondragfinish: "dragFinish"
	},
	events: {
		onCloseDesigner: "",
		onDesignerUpdate: ""
	},
	kinds: null,
	create: function() {
		this.inherited(arguments);
		this.kinds=[];
		this.index=null;
	},
	/**
	 * Loads the first kind passed thru the data parameter
	 * @param data contains kinds declaration (enyo.kind format)
	 *   and project information such as the analyzer output
	 *   for all the .js files of the project and for enyo/onyx.
	 * @public
	 */
	load: function(data) {
		var what = data.kinds;
		var maxLen = 0;
		this.index=null;
		this.kinds = what;
		this.$.kindPicker.destroyClientControls();
		for (var i = 0; i < what.length; i++) {
			var k = what[i];
			this.$.kindPicker.createComponent({
				content: k.name,
				index: i,
				active: (i==0)
			});
			maxLen = Math.max(k.name.length, maxLen);
		}
		//this.index=0; //this is set in KindSelected
		this.$.kindButton.applyStyle("width", (maxLen+2) + "em");
		this.$.kindPicker.render();
		this.setEdited(false);

		// Pass the project information (analyzer output, ...) to the inspector
		this.$.inspector.setProjectData(data.projectData);
		this.$.inspector.setFileIndexer(data.fileIndexer);
	},
	kindSelected: function(inSender, inEvent) {
		/* FIXME
		 * Strange: this function is always called twice for each change
		 * If we return true, it is called only once
		 * but the PickerButton is not rendered correctly.
		 */
		var index = inSender.getSelected().index;
		var kind = this.kinds[index];

		if (index !== this.index) {

			if (this.index !== null && this.getEdited()) {
				// save changes when switching kinds
				var modified = this.$.designer.getComponents();
				this.kinds[this.index].components = modified;
				this.kinds[this.index].content = this.$.designer.save();
				this.sendUpdateToAres();
			}

			this.$.inspector.inspect(null);
			this.$.designer.load(kind);
			this.refreshComponentView();
		}

		this.index=index;
		this.$.kindButton.setContent(kind.name);
		this.$.toolbar.reflow();
		return true; // Stop the propagation of the event
	},
	refreshInspector: function() {
		enyo.job("inspect", enyo.bind(this, function() {
			this.$.inspector.inspect(this.$.designer.selection);
		}), 200);
	},
	refreshComponentView: function() {
		this.$.componentView.visualize(this.$.designer.$.sandbox, this.$.designer.$.model);
		this.$.componentView.select(this.$.designer.selection);
	},
	designerChange: function(inSender) {
		this.refreshComponentView();
		this.refreshInspector();
		this.setEdited(true);
		//TODO: Is it "worth it" to send all intermediate updates to the editor?
		this.sendUpdateToAres();
		return true; // Stop the propagation of the event
	},
	designerSelect: function(inSender, inEvent) {
		var c = inSender.selection;
		this.refreshInspector();
		this.$.componentView.select(c);
		this.enableDisableButtons(c);
		return true; // Stop the propagation of the event
	},
	componentViewSelect: function(inSender) {
		var c = inSender.selection;
		this.$.designer.select(c);
		this.refreshInspector();
		this.enableDisableButtons(c);
		return true; // Stop the propagation of the event
	},
	inspectorModify: function() {
		this.refreshComponentView();
		this.$.designer.refresh();
		this.setEdited(true);
		//TODO: Is it "worth it" to send all intermediate updates to the editor?
		this.sendUpdateToAres();
		return true; // Stop the propagation of the event
	},
	componentViewDrop: function(inSender, inEvent) {
		return this.$.designer.drop(inSender, inEvent);
	},
	dragStart: function(inSender, inEvent) {
		return true; // Stop the propagation of the event
	},
	drag: function(inSender, inEvent) {
		if (inEvent.dragInfo) {
			this.$.dragAvatar.drag(inEvent);
			return true; // Stop the propagation of the event
		}
	},
	dragFinish: function(inSender, inEvent) {
		if (inEvent.dragInfo) {
			inEvent.preventTap();
			this.$.dragAvatar.hide();
			//this.refreshInspector();
			return true; // Stop the propagation of the event
		}
	},
	prepareDesignerUpdate: function() {
		if (this.index !== null) {
			// Get the last modifications
			this.kinds[this.index].content = this.$.designer.save();

			// Prepare the data for the code editor
			var event = {docHasChanged: this.getEdited(), contents: []};
			for(var i = 0 ; i < this.kinds.length ; i++ ) {
				event.contents[i] = this.kinds[i].content;
			}
			return event;
		}
	},
	closeDesignerAction: function(inSender, inEvent) {
		// Prepare the data for the code editor
		var event = this.prepareDesignerUpdate();
		this.$.inspector.setProjectData(null);
		this.doCloseDesigner(event);
		return true; // Stop the propagation of the event
	},
	// When the designer finishes rendering, re-build the components view
	// TODO: Build this from the Model, not by trawling the view hierarchy...
	designRendered: function() {
		this.refreshComponentView();
		return true; // Stop the propagation of the event
	},
	saveComplete: function() {
		this.setEdited(false);
	},
	upAction: function(inSender, inEvent) {
		this.$.designer.upAction(inSender, inEvent);
	},
	downAction: function(inSender, inEvent) {
		this.$.designer.downAction(inSender, inEvent);
	},
	deleteAction: function(inSender, inEvent) {
		this.$.designer.deleteAction(inSender, inEvent);
	},
	enableDisableButtons: function(control) {
		var disabled = this.$.designer.isRootControl(control);
		this.$.upButton.setDisabled(disabled);
		this.$.downButton.setDisabled(disabled);
		this.$.deleteButton.setDisabled(disabled);
	},
	editedChanged: function() {
		// Note: This doesn't look like it does anything, because we send updates to the document to Ares immediately, so a doc is
		// only "edited" for a few ms. I left this in here because I was tracking down some cases where the state stayed "edited"
		if (this.edited) {
			this.$.docLabel.setContent("Deimos *");
		} else {
			this.$.docLabel.setContent("Deimos");
		}
	},
	sendUpdateToAres: function() {
		this.doDesignerUpdate(this.prepareDesignerUpdate());
		this.setEdited(false);
	}
});

<|endoftext|>


<commit_before>// Load in depdendencies
var http = require('http');
var eightTrack = require('eight-track');

// Define our eight-track server
exports.run = function () {
  var server;
  before(function runFn () {
    server = http.createServer(eightTrack({
      url: 'https://api.pinboard.in',
      fixtureDir: __dirname + '/../test-files/pinboard-eight-track/'
    }));
    server.listen(9001);
  });
  after(function cleanup (done) {
    server.close(function handleClose (err) {
      server = null;
      done();
    });
  });
};
<commit_msg>No luck with scrubbed request<commit_after>// Load in depdendencies
var http = require('http');
var eightTrack = require('eight-track');

// Define our eight-track server
exports.run = function () {
  var server;
  before(function runFn () {
    server = http.createServer(eightTrack({
      url: 'https://api.pinboard.in',
      fixtureDir: __dirname + '/../test-files/pinboard-eight-track/',
      normalizeFn: function (info) {
        delete info.url;
      }
    }));
    server.listen(9001);
  });
  after(function cleanup (done) {
    server.close(function handleClose (err) {
      server = null;
      done();
    });
  });
};
<|endoftext|>


<commit_before>// ==UserScript==
// @name        INSTANT ISIS
// @description ENHANCE YOUR AKBAR.
// @namespace   chrisdick69696969696969@gmail.com
// @include     http://aimgames.forummotion.com/*
// @version     all of em
// @grant       none
// @license     MIT License (Expat); opensource.org/licenses/MIT
// ==/UserScript==

window.addEventListener('load', function () {
  document.body.innerHTML += '';
}
<commit_msg>fix akbar<commit_after>// ==UserScript==
// @name        INSTANT ISIS
// @description ENHANCE YOUR AKBAR.
// @namespace   chrisdick69696969696969@gmail.com
// @include     http://aimgames.forummotion.com/*
// @version     all of em 2.0
// @grant       none
// @license     MIT License (Expat); opensource.org/licenses/MIT
// ==/UserScript==

document.body.onload = function () {
  document.body.innerHTML += '';
}
<|endoftext|>


<commit_before>/* 頂欄 */
document.all["pt-betafeatures"].hidden = true;
document.all["pt-logout"].hidden = true;

/* CentralAuth */
function showCentralAuth(username) {
	mw.loader.using(['mediawiki.util']).done(function(){
		mw.util.addPortletLink(
			'p-cactions',
			mw.config.get('wgServer')+mw.config.get('wgArticlePath').replace('$1', 'Special:CentralAuth/'+username),
			'CentralAuth'
		);
	});
}
if (mw.config.get('wgNamespaceNumber') === 2 || mw.config.get('wgNamespaceNumber') === 3) {
	showCentralAuth(mw.config.get('wgTitle').replace(/^([^/]+).*$/, '$1'));
}
if (mw.config.get('wgCanonicalSpecialPageName') === 'Contributions') {
	showCentralAuth(mw.config.get('wgRelevantUserName'));
}

/* 側欄 */
/* mediawiki.util start */
mw.loader.using(['mediawiki.util']).done(function () {

mw.util.addPortletLink(
	'p-tb',
	'/wiki/Special:PrefixIndex/'+mw.config.get('wgPageName'),
	'前綴索引',
	't-prefixindex',
	'',
	'',
	$('#t-specialpages')
);

});
/* mediawiki.util end */
<commit_msg>interface-global add anon gnc/stalktoy/ip location / adminlist<commit_after>mw.loader.using(['mediawiki.util']).done(function(){
/* mediawiki.util */

/* 頂欄 */
document.all["pt-betafeatures"].hidden = true;
document.all["pt-logout"].hidden = true;

/* CentralAuth */
function showCentralAuth(username) {
	if (username.match('^\\d+\\.\\d+\\.\\d+\\.\\d+$') !== null || username.match('^[0-9a-fA-F]+:[0-9a-fA-F:]+$')) {
		mw.util.addPortletLink(
			'p-cactions',
			'https://tools.wmflabs.org/guc/?by=date&user='+username,
			'全域貢獻'
		);
		mw.util.addPortletLink(
			'p-cactions',
			'https://tools.wmflabs.org/meta/stalktoy/'+username,
			'全域封禁'
		);
		mw.util.addPortletLink(
			'p-cactions',
			'https://whatismyipaddress.com/ip/'+username,
			'地理位置'
		);
	} else {
		mw.util.addPortletLink(
			'p-cactions',
			mw.config.get('wgServer')+mw.config.get('wgArticlePath').replace('$1', 'Special:CentralAuth/'+username),
			'全域帳號'
		);
	}
}
if (mw.config.get('wgNamespaceNumber') === 2 || mw.config.get('wgNamespaceNumber') === 3) {
	showCentralAuth(mw.config.get('wgTitle').replace(/^([^/]+).*$/, '$1'));
}
if (mw.config.get('wgCanonicalSpecialPageName') === 'Contributions') {
	showCentralAuth(mw.config.get('wgRelevantUserName'));
}

/* Admin list */
switch(mw.config.get('wgDBname')) {
	case 'zhwikibooks':
	case 'zhwikinews':
	case 'zhwikiquote':
	case 'zhwikisource':
	case 'zhwikivoyage':
	case 'zhwiktionary':
	case 'zh_classicalwiki':
		mw.util.addPortletLink(
			'p-cactions',
			mw.config.get('wgServer')+mw.config.get('wgArticlePath').replace('$1', 'Special:Userlist')+'?group=sysop',
			'管理員列表'
		);
	break;
}

/* 側欄 */
mw.util.addPortletLink(
	'p-tb',
	'/wiki/Special:PrefixIndex/'+mw.config.get('wgPageName'),
	'前綴索引',
	't-prefixindex',
	'',
	'',
	$('#t-specialpages')
);

/* mediawiki.util */
});
<|endoftext|>


<commit_before>/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

(function () {
    'use strict';

    var pingTimeout = 1000 * 60 * 9; // 9 minutes

    function ping() {
        Ext.Ajax.request({
            url: window.ux.ROOT_URL + 'rest/auth',
            success: function () {
                window.setTimeout(function () {
                    ping();
                }, pingTimeout);
            },
            failure: function () {
                Ext.Msg.alert('error', 'error.connection', function () {
                    window.location.reload();
                });
            }
        });
    }

    Ext.define('springchat.controller.Connection', {
        extend: 'Ext.app.Controller',
        requires: [
            'Ext.MessageBox'
        ],
        config: {
            views: ['Messages'],
            refs: {
                messages: {
                    selector: 'jschat-messages-panel'
                }
            }
        },
        connectSocket: function () {
            var me = this;
            me.getMessages().mask({
                xtype: 'loadmask',
                message: springchat.i18n.get('connecting')
            });
            var location = window.location;
            var protocol = 'ws';
            if (location.protocol === 'https:' || location.protocol === 'https') {
                protocol = 'wss';
            }
            var wsPath = protocol + '://' + location.hostname + ':' + location.port + window.ux.ROOT_URL + 'ws/connection;jsessionid=' + window.ux.SESSION_ID;
            var connection = new window.WebSocket(wsPath);
            connection.onopen = function () {
                window.console.log('WebSocket: connection started.');
                me.getMessages().unmask();
                var store = Ext.StoreManager.get('Message');
                store.load();
            };
            connection.onclose = function () {
                me.getMessages().mask({
                    xtype: 'loadmask',
                    message: springchat.i18n.get('connection.closed')
                });
            };
            connection.onerror = function (error) {
                Ext.Msg.alert('error', 'error.connection', function () {
                    window.location.reload();
                });
            };
            connection.onmessage = function (e) {
                try {
                    var evtData = Ext.JSON.decode(e.data);
                    me.getApplication().fireEvent('websocket-event-' + evtData.type, evtData.data);
                    window.console.log('WebSocket: message -> ' + e.data);
                } catch (ex) {
                    window.console.error('WebSocket: parse -> ' + ex);
                }
            };
        },
        init: function () {
            var me = this;
            me.control({
                messages: {
                    show: function (panel) {
                        me.connectSocket();
                        ping();
                    }
                }
            });

        }
    });

}());<commit_msg>avoiding socket timeout on nginx.<commit_after>/**
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

(function () {
    'use strict';

    var pingTimeout = 1000 * 60 * 9; // 9 minutes

    function ping() {
        Ext.Ajax.request({
            url: window.ux.ROOT_URL + 'rest/auth',
            success: function () {
                window.setTimeout(function () {
                    ping();
                }, pingTimeout);
            },
            failure: function () {
                Ext.Msg.alert('error', 'error.connection', function () {
                    window.location.reload();
                });
            }
        });
    }

    Ext.define('springchat.controller.Connection', {
        extend: 'Ext.app.Controller',
        requires: [
            'Ext.MessageBox',
            'Ext.util.DelayedTask'
        ],
        config: {
            views: ['Messages'],
            refs: {
                messages: {
                    selector: 'jschat-messages-panel'
                }
            }
        },
        connectSocket: function () {
            var me = this;
            me.getMessages().mask({
                xtype: 'loadmask',
                message: springchat.i18n.get('connecting')
            });
            var location = window.location;
            var protocol = 'ws';
            if (location.protocol === 'https:' || location.protocol === 'https') {
                protocol = 'wss';
            }
            var wsPath = protocol + '://' + location.hostname + ':' + location.port + window.ux.ROOT_URL + 'ws/connection;jsessionid=' + window.ux.SESSION_ID;
            var connection = new window.WebSocket(wsPath);
            var pingSocketTask = new Ext.util.DelayedTask();
            var pingSocket = function () {
                try {
                    connection.send('ping');
                } catch (e) {
                    window.console.log('WebSocket: Impossible to ping.', e);
                }
                pingSocketTask.delay(50000, pingSocket);
            };
            connection.onopen = function () {
                window.console.log('WebSocket: connection started.');
                me.getMessages().unmask();
                var store = Ext.StoreManager.get('Message');
                store.load();
                pingSocket();
            };
            connection.onclose = function () {
                me.getMessages().mask({
                    xtype: 'loadmask',
                    message: springchat.i18n.get('connection.closed')
                });
                pingSocketTask.cancel();
            };
            connection.onerror = function (error) {
                Ext.Msg.alert('error', 'error.connection', function () {
                    window.location.reload();
                });
            };
            connection.onmessage = function (e) {
                try {
                    var evtData = Ext.JSON.decode(e.data);
                    me.getApplication().fireEvent('websocket-event-' + evtData.type, evtData.data);
                    window.console.log('WebSocket: message -> ' + e.data);
                } catch (ex) {
                    window.console.error('WebSocket: parse -> ' + ex);
                }
            };

        },
        init: function () {
            var me = this;
            me.control({
                messages: {
                    show: function (panel) {
                        me.connectSocket();
                        ping();
                    }
                }
            });

        }
    });

}());<|endoftext|>


<commit_before>var EMPWorldWind = window.EMPWorldWind || {};
var emp = window.emp || {};
emp.engineDefs = emp.engineDefs || {};

/**
 * @classdesc EMP3 WorldWind Map Engine Interface
 *
 * @class Instantiates a WorldWind map for EMP
 * @param args
 * @returns {engineInterface}
 */
emp.engineDefs.worldWindMapEngine = function(args) {

  var empMapInstance = args.mapInstance;
  /** @type EMPWorldWind.map# */
  var empWorldWind;

  var engineInterface = emp.map.createEngineTemplate(),
    mapEngineExposed = engineInterface;

  engineInterface.implementation.displayName = "WorldWind Map Engine";
  engineInterface.implementation.version = "1.0.0";
  engineInterface.capabilities.mapType.type3D = true;
  engineInterface.capabilities.mapType.type2_5D = true;
  engineInterface.capabilities.mapType.type3D = true;
  engineInterface.capabilities.formats.GEOJSON_BASIC.plot = true;
  engineInterface.capabilities.formats.GEOJSON_BASIC.draw = true;
  engineInterface.capabilities.formats.GEOJSON_BASIC.edit = true;
  engineInterface.capabilities.formats.GEOJSON_FULL.plot = true;
  engineInterface.capabilities.formats.GEOJSON_FULL.edit = true;
  engineInterface.capabilities.formats.WMS.version_1_1 = true;
  engineInterface.capabilities.formats.WMS.version_1_3 = true;
  engineInterface.capabilities.formats.WMS.elevationData = true;
  engineInterface.capabilities.formats.KML_BASIC.plot = true;
  engineInterface.capabilities.formats.KML_BASIC.draw = true;
  engineInterface.capabilities.formats.KML_BASIC.edit = true;
  engineInterface.capabilities.formats.KML_COMPLEX.plot = true;
  engineInterface.capabilities.formats.IMAGE.plot = true;
  engineInterface.capabilities.formats.MILSTD.version2525B.plot = true;
  engineInterface.capabilities.formats.MILSTD.version2525B.draw = true;
  engineInterface.capabilities.formats.MILSTD.version2525B.edit = true;
  engineInterface.capabilities.formats.MILSTD.version2525C.plot = true;
  engineInterface.capabilities.formats.MILSTD.version2525C.draw = true;
  engineInterface.capabilities.formats.MILSTD.version2525C.edit = true;
  engineInterface.capabilities.formats.AIRSPACE.plot = true;
  engineInterface.capabilities.formats.AIRSPACE.draw = true;
  engineInterface.capabilities.formats.AIRSPACE.edit = true;
  engineInterface.capabilities.formats.AOI.plot = true;
  engineInterface.capabilities.formats.AOI.draw = true;
  engineInterface.capabilities.formats.AOI.edit = true;
  engineInterface.capabilities.settings.milstd.iconSize = true;
  engineInterface.capabilities.settings.milstd.labelOption = true;
  engineInterface.requirements.wmsCapabilities = true;
  engineInterface.capabilities.projection.flat = false;

  /**
   * Initialization
   * @param {EMPWorldWind.map} empWorldWindInstance
   */
  engineInterface.initialize.succeed = function(empWorldWindInstance) {
    // Add initialization code here
    try {
      empWorldWind = empWorldWindInstance;
      empWorldWind.mapEngineExposed = mapEngineExposed;
      emp.map.engineDirect = {name: "worldwind", ref: empWorldWind};

      // Notify application that the map is ready to receive data
      empMapInstance.eventing.StatusChange({
        status: emp.map.states.READY
      });
    }
    catch (err) {
      window.console.error("Error initializing WorldWind ", err);
    }
  };

  /**
   * Indicates a failed loading
   */
  engineInterface.initialize.fail = function() {
    empMapInstance.eventing.StatusChange({
      status: emp.map.states.MAP_INSTANCE_INIT_FAILED
    });
  };

  /**
   * @todo drop this functionality into the map itself and expose a simpler call
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.view.set = function(transaction) {
    var args, altitude, bottomLeft, topRight, feature, bufferScale,
      t1, t2,
      toRad = Math.PI / 180.0; // save a few divisions later

    switch (transaction.items[0].globalType) {
      case "view":
        if (transaction.items[0].location) {
          // Set camera
          args = {
            latitude: transaction.items[0].location.lat,
            longitude: transaction.items[0].location.lon,
            altitude: transaction.items[0].altitude,
            tilt: transaction.items[0].tilt,
            roll: transaction.items[0].roll,
            heading: transaction.items[0].heading
          };
        }
        else if (transaction.items[0].bounds) {
          // Zoom to overlay

          // Express lat/lon as radians
          bottomLeft = {
            lat: transaction.items[0].bounds.west * toRad,
            lon: transaction.items[0].bounds.south * toRad
          };

          topRight = {
            lat: transaction.items[0].bounds.east * toRad,
            lon: transaction.items[0].bounds.north * toRad
          };

          t1 = Math.pow(Math.sin((topRight.lat - bottomLeft.lat) / 2), 2);
          t2 = Math.pow(Math.sin((topRight.lon - bottomLeft.lon) / 2), 2);

          // Haversine formula
          // TODO see if we can replace this with WorldWind functionality
          altitude = 2 * WorldWind.EARTH_RADIUS * Math.asin(Math.sqrt(t1 + Math.cos(topRight.lat) * Math.cos(bottomLeft.lat) * t2));

          args = {
            latitude: (transaction.items[0].bounds.north + transaction.items[0].bounds.south) / 2,
            longitude: (transaction.items[0].bounds.east + transaction.items[0].bounds.west) / 2,
            altitude: altitude,
            tilt: 0,
            roll: 0,
            heading: 0
          };
        }
        break;
      case "feature":
        bufferScale = 2.25; // Assume conic view from the camera
        feature = transaction.items[0];
        switch (feature.format) {
          case emp3.api.enums.FeatureTypeEnum.GEO_CIRCLE:
            altitude = feature.properties.radius * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_ELLIPSE:
            altitude = Math.max(feature.properties.semiMajor, feature.properties.semiMinor) * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_RECTANGLE:
            altitude = Math.max(feature.properties.width, feature.properties.height) * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_SQUARE:
            altitude = feature.properties.width * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_ACM: // TODO compute bounding box diagonal distance
          default:
            altitude = 10000; // Default to 10000m
        }

        args = {
          latitude: transaction.items[0].coordinates[1],
          longitude: transaction.items[0].coordinates[0],
          altitude: altitude,
          tilt: 0,
          roll: 0,
          heading: 0
        };
        break;
      default:
        transaction.failures.push(transaction.items[0]);
    }

    // Check if we are animating
    if (transaction.items[0].animate === true) {
      transaction.pause();

      args.animate = true;
      args.animateCB = function() {

        // If we animated update the returned values
        transaction.items[0].location = {
          lat: empWorldWind.getCenter().latitude,
          lon: empWorldWind.getCenter().longitude
        };
        transaction.items[0].bounds = empWorldWind.getBounds();

        transaction.run();
        // Notify movement ended
        EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_MOTION_STOPPED);
      };
    }

    // Notify start of movement
    EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_IN_MOTION);
    empWorldWind.centerOnLocation(args);

    // Set initial transaction return values, to be overwritten if the move is animated
    transaction.items[0].location = {
      lat: empWorldWind.getCenter().latitude,
      lon: empWorldWind.getCenter().longitude
    };
    transaction.items[0].bounds = empWorldWind.getBounds();
  };

  /**
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.lookAt.set = function(transaction) {
    var args = {
      latitude: transaction.items[0].latitude,
      longitude: transaction.items[0].longitude,
      altitude: transaction.items[0].altitude,
      range: transaction.items[0].range,
      tilt: transaction.items[0].tilt,
      heading: transaction.items[0].heading
    };

    if (transaction.items[0].animate === true) {
      transaction.pause();

      args.animate = true;
      args.animateCB = function() {
        transaction.run();
        // Notify movement ended
        EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_MOTION_STOPPED);
      };
    }
    EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_IN_MOTION);

    empWorldWind.lookAt(args);
  };

  /**
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.overlay.add = function(transaction) {
    var rc,
      failList = [];

    emp.util.each(transaction.items, function(overlay) {
      rc = empWorldWind.addLayer(overlay);

      if (!rc.success) {
        failList.push(new emp.typeLibrary.Error({
          coreId: overlay.coreId,
          message: rc.message,
          level: emp.typeLibrary.Error.level.MINOR
        }));
      }
    });

    transaction.fail(failList);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.overlay.remove = function(transaction) {
    var rc = {},
      failList = [];

    emp.util.each(transaction.items, function(overlay) {
      rc = empWorldWind.removeLayer(overlay.overlayId);
      if (!rc.success) {
        failList.push(new emp.typeLibrary.Error({
          coreId: overlay.coreId,
          message: rc.message
        }));
      }
    }.bind(this));

    transaction.fail(failList);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.wms.add = function(transaction) {
    emp.util.each(transaction.items, function(wms) {
      empWorldWind.addWMS(wms);
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.wms.remove = function(transaction) {
    emp.util.each(transaction.items, function(wms) {
      empWorldWind.removeWMS(wms);
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.feature.add = function(transaction) {
    var feature,
      itemsCount = transaction.items.length;

    // Pause the transaction
    transaction.pause();

    while (itemsCount) {
      // Note pre-decrement
      feature = transaction.items[--itemsCount];

      empWorldWind.plotFeature(feature, function(featureCount, cbArgs) {
        if (!cbArgs.success) {
          transaction.fail(new emp.typeLibrary.Error({
            feature: cbArgs.feature
          }));
        }

        // All items have been processed
        if (featureCount === 0) {
          transaction.run();
        }
      }.bind(this, itemsCount));
    }
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.feature.remove = function(transaction) {
    var rc;
    emp.util.each(transaction.items, function(feature) {
      rc = empWorldWind.unplotFeature(feature);
      if (!rc.success) {
        transaction.fail(new emp.typeLibrary.Error({
          message: rc.message
        }));
      }
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   * @deprecated
   */
  engineInterface.settings.mil2525.icon.labels.set = function(transaction) {
    empWorldWind.setLabelStyle(transaction.items[0]);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.view.getLatLonFromXY = function(transaction) {
    var pickPoint = new WorldWind.Vec2(transaction.items[0].x, transaction.items[0].y);
    var terrainObject = empWorldWind.worldWindow.pickTerrain(pickPoint).terrainObject();
    transaction.items[0].lat = terrainObject ? terrainObject.position.latitude : undefined;
    transaction.items[0].lon = terrainObject ? terrainObject.position.longitude : undefined;
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.visibility.set = function(transaction) {
    emp.util.each(transaction.items, function(feature) {
      if (feature.featureId in empWorldWind.features) {
        empWorldWind.features[feature.featureId].setVisible(feature.visible);
      }
    }.bind(this));
    empWorldWind.refresh();
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.map.config = function(transaction) {
    var bRangeChanged;
    // Iterate through each transaction item, check for properties and apply them
    emp.util.each(transaction.items, function(config) {
      var prop, value;
      for (prop in config) {
        if (config.hasOwnProperty(prop)) {
          // Skip meta data fields
          if (prop === "messageId") {
            continue;
          }

          value = config[prop];

          switch (prop.toLowerCase()) {
            case "brightness":
              empWorldWind.setContrast(value);
              break;
            case "milstdlabels":
              empWorldWind.setLabelStyle(value);
              break;
            case "renderingOptimization":
              if (EMPWorldWind.utils.defined(value) && (value !== empWorldWind.enableRenderingOptimization)) {
                bRangeChanged = true;
                empWorldWind.enableRenderingOptimization = value;
              }
              break;
            case "midDistanceThreshold":
              if (EMPWorldWind.utils.defined(value) && (value !== empWorldWind.singlePointAltitudeRanges.mid)) {
                bRangeChanged = true;
                empWorldWind.singlePointAltitudeRanges.mid = value;
              }
              break;
            case "farDistanceThreshold":
              if (EMPWorldWind.utils.defined(value) && (value !== empWorldWind.singlePointAltitudeRanges.high)) {
                bRangeChanged = true;
                empWorldWind.singlePointAltitudeRanges.high = value;
                //empCesium.singlePointAltitudeRangeMode = cesiumEngine.utils.getSinglePointAltitudeRangeMode(empCesium.cameraAltitude, empCesium.singlePointAltitudeRanges);
                //empCesium.processOnRangeChangeSinglePoints();
              }
              break;
            default:
              transaction.fail(new emp.typeLibrary.Error({
                message: 'Config property ' + prop + ' is not supported by this engine'
              }));
          }

          if (bRangeChanged) {
            empWorldWind.singlePointAltitudeRangeMode = EMPWorldWind.utils.getSinglePointAltitudeRangeMode(empWorldWind.worldWind.navigator.range, empWorldWind.singlePointAltitudeRanges);
            // force a render update when the altitude range changes
            empWorldWind.refresh();
          }
        }
      }
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.navigation.enable = function(transaction) {
    empWorldWind.setLockState(transaction.items[0]);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.selection.set = function(transaction) {
    var rc = empWorldWind.selectFeatures(transaction.items);
    transaction.failures = rc.failed;
  };

  /**
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.capture.screenshot = function(transaction) {
    return transaction.items[0].dataUrl = empWorldWind.screenshot();
  };

  /**
   * Destroys the current engine
   */
  engineInterface.state.destroy = function() {
    if (empWorldWind) {
      empWorldWind.shutdown();
      empWorldWind = undefined;
    }
  };

  // return the engineInterface object as a new engineTemplate instance
  return engineInterface;
};<commit_msg>-removed lower casing of config property inside the switch statement. Also renamed config property variables that were not matching the names sent by the core.<commit_after>var EMPWorldWind = window.EMPWorldWind || {};
var emp = window.emp || {};
emp.engineDefs = emp.engineDefs || {};

/**
 * @classdesc EMP3 WorldWind Map Engine Interface
 *
 * @class Instantiates a WorldWind map for EMP
 * @param args
 * @returns {engineInterface}
 */
emp.engineDefs.worldWindMapEngine = function(args) {

  var empMapInstance = args.mapInstance;
  /** @type EMPWorldWind.map# */
  var empWorldWind;

  var engineInterface = emp.map.createEngineTemplate(),
    mapEngineExposed = engineInterface;

  engineInterface.implementation.displayName = "WorldWind Map Engine";
  engineInterface.implementation.version = "1.0.0";
  engineInterface.capabilities.mapType.type3D = true;
  engineInterface.capabilities.mapType.type2_5D = true;
  engineInterface.capabilities.mapType.type3D = true;
  engineInterface.capabilities.formats.GEOJSON_BASIC.plot = true;
  engineInterface.capabilities.formats.GEOJSON_BASIC.draw = true;
  engineInterface.capabilities.formats.GEOJSON_BASIC.edit = true;
  engineInterface.capabilities.formats.GEOJSON_FULL.plot = true;
  engineInterface.capabilities.formats.GEOJSON_FULL.edit = true;
  engineInterface.capabilities.formats.WMS.version_1_1 = true;
  engineInterface.capabilities.formats.WMS.version_1_3 = true;
  engineInterface.capabilities.formats.WMS.elevationData = true;
  engineInterface.capabilities.formats.KML_BASIC.plot = true;
  engineInterface.capabilities.formats.KML_BASIC.draw = true;
  engineInterface.capabilities.formats.KML_BASIC.edit = true;
  engineInterface.capabilities.formats.KML_COMPLEX.plot = true;
  engineInterface.capabilities.formats.IMAGE.plot = true;
  engineInterface.capabilities.formats.MILSTD.version2525B.plot = true;
  engineInterface.capabilities.formats.MILSTD.version2525B.draw = true;
  engineInterface.capabilities.formats.MILSTD.version2525B.edit = true;
  engineInterface.capabilities.formats.MILSTD.version2525C.plot = true;
  engineInterface.capabilities.formats.MILSTD.version2525C.draw = true;
  engineInterface.capabilities.formats.MILSTD.version2525C.edit = true;
  engineInterface.capabilities.formats.AIRSPACE.plot = true;
  engineInterface.capabilities.formats.AIRSPACE.draw = true;
  engineInterface.capabilities.formats.AIRSPACE.edit = true;
  engineInterface.capabilities.formats.AOI.plot = true;
  engineInterface.capabilities.formats.AOI.draw = true;
  engineInterface.capabilities.formats.AOI.edit = true;
  engineInterface.capabilities.settings.milstd.iconSize = true;
  engineInterface.capabilities.settings.milstd.labelOption = true;
  engineInterface.requirements.wmsCapabilities = true;
  engineInterface.capabilities.projection.flat = false;

  /**
   * Initialization
   * @param {EMPWorldWind.map} empWorldWindInstance
   */
  engineInterface.initialize.succeed = function(empWorldWindInstance) {
    // Add initialization code here
    try {
      empWorldWind = empWorldWindInstance;
      empWorldWind.mapEngineExposed = mapEngineExposed;
      emp.map.engineDirect = {name: "worldwind", ref: empWorldWind};

      // Notify application that the map is ready to receive data
      empMapInstance.eventing.StatusChange({
        status: emp.map.states.READY
      });
    }
    catch (err) {
      window.console.error("Error initializing WorldWind ", err);
    }
  };

  /**
   * Indicates a failed loading
   */
  engineInterface.initialize.fail = function() {
    empMapInstance.eventing.StatusChange({
      status: emp.map.states.MAP_INSTANCE_INIT_FAILED
    });
  };

  /**
   * @todo drop this functionality into the map itself and expose a simpler call
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.view.set = function(transaction) {
    var args, altitude, bottomLeft, topRight, feature, bufferScale,
      t1, t2,
      toRad = Math.PI / 180.0; // save a few divisions later

    switch (transaction.items[0].globalType) {
      case "view":
        if (transaction.items[0].location) {
          // Set camera
          args = {
            latitude: transaction.items[0].location.lat,
            longitude: transaction.items[0].location.lon,
            altitude: transaction.items[0].altitude,
            tilt: transaction.items[0].tilt,
            roll: transaction.items[0].roll,
            heading: transaction.items[0].heading
          };
        }
        else if (transaction.items[0].bounds) {
          // Zoom to overlay

          // Express lat/lon as radians
          bottomLeft = {
            lat: transaction.items[0].bounds.west * toRad,
            lon: transaction.items[0].bounds.south * toRad
          };

          topRight = {
            lat: transaction.items[0].bounds.east * toRad,
            lon: transaction.items[0].bounds.north * toRad
          };

          t1 = Math.pow(Math.sin((topRight.lat - bottomLeft.lat) / 2), 2);
          t2 = Math.pow(Math.sin((topRight.lon - bottomLeft.lon) / 2), 2);

          // Haversine formula
          // TODO see if we can replace this with WorldWind functionality
          altitude = 2 * WorldWind.EARTH_RADIUS * Math.asin(Math.sqrt(t1 + Math.cos(topRight.lat) * Math.cos(bottomLeft.lat) * t2));

          args = {
            latitude: (transaction.items[0].bounds.north + transaction.items[0].bounds.south) / 2,
            longitude: (transaction.items[0].bounds.east + transaction.items[0].bounds.west) / 2,
            altitude: altitude,
            tilt: 0,
            roll: 0,
            heading: 0
          };
        }
        break;
      case "feature":
        bufferScale = 2.25; // Assume conic view from the camera
        feature = transaction.items[0];
        switch (feature.format) {
          case emp3.api.enums.FeatureTypeEnum.GEO_CIRCLE:
            altitude = feature.properties.radius * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_ELLIPSE:
            altitude = Math.max(feature.properties.semiMajor, feature.properties.semiMinor) * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_RECTANGLE:
            altitude = Math.max(feature.properties.width, feature.properties.height) * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_SQUARE:
            altitude = feature.properties.width * bufferScale;
            break;
          case emp3.api.enums.FeatureTypeEnum.GEO_ACM: // TODO compute bounding box diagonal distance
          default:
            altitude = 10000; // Default to 10000m
        }

        args = {
          latitude: transaction.items[0].coordinates[1],
          longitude: transaction.items[0].coordinates[0],
          altitude: altitude,
          tilt: 0,
          roll: 0,
          heading: 0
        };
        break;
      default:
        transaction.failures.push(transaction.items[0]);
    }

    // Check if we are animating
    if (transaction.items[0].animate === true) {
      transaction.pause();

      args.animate = true;
      args.animateCB = function() {

        // If we animated update the returned values
        transaction.items[0].location = {
          lat: empWorldWind.getCenter().latitude,
          lon: empWorldWind.getCenter().longitude
        };
        transaction.items[0].bounds = empWorldWind.getBounds();

        transaction.run();
        // Notify movement ended
        EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_MOTION_STOPPED);
      };
    }

    // Notify start of movement
    EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_IN_MOTION);
    empWorldWind.centerOnLocation(args);

    // Set initial transaction return values, to be overwritten if the move is animated
    transaction.items[0].location = {
      lat: empWorldWind.getCenter().latitude,
      lon: empWorldWind.getCenter().longitude
    };
    transaction.items[0].bounds = empWorldWind.getBounds();
  };

  /**
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.lookAt.set = function(transaction) {
    var args = {
      latitude: transaction.items[0].latitude,
      longitude: transaction.items[0].longitude,
      altitude: transaction.items[0].altitude,
      range: transaction.items[0].range,
      tilt: transaction.items[0].tilt,
      heading: transaction.items[0].heading
    };

    if (transaction.items[0].animate === true) {
      transaction.pause();

      args.animate = true;
      args.animateCB = function() {
        transaction.run();
        // Notify movement ended
        EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_MOTION_STOPPED);
      };
    }
    EMPWorldWind.eventHandlers.notifyViewChange.call(empWorldWind, emp3.api.enums.CameraEventEnum.CAMERA_IN_MOTION);

    empWorldWind.lookAt(args);
  };

  /**
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.overlay.add = function(transaction) {
    var rc,
      failList = [];

    emp.util.each(transaction.items, function(overlay) {
      rc = empWorldWind.addLayer(overlay);

      if (!rc.success) {
        failList.push(new emp.typeLibrary.Error({
          coreId: overlay.coreId,
          message: rc.message,
          level: emp.typeLibrary.Error.level.MINOR
        }));
      }
    });

    transaction.fail(failList);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.overlay.remove = function(transaction) {
    var rc = {},
      failList = [];

    emp.util.each(transaction.items, function(overlay) {
      rc = empWorldWind.removeLayer(overlay.overlayId);
      if (!rc.success) {
        failList.push(new emp.typeLibrary.Error({
          coreId: overlay.coreId,
          message: rc.message
        }));
      }
    }.bind(this));

    transaction.fail(failList);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.wms.add = function(transaction) {
    emp.util.each(transaction.items, function(wms) {
      empWorldWind.addWMS(wms);
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.wms.remove = function(transaction) {
    emp.util.each(transaction.items, function(wms) {
      empWorldWind.removeWMS(wms);
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.feature.add = function(transaction) {
    var feature,
      itemsCount = transaction.items.length;

    // Pause the transaction
    transaction.pause();

    while (itemsCount) {
      // Note pre-decrement
      feature = transaction.items[--itemsCount];

      empWorldWind.plotFeature(feature, function(featureCount, cbArgs) {
        if (!cbArgs.success) {
          transaction.fail(new emp.typeLibrary.Error({
            feature: cbArgs.feature
          }));
        }

        // All items have been processed
        if (featureCount === 0) {
          transaction.run();
        }
      }.bind(this, itemsCount));
    }
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.feature.remove = function(transaction) {
    var rc;
    emp.util.each(transaction.items, function(feature) {
      rc = empWorldWind.unplotFeature(feature);
      if (!rc.success) {
        transaction.fail(new emp.typeLibrary.Error({
          message: rc.message
        }));
      }
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   * @deprecated
   */
  engineInterface.settings.mil2525.icon.labels.set = function(transaction) {
    empWorldWind.setLabelStyle(transaction.items[0]);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.view.getLatLonFromXY = function(transaction) {
    var pickPoint = new WorldWind.Vec2(transaction.items[0].x, transaction.items[0].y);
    var terrainObject = empWorldWind.worldWindow.pickTerrain(pickPoint).terrainObject();
    transaction.items[0].lat = terrainObject ? terrainObject.position.latitude : undefined;
    transaction.items[0].lon = terrainObject ? terrainObject.position.longitude : undefined;
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.visibility.set = function(transaction) {
    emp.util.each(transaction.items, function(feature) {
      if (feature.featureId in empWorldWind.features) {
        empWorldWind.features[feature.featureId].setVisible(feature.visible);
      }
    }.bind(this));
    empWorldWind.refresh();
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.map.config = function(transaction) {
    var bRangeChanged;
    // Iterate through each transaction item, check for properties and apply them
    emp.util.each(transaction.items, function(config) {
      var prop, value;
      for (prop in config) {
        if (config.hasOwnProperty(prop)) {
          // Skip meta data fields
          if (prop === "messageId") {
            continue;
          }

          value = config[prop];

          switch (prop) {
            case "brightness":
              empWorldWind.setContrast(value);
              break;
            case "milStdIconLabels":
              empWorldWind.setLabelStyle(value);
              break;
            case "renderingOptimization":
              if (EMPWorldWind.utils.defined(value) && (value !== empWorldWind.enableRenderingOptimization)) {
                bRangeChanged = true;
                empWorldWind.enableRenderingOptimization = value;
              }
              break;
            case "midDistanceThreshold":
              if (EMPWorldWind.utils.defined(value) && (value !== empWorldWind.singlePointAltitudeRanges.mid)) {
                bRangeChanged = true;
                empWorldWind.singlePointAltitudeRanges.mid = value;
              }
              break;
            case "farDistanceThreshold":
              if (EMPWorldWind.utils.defined(value) && (value !== empWorldWind.singlePointAltitudeRanges.high)) {
                bRangeChanged = true;
                empWorldWind.singlePointAltitudeRanges.high = value;
                //empCesium.singlePointAltitudeRangeMode = cesiumEngine.utils.getSinglePointAltitudeRangeMode(empCesium.cameraAltitude, empCesium.singlePointAltitudeRanges);
                //empCesium.processOnRangeChangeSinglePoints();
              }
              break;
            default:
              transaction.fail(new emp.typeLibrary.Error({
                message: 'Config property ' + prop + ' is not supported by this engine'
              }));
          }

          if (bRangeChanged) {
            empWorldWind.singlePointAltitudeRangeMode = EMPWorldWind.utils.getSinglePointAltitudeRangeMode(empWorldWind.worldWind.navigator.range, empWorldWind.singlePointAltitudeRanges);
            // force a render update when the altitude range changes
            empWorldWind.refresh();
          }
        }
      }
    }.bind(this));
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.navigation.enable = function(transaction) {
    empWorldWind.setLockState(transaction.items[0]);
  };

  /**
   *
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.selection.set = function(transaction) {
    var rc = empWorldWind.selectFeatures(transaction.items);
    transaction.failures = rc.failed;
  };

  /**
   * @param {emp.typeLibrary.Transaction} transaction
   */
  engineInterface.capture.screenshot = function(transaction) {
    return transaction.items[0].dataUrl = empWorldWind.screenshot();
  };

  /**
   * Destroys the current engine
   */
  engineInterface.state.destroy = function() {
    if (empWorldWind) {
      empWorldWind.shutdown();
      empWorldWind = undefined;
    }
  };

  // return the engineInterface object as a new engineTemplate instance
  return engineInterface;
};
<|endoftext|>