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

const Location = require('./Location');

const TestExpectation = {
  Ok: 'ok',
  Fail: 'fail',
};

class Test {
  constructor(suite, name, callback, location) {
    this._suite = suite;
    this._name = name;
    this._fullName = (suite.fullName() + ' ' + name).trim();
    this._skipped = false;
    this._expectation = TestExpectation.Ok;
    this._body = callback;
    this._location = location;
    this._timeout = 100000000;
    this._environments = [];
    this.Expectations = { ...TestExpectation };
  }

  suite() {
    return this._suite;
  }

  name() {
    return this._name;
  }

  fullName() {
    return this._fullName;
  }

  location() {
    return this._location;
  }

  body() {
    return this._body;
  }

  skipped() {
    return this._skipped;
  }

  setSkipped(skipped) {
    this._skipped = skipped;
    return this;
  }

  timeout() {
    return this._timeout;
  }

  setTimeout(timeout) {
    this._timeout = timeout;
    return this;
  }

  expectation() {
    return this._expectation;
  }

  setExpectation(expectation) {
    this._expectation = expectation;
    return this;
  }

  addEnvironment(environment) {
    this._environments.push(environment);
    return this;
  }

  removeEnvironment(environment) {
    const index = this._environments.indexOf(environment);
    if (index === -1)
      throw new Error(`Environment "${environment.name()}" cannot be removed because it was not added to the suite "${this.fullName()}"`);
    this._environments.splice(index, 1);
    return this;
  }
}

class Suite {
  constructor(parentSuite, name, location) {
    this._parentSuite = parentSuite;
    this._name = name;
    this._fullName = (parentSuite ? parentSuite.fullName() + ' ' + name : name).trim();
    this._location = location;
    this._skipped = false;
    this._expectation = TestExpectation.Ok;

    this._defaultEnvironment = {
      name() { return this._fullName; },
    };

    this._environments = [this._defaultEnvironment];
    this.Expectations = { ...TestExpectation };
  }

  _addHook(name, callback) {
    if (this._defaultEnvironment[name])
      throw new Error(`ERROR: cannot re-assign hook "${name}" for suite "${this._fullName}"`);
    this._defaultEnvironment[name] = callback;
  }

  beforeEach(callback) { this._addHook('beforeEach', callback); }
  afterEach(callback) { this._addHook('afterEach', callback); }
  beforeAll(callback) { this._addHook('beforeAll', callback); }
  afterAll(callback) { this._addHook('afterAll', callback); }
  globalSetup(callback) { this._addHook('globalSetup', callback); }
  globalTeardown(callback) { this._addHook('globalTeardown', callback); }

  parentSuite() { return this._parentSuite; }

  name() { return this._name; }

  fullName() { return this._fullName; }

  skipped() { return this._skipped; }

  setSkipped(skipped) {
    this._skipped = skipped;
    return this;
  }

  location() { return this._location; }

  expectation() { return this._expectation; }

  setExpectation(expectation) {
    this._expectation = expectation;
    return this;
  }

  addEnvironment(environment) {
    this._environments.push(environment);
    return this;
  }

  removeEnvironment(environment) {
    const index = this._environments.indexOf(environment);
    if (index === -1)
      throw new Error(`Environment "${environment.name()}" cannot be removed because it was not added to the suite "${this.fullName()}"`);
    this._environments.splice(index, 1);
    return this;
  }
}

module.exports = { TestExpectation, Test, Suite };
<commit_msg>testrunner: fix default environment name (#2870)<commit_after>/**
 * Copyright 2017 Google Inc. All rights reserved.
 * Modifications copyright (c) Microsoft Corporation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

const Location = require('./Location');

const TestExpectation = {
  Ok: 'ok',
  Fail: 'fail',
};

class Test {
  constructor(suite, name, callback, location) {
    this._suite = suite;
    this._name = name;
    this._fullName = (suite.fullName() + ' ' + name).trim();
    this._skipped = false;
    this._expectation = TestExpectation.Ok;
    this._body = callback;
    this._location = location;
    this._timeout = 100000000;
    this._environments = [];
    this.Expectations = { ...TestExpectation };
  }

  suite() {
    return this._suite;
  }

  name() {
    return this._name;
  }

  fullName() {
    return this._fullName;
  }

  location() {
    return this._location;
  }

  body() {
    return this._body;
  }

  skipped() {
    return this._skipped;
  }

  setSkipped(skipped) {
    this._skipped = skipped;
    return this;
  }

  timeout() {
    return this._timeout;
  }

  setTimeout(timeout) {
    this._timeout = timeout;
    return this;
  }

  expectation() {
    return this._expectation;
  }

  setExpectation(expectation) {
    this._expectation = expectation;
    return this;
  }

  addEnvironment(environment) {
    this._environments.push(environment);
    return this;
  }

  removeEnvironment(environment) {
    const index = this._environments.indexOf(environment);
    if (index === -1)
      throw new Error(`Environment "${environment.name()}" cannot be removed because it was not added to the suite "${this.fullName()}"`);
    this._environments.splice(index, 1);
    return this;
  }
}

class Suite {
  constructor(parentSuite, name, location) {
    this._parentSuite = parentSuite;
    this._name = name;
    const fullName = (parentSuite ? parentSuite.fullName() + ' ' + name : name).trim();
    this._fullName = fullName;
    this._location = location;
    this._skipped = false;
    this._expectation = TestExpectation.Ok;

    this._defaultEnvironment = {
      name() { return fullName; },
    };

    this._environments = [this._defaultEnvironment];
    this.Expectations = { ...TestExpectation };
  }

  _addHook(name, callback) {
    if (this._defaultEnvironment[name])
      throw new Error(`ERROR: cannot re-assign hook "${name}" for suite "${this._fullName}"`);
    this._defaultEnvironment[name] = callback;
  }

  beforeEach(callback) { this._addHook('beforeEach', callback); }
  afterEach(callback) { this._addHook('afterEach', callback); }
  beforeAll(callback) { this._addHook('beforeAll', callback); }
  afterAll(callback) { this._addHook('afterAll', callback); }
  globalSetup(callback) { this._addHook('globalSetup', callback); }
  globalTeardown(callback) { this._addHook('globalTeardown', callback); }

  parentSuite() { return this._parentSuite; }

  name() { return this._name; }

  fullName() { return this._fullName; }

  skipped() { return this._skipped; }

  setSkipped(skipped) {
    this._skipped = skipped;
    return this;
  }

  location() { return this._location; }

  expectation() { return this._expectation; }

  setExpectation(expectation) {
    this._expectation = expectation;
    return this;
  }

  addEnvironment(environment) {
    this._environments.push(environment);
    return this;
  }

  removeEnvironment(environment) {
    const index = this._environments.indexOf(environment);
    if (index === -1)
      throw new Error(`Environment "${environment.name()}" cannot be removed because it was not added to the suite "${this.fullName()}"`);
    this._environments.splice(index, 1);
    return this;
  }
}

module.exports = { TestExpectation, Test, Suite };
<|endoftext|>


<commit_before>'use strict';

/**
 * @license
 * (c) 2014 Cluster Labs, Inc. https://cluster.co/
 * License: MIT
 */

var fs = require('fs');

var Handlebars = require('handlebars');

var loader = require('./loader/loader');
var scriptresource = require('./loader/scriptresource');
var util = require('./util');

var TargetEnvironment = scriptresource.TargetEnvironment;

Handlebars.registerHelper('json', function(arg) {
  return new Handlebars.SafeString(util.safeJSONStringify(arg));
});

var BOOTSTRAP_TEMPLATE = (function() {
  var templateSource = fs.readFileSync(__dirname + '/bootstrap.html').toString();
  return Handlebars.compile(templateSource);
})();

var NET_SERVER_MODULE = 'skit.platform.net:server';
var NAVIGATION_MODULE = 'skit.platform.navigation';
var PROXY_MODULE = 'skit.platform.netproxy';
var PROXY_RESOURCE = PROXY_MODULE + ':js';

function ControllerServer(server, controllerModule, request) {
  this.server = server;
  this.module = controllerModule;
  this.resources = loader.loadResourcesForModule(controllerModule);
  this.request = request;

  this.code = null;
  this.responseHeaders = {};
  this.responseBody = null;
  this.exception = null;
  this.errorMessage = null;
  this.redirectUrl = null;

  this.setupProxies_();
  this.setupNet_();
};

ControllerServer.prototype.isDone = function() {
  return this.code !== null;
};

ControllerServer.prototype.maybeFinish = function() {
  if (this.isDone() && this.onResponse_) {
    this.onResponse_();
  }
};

ControllerServer.prototype.error = function(code, message, exception) {
  if (this.isDone()) {
    return;
  }

  this.code = code;
  this.errorMessage = message;
  this.exception = exception;

  this.maybeFinish();
};
ControllerServer.prototype.navigate = function(toUrl) {
  if (this.isDone()) {
    return;
  }

  this.code = 302;
  this.redirectUrl = toUrl;

  this.maybeFinish();
};
ControllerServer.prototype.finish = function(code, headers, body) {
  if (this.isDone()) {
    return;
  }

  this.code = 200;
  this.responseHeaders = headers;
  this.responseBody = body;

  this.maybeFinish();
};

ControllerServer.prototype.setupProxies_ = function() {
  var netproxy = this.resources.objectsByModulePath[PROXY_MODULE];
  if (!netproxy) {
    return;
  }

  this.server.eachProxy(function(name, proxy) {
    var reqWrap = {
      getCookie: this.request.getCookie
    };
    var resWrap = {
      getCookie: this.request.getCookie,
      setCookie: this.request.setCookie
    };

    var apiRequest;
    netproxy.__register__(name, {
      modifyRequest: (function(apiRequest_) {
        apiRequest = apiRequest_;
        try {
          proxy.modifyRequest(reqWrap, apiRequest);
        } catch(e) {
          this.error(502, 'Proxy modifyRequest error.', e);
        }
      }).bind(this),
      modifyResponse: (function(apiResponse) {
        try {
          proxy.modifyResponse(apiRequest, apiResponse, resWrap);
        } catch(e) {
          this.error(502, 'Proxy modifyResponse error.', e);
        }
      }).bind(this)
    }, this);
  }, this);
};

ControllerServer.prototype.setupNet_ = function() {
  var net = this.resources.objectsByModulePath[NET_SERVER_MODULE];
  if (!net) {
    return;
  }

  net.__setErrorHandler__((function(e) {
    this.error(502, 'Net error.', e);
  }).bind(this));
};

ControllerServer.prototype.serve = function(onResponse, opt_context) {
  this.onResponse_ = onResponse.bind(opt_context);

  var ControllerKlass = this.resources.objectsByModulePath[this.module.modulePath];
  if (!ControllerKlass || !ControllerKlass.__controller__) {
    this.error(404, this.module.modulePath + ' is not a controller. Use Controller.create({}) to define your controller.');
    return;
  }

  var requestWrap = {
    url: this.request.url,
    params: this.request.params,
    query: this.request.query,
  };
  this.controller = new ControllerKlass(requestWrap);

  var controllersToLoadInOrder = [];
  var CurrentControllerKlass = ControllerKlass;
  while (CurrentControllerKlass) {
    controllersToLoadInOrder.unshift(CurrentControllerKlass);
    CurrentControllerKlass = CurrentControllerKlass.__parent__;
  }

  var allControllerArgs = [];

  var loadNext = (function() {
    var CurrentControllerKlass = controllersToLoadInOrder.shift();
    if (!CurrentControllerKlass) {
      this.render(ControllerKlass, allControllerArgs);
      return;
    }

    this.preloadController(CurrentControllerKlass, function(controllerArgs) {
      allControllerArgs.push(controllerArgs);
      loadNext();
    });
  }).bind(this);

  loadNext();
};

ControllerServer.prototype.preloadTimedOut = function() {
  this.error(502, 'Preload never finished; call the function passed to __preload__ when finished loading.');
};

ControllerServer.prototype.preloadController = function(ControllerKlass, onComplete) {
  var navigation = this.resources.objectsByModulePath[NAVIGATION_MODULE];
  if (navigation) {
    navigation.__reset__(this.request.url, this.request.headers['user-agent']);
  }

  var hasPreload = ControllerKlass.prototype.hasOwnProperty('__preload__');
  var preload = ControllerKlass.prototype.__preload__;
  if (!hasPreload) {
    preload = function defaultPreload(f) { f(); };
  }

  var timeout = setTimeout(this.preloadTimedOut.bind(this), 10000.0);

  var preloadComplete = (function(var_args) {
    clearTimeout(timeout);

    if (this.isDone()) {
      return;
    }

    if (navigation) {
      if (navigation.__notfound__()) {
        this.error(404, 'Resource not found at this path.');
        return;
      }

      var redirectUrl = navigation.__redirect__();
      if (redirectUrl) {
        this.navigate(redirectUrl);
        return;
      }
    }

    var controllerArgs = Array.prototype.slice.call(arguments);

    var hasLoad = ControllerKlass.prototype.hasOwnProperty('__load__');
    var load = hasLoad ? ControllerKlass.prototype.__load__ : function defaultLoad() {};
    load.apply(this.controller, controllerArgs);

    onComplete(controllerArgs);
  }).bind(this);

  try {
    preload.call(this.controller, preloadComplete);
  } catch (e) {
    clearTimeout(timeout);
    this.error(502, 'Error during preload.', e);
  }
};

ControllerServer.prototype.render = function(ControllerKlass, allControllerArgs) {
  try {
    var title = this.controller.getFullTitle();
    var meta = this.controller.getFullMeta();
    var body = this.controller.renderFullBody();
  } catch (e) {
    this.error(500, 'Error rendering content.', e);
    return;
  }

  var cssUrls = this.resources.cssResources.map(function(resource) {
    return this.server.getResourceUrl(resource);
  }, this);
  cssUrls = util.unique(cssUrls);

  var scripts = this.resources.scriptResources;
  var scriptUrls = scripts.map(function(resource) {
    if (!resource.includeInEnvironment(TargetEnvironment.BROWSER)) {
      // continue
      return null;
    }
    return this.server.getResourceUrl(resource);
  }, this);
  scriptUrls = util.unique(scriptUrls.filter(function(url) { return !!url; }));

  var clientProxyObjects = [];
  this.server.eachProxy(function(name, proxy) {
    clientProxyObjects.push({
      name: name,
      csrfToken: proxy.generateCSRF(this.request)
    });
  }, this);

  var controllerModuleResourcePath = scripts[scripts.length - 1].modulePath;
  var html = BOOTSTRAP_TEMPLATE({
    title: title,
    meta: meta,
    body: body,
    currentUrlAfterRedirect: this.request.originalUrl !== this.request.url ? this.request.url : null,

    cssUrls: cssUrls,
    scriptUrls: scriptUrls,

    netproxyModulePath: PROXY_RESOURCE,
    clientProxyObjects: clientProxyObjects,

    requestWrap: this.controller.request,
    controllerModulePath: controllerModuleResourcePath,
    allControllerArgs: allControllerArgs
  });

  // TODO(taylor): Render CSS before the preload is done.
  this.finish(200, {'Content-Type': 'text/html; charset=utf-8'}, html);
};

module.exports = ControllerServer;
<commit_msg>Include host in request so we can look at where we are.<commit_after>'use strict';

/**
 * @license
 * (c) 2014 Cluster Labs, Inc. https://cluster.co/
 * License: MIT
 */

var fs = require('fs');

var Handlebars = require('handlebars');

var loader = require('./loader/loader');
var scriptresource = require('./loader/scriptresource');
var util = require('./util');

var TargetEnvironment = scriptresource.TargetEnvironment;

Handlebars.registerHelper('json', function(arg) {
  return new Handlebars.SafeString(util.safeJSONStringify(arg));
});

var BOOTSTRAP_TEMPLATE = (function() {
  var templateSource = fs.readFileSync(__dirname + '/bootstrap.html').toString();
  return Handlebars.compile(templateSource);
})();

var NET_SERVER_MODULE = 'skit.platform.net:server';
var NAVIGATION_MODULE = 'skit.platform.navigation';
var PROXY_MODULE = 'skit.platform.netproxy';
var PROXY_RESOURCE = PROXY_MODULE + ':js';

function ControllerServer(server, controllerModule, request) {
  this.server = server;
  this.module = controllerModule;
  this.resources = loader.loadResourcesForModule(controllerModule);
  this.request = request;

  this.code = null;
  this.responseHeaders = {};
  this.responseBody = null;
  this.exception = null;
  this.errorMessage = null;
  this.redirectUrl = null;

  this.setupProxies_();
  this.setupNet_();
};

ControllerServer.prototype.isDone = function() {
  return this.code !== null;
};

ControllerServer.prototype.maybeFinish = function() {
  if (this.isDone() && this.onResponse_) {
    this.onResponse_();
  }
};

ControllerServer.prototype.error = function(code, message, exception) {
  if (this.isDone()) {
    return;
  }

  this.code = code;
  this.errorMessage = message;
  this.exception = exception;

  this.maybeFinish();
};
ControllerServer.prototype.navigate = function(toUrl) {
  if (this.isDone()) {
    return;
  }

  this.code = 302;
  this.redirectUrl = toUrl;

  this.maybeFinish();
};
ControllerServer.prototype.finish = function(code, headers, body) {
  if (this.isDone()) {
    return;
  }

  this.code = 200;
  this.responseHeaders = headers;
  this.responseBody = body;

  this.maybeFinish();
};

ControllerServer.prototype.setupProxies_ = function() {
  var netproxy = this.resources.objectsByModulePath[PROXY_MODULE];
  if (!netproxy) {
    return;
  }

  this.server.eachProxy(function(name, proxy) {
    var reqWrap = {
      getCookie: this.request.getCookie
    };
    var resWrap = {
      getCookie: this.request.getCookie,
      setCookie: this.request.setCookie
    };

    var apiRequest;
    netproxy.__register__(name, {
      modifyRequest: (function(apiRequest_) {
        apiRequest = apiRequest_;
        try {
          proxy.modifyRequest(reqWrap, apiRequest);
        } catch(e) {
          this.error(502, 'Proxy modifyRequest error.', e);
        }
      }).bind(this),
      modifyResponse: (function(apiResponse) {
        try {
          proxy.modifyResponse(apiRequest, apiResponse, resWrap);
        } catch(e) {
          this.error(502, 'Proxy modifyResponse error.', e);
        }
      }).bind(this)
    }, this);
  }, this);
};

ControllerServer.prototype.setupNet_ = function() {
  var net = this.resources.objectsByModulePath[NET_SERVER_MODULE];
  if (!net) {
    return;
  }

  net.__setErrorHandler__((function(e) {
    this.error(502, 'Net error.', e);
  }).bind(this));
};

ControllerServer.prototype.serve = function(onResponse, opt_context) {
  this.onResponse_ = onResponse.bind(opt_context);

  var ControllerKlass = this.resources.objectsByModulePath[this.module.modulePath];
  if (!ControllerKlass || !ControllerKlass.__controller__) {
    this.error(404, this.module.modulePath + ' is not a controller. Use Controller.create({}) to define your controller.');
    return;
  }

  var requestWrap = {
    url: this.request.url,
    params: this.request.params,
    query: this.request.query,
    host: this.request.headers['host'],
  };
  this.controller = new ControllerKlass(requestWrap);

  var controllersToLoadInOrder = [];
  var CurrentControllerKlass = ControllerKlass;
  while (CurrentControllerKlass) {
    controllersToLoadInOrder.unshift(CurrentControllerKlass);
    CurrentControllerKlass = CurrentControllerKlass.__parent__;
  }

  var allControllerArgs = [];

  var loadNext = (function() {
    var CurrentControllerKlass = controllersToLoadInOrder.shift();
    if (!CurrentControllerKlass) {
      this.render(ControllerKlass, allControllerArgs);
      return;
    }

    this.preloadController(CurrentControllerKlass, function(controllerArgs) {
      allControllerArgs.push(controllerArgs);
      loadNext();
    });
  }).bind(this);

  loadNext();
};

ControllerServer.prototype.preloadTimedOut = function() {
  this.error(502, 'Preload never finished; call the function passed to __preload__ when finished loading.');
};

ControllerServer.prototype.preloadController = function(ControllerKlass, onComplete) {
  var navigation = this.resources.objectsByModulePath[NAVIGATION_MODULE];
  if (navigation) {
    navigation.__reset__(this.request.url, this.request.headers['user-agent']);
  }

  var hasPreload = ControllerKlass.prototype.hasOwnProperty('__preload__');
  var preload = ControllerKlass.prototype.__preload__;
  if (!hasPreload) {
    preload = function defaultPreload(f) { f(); };
  }

  var timeout = setTimeout(this.preloadTimedOut.bind(this), 10000.0);

  var preloadComplete = (function(var_args) {
    clearTimeout(timeout);

    if (this.isDone()) {
      return;
    }

    if (navigation) {
      if (navigation.__notfound__()) {
        this.error(404, 'Resource not found at this path.');
        return;
      }

      var redirectUrl = navigation.__redirect__();
      if (redirectUrl) {
        this.navigate(redirectUrl);
        return;
      }
    }

    var controllerArgs = Array.prototype.slice.call(arguments);

    var hasLoad = ControllerKlass.prototype.hasOwnProperty('__load__');
    var load = hasLoad ? ControllerKlass.prototype.__load__ : function defaultLoad() {};
    load.apply(this.controller, controllerArgs);

    onComplete(controllerArgs);
  }).bind(this);

  try {
    preload.call(this.controller, preloadComplete);
  } catch (e) {
    clearTimeout(timeout);
    this.error(502, 'Error during preload.', e);
  }
};

ControllerServer.prototype.render = function(ControllerKlass, allControllerArgs) {
  try {
    var title = this.controller.getFullTitle();
    var meta = this.controller.getFullMeta();
    var body = this.controller.renderFullBody();
  } catch (e) {
    this.error(500, 'Error rendering content.', e);
    return;
  }

  var cssUrls = this.resources.cssResources.map(function(resource) {
    return this.server.getResourceUrl(resource);
  }, this);
  cssUrls = util.unique(cssUrls);

  var scripts = this.resources.scriptResources;
  var scriptUrls = scripts.map(function(resource) {
    if (!resource.includeInEnvironment(TargetEnvironment.BROWSER)) {
      // continue
      return null;
    }
    return this.server.getResourceUrl(resource);
  }, this);
  scriptUrls = util.unique(scriptUrls.filter(function(url) { return !!url; }));

  var clientProxyObjects = [];
  this.server.eachProxy(function(name, proxy) {
    clientProxyObjects.push({
      name: name,
      csrfToken: proxy.generateCSRF(this.request)
    });
  }, this);

  var controllerModuleResourcePath = scripts[scripts.length - 1].modulePath;
  var html = BOOTSTRAP_TEMPLATE({
    title: title,
    meta: meta,
    body: body,
    currentUrlAfterRedirect: this.request.originalUrl !== this.request.url ? this.request.url : null,

    cssUrls: cssUrls,
    scriptUrls: scriptUrls,

    netproxyModulePath: PROXY_RESOURCE,
    clientProxyObjects: clientProxyObjects,

    requestWrap: this.controller.request,
    controllerModulePath: controllerModuleResourcePath,
    allControllerArgs: allControllerArgs
  });

  // TODO(taylor): Render CSS before the preload is done.
  this.finish(200, {'Content-Type': 'text/html; charset=utf-8'}, html);
};

module.exports = ControllerServer;
<|endoftext|>


<commit_before>var DeviceConfiguration = (function(){
    var identity = Date.now();
    var currentDevice = "browser";
    var orientation = "landscape";
    var returnCurrentDeviceFunction = function(){
        return currentDevice;
    };
    var allowedToHideHeader = false;
    // the default states of the various sections
    var sectionsVisible = {//All false because the application's start state is the search screen.  onHistory will restore them.
        tools:false,
        slides:false,
        header:false
    };
    var setSectionVisibility = function(section,visible){
        if (currentDevice != "projector"){
            if ((allowedToHideHeader || section != "header") && (visible == true || visible == false)){
                sectionsVisible[section] = visible;
            }
        }
    };
    var alterCurrentDeviceFunction = function(newDevice){
        currentDevice = newDevice;
        actOnCurrentDevice();
    };
    var tryToDetermineCurrentDevice = function(){
        if ((navigator.userAgent.match(/iPhone/i) != null) || (navigator.userAgent.match(/iPod/i) != null)) {
            currentDevice = "iPhone";
        } else if (navigator.userAgent.match(/iPad/i) != null){
            currentDevice = "iPad";
        } else {
            currentDevice = "browser";
        }
    };
    var setDefaultOptions = function(){
        tryToDetermineCurrentDevice();
        $("#absoluteCloseButton").removeClass("closeButton").text("").click(bounceAnd(function(){}));
        $("#applicationMenuButton").show();
        fitFunction = defaultFitFunction;
        zoomToPage();
        fitFunction();
    };
    var setProjectorOptions = function(){
        Conversations.enableSyncMove();
        UserSettings.setIsInteractive(false);
        currentDevice = "projector";
        fitFunction = projectorFitFunction;
        zoomToFit();
        $("#absoluteCloseButton").addClass("closeButton").text("X").click(bounceAnd(function(){
            UserSettings.setIsInteractive(true);
            DeviceConfiguration.setHeader(true);
            DeviceConfiguration.setTools(true);
            DeviceConfiguration.setSlides(true);
            setDefaultOptions();
        }));
        $("#applicationMenuButton").hide();
        Modes.none.activate();
        fitFunction();
    };
    var setIPhoneOptions = function(){
        setDefaultOptions();
    };
    var setIPadOptions = function(){
        setDefaultOptions();
    };
    var getDeviceDimensions = function(){
        var deviceHeight = 0;
        var deviceWidth = 0;
        var matchMetaTag = function(metaName,metaValue){
            return (navigator.standalone && _.any(_.filter(document.getElementsByTagName("meta"),function(i){return i.name.toLowerCase().trim() == metaName.toLowerCase().trim();}),function(i){return i.content.toLowerCase().trim() == metaValue.toLowerCase().trim();}));
        }
        switch (currentDevice){
        case "iPhone":
            deviceHeight += screen.height;
            deviceWidth += screen.width;
            if (window.orientation && (window.orientation == 90 || window.orientation == 270 || window.orientation == -90 || window.orientation == -270)){
                orientation = "landscape";
                var temp = deviceHeight;
                deviceHeight = deviceWidth;
                deviceWidth = temp;
            } else if (window.orientation && (window.orientation == 0 || window.orientation == 180 || window.orientation == -180 || window.orientation == 360 || window.orientation == -360)){
                orientation = "portrait";
            }
            if (!(matchMetaTag("apple-mobile-web-app-capable","yes"))){
                if (window.innerHeight > window.innerWidth){
                    deviceHeight -= 44;
                }       else {
                    deviceHeight -= 32;
                }
            }
            if (!(matchMetaTag("apple-mobile-web-app-status-bar-style","black-translucent"))){
                deviceHeight -= 20;
            }
            // as additional gesture wiggle-room
            deviceHeight -= 20;
            break;
        case "iPad":
            deviceHeight += screen.height;
            deviceWidth += screen.width;
            if (window.orientation && (window.orientation == 90 || window.orientation == 270 || window.orientation == -90 || window.orientation == -270)){
                orientation = "landscape";
                var temp = deviceHeight;
                deviceHeight = deviceWidth;
                deviceWidth = temp;
            } else if (window.orientation && (window.orientation == 0 || window.orientation == 180 || window.orientation == -180 || window.orientation == 360 || window.orientation == -360)){
                orientation = "portrait";
            }
            if (window.innerHeight == 768 && window.innerWidth == 1024){
                orientation = "landscape";
            } else if (window.innerWidth == 768 && window.innerHeight == 1024){
                orientation = "portrait";
            }
            if (!(matchMetaTag("apple-mobile-web-app-capable","yes"))){
                deviceHeight -= 58;
                // as additional gesture wiggle-room
                deviceHeight -= 20;
            }
            if (!(matchMetaTag("apple-mobile-web-app-status-bar-style","black-translucent"))){
                deviceHeight -= 20;
            }
            break;
        default:
            deviceHeight = window.innerHeight;
            deviceWidth = window.innerWidth;
            break;
        }
        return {height:deviceHeight,width:deviceWidth};
    };
    var defaultFitFunction = function(){customizableFitFunction(sectionsVisible.header,sectionsVisible.tools,sectionsVisible.slides);};
    var fitFunction = defaultFitFunction;
    var projectorFitFunction = function(){customizableFitFunction(false,false,false);};
    var customizableFitFunction = function(showHeader,showTools,showSlides){
        var toolsColumn = $("#toolsColumn");
        var tools = $("#ribbon").find(".toolbar");
        var subTools = $(".modeSpecificTool");

        var boardHeader = $("#boardHeader");
        var applicationMenu = $("#applicationMenu");
        var container = $("#boardContainer");

        var thumbsColumn = $("#thumbsColumn");
        var slideContainer = $("#slideContainer");
        var thumbScrollContainer = $("#thumbScrollContainer");
        var thumbs = $(".thumbnail");

        var deviceDimensions = getDeviceDimensions();
        var width = deviceDimensions.width;

        try{
            var performRemeasure = function(){
                var toolSize = 0;
                var subSize = 0;
                var subSizeOffset = 0;
                var toolWidth = 0;
                var preferredToolModeSize = parseInt(UserSettings.getUserPref("toolModeSize"));
                var xOffset = 0;
                var yOffset = 0;

                if (showHeader == true){
                    boardHeader.show();
                    //boardHeader.width(width);
                    applicationMenu.show();
                    //applicationMenu.width(preferredToolModeSize);
                } else {
                    //boardHeader.width(0);
                    //applicationMenu.width(0);
                    applicationMenu.hide();
                    boardHeader.hide();
                }

                var height = deviceDimensions.height - $(".shrinkWrappedRow").height();
                if (showTools == true){
                    toolSize = preferredToolModeSize;
                    subSize = parseInt(UserSettings.getUserPref("subModeSize"));
                    subSizeOffset = 10; //Woo!  Magic number!  It's the left offset of the submode button
                    toolWidth = Math.max(toolSize,subSize + subSizeOffset);
                    //toolsColumn.width(toolWidth).css("max-width",px(208)).height(height);
                    tools.show();
										subTools.show();
                    //subTools.height(subSize).css("min-width",px(toolWidth - subSizeOffset)).show();
                    toolsColumn.show();
                } else {
                    xOffset += 4;
                    //subTools.height(0).css("min-width",px(0));
                    subTools.hide();
                    tools.hide();
                    //toolsColumn.width(0).height(0);
                    toolsColumn.hide();
                }
								/*
                var thumbWidth = 0;
                var thumbHeight = 0;
								*/
                if (showSlides == true){
                    thumbsColumn.show();
										/*
                    thumbWidth = parseInt(UserSettings.getUserPref("thumbnailSize"));
                    thumbHeight = thumbWidth * 0.75;
										*/
                } else {
                    //xOffset += 4;
                    thumbsColumn.hide();
                }
								/*
                var thumbScrollOffset = 35;
                var thumbContainerWidth = thumbWidth;
                if (thumbWidth > 0){
                    thumbContainerWidth = thumbContainerWidth + thumbScrollOffset;
                }
								*/
								/*
                thumbsColumn.width(thumbContainerWidth).height(height).css("display","block");
                thumbScrollContainer.width(thumbContainerWidth).height(height);
                slideContainer.width(thumbContainerWidth).height(height);
                $(".slideButtonContainer").width(thumbWidth).height(thumbHeight).css("margin",px(10));
                thumbs.width(thumbWidth).height(thumbHeight);
                $("#addSlideButton").css("margin",px(10));
								*/
                var gestureWiggleRoomWidth = 0; // magic number to create a bit of wiggle room for the gestures
                var gestureWiggleRoomHeight = 0; // magic number to create a bit of wiggle room for the gesture
                if (currentDevice != "projector"){
                    gestureWiggleRoomHeight = 15;
                    height -= yOffset / 2;
                    width -= xOffset;
                }
/*
                $("#masterLayout").height(height).width(width).css({
                    "margin-left":px(xOffset / 2),
                    "margin-top":px(yOffset / 2)
                });
*/
                var actualToolsWidth = toolsColumn.width();
                var actualThumbsWidth = thumbsColumn.width();
                var padding = 0;
                var containerWidth = width - (actualToolsWidth + actualThumbsWidth + gestureWiggleRoomWidth);
                var containerHeight = height - gestureWiggleRoomHeight;
                $("#notices").height(gestureWiggleRoomHeight);
                var container = $("#boardContainer");

                //$("#boardColumn").width(containerWidth).height(containerHeight);
                //container.width(containerWidth).height(containerHeight);
								/*
                board.attr("width",px(containerWidth - padding));
                board.attr("height",px(containerHeight - padding));
                board.width(containerWidth - padding);
                board.height(containerHeight - padding);
								*/
                boardWidth = containerWidth - padding;
                boardHeight = containerHeight - padding;
								/*
                if ("documentElement" in document){
                    $(document.documentElement).width(deviceDimensions.width).css("min-width",deviceDimensions.width).css("max-width",deviceDimensions.width).height(deviceDimensions.height).css("min-height",deviceDimensions.height).css("max-height",deviceDimensions.height);
                }
                $(document.body).width(deviceDimensions.width).css("min-width",deviceDimensions.width).css("max-width",deviceDimensions.width).height(deviceDimensions.height).css("min-height",deviceDimensions.height).css("max-height",deviceDimensions.height);
                $(document).width(deviceDimensions.width).css("min-width",deviceDimensions.width).css("max-width",deviceDimensions.width).height(deviceDimensions.height).css("min-height",deviceDimensions.height).css("max-height",deviceDimensions.height);
								*/
            }
            performRemeasure();
            //performRemeasure();
            IncludeView.default();
        }
        catch(e){
            console.log("exception in fit",e);
        }
        window.scrollTo(1,1);
        window.scrollTo(0,0);
    };
    var innerFit = function(){
        if (fitFunction){
            fitFunction();
        }
    }
    var outerFit = function(){
        innerFit();
        //                      _.throttle(_.debounce(innerFit,150,false),100)();
    };
    var initialized = false;
    Progress.onLayoutUpdated["DeviceConfiguration"] = outerFit;
    Progress.historyReceived.DeviceConfiguration_showChrome = function(){
        try{
            if(UserSettings.getIsInteractive()){
                DeviceConfiguration.setSlides(true);
                DeviceConfiguration.setTools(true);
                if(!initialized){
                    Modes.draw.activate();
                    if(DeviceConfiguration.getCurrentDevice() == "iPad"){
                        $("#panMode").remove();
                    }
                }
            }
            else{
                DeviceConfiguration.setSlides(false);
                DeviceConfiguration.setTools(false);
                if(!initialized){
                    Modes.none.activate();
                }
            }
            initialized = true;
        }
        catch(e){
            console.log("Progress.historyRedceived.DeviceConfiguration_showChrome",e);
        }
    }

    $(function(){
        // set up orientation and resize handlers
        var w = $(window);
        if (window.orientation){
            w.on("orientationchange",outerFit);
        }
        w.resize(outerFit);
        /* $.get(
         //this is a quick and dirty workaround to ensure that the devices log their useragent in a stateful manner on lift's end
         "/logDevice",
         {},
         function(data){
         }
         );
         */
        $("#toolsToggleButton").on("click",bounceAnd(function(){
            setSectionVisibility("tools",!sectionsVisible.tools);
            outerFit();
        }));
        $("#slidesToggleButton").on("click",bounceAnd(function(){
            setSectionVisibility("slides",!sectionsVisible.slides);
            outerFit();
        }));
    });
    var actOnCurrentDevice = function(){
        switch (currentDevice){
        case "browser":
            setDefaultOptions();
            break;
        case "projector":
            setProjectorOptions();
            break;
        case "iPhone":
            setIPhoneOptions();
            break;
        case "iPad":
            setIPadOptions();
            break;
        default:
            setDefaultOptions();
            break;
        }
    };
    var defaultFitIfMissing = function(){
        if(!fitFunction){
            fitFunction = defaultFitFunction;
        }
    }
    var sectionToggler = function(section){
        return function(){
            setSectionVisibility(section,!sectionsVisible[section]);
            defaultFitIfMissing();
        };
    }
    var sectionSetter = function(section){
        return function(state){
            setSectionVisibility(section,state);
            defaultFitIfMissing();
        }
    }
    return {
        getCurrentDevice:returnCurrentDeviceFunction,
        setCurrentDevice:alterCurrentDeviceFunction,
        applyFit:function(){
            defaultFitIfMissing();
            fitFunction();
        },
        tempFit:function(showHeader,showTools,showSlides){
            setSectionVisibility("header",showHeader);
            setSectionVisibility("tools",showTools);
            setSectionVisibility("slides",showSlides);
            defaultFitIfMissing();
            fitFunction();
        },
        setHeader:sectionSetter("header"),
        setTools:sectionSetter("tools"),
        setSlides:sectionSetter("slides"),
        toggleHeader:sectionToggler("header"),
        toggleTools:sectionToggler("tools"),
        toggleSlides:sectionToggler("slides"),
        getIdentity:function(){
            return identity;
        },
        resetCurrentDevice:function(){
            tryToDetermineCurrentDevice();
            actOnCurrentDevice();
        }
    };
})();
<commit_msg>further tweaks to positioning and sizing from deviceConfiguration<commit_after>var DeviceConfiguration = (function(){
    var identity = Date.now();
    var currentDevice = "browser";
    var orientation = "landscape";
    var returnCurrentDeviceFunction = function(){
        return currentDevice;
    };
    var allowedToHideHeader = false;
    // the default states of the various sections
    var sectionsVisible = {//All false because the application's start state is the search screen.  onHistory will restore them.
        tools:false,
        slides:false,
        header:false
    };
    var setSectionVisibility = function(section,visible){
        if (currentDevice != "projector"){
            if ((allowedToHideHeader || section != "header") && (visible == true || visible == false)){
                sectionsVisible[section] = visible;
            }
        }
    };
    var alterCurrentDeviceFunction = function(newDevice){
        currentDevice = newDevice;
        actOnCurrentDevice();
    };
    var tryToDetermineCurrentDevice = function(){
        if ((navigator.userAgent.match(/iPhone/i) != null) || (navigator.userAgent.match(/iPod/i) != null)) {
            currentDevice = "iPhone";
        } else if (navigator.userAgent.match(/iPad/i) != null){
            currentDevice = "iPad";
        } else {
            currentDevice = "browser";
        }
    };
    var setDefaultOptions = function(){
        tryToDetermineCurrentDevice();
        $("#absoluteCloseButton").removeClass("closeButton").text("").click(bounceAnd(function(){}));
        $("#applicationMenuButton").show();
        fitFunction = defaultFitFunction;
        zoomToPage();
        fitFunction();
    };
    var setProjectorOptions = function(){
        Conversations.enableSyncMove();
        UserSettings.setIsInteractive(false);
        currentDevice = "projector";
        fitFunction = projectorFitFunction;
        zoomToFit();
        $("#absoluteCloseButton").addClass("closeButton").text("X").click(bounceAnd(function(){
            UserSettings.setIsInteractive(true);
            DeviceConfiguration.setHeader(true);
            DeviceConfiguration.setTools(true);
            DeviceConfiguration.setSlides(true);
            setDefaultOptions();
        }));
        $("#applicationMenuButton").hide();
        Modes.none.activate();
        fitFunction();
    };
    var setIPhoneOptions = function(){
        setDefaultOptions();
    };
    var setIPadOptions = function(){
        setDefaultOptions();
    };
    var getDeviceDimensions = function(){
        var deviceHeight = 0;
        var deviceWidth = 0;
        var matchMetaTag = function(metaName,metaValue){
            return (navigator.standalone && _.any(_.filter(document.getElementsByTagName("meta"),function(i){return i.name.toLowerCase().trim() == metaName.toLowerCase().trim();}),function(i){return i.content.toLowerCase().trim() == metaValue.toLowerCase().trim();}));
        }
        switch (currentDevice){
        case "iPhone":
            deviceHeight += screen.height;
            deviceWidth += screen.width;
            if (window.orientation && (window.orientation == 90 || window.orientation == 270 || window.orientation == -90 || window.orientation == -270)){
                orientation = "landscape";
                var temp = deviceHeight;
                deviceHeight = deviceWidth;
                deviceWidth = temp;
            } else if (window.orientation && (window.orientation == 0 || window.orientation == 180 || window.orientation == -180 || window.orientation == 360 || window.orientation == -360)){
                orientation = "portrait";
            }
            if (!(matchMetaTag("apple-mobile-web-app-capable","yes"))){
                if (window.innerHeight > window.innerWidth){
                    deviceHeight -= 44;
                }       else {
                    deviceHeight -= 32;
                }
            }
            if (!(matchMetaTag("apple-mobile-web-app-status-bar-style","black-translucent"))){
                deviceHeight -= 20;
            }
            // as additional gesture wiggle-room
            deviceHeight -= 20;
            break;
        case "iPad":
            deviceHeight += screen.height;
            deviceWidth += screen.width;
            if (window.orientation && (window.orientation == 90 || window.orientation == 270 || window.orientation == -90 || window.orientation == -270)){
                orientation = "landscape";
                var temp = deviceHeight;
                deviceHeight = deviceWidth;
                deviceWidth = temp;
            } else if (window.orientation && (window.orientation == 0 || window.orientation == 180 || window.orientation == -180 || window.orientation == 360 || window.orientation == -360)){
                orientation = "portrait";
            }
            if (window.innerHeight == 768 && window.innerWidth == 1024){
                orientation = "landscape";
            } else if (window.innerWidth == 768 && window.innerHeight == 1024){
                orientation = "portrait";
            }
            if (!(matchMetaTag("apple-mobile-web-app-capable","yes"))){
                deviceHeight -= 58;
                // as additional gesture wiggle-room
                deviceHeight -= 20;
            }
            if (!(matchMetaTag("apple-mobile-web-app-status-bar-style","black-translucent"))){
                deviceHeight -= 20;
            }
            break;
        default:
            deviceHeight = window.innerHeight;
            deviceWidth = window.innerWidth;
            break;
        }
        return {height:deviceHeight,width:deviceWidth};
    };
    var defaultFitFunction = function(){customizableFitFunction(sectionsVisible.header,sectionsVisible.tools,sectionsVisible.slides);};
    var fitFunction = defaultFitFunction;
    var projectorFitFunction = function(){customizableFitFunction(false,false,false);};
    var customizableFitFunction = function(showHeader,showTools,showSlides){
        var toolsColumn = $("#toolsColumn");
        var tools = $("#ribbon").find(".toolbar");
        var subTools = $(".modeSpecificTool");

        var boardHeader = $("#boardHeader");
        var applicationMenu = $("#applicationMenu");
        var container = $("#boardContainer");

        var thumbsColumn = $("#thumbsColumn");
        var slideContainer = $("#slideContainer");
        var thumbScrollContainer = $("#thumbScrollContainer");
        var thumbs = $(".thumbnail");

        var deviceDimensions = getDeviceDimensions();
        var width = deviceDimensions.width;
				var height = deviceDimensions.height;// - $(".shrinkWrappedRow").height();
        try{
            var performRemeasure = function(){
                var toolSize = 0;
                var subSize = 0;
                var subSizeOffset = 0;
                var toolWidth = 0;
                var preferredToolModeSize = parseInt(UserSettings.getUserPref("toolModeSize"));
                var xOffset = 0;
                var yOffset = 0;

                if (showHeader == true){
                    boardHeader.show();
                    //boardHeader.width(width);
                    applicationMenu.show();
                    //applicationMenu.width(preferredToolModeSize);
                } else {
                    //boardHeader.width(0);
                    //applicationMenu.width(0);
                    applicationMenu.hide();
                    boardHeader.hide();
                }

                //var height = deviceDimensions.height - $(".shrinkWrappedRow").height();
                if (showTools == true){
                    ///toolSize = preferredToolModeSize;
                    //subSize = parseInt(UserSettings.getUserPref("subModeSize"));
                    //subSizeOffset = 10; //Woo!  Magic number!  It's the left offset of the submode button
                    //toolWidth = Math.max(toolSize,subSize + subSizeOffset);
                    //toolsColumn.width(toolWidth).css("max-width",px(208)).height(height);
                    tools.show();
										subTools.show();
                    //subTools.height(subSize).css("min-width",px(toolWidth - subSizeOffset)).show();
                    toolsColumn.show();
                } else {
                    //xOffset += 4;
                    //subTools.height(0).css("min-width",px(0));
                    subTools.hide();
                    tools.hide();
                    //toolsColumn.width(0).height(0);
                    toolsColumn.hide();
                }
								/*
                var thumbWidth = 0;
                var thumbHeight = 0;
								*/
                if (showSlides == true){
                    thumbsColumn.show();
										/*
                    thumbWidth = parseInt(UserSettings.getUserPref("thumbnailSize"));
                    thumbHeight = thumbWidth * 0.75;
										*/
                } else {
                    //xOffset += 4;
                    thumbsColumn.hide();
                }
								/*
                var thumbScrollOffset = 35;
                var thumbContainerWidth = thumbWidth;
                if (thumbWidth > 0){
                    thumbContainerWidth = thumbContainerWidth + thumbScrollOffset;
                }
								*/
								/*
                thumbsColumn.width(thumbContainerWidth).height(height).css("display","block");
                thumbScrollContainer.width(thumbContainerWidth).height(height);
                slideContainer.width(thumbContainerWidth).height(height);
                $(".slideButtonContainer").width(thumbWidth).height(thumbHeight).css("margin",px(10));
                thumbs.width(thumbWidth).height(thumbHeight);
                $("#addSlideButton").css("margin",px(10));
								*/
                //var gestureWiggleRoomWidth = 0; // magic number to create a bit of wiggle room for the gestures
                //var gestureWiggleRoomHeight = 0; // magic number to create a bit of wiggle room for the gesture
								/*
                if (currentDevice != "projector"){
                    gestureWiggleRoomHeight = 15;
                    height -= yOffset / 2;
                    width -= xOffset;
                }
								*/
/*
                $("#masterLayout").height(height).width(width).css({
                    "margin-left":px(xOffset / 2),
                    "margin-top":px(yOffset / 2)
                });
*/
								//width = $("#masterLayout").width();
								//height = $("#masterLayout").height();
								/*
                var actualToolsWidth = toolsColumn.width();
                var actualThumbsWidth = thumbsColumn.width();
                var padding = 0;
                var containerWidth = width - (actualToolsWidth + actualThumbsWidth + gestureWiggleRoomWidth);
                var containerHeight = height - gestureWiggleRoomHeight;
                $("#notices").height(gestureWiggleRoomHeight);
                var container = $("#boardContainer");
*/
                //$("#boardColumn").width(containerWidth).height(containerHeight);
                //container.width(containerWidth).height(containerHeight);
								/*
                board.attr("width",px(containerWidth - padding));
                board.attr("height",px(containerHeight - padding));
                board.width(containerWidth - padding);
                board.height(containerHeight - padding);
								*/
								/*
                boardWidth = containerWidth - padding;
                boardHeight = containerHeight - padding;
*/
								var board = $("#board");
								boardWidth = board.width();
								boardHeight = board.height();
								/*
                if ("documentElement" in document){
                    $(document.documentElement).width(deviceDimensions.width).css("min-width",deviceDimensions.width).css("max-width",deviceDimensions.width).height(deviceDimensions.height).css("min-height",deviceDimensions.height).css("max-height",deviceDimensions.height);
                }
                $(document.body).width(deviceDimensions.width).css("min-width",deviceDimensions.width).css("max-width",deviceDimensions.width).height(deviceDimensions.height).css("min-height",deviceDimensions.height).css("max-height",deviceDimensions.height);
                $(document).width(deviceDimensions.width).css("min-width",deviceDimensions.width).css("max-width",deviceDimensions.width).height(deviceDimensions.height).css("min-height",deviceDimensions.height).css("max-height",deviceDimensions.height);
								*/
            }
            performRemeasure();
            //performRemeasure();
            IncludeView.default();
        }
        catch(e){
            console.log("exception in fit",e);
        }
        window.scrollTo(1,1);
        window.scrollTo(0,0);
    };
    var innerFit = function(){
        if (fitFunction){
            fitFunction();
        }
    }
    var outerFit = function(){
        innerFit();
        //                      _.throttle(_.debounce(innerFit,150,false),100)();
    };
    var initialized = false;
    Progress.onLayoutUpdated["DeviceConfiguration"] = outerFit;
    Progress.historyReceived.DeviceConfiguration_showChrome = function(){
        try{
            if(UserSettings.getIsInteractive()){
                DeviceConfiguration.setSlides(true);
                DeviceConfiguration.setTools(true);
                if(!initialized){
                    Modes.draw.activate();
                    if(DeviceConfiguration.getCurrentDevice() == "iPad"){
                        $("#panMode").remove();
                    }
                }
            }
            else{
                DeviceConfiguration.setSlides(false);
                DeviceConfiguration.setTools(false);
                if(!initialized){
                    Modes.none.activate();
                }
            }
            initialized = true;
        }
        catch(e){
            console.log("Progress.historyRedceived.DeviceConfiguration_showChrome",e);
        }
    }

    $(function(){
        // set up orientation and resize handlers
        var w = $(window);
        if (window.orientation){
            w.on("orientationchange",outerFit);
        }
        w.resize(outerFit);
        /* $.get(
         //this is a quick and dirty workaround to ensure that the devices log their useragent in a stateful manner on lift's end
         "/logDevice",
         {},
         function(data){
         }
         );
         */
        $("#toolsToggleButton").on("click",bounceAnd(function(){
            setSectionVisibility("tools",!sectionsVisible.tools);
            outerFit();
        }));
        $("#slidesToggleButton").on("click",bounceAnd(function(){
            setSectionVisibility("slides",!sectionsVisible.slides);
            outerFit();
        }));
    });
    var actOnCurrentDevice = function(){
        switch (currentDevice){
        case "browser":
            setDefaultOptions();
            break;
        case "projector":
            setProjectorOptions();
            break;
        case "iPhone":
            setIPhoneOptions();
            break;
        case "iPad":
            setIPadOptions();
            break;
        default:
            setDefaultOptions();
            break;
        }
    };
    var defaultFitIfMissing = function(){
        if(!fitFunction){
            fitFunction = defaultFitFunction;
        }
    }
    var sectionToggler = function(section){
        return function(){
            setSectionVisibility(section,!sectionsVisible[section]);
            defaultFitIfMissing();
        };
    }
    var sectionSetter = function(section){
        return function(state){
            setSectionVisibility(section,state);
            defaultFitIfMissing();
        }
    }
    return {
        getCurrentDevice:returnCurrentDeviceFunction,
        setCurrentDevice:alterCurrentDeviceFunction,
        applyFit:function(){
            defaultFitIfMissing();
            fitFunction();
        },
        tempFit:function(showHeader,showTools,showSlides){
            setSectionVisibility("header",showHeader);
            setSectionVisibility("tools",showTools);
            setSectionVisibility("slides",showSlides);
            defaultFitIfMissing();
            fitFunction();
        },
        setHeader:sectionSetter("header"),
        setTools:sectionSetter("tools"),
        setSlides:sectionSetter("slides"),
        toggleHeader:sectionToggler("header"),
        toggleTools:sectionToggler("tools"),
        toggleSlides:sectionToggler("slides"),
        getIdentity:function(){
            return identity;
        },
        resetCurrentDevice:function(){
            tryToDetermineCurrentDevice();
            actOnCurrentDevice();
        }
    };
})();
<|endoftext|>


<commit_before>export default {
  lang: 'pt-br',
  label: {
    clear: 'Limpar',
    ok: 'OK',
    cancel: 'Cancelar',
    close: 'Fechar',
    set: 'Escolher',
    select: 'Selecionar',
    reset: 'Redefinir',
    remove: 'Remover',
    update: 'Atualizar',
    create: 'Criar',
    search: 'Buscar',
    filter: 'Filtrar',
    refresh: 'Recarregar'
  },
  date: {
    days: 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),
    daysShort: 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
    months: 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
    monthsShort: 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
    firstDayOfWeek: 0, // 0-6, 0 - Sunday, 1 Monday, ...
    format24h: true
  },
  pullToRefresh: {
    pull: 'Puxe para recarregar',
    release: 'Solte para recarregar',
    refresh: 'Recarregando...'
  },
  table: {
    noData: 'Sem dados disponíveis',
    noResults: 'Nenhum dado correspondente encontrado',
    loading: 'Carregando...',
    selectedRecords: function (rows) {
      return rows > 0
        ? rows + ' linha' + (rows === 1 ? ' selecionada' : 's selecionadas') + '.'
        : 'Nenhuma linha selecionada.'
    },
    recordsPerPage: 'Linhas por página:',
    allRows: 'Todas',
    pagination: function (start, end, total) {
      return start + '-' + end + ' de ' + total
    },
    columns: 'Colunas'
  },
  editor: {
    url: 'URL',
    bold: 'Negrito',
    italic: 'Itálico',
    strikethrough: 'Riscado',
    underline: 'Sublinhado',
    unorderedList: 'Lista Não-ordenada',
    orderedList: 'Lista Ordenada',
    subscript: 'Subscrito',
    superscript: 'Sobrescrito',
    hyperlink: 'Hyperlink',
    toggleFullscreen: 'Tela Cheia',
    quote: 'Citação',
    left: 'Alinhado à esquerda',
    center: 'Alinhado ao centro',
    right: 'Alinhado à direita',
    justify: 'Justificado',
    print: 'Imprimir',
    outdent: 'Diminuir indentação',
    indent: 'Aumentar indentação',
    removeFormat: 'Remover formatação',
    formatting: 'Formatação',
    fontSize: 'Tamanho de Fonte',
    align: 'Alinhar',
    hr: 'Inserir Divisória Horizontal',
    undo: 'Desfazer',
    redo: 'Refazer',
    header1: 'Cabeçalho 1',
    header2: 'Cabeçalho 2',
    header3: 'Cabeçalho 3',
    header4: 'Cabeçalho 4',
    header5: 'Cabeçalho 5',
    header6: 'Cabeçalho 6',
    paragraph: 'Parágrafo',
    code: 'Código',
    size1: 'Muito pequeno',
    size2: 'Pequeno',
    size3: 'Normal',
    size4: 'Médio',
    size5: 'Grande',
    size6: 'Enorme',
    size7: 'Máximo',
    defaultFont: 'Fonte Padrão'
  },
  tree: {
    noNodes: 'Sem nós disponíveis',
    noResults: 'Nenhum nó correspondente encontrado'
  }
}
<commit_msg>Brazilian portuguese localization updates. (#2351)<commit_after>export default {
  lang: 'pt-br',
  label: {
    clear: 'Limpar',
    ok: 'OK',
    cancel: 'Cancelar',
    close: 'Fechar',
    set: 'Escolher',
    select: 'Selecionar',
    reset: 'Redefinir',
    remove: 'Remover',
    update: 'Atualizar',
    create: 'Criar',
    search: 'Buscar',
    filter: 'Filtrar',
    refresh: 'Recarregar'
  },
  date: {
    days: 'Domingo_Segunda-feira_Terça-feira_Quarta-feira_Quinta-feira_Sexta-feira_Sábado'.split('_'),
    daysShort: 'Dom_Seg_Ter_Qua_Qui_Sex_Sáb'.split('_'),
    months: 'Janeiro_Fevereiro_Março_Abril_Maio_Junho_Julho_Agosto_Setembro_Outubro_Novembro_Dezembro'.split('_'),
    monthsShort: 'Jan_Fev_Mar_Abr_Mai_Jun_Jul_Ago_Set_Out_Nov_Dez'.split('_'),
    firstDayOfWeek: 0, // 0-6, 0 - Sunday, 1 Monday, ...
    format24h: true
  },
  pullToRefresh: {
    pull: 'Puxe para recarregar',
    release: 'Solte para recarregar',
    refresh: 'Recarregando...'
  },
  table: {
    noData: 'Sem dados disponíveis',
    noResults: 'Nenhum dado correspondente encontrado',
    loading: 'Carregando...',
    selectedRecords: function (rows) {
      return rows > 0
        ? rows + ' registro' + (rows === 1 ? ' selecionado' : 's selecionados') + '.'
        : 'Nenhum registro selecionado.'
    },
    recordsPerPage: 'Registros por página:',
    allRows: 'Todos',
    pagination: function (start, end, total) {
      return start + '-' + end + ' de ' + total
    },
    columns: 'Colunas'
  },
  editor: {
    url: 'URL',
    bold: 'Negrito',
    italic: 'Itálico',
    strikethrough: 'Riscado',
    underline: 'Sublinhado',
    unorderedList: 'Lista não-ordenada',
    orderedList: 'Lista ordenada',
    subscript: 'Subscrito',
    superscript: 'Sobrescrito',
    hyperlink: 'Hyperlink',
    toggleFullscreen: 'Tela cheia',
    quote: 'Citação',
    left: 'Alinhado à esquerda',
    center: 'Alinhado ao centro',
    right: 'Alinhado à direita',
    justify: 'Justificado',
    print: 'Imprimir',
    outdent: 'Diminuir indentação',
    indent: 'Aumentar indentação',
    removeFormat: 'Remover formatação',
    formatting: 'Formatação',
    fontSize: 'Tamanho de fonte',
    align: 'Alinhar',
    hr: 'Inserir divisória horizontal',
    undo: 'Desfazer',
    redo: 'Refazer',
    header1: 'Cabeçalho 1',
    header2: 'Cabeçalho 2',
    header3: 'Cabeçalho 3',
    header4: 'Cabeçalho 4',
    header5: 'Cabeçalho 5',
    header6: 'Cabeçalho 6',
    paragraph: 'Parágrafo',
    code: 'Código',
    size1: 'Muito pequeno',
    size2: 'Pequeno',
    size3: 'Normal',
    size4: 'Médio',
    size5: 'Grande',
    size6: 'Enorme',
    size7: 'Máximo',
    defaultFont: 'Fonte padrão'
  },
  tree: {
    noNodes: 'Sem nós disponíveis',
    noResults: 'Nenhum nó correspondente encontrado'
  }
}
<|endoftext|>


<commit_before>const gitUsername = require('git-user-name')();
const resolve = require('resolve-dir');
const subdirs = require('subdirs');
const isGit = require('is-git');
const gitlog = require('gitlog');
const path = require('path');
const async = require("async");

/**
 * Go through all `repos` and look for subdirectories up to a given `depth`
 * and look for repositories.
 * Calls `callback` with array of repositories.
 */
function findGitRepos(repos, depth, callback) {
  let allRepos = [];
  async.each(repos, (repo, repoDone) => {
    repo = resolve(repo);
    subdirs(repo, depth, (err, dirs) => {
      if (err) {
        switch (err.code) {
          case 'ENOENT':
            return callback(`Could not open directory directory: ${err.path}\n`, null);
          case 'EACCES':
            return; //ignore if no access
          default:
            return callback(`Error "${err.code}" doing "${err.syscall}" on directory: ${err.path}\n`, null);
        }
      }
      if (dirs) dirs.push(repo);
      async.each(dirs, (dir, dirDone) => {
        isGit(dir, (err, isGit) => {
          if (err) {
            return callback(err, null);
          }
          if (!dir.includes('.git') && isGit) {
            allRepos.push(dir);
          }
          dirDone();
        });
      }, repoDone);
    });
  }, err => {
    callback(err, allRepos.sort().reverse());
  });
}

/**
 * returns all commits of the last given `days`.
 * Calls `callback` with line-seperated-strings of the formatted commits.
 */
function getCommitsFromRepos(repos, days, callback) {
  let cmts = [];
  async.each(repos, (repo, repoDone) => {
    try {
      gitlog({
        repo: repo,
        number: 100, //max commit count
        since: `${days} days ago`,
        fields: ['abbrevHash', 'subject', 'authorDateRel', 'authorName'],
        author: gitUsername
      }, (err, logs) => {
        // Error
        if (err)
          return callback(err, null);

        // Repo path
        if (logs.length >= 1)
          cmts.push(repo);

        // Commit
        logs.forEach(c => {
          if (c.status && c.status.length)
            cmts.push(`${c.abbrevHash} - ${c.subject} (${c.authorDateRel}) <${c.authorName.replace('@end@\n','')}>`);
        });
        repoDone();
      });
    } catch(err) {
      callback(err, null);
    }
  }, err => {
    callback(err, cmts.length > 0 ? cmts.join('\n') : "Nothing yet. Start small!");
  });
}

module.exports.findGitRepos = findGitRepos;
module.exports.getCommitsFromRepos = getCommitsFromRepos;
<commit_msg>added error handler if .gitconfig is missing; fixes #90<commit_after>const resolve = require('resolve-dir');
const subdirs = require('subdirs');
const isGit = require('is-git');
const gitlog = require('gitlog');
const path = require('path');
const async = require("async");

try {
  const gitUsername = require('git-user-name')();
} catch(err) {
  console.error(`ERROR reading git-config.
    Use e.g. 'git config --global user.name "Mona Lisa"'.
    See 'man git config' for further information.
  `);
  return process.exit(0);
}

/**
 * Go through all `repos` and look for subdirectories up to a given `depth`
 * and look for repositories.
 * Calls `callback` with array of repositories.
 */
function findGitRepos(repos, depth, callback) {
  let allRepos = [];
  async.each(repos, (repo, repoDone) => {
    repo = resolve(repo);
    subdirs(repo, depth, (err, dirs) => {
      if (err) {
        switch (err.code) {
          case 'ENOENT':
            return callback(`Could not open directory directory: ${err.path}\n`, null);
          case 'EACCES':
            return; //ignore if no access
          default:
            return callback(`Error "${err.code}" doing "${err.syscall}" on directory: ${err.path}\n`, null);
        }
      }
      if (dirs) dirs.push(repo);
      async.each(dirs, (dir, dirDone) => {
        isGit(dir, (err, isGit) => {
          if (err) {
            return callback(err, null);
          }
          if (!dir.includes('.git') && isGit) {
            allRepos.push(dir);
          }
          dirDone();
        });
      }, repoDone);
    });
  }, err => {
    callback(err, allRepos.sort().reverse());
  });
}

/**
 * returns all commits of the last given `days`.
 * Calls `callback` with line-seperated-strings of the formatted commits.
 */
function getCommitsFromRepos(repos, days, callback) {
  let cmts = [];
  async.each(repos, (repo, repoDone) => {
    try {
      gitlog({
        repo: repo,
        number: 100, //max commit count
        since: `${days} days ago`,
        fields: ['abbrevHash', 'subject', 'authorDateRel', 'authorName'],
        author: gitUsername
      }, (err, logs) => {
        // Error
        if (err)
          return callback(err, null);

        // Repo path
        if (logs.length >= 1)
          cmts.push(repo);

        // Commit
        logs.forEach(c => {
          if (c.status && c.status.length)
            cmts.push(`${c.abbrevHash} - ${c.subject} (${c.authorDateRel}) <${c.authorName.replace('@end@\n','')}>`);
        });
        repoDone();
      });
    } catch(err) {
      callback(err, null);
    }
  }, err => {
    callback(err, cmts.length > 0 ? cmts.join('\n') : "Nothing yet. Start small!");
  });
}

module.exports.findGitRepos = findGitRepos;
module.exports.getCommitsFromRepos = getCommitsFromRepos;
<|endoftext|>


<commit_before>var suite = new core.testrunner.Suite("Type/Object");

suite.test("clone", function()
{
  var orig = {x:1,y:2,z:3,a:true,b:false,toString:123};
  var clone = core.Object.clone(orig);
  this.isNotIdentical(orig, clone);

  this.isEqual(core.Object.getKeys(orig).join(","), core.Object.getKeys(clone).join(","))
  this.isEqual(core.Object.getValues(orig).join(","), core.Object.getValues(clone).join(","))
});

suite.test("forAll", function()
{
  var test = this;
  var basic = {x:1,y:2,z:3,a:true,b:false,toString:123};
  var keys = [];
  var values = [];

  core.Object.forAll(basic, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, basic);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "1,2,3,true,false,123");
  this.isEqual(keys.join(","), "x,y,z,a,b,toString");
});

suite.test("forAll - extended", function()
{
  var test = this;

  var construct = Function();
  construct.prototype = {x:1,y:2,z:3,a:true,b:false,toString:123};

  var extended = new construct();
  extended.local1 = 42;
  extended.local2 = "hello";

  var keys = [];
  var values = [];

  core.Object.forAll(extended, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, extended);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "42,hello,1,2,3,true,false,123");
  this.isEqual(keys.join(","), "local1,local2,x,y,z,a,b,toString");
});

suite.test("forEach", function()
{
  var test = this;
  var basic = {x:1,y:2,z:3,a:true,b:false,toString:123};
  var keys = [];
  var values = [];

  core.Object.forEach(basic, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, basic);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "1,2,3,true,false,123");
  this.isEqual(keys.join(","), "x,y,z,a,b,toString");
});

suite.test("forEach - extended", function()
{
  var test = this;

  var construct = Function();
  construct.prototype = {x:1,y:2,z:3,a:true,b:false,toString:123};

  var extended = new construct();
  extended.local1 = 42;
  extended.local2 = "hello";

  var keys = [];
  var values = [];

  core.Object.forEach(extended, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, extended);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "42,hello");
  this.isEqual(keys.join(","), "local1,local2");
});

suite.test("getKeys", function()
{
  var keys = core.Object.getKeys({x:1, y:2, z:3}).join(",");
  this.isEqual(keys, "x,y,z");

  var keys = core.Object.getKeys({x:1, y:2, z:3, toString:4}).join(",");
  this.isEqual(keys, "x,y,z,toString");
});

suite.test("getLength", function()
{

});

suite.test("getValues", function()
{
  var values = core.Object.getValues({x:1, y:2, z:3}).sort().join(",");
  this.isEqual(values, "1,2,3");

  var values = core.Object.getValues({x:1, y:2, z:3, toString:4}).join(",");
  this.isEqual(values, "1,2,3,4");
});

suite.test("isEmpty", function()
{
  // toString etc. are special in IE because these are built-in keys
  this.isTrue(core.Object.isEmpty({}));
  this.isTrue(!core.Object.isEmpty({toString:null}));
  this.isTrue(!core.Object.isEmpty({toString:null, hello:null, foo:1}));
});

suite.test("pick", function()
{

});

suite.test("translate", function()
{

});
<commit_msg>Added test for getLength()<commit_after>var suite = new core.testrunner.Suite("Type/Object");

suite.test("clone", function()
{
  var orig = {x:1,y:2,z:3,a:true,b:false,toString:123};
  var clone = core.Object.clone(orig);
  this.isNotIdentical(orig, clone);

  this.isEqual(core.Object.getKeys(orig).join(","), core.Object.getKeys(clone).join(","))
  this.isEqual(core.Object.getValues(orig).join(","), core.Object.getValues(clone).join(","))
});

suite.test("forAll", function()
{
  var test = this;
  var basic = {x:1,y:2,z:3,a:true,b:false,toString:123};
  var keys = [];
  var values = [];

  core.Object.forAll(basic, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, basic);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "1,2,3,true,false,123");
  this.isEqual(keys.join(","), "x,y,z,a,b,toString");
});

suite.test("forAll - extended", function()
{
  var test = this;

  var construct = Function();
  construct.prototype = {x:1,y:2,z:3,a:true,b:false,toString:123};

  var extended = new construct();
  extended.local1 = 42;
  extended.local2 = "hello";

  var keys = [];
  var values = [];

  core.Object.forAll(extended, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, extended);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "42,hello,1,2,3,true,false,123");
  this.isEqual(keys.join(","), "local1,local2,x,y,z,a,b,toString");
});

suite.test("forEach", function()
{
  var test = this;
  var basic = {x:1,y:2,z:3,a:true,b:false,toString:123};
  var keys = [];
  var values = [];

  core.Object.forEach(basic, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, basic);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "1,2,3,true,false,123");
  this.isEqual(keys.join(","), "x,y,z,a,b,toString");
});

suite.test("forEach - extended", function()
{
  var test = this;

  var construct = Function();
  construct.prototype = {x:1,y:2,z:3,a:true,b:false,toString:123};

  var extended = new construct();
  extended.local1 = 42;
  extended.local2 = "hello";

  var keys = [];
  var values = [];

  core.Object.forEach(extended, function(value, key, object) {

    this.isIdentical(this, test);
    this.isIdentical(object, extended);

    values.push(value);
    keys.push(key);

  }, this);

  this.isEqual(values.join(","), "42,hello");
  this.isEqual(keys.join(","), "local1,local2");
});

suite.test("getKeys", function()
{
  var keys = core.Object.getKeys({x:1, y:2, z:3}).join(",");
  this.isEqual(keys, "x,y,z");

  var keys = core.Object.getKeys({x:1, y:2, z:3, toString:4}).join(",");
  this.isEqual(keys, "x,y,z,toString");
});

suite.test("getLength", function()
{
  var plain = {x:1, y:2, z:3};
  this.isEqual(core.Object.getLength(plain), 3);

  var construct = Function();
  construct.prototype = {x:1,y:2,z:3,a:true,b:false,toString:123};
  var extended = new construct();
  extended.localKey = 42;
  extended.toString = 3;
  this.isEqual(core.Object.getLength(extended), 2);
});

suite.test("getValues", function()
{
  var values = core.Object.getValues({x:1, y:2, z:3}).sort().join(",");
  this.isEqual(values, "1,2,3");

  var values = core.Object.getValues({x:1, y:2, z:3, toString:4}).join(",");
  this.isEqual(values, "1,2,3,4");
});

suite.test("isEmpty", function()
{
  // toString etc. are special in IE because these are built-in keys
  this.isTrue(core.Object.isEmpty({}));
  this.isTrue(!core.Object.isEmpty({toString:null}));
  this.isTrue(!core.Object.isEmpty({toString:null, hello:null, foo:1}));
});

suite.test("pick", function()
{

});

suite.test("translate", function()
{

});
<|endoftext|>


<commit_before>describe('angular-locker', function () {

	var provider, locker, store = {}, prefix = 'locker.';

	beforeEach(module('angular-locker', function (lockerProvider) {
		provider = lockerProvider;
		locker = lockerProvider.$get();

		// localStorage mocks
		// spyOn(localStorage, 'setItem').and.callFake(function(key, value) {
		// 	store[key] = value;
		// });
		// spyOn(localStorage, 'getItem').and.callFake(function(key) {
		// 	return store[key];
		// });
		// spyOn(localStorage, 'removeItem').and.callFake(function(key) {
		// 	delete store[key];
		// });
		// spyOn(localStorage, 'hasOwnProperty').and.callFake(function(key) {
		// 	return store.hasOwnProperty(key);
		// });
		// spyOn(localStorage, 'clear').and.callFake(function() {
		// 	store = {};
		// });

	}));

	afterEach(function() {
		store = {};
	});

	describe('lockerProvider', function () {

		it('should be defined', inject(function () {
			expect(provider).toBeDefined();
		}));

		it('should set a default storage driver', inject(function () {
			expect( provider.getStorageDriver() ).toEqual('local');
			provider.setStorageDriver('session');
			expect( provider.getStorageDriver() ).toEqual('session');
		}));

		it('should set a default storage driver via function', inject(function () {
			expect( provider.getStorageDriver() ).toEqual('local');
			provider.setStorageDriver(function () {
				var shouldUseSession = true;
				if (shouldUseSession) return 'session';
			});
			expect( provider.getStorageDriver() ).toEqual('session');
		}));

		it('should set a default namespace', inject(function () {
			expect( provider.getNamespace() ).toEqual('locker');
			provider.setNamespace('myApp');
			expect( provider.getNamespace() ).toEqual('myApp');
		}));

		it('should set a default namespace via function', inject(function () {
			expect( provider.getNamespace() ).toEqual('locker');
			provider.setNamespace(function () {
				var arr = ['myApp', 'coolApp', 'somethingElse'];
				return arr[1];
			});
			expect( provider.getNamespace() ).toEqual('coolApp');
		}));

	});

	describe('lockerService', function () {

		describe('adding items to locker', function () {

			it('should put a string into the locker', inject(function () {
				var str = 'someVal';
				locker.put('someKey', str);

				expect( locker.get('someKey') ).toEqual(str);
			}));

			it('should put an object into the locker', inject(function () {
				var obj = {
					foo: 'bar',
					bar: 'baz',
					baz: {
						foo: true,
						bar: false,
						baz: 12.34
					}
				};

				locker.put('objectKey', obj);

				var result = locker.get('objectKey');

				expect( result ).toEqual(obj);
				expect( result.baz.bar ).toBeFalsy();
			}));

			it('should put an array into the locker', inject(function () {
				var arr1 = ['foo', 123.456, true, { foo: 'bar' }];
				var arr2 = ['foo', 'bar', 'baz'];

				locker.put('arrayKey1', arr1);
				locker.put('arrayKey2', arr2);

				var result1 = locker.get('arrayKey1');
				var result2 = locker.get('arrayKey2');

				expect( result1 ).toEqual(arr1);
				expect( result2 ).toEqual(arr2);

				expect( result1[3].foo ).toEqual('bar');
				expect( result2[0] ).toEqual('foo');
			}));

			it('should put a key value object into the locker via first param', inject(function () {
				var obj = {
					foo: 'bar',
					bar: 'baz',
					baz: {
						foo: 'baz'
					},
					bob: {
						lorem: true
					}
				};

				locker.put(obj);

				expect( locker.get('foo') ).toEqual('bar');
				expect( locker.get('baz') ).toEqual({ foo: 'baz' });
				expect( locker.get('bob').lorem ).toBeTruthy();
			}));

			it('should put an item into the locker when passing a function', inject(function () {

				locker.put('fnKey', function () {
					return 12 * 12;
				});

				expect( locker.get('fnKey') ).toEqual(144);
			}));

			it('should put an item into the locker if it doesn\'t already exist', inject(function () {

				locker.put('foo', 'loremipsumdolorsitamet');
				var added = locker.add('foo', ['foo', 'bar', 'baz']);

				locker.put('bar', 'foobarbazbob');
				var added2 = locker.add('bar1', 'foobazbob');

				expect( added ).toBeFalsy();
				expect( added2 ).toBeTruthy();

				expect( locker.get('foo') ).toEqual('loremipsumdolorsitamet');
				expect( locker.get('bar1') ).toEqual('foobazbob');
			}));

			it('should put an item into the locker in a different namespace', inject(function () {
				locker.put('foo', 'defaultNamespace');
				locker.setNamespace('someOtherNamespace').put('foo', 'newNamespace');

				expect( locker.get('foo') ).toEqual('newNamespace');
				expect( locker.setNamespace('locker').get('foo') ).toEqual('defaultNamespace');
			}));

			it('should return false if key/value params are missing', inject(function () {

				var result1 = locker.put('aKey');
				var result2 = locker.put(null, 'aVal');

				expect( result1 && result2 ).toBeFalsy();
			}));

			// it('should fail silently if my value cannot be serialized', inject(function () {

			// 	var malformedArray = [{a:[{}]}];

			// 	var result = locker.put('aKey', malformedArray).get('aKey');

			// 	expect( result ).toBeDefined();
			// 	console.log(result);
			// 	expect( angular.isArray(result) ).toBeFalsy();
			// }));

		});

		describe('retrieving items from locker', function () {

			it('should return specified default value if item not in locker', inject(function () {
				var obj = { foo: 'bar', bar: 123, baz: true }, str = 'defaultValue';

				locker.put('somethingThatDoesExist', 'exists');

				var result = locker.get('somethingThatDoesExist', str);
				var result2 = locker.get('somethingElseThatDoesntExist', { foo: 'bar', bar: 123, baz: true });

				expect( result ).not.toEqual(str);
				expect( result2 ).toEqual(obj);
			}));

			it('should return a value and then delete the item', inject(function () {
				var str = 'someVal456';
				locker.put('someKey123', str);

				var value = locker.pull('someKey123');

				expect( value ).toEqual(str);
				expect( locker.get('someKey123') ).toBeUndefined();
			}));

			it('should return all items within current namespace', inject(function () {

				locker.empty();

				for (var i=0; i<20; i++) {
					locker.put('aKey' + i, 'aVal' + i);
				}

				locker.put('something.foo.bar', ['someValue']);

				// var all = store;
				var all = locker.all();
				var none = locker.setNamespace('something').all();

				expect( angular.isObject(all) && angular.isObject(none) ).toBeTruthy();
				expect( Object.keys(none).length ).toEqual(0);
				expect( Object.keys(all) ).toContain('aKey12');
				expect( Object.keys(all) ).toContain('something.foo.bar');
				expect( Object.keys(all).length ).toEqual(21);
			}));

		});

		describe('removing items from locker', function () {

			it('should remove an item from locker', inject(function () {
				locker.put('someKey', 'someVal');
				expect( locker.get('someKey') ).toEqual('someVal');

				locker.remove('someKey');

				expect( locker.get('someKey') ).toBeUndefined();
			}));

			it('should remove multiple items from locker by passing an array', inject(function () {

				locker.put('objectKey', {foo: 'bar'});
				locker.put('arrayKey', ['foo', 'bar']);
				locker.put('foo', 'bar');

				expect( locker.get('objectKey') ).toBeDefined();
				expect( locker.get('arrayKey') ).toBeDefined();
				expect( locker.get('foo') ).toBeDefined();

				locker.remove(['objectKey', 'arrayKey1', 'foo']);

				expect( locker.get('objectKey') ).toBeUndefined();
				expect( locker.get('arrayKey1') ).toBeUndefined();
				expect( locker.get('foo') ).toBeUndefined();
			}));

			it('should remove all items within a namespace', inject(function () {
				provider.setNamespace('someOtherNamespace');
				locker.put('keyInOtherNamespace', 'someVal');
				locker.setNamespace('wontBeCleaned').put('keyInOtherNamespace', 'someVal');

				locker.clean('someOtherNamespace');

				expect( locker.setNamespace('locker').get('keyInOtherNamespace') ).toBeUndefined();
				expect( locker.setNamespace('wontBeCleaned').get('keyInOtherNamespace') ).toBeDefined();
			}));

			it('should empty the locker', inject(function () {

				locker.put('anotherKey', { someObj: true, foo: 'barbaz' });

				locker.empty();

				expect( locker.get('anotherKey') ).toBeUndefined();

			}));

		});

		describe('checking existence in locker', function () {

			it('should determine whether an item exists in locker', inject(function () {
				locker.put('randKey', Math.random());

				expect( locker.has('randKey') ).toBeTruthy();
				expect( locker.has('loremipsumdolorsitamet') ).toBeFalsy();
			}));

			it('should determine whether an item exists in locker within another namespace', inject(function () {
				locker.setNamespace('differentNs').put('randKeyNs', Math.random());

				expect( locker.setNamespace('differentNs').has('randKeyNs') ).toBeTruthy();
				expect( locker.setNamespace('loremipsumdolorsitamet').has('randKeyNs') ).toBeFalsy();
			}));

		});

	});

});<commit_msg>adding more tests to improve coverage<commit_after>describe('angular-locker', function () {

	var provider, locker, store = {}, prefix = 'locker.';

	beforeEach(module('angular-locker', function (lockerProvider) {
		provider = lockerProvider;
		locker = lockerProvider.$get();

		// localStorage mocks
		// spyOn(localStorage, 'setItem').and.callFake(function(key, value) {
		// 	store[key] = value;
		// });
		// spyOn(localStorage, 'getItem').and.callFake(function(key) {
		// 	return store[key];
		// });
		// spyOn(localStorage, 'removeItem').and.callFake(function(key) {
		// 	delete store[key];
		// });
		// spyOn(localStorage, 'hasOwnProperty').and.callFake(function(key) {
		// 	return store.hasOwnProperty(key);
		// });
		// spyOn(localStorage, 'clear').and.callFake(function() {
		// 	store = {};
		// });

	}));

	afterEach(function() {
		store = {};
	});

	describe('lockerProvider', function () {

		it('should be defined', inject(function () {
			expect(provider).toBeDefined();
		}));

		it('should set a default storage driver', inject(function () {
			expect( provider.getStorageDriver() ).toEqual('local');
			provider.setStorageDriver('session');
			expect( provider.getStorageDriver() ).toEqual('session');

			provider.setStorageDriver('somethingNotExpected');
			expect( provider.getStorageDriver() ).toEqual('local');
		}));

		it('should set a default storage driver via function', inject(function () {
			expect( provider.getStorageDriver() ).toEqual('local');
			provider.setStorageDriver(function () {
				var shouldUseSession = true;
				if (shouldUseSession) return 'session';
			});
			expect( provider.getStorageDriver() ).toEqual('session');
		}));

		it('should set a default namespace', inject(function () {
			expect( provider.getNamespace() ).toEqual('locker');
			provider.setNamespace('myApp');
			expect( provider.getNamespace() ).toEqual('myApp');
			provider.setNamespace('');
			expect( provider.getNamespace() ).toEqual('');
		}));

		it('should set a default namespace via function', inject(function () {
			expect( provider.getNamespace() ).toEqual('locker');
			provider.setNamespace(function () {
				var arr = ['myApp', 'coolApp', 'somethingElse'];
				return arr[1];
			});
			expect( provider.getNamespace() ).toEqual('coolApp');
		}));

	});

	describe('lockerService', function () {

		describe('adding items to locker', function () {

			it('should put a string into the locker', inject(function () {
				var str = 'someVal';
				locker.put('someKey', str);

				expect( locker.get('someKey') ).toEqual(str);
			}));

			it('should put an object into the locker', inject(function () {
				var obj = {
					foo: 'bar',
					bar: 'baz',
					baz: {
						foo: true,
						bar: false,
						baz: 12.34
					}
				};

				locker.put('objectKey', obj);

				var result = locker.get('objectKey');

				expect( result ).toEqual(obj);
				expect( result.baz.bar ).toBeFalsy();
			}));

			it('should put an array into the locker', inject(function () {
				var arr1 = ['foo', 123.456, true, { foo: 'bar' }];
				var arr2 = ['foo', 'bar', 'baz'];

				locker.put('arrayKey1', arr1);
				locker.put('arrayKey2', arr2);

				var result1 = locker.get('arrayKey1');
				var result2 = locker.get('arrayKey2');

				expect( result1 ).toEqual(arr1);
				expect( result2 ).toEqual(arr2);

				expect( result1[3].foo ).toEqual('bar');
				expect( result2[0] ).toEqual('foo');
			}));

			it('should put a key value object into the locker via first param', inject(function () {
				var obj = {
					foo: 'bar',
					bar: 'baz',
					baz: {
						foo: 'baz'
					},
					bob: {
						lorem: true
					}
				};

				locker.put(obj);

				expect( locker.get('foo') ).toEqual('bar');
				expect( locker.get('baz') ).toEqual({ foo: 'baz' });
				expect( locker.get('bob').lorem ).toBeTruthy();
			}));

			it('should put an item into the locker when passing a function', inject(function () {

				locker.put('fnKey', function () {
					return 12 * 12;
				});

				expect( locker.get('fnKey') ).toEqual(144);
			}));

			it('should put an item into the locker if it doesn\'t already exist', inject(function () {

				locker.put('foo', 'loremipsumdolorsitamet');
				var added = locker.add('foo', ['foo', 'bar', 'baz']);

				locker.put('bar', 'foobarbazbob');
				var added2 = locker.add('bar1', 'foobazbob');

				expect( added ).toBeFalsy();
				expect( added2 ).toBeTruthy();

				expect( locker.get('foo') ).toEqual('loremipsumdolorsitamet');
				expect( locker.get('bar1') ).toEqual('foobazbob');
			}));

			it('should put an item into the locker in a different namespace', inject(function () {
				locker.put('foo', 'defaultNamespace');
				locker.setNamespace('someOtherNamespace').put('foo', 'newNamespace');

				expect( locker.get('foo') ).toEqual('newNamespace');
				expect( locker.setNamespace('locker').get('foo') ).toEqual('defaultNamespace');
			}));

			it('should return false if key/value params are missing', inject(function () {

				var result1 = locker.put('aKey');
				var result2 = locker.put(null, 'aVal');

				expect( result1 && result2 ).toBeFalsy();
			}));

			// it('should fail silently if my value cannot be serialized', inject(function () {

				// expect( function () {
				// 	locker.put('someKey', ['foo']).toThrowError("quux");
				// } )

				// 	var malformedArray = [{a:[{}]}];

				// 	var result = locker.put('aKey', malformedArray).get('aKey');

				// 	expect( result ).toBeDefined();
				// 	console.log(result);
				// 	expect( angular.isArray(result) ).toBeFalsy();
			// }));

			it('should catch the error when the browser reports storage is full', inject(function () {

				var error = new Error();
				error.name = 'QUOTA_EXCEEDED_ERR';

				spyOn(localStorage, 'setItem').and.throwError(error);
				spyOn(console, 'warn');

				locker.put('someKey', ['foo']);

				expect(console.warn).toHaveBeenCalled();
			}));

			it('should catch the error when an item couldn\'t be added for some other reason', inject(function () {

				spyOn(localStorage, 'setItem').and.throwError();
				spyOn(console, 'warn');

				locker.put('someKey', ['foo']);

				expect(console.warn).toHaveBeenCalled();
			}));

		});

		describe('retrieving items from locker', function () {

			it('should return specified default value if item not in locker', inject(function () {
				var obj = { foo: 'bar', bar: 123, baz: true }, str = 'defaultValue';

				locker.put('somethingThatDoesExist', 'exists');

				var result = locker.get('somethingThatDoesExist', str);
				var result2 = locker.get('somethingElseThatDoesntExist', { foo: 'bar', bar: 123, baz: true });

				expect( result ).not.toEqual(str);
				expect( result2 ).toEqual(obj);
			}));

			it('should return a value and then delete the item', inject(function () {
				var str = 'someVal456';
				locker.put('someKey123', str);

				var value = locker.pull('someKey123');

				expect( value ).toEqual(str);
				expect( locker.get('someKey123') ).toBeUndefined();
			}));

			it('should return all items within current namespace', inject(function () {

				locker.empty();

				for (var i=0; i<20; i++) {
					locker.put('aKey' + i, 'aVal' + i);
				}

				locker.put('something.foo.bar', ['someValue']);

				// var all = store;
				var all = locker.all();
				var none = locker.setNamespace('something').all();

				expect( angular.isObject(all) && angular.isObject(none) ).toBeTruthy();
				expect( Object.keys(none).length ).toEqual(0);

				expect( all ).toEqual(jasmine.objectContaining({ 'aKey12': 'aVal12' }));

				expect( Object.keys(all) ).toContain('aKey12');
				expect( Object.keys(all) ).toContain('something.foo.bar');
				expect( Object.keys(all).length ).toEqual(21);
			}));

		});

		describe('removing items from locker', function () {

			it('should remove an item from locker', inject(function () {
				locker.put('someKey', 'someVal');
				expect( locker.get('someKey') ).toEqual('someVal');

				locker.remove('someKey');

				expect( locker.get('someKey') ).toBeUndefined();
			}));

			it('should remove multiple items from locker by passing an array', inject(function () {

				locker.put('objectKey', {foo: 'bar'});
				locker.put('arrayKey', ['foo', 'bar']);
				locker.put('foo', 'bar');

				expect( locker.get('objectKey') ).toBeDefined();
				expect( locker.get('arrayKey') ).toBeDefined();
				expect( locker.get('foo') ).toBeDefined();

				locker.remove(['objectKey', 'arrayKey1', 'foo']);

				expect( locker.get('objectKey') ).toBeUndefined();
				expect( locker.get('arrayKey1') ).toBeUndefined();
				expect( locker.get('foo') ).toBeUndefined();
			}));

			it('should remove all items within a namespace', inject(function () {
				provider.setNamespace('someOtherNamespace');
				locker.put('keyInOtherNamespace', 'someVal');
				locker.setNamespace('wontBeCleaned').put('keyInOtherNamespace', 'someVal');

				locker.clean('someOtherNamespace');

				expect( locker.setNamespace('locker').get('keyInOtherNamespace') ).toBeUndefined();
				expect( locker.setNamespace('wontBeCleaned').get('keyInOtherNamespace') ).toBeDefined();
			}));

			it('should empty the locker', inject(function () {

				locker.put('anotherKey', { someObj: true, foo: 'barbaz' });

				locker.empty();

				expect( locker.get('anotherKey') ).toBeUndefined();

			}));

		});

		describe('checking existence in locker', function () {

			it('should determine whether an item exists in locker', inject(function () {
				locker.put('randKey', Math.random());

				expect( locker.has('randKey') ).toBeTruthy();
				expect( locker.has('loremipsumdolorsitamet') ).toBeFalsy();
			}));

			it('should determine whether an item exists in locker within another namespace', inject(function () {
				locker.setNamespace('differentNs').put('randKeyNs', Math.random());

				expect( locker.setNamespace('differentNs').has('randKeyNs') ).toBeTruthy();
				expect( locker.setNamespace('loremipsumdolorsitamet').has('randKeyNs') ).toBeFalsy();
			}));

		});

	});

});<|endoftext|>