<commit_before>/**
 * Created by arming on 6/15/16.
 */
'use strict'
const ValueException = require('./exceptions').ValueException
const TypeException = require('./exceptions').TypeException
const Mapping = require('./mapping').Mapping
const Output = require('./output').Output
const Parameter = require('./parameter').Parameter
const WKResource = require('./resource').WKResource
const path = require('path')

/** @module Core */

function _handleDuplicateKey (key) {
  console.log('Duplicate key ' + key)
  throw new ValueException('duplicate key "%s" detected' % key)
}

function _update (d, values) {
  if (Array.isArray(values)) {
    values.forEach((v) => {
      if (v.WKName in d) {
        _handleDuplicateKey(v.WKName)
      }
      d[v.WKName] = v
    })
  } else {
    if (values.WKName in d) {
      _handleDuplicateKey(values.WKName)
    }
    d[values.WKName] = values
  }
  return values
}

function _populateFromExisting(newTemplate, existingTemplate) {
  for (let param in existingTemplate.Parameters) {
    let newParam = new Parameter(param, existingTemplate.Parameters[param])
    newTemplate.add(newParam)
  }
  for (let output in existingTemplate.Outputs) {
    let newOutput = new Output(output, existingTemplate.Outputs[output])
    newTemplate.add(newOutput)
  }
  for (let mapping in existingTemplate.Mappings) {
    let newMapping = new Mapping(mapping, existingTemplate.Mappings[mapping])
    newTemplate.add(newMapping)
  }
  for (let resource in existingTemplate.Resources) {
    let typeSplit = existingTemplate.Resources[resource].Type.split('::')
    let resourceGroupName = typeSplit[1]
    let resourceGroup
    let resourceName = typeSplit[2]
    if (typeSplit[0] === 'Custom') {
      resourceGroup = require(path.join(__dirname, 'resources', 'cloudformation'))
      resourceName = 'CustomResource'
    } else {
      resourceGroup = require(path.join(__dirname, 'resources', resourceGroupName.toLowerCase()))
      if (resourceGroupName === 'Lambda' && resourceName === 'Function') {
        resourceName = 'LambdaFunction'
      }
    }
    let temp = Object.create(resourceGroup[resourceName].prototype)
    let newResource = Reflect.construct(resourceGroup[resourceName], [resource, existingTemplate.Resources[resource].Properties])
    newTemplate.add(newResource)
  }
}

/**
 * @memberof module:Core
 */
function Template (template) {
  this.Description = ''
  this.Metadata = {}
  this.Conditions = {}
  this.Mappings = {}
  this.Outputs = {}
  this.Parameters = {}
  this.Resources = {}
  this.AWSTemplateFormatVersion = '2010-09-09'
  if (template) {
    _populateFromExisting(this, template)
  }
}

/**
 * Add an element to the Template
 * @param element
 */
Template.prototype.add = function (element) {
  if (element instanceof Parameter) {
    _update(this.Parameters, element)
  } else if (element instanceof WKResource) {
    _update(this.Resources, element)
  } else if (element instanceof Output) {
    _update(this.Outputs, element)
  } else if (element instanceof Mapping) {
    _update(this.Mappings, element)
  } else {
    throw new TypeException(element + ' is not a valid type and cannot be added to the template.')
  }
}

/**
 * Set the metadata value of the template
 * @param metadata
 */
Template.prototype.setMetadata = function (metadata) {
  this.Metadata = metadata
}

/**
 * Set the version value of the template
 * @param version
 */
Template.prototype.setVersion = function (version) {
  this.Version = version
}

/**
 * Add a description to the template
 * @param description
 */
Template.prototype.setDescription = function (description) {
  this.Description = description
}

/**
 * Add a condition to the template
 * @param name
 * @param condition
 */
Template.prototype.addCondition = function (name, condition) {
  this.Conditions[name] = condition
}

/**
 *
 * @param callback
 */
Template.prototype.toJsonAsync = function (callback) {
  if (callback) {
    let result = this.toJson()
    if (result.Errors) {
      callback(result.Errors, result.Template)
    } else {
      callback(null, result.Template)
    }
  } else {
    return new Promise((resolve, reject) => {
      process.nextTick(() => {
        let result = this.toJson()
        if (result.Errors) {
          reject({ Errors: result.Errors, Template: result.Template })
        } else {
          resolve(result.Template)
        }
      })
    })
  }
}

/**
 * Returns a CloudFormation JSON template string
 * @returns {Object}
 */
Template.prototype.toJson = function () {
  let j = JSON.parse(JSON.stringify(this))
  let errors = []
  for (let param in this.Parameters) {
    try {
      j.Parameters[param] = this.Parameters[param].toJson()
    } catch (e) {
      errors.push(e.message)
    }
  }
  for (let resource in this.Resources) {
    let result = this.Resources[resource].toJson()
    if (result.errors) {
      result.errors.forEach((e) => {
        errors.push(e)
      })
    }
    j.Resources[resource] = result.json
  }
  for (let output in this.Outputs) {
    try {
      j.Outputs[output] = this.Outputs[output].toJson()
    } catch (e) {
      errors.push(e.message)
    }
  }
  for (let map in this.Mappings) {
    if (this.Mappings[map] instanceof Mapping) {
      try {
        j.Mappings[map] = this.Mappings[map].toJson()
      } catch (e) {
        errors.push(e.message)
      }
    } else {
      j.Mappings[map] = this.Mappings[map]
    }
  }
  if (Object.keys(j.Metadata).length === 0) {
    delete j.Metadata
  }
  if (Object.keys(j.Conditions).length === 0) {
    delete j.Conditions
  }
  if (Object.keys(j.Mappings).length === 0) {
    delete j.Mappings
  }
  if (Object.keys(j.Outputs).length === 0) {
    delete j.Outputs
  }
  if (Object.keys(j.Parameters).length === 0) {
    delete j.Parameters
  }
  if (j.Description === '') {
    delete j.Description
  }
  if (errors.length === 0) {
    errors = null
  }
  return {
    Errors: errors,
    Template: JSON.stringify(j, null, 2)
  }
}

Template.prototype.toYAML = function () {

}

module.exports = {
  Template: Template
}
<commit_msg>Adding YAML output support.<commit_after>/**
 * Created by arming on 6/15/16.
 */
'use strict'
const ValueException = require('./exceptions').ValueException
const TypeException = require('./exceptions').TypeException
const Mapping = require('./mapping').Mapping
const Output = require('./output').Output
const Parameter = require('./parameter').Parameter
const WKResource = require('./resource').WKResource
const path = require('path')
const yaml = require('js-yaml')

/** @module Core */

function _handleDuplicateKey (key) {
  console.log('Duplicate key ' + key)
  throw new ValueException('duplicate key "%s" detected' % key)
}

function _update (d, values) {
  if (Array.isArray(values)) {
    values.forEach((v) => {
      if (v.WKName in d) {
        _handleDuplicateKey(v.WKName)
      }
      d[v.WKName] = v
    })
  } else {
    if (values.WKName in d) {
      _handleDuplicateKey(values.WKName)
    }
    d[values.WKName] = values
  }
  return values
}

function _populateFromExisting(newTemplate, existingTemplate) {
  for (let param in existingTemplate.Parameters) {
    let newParam = new Parameter(param, existingTemplate.Parameters[param])
    newTemplate.add(newParam)
  }
  for (let output in existingTemplate.Outputs) {
    let newOutput = new Output(output, existingTemplate.Outputs[output])
    newTemplate.add(newOutput)
  }
  for (let mapping in existingTemplate.Mappings) {
    let newMapping = new Mapping(mapping, existingTemplate.Mappings[mapping])
    newTemplate.add(newMapping)
  }
  for (let resource in existingTemplate.Resources) {
    let typeSplit = existingTemplate.Resources[resource].Type.split('::')
    let resourceGroupName = typeSplit[1]
    let resourceGroup
    let resourceName = typeSplit[2]
    if (typeSplit[0] === 'Custom') {
      resourceGroup = require(path.join(__dirname, 'resources', 'cloudformation'))
      resourceName = 'CustomResource'
    } else {
      resourceGroup = require(path.join(__dirname, 'resources', resourceGroupName.toLowerCase()))
      if (resourceGroupName === 'Lambda' && resourceName === 'Function') {
        resourceName = 'LambdaFunction'
      }
    }
    let temp = Object.create(resourceGroup[resourceName].prototype)
    let newResource = Reflect.construct(resourceGroup[resourceName], [resource, existingTemplate.Resources[resource].Properties])
    newTemplate.add(newResource)
  }
}

/**
 * @memberof module:Core
 */
function Template (template) {
  this.Description = ''
  this.Metadata = {}
  this.Conditions = {}
  this.Mappings = {}
  this.Outputs = {}
  this.Parameters = {}
  this.Resources = {}
  this.AWSTemplateFormatVersion = '2010-09-09'
  if (template) {
    _populateFromExisting(this, template)
  }
}

/**
 * Add an element to the Template
 * @param element
 */
Template.prototype.add = function (element) {
  if (element instanceof Parameter) {
    _update(this.Parameters, element)
  } else if (element instanceof WKResource) {
    _update(this.Resources, element)
  } else if (element instanceof Output) {
    _update(this.Outputs, element)
  } else if (element instanceof Mapping) {
    _update(this.Mappings, element)
  } else {
    throw new TypeException(element + ' is not a valid type and cannot be added to the template.')
  }
}

/**
 * Set the metadata value of the template
 * @param metadata
 */
Template.prototype.setMetadata = function (metadata) {
  this.Metadata = metadata
}

/**
 * Set the version value of the template
 * @param version
 */
Template.prototype.setVersion = function (version) {
  this.Version = version
}

/**
 * Add a description to the template
 * @param description
 */
Template.prototype.setDescription = function (description) {
  this.Description = description
}

/**
 * Add a condition to the template
 * @param name
 * @param condition
 */
Template.prototype.addCondition = function (name, condition) {
  this.Conditions[name] = condition
}

/**
 *
 * @param callback
 */
Template.prototype.toJsonAsync = function (callback) {
  if (callback) {
    let result = this.toJson()
    if (result.Errors) {
      callback(result.Errors, result.Template)
    } else {
      callback(null, result.Template)
    }
  } else {
    return new Promise((resolve, reject) => {
      process.nextTick(() => {
        let result = this.toJson()
        if (result.Errors) {
          reject({ Errors: result.Errors, Template: result.Template })
        } else {
          resolve(result.Template)
        }
      })
    })
  }
}

/**
 * Returns a CloudFormation JSON template string
 * @returns {Object}
 */
Template.prototype.toJson = function () {
  let j = JSON.parse(JSON.stringify(this))
  let errors = []
  for (let param in this.Parameters) {
    try {
      j.Parameters[param] = this.Parameters[param].toJson()
    } catch (e) {
      errors.push(e.message)
    }
  }
  for (let resource in this.Resources) {
    let result = this.Resources[resource].toJson()
    if (result.errors) {
      result.errors.forEach((e) => {
        errors.push(e)
      })
    }
    j.Resources[resource] = result.json
  }
  for (let output in this.Outputs) {
    try {
      j.Outputs[output] = this.Outputs[output].toJson()
    } catch (e) {
      errors.push(e.message)
    }
  }
  for (let map in this.Mappings) {
    if (this.Mappings[map] instanceof Mapping) {
      try {
        j.Mappings[map] = this.Mappings[map].toJson()
      } catch (e) {
        errors.push(e.message)
      }
    } else {
      j.Mappings[map] = this.Mappings[map]
    }
  }
  if (Object.keys(j.Metadata).length === 0) {
    delete j.Metadata
  }
  if (Object.keys(j.Conditions).length === 0) {
    delete j.Conditions
  }
  if (Object.keys(j.Mappings).length === 0) {
    delete j.Mappings
  }
  if (Object.keys(j.Outputs).length === 0) {
    delete j.Outputs
  }
  if (Object.keys(j.Parameters).length === 0) {
    delete j.Parameters
  }
  if (j.Description === '') {
    delete j.Description
  }
  if (errors.length === 0) {
    errors = null
  }
  return {
    Errors: errors,
    Template: JSON.stringify(j, null, 2)
  }
}

Template.prototype.toYAML = function () {
  let jsonResult = this.toJson()
  return { Errors: jsonResult.errors, Template: yaml.safeDump(JSON.parse(jsonResult.Template)) }
}

module.exports = {
  Template: Template
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * tabiframe.js
 *
 * tabiframe implements the <tab-iframe> tab. It's a wrapper
 * around a <iframe mozbrowser>.
 *
 */

define(['js/eventemitter'], function(EventEmitter) {

  'use strict';

  const MIN_ZOOM = 0.5;
  const MAX_ZOOM = 2;

  const IFRAME_EVENTS = [
    'mozbrowserasyncscroll', 'mozbrowserclose', 'mozbrowsercontextmenu',
    'mozbrowsererror', 'mozbrowsericonchange', 'mozbrowserloadend',
    'mozbrowserloadstart', 'mozbrowserlocationchange', 'mozbrowseropenwindow',
    'mozbrowsersecuritychange', 'mozbrowsershowmodalprompt', 'mozbrowsertitlechange',
    'mozbrowserusernameandpasswordrequired'
  ];

  // Non-Remote iframes may steal the focus :/
  const INPROCESS_URLS = [
       'about:addons'
     , 'about:config'
     , 'about:cache'
     , 'about:crashes'
     , 'about:debugging'
     , 'about:devtools-toolbox'
     , 'about:downloads'
     , 'about:healthreport'
     , 'about:networking'
     , 'about:newtab'
     , 'about:performance'
     , 'about:plugins'
     , 'about:preferences'
     , 'about:sharing'
     , 'about:support'
     , 'about:telemetry'
     , 'about:webrtc'
  ];

  let tabIframeProto = Object.create(HTMLElement.prototype);

  tabIframeProto.setLocation = function(url) {
    if (!this._innerIframe) {
      let loadInParent = INPROCESS_URLS.includes(url) || url.startsWith("browserui://");
      this._createInnerIframe(!loadInParent);
    } else {
      this.updateRemoteNess(url);
    }

    if (window.IS_PRIVILEGED) {
      this._innerIframe.src = url;
    } else {
      this._innerIframe.src = 'data:,' + url;
    }
  };

  tabIframeProto.updateRemoteNess = function(url) {
    // We may have to reload the location in a new iframe if the remoteness
    // doesn't match.
    let loadInParent = INPROCESS_URLS.includes(url) || url.startsWith("browserui://");
    if ( (this._innerIframe.getAttribute("remote") && loadInParent) ||
         (!this._innerIframe.getAttribute("remote") && !loadInParent ) ) {
      this._innerIframe.remove();
      this._createInnerIframe(!loadInParent);
      if (window.IS_PRIVILEGED) {
        this._innerIframe.src = url;
      } else {
        this._innerIframe.src = 'data:,' + url;
      }
    }
  };

  tabIframeProto.willBeVisibleSoon = function() {
    if (window.IS_PRIVILEGED && this._innerIframe) {
      this._innerIframe.setVisible(true);
    }
  };

  tabIframeProto.show = function() {
    this.removeAttribute('hidden');
    if (window.IS_PRIVILEGED && this._innerIframe) {
      this._innerIframe.setVisible(true);
    }
    this.emit('visible');
  };

  tabIframeProto.hide = function() {
    this.setAttribute('hidden', 'true');
    if (window.IS_PRIVILEGED && this._innerIframe) {
      this._innerIframe.setVisible(false);
    }
    this.emit('hidden');
  };

  tabIframeProto.createdCallback = function() {
    this._zoom = 1;
    this._clearTabData();
    EventEmitter.decorate(this);
  };

  tabIframeProto._createInnerIframe = function(remote) {
    let iframe = document.createElement('iframe');
    iframe.setAttribute('mozbrowser', 'true');
    iframe.setAttribute('flex', '1');
    if (remote) {
      iframe.setAttribute('remote', 'true');
    }
    iframe.setAttribute('mozallowfullscreen', 'true');
    this.appendChild(iframe);
    for (let eventName of IFRAME_EVENTS) {
      iframe.addEventListener(eventName, this);
    }
    this._innerIframe = iframe;
    this._applyZoom();
  };

  tabIframeProto.attachedCallback = function() {
  };

  tabIframeProto.detachedCallback = function() {
    if (this._innerIframe) {
      for (let eventName of IFRAME_EVENTS) {
        this._innerIframe.removeEventListener(eventName, this);
      }
    }
  };

  tabIframeProto.zoomIn = function() {
    this._zoom += 0.1;
    this._zoom = Math.min(MAX_ZOOM, this._zoom);
    this._applyZoom();
  };

  tabIframeProto.zoomOut = function() {
    this._zoom -= 0.1;
    this._zoom = Math.max(MIN_ZOOM, this._zoom);
    this._applyZoom();
  };

  tabIframeProto.resetZoom = function() {
    this._zoom = 1;
    this._applyZoom();
  };

  tabIframeProto._applyZoom = function() {
    if (this._innerIframe && window.IS_PRIVILEGED) {
      this._innerIframe.zoom(this._zoom);
    }
  };

  tabIframeProto.reload = function() {
    if (this._innerIframe) this._innerIframe.reload();
  };

  tabIframeProto.stop = function() {
    if (this._innerIframe) this._innerIframe.stop();
  };

  tabIframeProto.goBack = function() {
    if (this._innerIframe) this._innerIframe.goBack();
  };

  tabIframeProto.goForward = function() {
    if (this._innerIframe) this._innerIframe.goForward();
  };

  tabIframeProto._clearTabData = function() {
    this._loading = false;
    this._title = '';
    this._location = '';
    this._favicon = '';
    this._securityState = 'insecure';
    this._securityExtendedValidation = false;
  };

  Object.defineProperty(tabIframeProto, 'loading', {
    get: function() {
      return this._loading;
    }
  });

  Object.defineProperty(tabIframeProto, 'title', {
    get: function() {
      return this._title;
    }
  });

  Object.defineProperty(tabIframeProto, 'location', {
    get: function() {
      return this._location;
    }
  });

  Object.defineProperty(tabIframeProto, 'favicon', {
    get: function() {
      return this._favicon;
    }
  });

  Object.defineProperty(tabIframeProto, 'securityState', {
    get: function() {
      return this._securityState;
    }
  });

  Object.defineProperty(tabIframeProto, 'securityExtendedValidation', {
    get: function() {
      return this._securityExtendedValidation;
    }
  });

  tabIframeProto.canGoBack = function() {
    return new Promise((resolve, reject) => {
      if (!this._innerIframe) {
        return resolve(false);
      }
      this._innerIframe.getCanGoBack().onsuccess = r => {
        return resolve(r.target.result);
      };
    });
  };

  tabIframeProto.canGoForward = function() {
    return new Promise((resolve, reject) => {
      if (!this._innerIframe) {
        return resolve(false);
      }
      this._innerIframe.getCanGoForward().onsuccess = r => {
        return resolve(r.target.result);
      };
    });
  };

  tabIframeProto.focus = function() {
    if (this._innerIframe) {
      this._innerIframe.focus();
    }
  };

  tabIframeProto.userInput = '';

  tabIframeProto.handleEvent = function(e) {
    let somethingChanged = true;

    switch (e.type) {
      case 'mozbrowserloadstart':
        this._clearTabData();
        this._loading = true;
        break;
      case 'mozbrowserloadend':
        this._loading = false;
        break;
      case 'mozbrowsertitlechange':
        this._title = e.detail;
        break;
      case 'mozbrowserlocationchange':
        this.userInput = '';
        this._location = e.detail;
        this.updateRemoteNess(e.detail);
        break;
      case 'mozbrowsericonchange':
        this._favicon = e.detail.href;
        break;
      case 'mozbrowsererror':
        this._loading = false;
        break;
      case 'mozbrowsersecuritychange':
        this._securityState = e.detail.state;
        this._securityExtendedValidation = e.detail.extendedValidation;
        break;
      default:
        somethingChanged = false;
    }

    // Forward event
    this.emit(e.type, e, this);
  };

  let TabIframe = document.registerElement('tab-iframe', {prototype: tabIframeProto});
  return TabIframe;
});
<commit_msg>Add very basic support of tabs api to advanced and browserActions<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
 * tabiframe.js
 *
 * tabiframe implements the <tab-iframe> tab. It's a wrapper
 * around a <iframe mozbrowser>.
 *
 */

define(['js/eventemitter'], function(EventEmitter) {

  'use strict';

  const MIN_ZOOM = 0.5;
  const MAX_ZOOM = 2;

  const IFRAME_EVENTS = [
    'mozbrowserasyncscroll', 'mozbrowserclose', 'mozbrowsercontextmenu',
    'mozbrowsererror', 'mozbrowsericonchange', 'mozbrowserloadend',
    'mozbrowserloadstart', 'mozbrowserlocationchange', 'mozbrowseropenwindow',
    'mozbrowsersecuritychange', 'mozbrowsershowmodalprompt', 'mozbrowsertitlechange',
    'mozbrowserusernameandpasswordrequired'
  ];

  // Non-Remote iframes may steal the focus :/
  const INPROCESS_URLS = [
       'about:addons'
     , 'about:config'
     , 'about:cache'
     , 'about:crashes'
     , 'about:debugging'
     , 'about:devtools-toolbox'
     , 'about:downloads'
     , 'about:healthreport'
     , 'about:networking'
     , 'about:newtab'
     , 'about:performance'
     , 'about:plugins'
     , 'about:preferences'
     , 'about:sharing'
     , 'about:support'
     , 'about:telemetry'
     , 'about:webrtc'
  ];

  let tabsChannel = new BroadcastChannel('tabs');

  let tabIframeProto = Object.create(HTMLElement.prototype);

  tabIframeProto.setLocation = function(url) {
    if (!this._innerIframe) {
      let loadInParent = INPROCESS_URLS.includes(url) || url.startsWith("browserui://");
      this._createInnerIframe(!loadInParent);
    } else {
      this.updateRemoteNess(url);
    }

    if (window.IS_PRIVILEGED) {
      this._innerIframe.src = url;
    } else {
      this._innerIframe.src = 'data:,' + url;
    }
  };

  tabIframeProto.updateRemoteNess = function(url) {
    // We may have to reload the location in a new iframe if the remoteness
    // doesn't match.
    let loadInParent = INPROCESS_URLS.includes(url) || url.startsWith("browserui://");
    if ( (this._innerIframe.getAttribute("remote") && loadInParent) ||
         (!this._innerIframe.getAttribute("remote") && !loadInParent ) ) {
      this._innerIframe.remove();
      this._createInnerIframe(!loadInParent);
      if (window.IS_PRIVILEGED) {
        this._innerIframe.src = url;
      } else {
        this._innerIframe.src = 'data:,' + url;
      }
    }
  };

  tabIframeProto.willBeVisibleSoon = function() {
    if (window.IS_PRIVILEGED && this._innerIframe) {
      this._innerIframe.setVisible(true);
    }
  };

  tabIframeProto.show = function() {
    this.removeAttribute('hidden');
    if (window.IS_PRIVILEGED && this._innerIframe) {
      this._innerIframe.setVisible(true);
    }
    this.emit('visible');
  };

  tabIframeProto.hide = function() {
    this.setAttribute('hidden', 'true');
    if (window.IS_PRIVILEGED && this._innerIframe) {
      this._innerIframe.setVisible(false);
    }
    this.emit('hidden');
  };

  tabIframeProto.createdCallback = function() {
    this._zoom = 1;
    this._clearTabData();
    EventEmitter.decorate(this);
  };

  tabIframeProto._createInnerIframe = function(remote) {
    let iframe = document.createElement('iframe');
    iframe.setAttribute('mozbrowser', 'true');
    iframe.setAttribute('flex', '1');
    if (remote) {
      iframe.setAttribute('remote', 'true');
    }
    iframe.setAttribute('mozallowfullscreen', 'true');
    // Set this attribute for web extension.
    iframe.setAttribute('data-tab-id', this.tabId);
    this.appendChild(iframe);
    for (let eventName of IFRAME_EVENTS) {
      iframe.addEventListener(eventName, this);
    }
    this._innerIframe = iframe;
    this._applyZoom();
  };

  tabIframeProto.attachedCallback = function() {
  };

  tabIframeProto.detachedCallback = function() {
    if (this._innerIframe) {
      for (let eventName of IFRAME_EVENTS) {
        this._innerIframe.removeEventListener(eventName, this);
      }
    }
  };

  tabIframeProto.zoomIn = function() {
    this._zoom += 0.1;
    this._zoom = Math.min(MAX_ZOOM, this._zoom);
    this._applyZoom();
  };

  tabIframeProto.zoomOut = function() {
    this._zoom -= 0.1;
    this._zoom = Math.max(MIN_ZOOM, this._zoom);
    this._applyZoom();
  };

  tabIframeProto.resetZoom = function() {
    this._zoom = 1;
    this._applyZoom();
  };

  tabIframeProto._applyZoom = function() {
    if (this._innerIframe && window.IS_PRIVILEGED) {
      this._innerIframe.zoom(this._zoom);
    }
  };

  tabIframeProto.reload = function() {
    if (this._innerIframe) this._innerIframe.reload();
  };

  tabIframeProto.stop = function() {
    if (this._innerIframe) this._innerIframe.stop();
  };

  tabIframeProto.goBack = function() {
    if (this._innerIframe) this._innerIframe.goBack();
  };

  tabIframeProto.goForward = function() {
    if (this._innerIframe) this._innerIframe.goForward();
  };

  tabIframeProto._clearTabData = function() {
    this._loading = false;
    this._title = '';
    this._location = '';
    this._favicon = '';
    this._securityState = 'insecure';
    this._securityExtendedValidation = false;
  };

  Object.defineProperty(tabIframeProto, 'loading', {
    get: function() {
      return this._loading;
    }
  });

  Object.defineProperty(tabIframeProto, 'title', {
    get: function() {
      return this._title;
    }
  });

  Object.defineProperty(tabIframeProto, 'location', {
    get: function() {
      return this._location;
    }
  });

  Object.defineProperty(tabIframeProto, 'favicon', {
    get: function() {
      return this._favicon;
    }
  });

  Object.defineProperty(tabIframeProto, 'securityState', {
    get: function() {
      return this._securityState;
    }
  });

  Object.defineProperty(tabIframeProto, 'securityExtendedValidation', {
    get: function() {
      return this._securityExtendedValidation;
    }
  });

  let idCount = 1;
  Object.defineProperty(tabIframeProto, 'tabId', {
    get: function() {
      if (!this._tabId) {
        this._tabId = idCount++;
      }
      return this._tabId;
    }
  });

  tabIframeProto.canGoBack = function() {
    return new Promise((resolve, reject) => {
      if (!this._innerIframe) {
        return resolve(false);
      }
      this._innerIframe.getCanGoBack().onsuccess = r => {
        return resolve(r.target.result);
      };
    });
  };

  tabIframeProto.canGoForward = function() {
    return new Promise((resolve, reject) => {
      if (!this._innerIframe) {
        return resolve(false);
      }
      this._innerIframe.getCanGoForward().onsuccess = r => {
        return resolve(r.target.result);
      };
    });
  };

  tabIframeProto.focus = function() {
    if (this._innerIframe) {
      this._innerIframe.focus();
    }
  };

  tabIframeProto.userInput = '';

  tabIframeProto.handleEvent = function(e) {
    let somethingChanged = true;

    switch (e.type) {
      case 'mozbrowserloadstart':
        this._clearTabData();
        this._loading = true;
        break;
      case 'mozbrowserloadend':
        this._loading = false;
        break;
      case 'mozbrowsertitlechange':
        this._title = e.detail;
        tabsChannel.postMessage({ event: 'update', id: this.tabId, title: e.detail });
        break;
      case 'mozbrowserlocationchange':
        this.userInput = '';
        this._location = e.detail;
        this.updateRemoteNess(e.detail);
        tabsChannel.postMessage({ event: 'update', id: this.tabId, url: e.detail });
        break;
      case 'mozbrowsericonchange':
        this._favicon = e.detail.href;
        break;
      case 'mozbrowsererror':
        this._loading = false;
        break;
      case 'mozbrowsersecuritychange':
        this._securityState = e.detail.state;
        this._securityExtendedValidation = e.detail.extendedValidation;
        break;
      default:
        somethingChanged = false;
    }

    // Forward event
    this.emit(e.type, e, this);
  };

  let TabIframe = document.registerElement('tab-iframe', {prototype: tabIframeProto});
  return TabIframe;
});
<|endoftext|>


<commit_before>const TransportIPFS = require('./TransportIPFS');
const TransportHTTP = require('./TransportHTTP');
const Dweb = require('./Dweb');

// Utility packages (ours) Aand one-loners
const makepromises = require('./utils/makepromises');
function delay(ms, val) { return new Promise(resolve => {setTimeout(() => { resolve(val); },ms)})}

// Fake a browser like environment for some tests
const jsdom = require("jsdom");
const { JSDOM } = jsdom;        //TODO - figure out what this does, dont understand the Javascript
htmlfake = '<!DOCTYPE html>

Failed to load sb via StructuredBlock

Failed to load mb via MutableBlock

Failed to load sb via dwebfile

Failed to load mb via dwebfile

';
const dom = new JSDOM(htmlfake);
//console.log("XXX@8",dom.window.document.getElementById("myList.0").textContent); // Before loading = "Failed to load sb via StructuredBlock"
document = dom.window.document;   // Note in JS can't see "document" like can in python

//let transportclass = TransportIPFS
let transportclass = TransportHTTP
let verbose = false;
let blk;
let blk2;
let sb;

    transportclass.p_setup({}, verbose, {})
    .then((t) => {
        if (verbose) console.log("setup returned and transport set - including annoationList");
        Dweb.transport = t;
    })
    .then(() => transportclass.test(Dweb.transport, verbose))
    .then(() => Dweb.Block.test(Dweb.transport, verbose))
    .then(() => Dweb.StructuredBlock.test(Dweb.transport, document, verbose))
    .then((testobjs) => sb = testobjs.sb)
    .then(() => Dweb.MutableBlock.test(sb, Dweb.transport, verbose))
    .then(() => Dweb.CryptoLib.test(verbose))
    .then(() => verbose = true)
    //NEXT TEST FAILS
    //.then(() => Dweb.AccessControlList.p_test(verbose))
    //.then(() => Dweb.KeyChain.p_test(verbose))
    .then(() => console.log("delaying 10 secs"))
    .then(() => delay(10000))
    .then(()=>console.log("Completed test"))
    .catch((err) => console.log("Test failed", err))

/* path tests not done ... old ones
 console.log("Now test path using dwebfile and sb =======");
 verbose=false;
 Dweb.p_dwebfile("sb", sbhash, "langs/readme.md", ["p_elem", "myList.2", verbose, null]);
 console.log("Now test path using dwebfile and mb =======");
 Dweb.p_dwebfile("mb", mbhash, "langs/readme.md", ["p_elem", "myList.3", verbose, null]);
 console.log("END testing previouslyworking()");

 */<commit_msg>"node test_ipfs.js" works as a test<commit_after>const TransportIPFS = require('./TransportIPFS');
const TransportHTTP = require('./TransportHTTP');
const Dweb = require('./Dweb');

// Utility packages (ours) Aand one-loners
const makepromises = require('./utils/makepromises');
function delay(ms, val) { return new Promise(resolve => {setTimeout(() => { resolve(val); },ms)})}

// Fake a browser like environment for some tests
const jsdom = require("jsdom");
const { JSDOM } = jsdom;        //TODO - figure out what this does, dont understand the Javascript
htmlfake = '<!DOCTYPE html>

Failed to load sb via StructuredBlock

Failed to load mb via MutableBlock

Failed to load sb via dwebfile

Failed to load mb via dwebfile

';
const dom = new JSDOM(htmlfake);
//console.log("XXX@8",dom.window.document.getElementById("myList.0").textContent); // Before loading = "Failed to load sb via StructuredBlock"
document = dom.window.document;   // Note in JS can't see "document" like can in python

let transportclass = TransportIPFS
//let transportclass = TransportHTTP
let verbose = false;
let blk;
let blk2;
let sb;

    transportclass.p_setup({}, verbose, {})
    .then((t) => {
        if (verbose) console.log("setup returned and transport set - including annoationList");
        Dweb.transport = t;
    })
    .then(() => transportclass.test(Dweb.transport, verbose))
    .then(() => Dweb.Block.test(Dweb.transport, verbose))
    .then(() => Dweb.StructuredBlock.test(Dweb.transport, document, verbose))
    .then((testobjs) => sb = testobjs.sb)
    .then(() => Dweb.MutableBlock.test(sb, Dweb.transport, verbose))
    .then(() => Dweb.CryptoLib.test(verbose))
    .then(() => verbose = true)
    //NEXT TEST FAILS
    //.then(() => Dweb.AccessControlList.p_test(verbose))
    //.then(() => Dweb.KeyChain.p_test(verbose))
    .then(() => console.log("delaying 10 secs"))
    .then(() => delay(10000))
    .then(()=>console.log("Completed test"))
    .catch((err) => console.log("Test failed", err))

/* path tests not done ... old ones
 console.log("Now test path using dwebfile and sb =======");
 verbose=false;
 Dweb.p_dwebfile("sb", sbhash, "langs/readme.md", ["p_elem", "myList.2", verbose, null]);
 console.log("Now test path using dwebfile and mb =======");
 Dweb.p_dwebfile("mb", mbhash, "langs/readme.md", ["p_elem", "myList.3", verbose, null]);
 console.log("END testing previouslyworking()");

 */<|endoftext|>


<commit_before>describe.only("go.routing (views)", function() {
  var routing = go.routing;

  var setUp = routing.testHelpers.setUp,
      tearDown = routing.testHelpers.tearDown,
      modelData = routing.testHelpers.modelData,
      newRoutingDiagram = routing.testHelpers.newRoutingDiagram;

  var plumbing = go.components.plumbing,
      noConnections = plumbing.testHelpers.noConnections;

  var testHelpers = go.testHelpers,
      noElExists = testHelpers.noElExists,
      oneElExists = testHelpers.oneElExists,
      response = testHelpers.rpc.response,
      errorResponse = testHelpers.rpc.errorResponse,
      assertRequest = testHelpers.rpc.assertRequest;

  describe(".RoutingEndpointView", function() {
    var RoutingEndpointModel = routing.models.RoutingEndpointModel;

    var diagram,
        state,
        endpoint;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();

      state = diagram.states.get('channel1');

      var model = new RoutingEndpointModel({
        uuid: 'endpoint80',
        name: 'default'
      });

      endpoint = state.endpoints.add(
        'endpoints',
        {model: model},
        {render: false, silent: true});
    });

    afterEach(function() {
      tearDown();
    });

    describe(".render", function() {
      it("should display the endpoint name", function() {
        assert(noElExists(state.$('[data-uuid="endpoint80"]')));
        endpoint.render();

        assert(oneElExists(state.$('[data-uuid="endpoint80"]')));
        assert.equal(state.$('[data-uuid="endpoint80"]').text(), 'default');
      });
    });
  });

  describe(".RoutingEntryCollection", function() {
    var RoutingEntryCollection = routing.views.RoutingEntryCollection;

    var diagram,
        collection;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();

      collection = new RoutingEntryCollection({
        view: diagram,
        attr: 'routing_entries'
      });
    });

    afterEach(function() {
      tearDown();
    });

    describe(".accepts", function() {
      it("should determine if a source and target match the accepted pairs",
      function() {
        var e1 = diagram.endpoints.get('endpoint1'),
            e4 = diagram.endpoints.get('endpoint4'),
            e5 = diagram.endpoints.get('endpoint5'),
            e6 = diagram.endpoints.get('endpoint6'),
            e8 = diagram.endpoints.get('endpoint8');

        assert(collection.accepts(e1, e4));
        assert(collection.accepts(e4, e1));

        assert(collection.accepts(e5, e8));
        assert(collection.accepts(e8, e5));

        assert(collection.accepts(e1, e8));
        assert(collection.accepts(e8, e1));

        assert.isFalse(collection.accepts(e1, e5));
        assert.isFalse(collection.accepts(e5, e1));

        assert.isFalse(collection.accepts(e4, e5));
        assert.isFalse(collection.accepts(e5, e4));

        assert.isFalse(collection.accepts(e4, e6));
        assert.isFalse(collection.accepts(e6, e4));
      });
    });
  });

  describe(".RoutingStateView", function() {
    var RouterStateView = routing.views.RouterStateView,
        RouterModel = routing.models.RouterModel;

    var diagram,
        state,
        $column;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();

      var model = new RouterModel({
        uuid: 'router3',
        type: 'keyword',
        name: 'keyword-router',
        description: 'Keyword',
        channel_endpoints: [{uuid: 'endpoint12', name: 'default'}],
        conversation_endpoints: [
          {uuid: 'endpoint13', name: 'default'},
          {uuid: 'endpoint14', name: 'default'},
          {uuid: 'endpoint15', name: 'default'},
          {uuid: 'endpoint16', name: 'default'}
        ]
      });

      state = diagram.states.add('routers', new RouterStateView({
        model: model,
        diagram: diagram,
        collection: diagram.states.members.get('routers')
      }), {render: false, silent: true});

    });

    afterEach(function() {
      tearDown();
    });

    describe(".endpointsForSide", function() {
      it("should return the endpoints for a side", function() {
        assert.deepEqual(
          state.endpointsForSide('left'),
          [state.endpoints.get('endpoint12')]
        );
        assert.deepEqual(state.endpointsForSide('right'), [
          state.endpoints.get('endpoint13'),
          state.endpoints.get('endpoint14'),
          state.endpoints.get('endpoint15'),
          state.endpoints.get('endpoint16')
        ]);
      });
    });

    describe(".findMaxEndpoints", function() {
      it("should return the max of two endpoint arrays", function() {
        assert.equal(state.findMaxEndpoints(), 4);
      });
    });

    describe(".tooManyEndpoints", function() {
      it("should check if there are too many endpoints", function() {
        assert(state.tooManyEndpoints());
      });
    });

    describe(".stretchedHeight", function() {
      it("should calculate the new height", function() {
        state.heightPerEndpoint = 15;
        assert.equal(state.stretchedHeight(), 4 * 15);
      });
    });

    describe(".render", function() {
      beforeEach(function() {
        $column = $('#diagram #routers');
      });

      it("should append the state to its column", function() {
        assert(noElExists($column.find('[data-uuid="router3"]')));
        state.render();
        assert(oneElExists($column.find('[data-uuid="router3"]')));
      });

      it("should not set a new height for few endpoints", function(){
        state.maxEndpoints = 5;
        state.$el.height(10);
        state.render();
        assert.equal(state.$el.height(), 10);
      });

      it("should set a new heightfor many endpoints", function(){
        state.maxEndpoints = 3;
        state.heightPerEndpoint = 15;
        state.model.get('conversation_endpoints');
        state.$el.height(10);
        state.render();
        assert.equal(state.$el.height(), 4 * 15);
      });

      it("should render its endpoints", function() {
        assert(noElExists($column.find('[data-uuid="router3"] .endpoint')));
        state.render();
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint12"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint13"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint14"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint15"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint16"]'));
      });

      it("should display the state's name as a link", function() {
        assert(noElExists('[data-uuid="router3"] a.name'));
        state.render();

        assert(oneElExists('[data-uuid="router3"] a.name'));
        assert.equal(
          $('[data-uuid="router3"] a.name').text(),
          'keyword-router');
      });
    });
  });

  describe.only(".RoutingColumnView", function() {
    var RoutingColumnView = routing.views.RoutingColumnView;

    var diagram,
        column;

    var ToyRoutingColumnView = RoutingColumnView.extend({
      // choose one of the state collections to test with
      id: 'channels',
      collectionName: 'channels'
    });

    function $endpointAt(i) {
      return column.states
        .at(i).endpoints
        .at(0).$el
    }

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();
      column = new ToyRoutingColumnView({diagram: diagram});
    });

    afterEach(function() {
      tearDown();
    });

    describe("when a state is dragged", function() {
      it("should repaint", function() {
        var repainted = false;
        column.on('repaint', function() { repainted = true; });

        // jquery-simulate doesn't seem to be working with jquery ui here,
        // so we are invoking the callback directly
        column.onDrag();

        assert(repainted);
      });
    });

    describe(".render", function() {
      it("should render the states it contains", function() {
        assert(noElExists(column.$('.state')));
        column.render();

        assert(oneElExists(column.$('[data-uuid="channel1"]')));
        assert(oneElExists(column.$('[data-uuid="channel2"]')));
        assert(oneElExists(column.$('[data-uuid="channel3"]')));
      });
    });

    describe(".repaint", function() {
      it("should tell jsPlumb to manage all endpoints in the column", function() {
        diagram.model.set('channels', diagram.model.get('channels').first(3));

        sinon.spy(jsPlumb, 'manage');
        sinon.spy(jsPlumb, 'repaint');
        column.repaint();

        assert.equal($endpointAt(0).attr('id'), jsPlumb.manage.args[0][0]);
        assert.equal($endpointAt(0).get(0), jsPlumb.manage.args[0][1]);

        assert.equal($endpointAt(1).attr('id'), jsPlumb.manage.args[1][0]);
        assert.equal($endpointAt(1).get(0), jsPlumb.manage.args[1][1]);

        assert.equal($endpointAt(2).attr('id'), jsPlumb.manage.args[2][0]);
        assert.equal($endpointAt(2).get(0), jsPlumb.manage.args[2][1]);

        jsPlumb.manage.restore();
        jsPlumb.repaint.restore();

      });

      it("should tell jsPlumb to manage all endpoints in the column", function() {
        diagram.model.set('channels', diagram.model.get('channels').first(3));

        sinon.spy(jsPlumb, 'repaint');
        column.repaint();

        assert($endpointAt(0).is(jsPlumb.repaint.args[0][0]));
        assert($endpointAt(1).is(jsPlumb.repaint.args[1][0]));
        assert($endpointAt(2).is(jsPlumb.repaint.args[2][0]));

        assert.deepEqual(
          _.pick(jsPlumb.repaint.args[0][1], 'left', 'top'),
          $endpointAt(0).offset());

        assert.deepEqual(
          _.pick(jsPlumb.repaint.args[1][1], 'left', 'top'),
          $endpointAt(1).offset());

        assert.deepEqual(
          _.pick(jsPlumb.repaint.args[2][1], 'left', 'top'),
          $endpointAt(2).offset());

        jsPlumb.repaint.restore();
      });

      it("should trigger a 'repaint' event", function(done) {
        column
          .on('repaint', function() { done(); })
          .repaint();
      });
    });
  });

  describe(".RoutingDiagramView", function() {
    var diagram;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();
    });

    afterEach(function() {
      tearDown();
    });

    describe("on 'error:unsupported' connection events", function() {
      beforeEach(function() {
        diagram.render();
      });

      it("should detach the jsPlumb connection", function(done) {
        var e4 = diagram.endpoints.get('endpoint4'),
            e6 = diagram.endpoints.get('endpoint6');

        diagram.connections.on('error:unsupported', function() {
          assert(noConnections(e4, e6));
          done();
        });

        jsPlumb.connect({source: e4.$el, target: e6.$el});
      });
    });

    describe(".render", function() {
      it("should render the states in its channels column", function() {
        var $channels = $('#diagram #channels');

        assert(noElExists($channels.find('.state')));
        diagram.render();

        assert(oneElExists($channels.find('[data-uuid="channel1"]')));
        assert(oneElExists($channels.find('[data-uuid="channel2"]')));
        assert(oneElExists($channels.find('[data-uuid="channel3"]')));
      });

      it("should render the states in its routers column", function() {
        var $blocks = $('#diagram #routers');

        assert(noElExists($blocks.find('.state')));
        diagram.render();

        assert(oneElExists($blocks.find('[data-uuid="router1"]')));
        assert(oneElExists($blocks.find('[data-uuid="router2"]')));
      });

      it("should render the states in its conversations column", function() {
        var $conversations = $('#diagram #conversations');

        assert(noElExists($conversations.find('.state')));
        diagram.render();

        assert(oneElExists($conversations.find('[data-uuid="conversation1"]')));
        assert(oneElExists($conversations.find('[data-uuid="conversation2"]')));
      });

      it("should render the connections between states across columns",
      function() {
        var e1_e4 = diagram.connections.get('endpoint1-endpoint4');

        assert(_.isEmpty(jsPlumb.getConnections()));
        diagram.render();

        assert.deepEqual(
          jsPlumb.getConnections(),
          [e1_e4.plumbConnection]
        );
      });
    });
  });

  describe(".RoutingView", function() {
    var RoutingView = routing.views.RoutingView,
        RoutingModel = routing.models.RoutingModel;

    var view,
        server;

    beforeEach(function() {
      setUp();
      server = sinon.fakeServer.create();

      view = new RoutingView({
        el: '#routing',
        model: new RoutingModel(modelData),
        sessionId: '123'
      });

      view.save.notifier.animate = false;
      view.reset.notifier.animate = false;

      view.diagram.render();
    });

    afterEach(function() {
      view.remove();
      server.restore();
      tearDown();
    });

    describe("when the save button is clicked", function() {
      it("should issue a save api call with the routing table changes",
      function(done) {
        server.respondWith(function(req) {
          assertRequest(
            req,
            '/api/v1/go/api',
            'update_routing_table',
            ['campaign1', view.model.toJSON()]);

          done();
        });

        // modify the diagram
        view.diagram.connections.remove('endpoint1-endpoint4');
        assert.notDeepEqual(view.model.toJSON(), modelData);

        view.$('#save').click();
        server.respond();
      });

      it("should notify the user if the save was successful", function() {
        server.respondWith(response());

        view.$('#save').click();
        server.respond();

        assert.include(view.save.notifier.$el.text(), "Save successful.");
      });

      it("should notify the user if an error occured", function() {
        server.respondWith(errorResponse('Aaah!'));

        view.$('#save').click();
        server.respond();

        assert.include(view.save.notifier.$el.text(), "Save failed.");
      });
    });

    describe("when the reset button is clicked", function() {
      it("should reset the routing table changes", function(done) {
        assert.deepEqual(view.model.toJSON(), modelData);

        // modify the diagram
        view.diagram.connections.remove('endpoint1-endpoint4');
        assert.notDeepEqual(view.model.toJSON(), modelData);

        view.$('#reset').click();
        view.reset.once('success', function() {
          assert.deepEqual(view.model.toJSON(), modelData);
          done();
        });
      });

      it("should notify the user", function() {
        view.$('#reset').click();
        view.reset.once('success', function() {
          assert.include(view.reset.notifier.$el.text(), "Reset successful.");
        });
      });
    });
  });
});
<commit_msg>Remove onlys, again<commit_after>describe("go.routing (views)", function() {
  var routing = go.routing;

  var setUp = routing.testHelpers.setUp,
      tearDown = routing.testHelpers.tearDown,
      modelData = routing.testHelpers.modelData,
      newRoutingDiagram = routing.testHelpers.newRoutingDiagram;

  var plumbing = go.components.plumbing,
      noConnections = plumbing.testHelpers.noConnections;

  var testHelpers = go.testHelpers,
      noElExists = testHelpers.noElExists,
      oneElExists = testHelpers.oneElExists,
      response = testHelpers.rpc.response,
      errorResponse = testHelpers.rpc.errorResponse,
      assertRequest = testHelpers.rpc.assertRequest;

  describe(".RoutingEndpointView", function() {
    var RoutingEndpointModel = routing.models.RoutingEndpointModel;

    var diagram,
        state,
        endpoint;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();

      state = diagram.states.get('channel1');

      var model = new RoutingEndpointModel({
        uuid: 'endpoint80',
        name: 'default'
      });

      endpoint = state.endpoints.add(
        'endpoints',
        {model: model},
        {render: false, silent: true});
    });

    afterEach(function() {
      tearDown();
    });

    describe(".render", function() {
      it("should display the endpoint name", function() {
        assert(noElExists(state.$('[data-uuid="endpoint80"]')));
        endpoint.render();

        assert(oneElExists(state.$('[data-uuid="endpoint80"]')));
        assert.equal(state.$('[data-uuid="endpoint80"]').text(), 'default');
      });
    });
  });

  describe(".RoutingEntryCollection", function() {
    var RoutingEntryCollection = routing.views.RoutingEntryCollection;

    var diagram,
        collection;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();

      collection = new RoutingEntryCollection({
        view: diagram,
        attr: 'routing_entries'
      });
    });

    afterEach(function() {
      tearDown();
    });

    describe(".accepts", function() {
      it("should determine if a source and target match the accepted pairs",
      function() {
        var e1 = diagram.endpoints.get('endpoint1'),
            e4 = diagram.endpoints.get('endpoint4'),
            e5 = diagram.endpoints.get('endpoint5'),
            e6 = diagram.endpoints.get('endpoint6'),
            e8 = diagram.endpoints.get('endpoint8');

        assert(collection.accepts(e1, e4));
        assert(collection.accepts(e4, e1));

        assert(collection.accepts(e5, e8));
        assert(collection.accepts(e8, e5));

        assert(collection.accepts(e1, e8));
        assert(collection.accepts(e8, e1));

        assert.isFalse(collection.accepts(e1, e5));
        assert.isFalse(collection.accepts(e5, e1));

        assert.isFalse(collection.accepts(e4, e5));
        assert.isFalse(collection.accepts(e5, e4));

        assert.isFalse(collection.accepts(e4, e6));
        assert.isFalse(collection.accepts(e6, e4));
      });
    });
  });

  describe(".RoutingStateView", function() {
    var RouterStateView = routing.views.RouterStateView,
        RouterModel = routing.models.RouterModel;

    var diagram,
        state,
        $column;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();

      var model = new RouterModel({
        uuid: 'router3',
        type: 'keyword',
        name: 'keyword-router',
        description: 'Keyword',
        channel_endpoints: [{uuid: 'endpoint12', name: 'default'}],
        conversation_endpoints: [
          {uuid: 'endpoint13', name: 'default'},
          {uuid: 'endpoint14', name: 'default'},
          {uuid: 'endpoint15', name: 'default'},
          {uuid: 'endpoint16', name: 'default'}
        ]
      });

      state = diagram.states.add('routers', new RouterStateView({
        model: model,
        diagram: diagram,
        collection: diagram.states.members.get('routers')
      }), {render: false, silent: true});

    });

    afterEach(function() {
      tearDown();
    });

    describe(".endpointsForSide", function() {
      it("should return the endpoints for a side", function() {
        assert.deepEqual(
          state.endpointsForSide('left'),
          [state.endpoints.get('endpoint12')]
        );
        assert.deepEqual(state.endpointsForSide('right'), [
          state.endpoints.get('endpoint13'),
          state.endpoints.get('endpoint14'),
          state.endpoints.get('endpoint15'),
          state.endpoints.get('endpoint16')
        ]);
      });
    });

    describe(".findMaxEndpoints", function() {
      it("should return the max of two endpoint arrays", function() {
        assert.equal(state.findMaxEndpoints(), 4);
      });
    });

    describe(".tooManyEndpoints", function() {
      it("should check if there are too many endpoints", function() {
        assert(state.tooManyEndpoints());
      });
    });

    describe(".stretchedHeight", function() {
      it("should calculate the new height", function() {
        state.heightPerEndpoint = 15;
        assert.equal(state.stretchedHeight(), 4 * 15);
      });
    });

    describe(".render", function() {
      beforeEach(function() {
        $column = $('#diagram #routers');
      });

      it("should append the state to its column", function() {
        assert(noElExists($column.find('[data-uuid="router3"]')));
        state.render();
        assert(oneElExists($column.find('[data-uuid="router3"]')));
      });

      it("should not set a new height for few endpoints", function(){
        state.maxEndpoints = 5;
        state.$el.height(10);
        state.render();
        assert.equal(state.$el.height(), 10);
      });

      it("should set a new heightfor many endpoints", function(){
        state.maxEndpoints = 3;
        state.heightPerEndpoint = 15;
        state.model.get('conversation_endpoints');
        state.$el.height(10);
        state.render();
        assert.equal(state.$el.height(), 4 * 15);
      });

      it("should render its endpoints", function() {
        assert(noElExists($column.find('[data-uuid="router3"] .endpoint')));
        state.render();
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint12"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint13"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint14"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint15"]'));
        assert(oneElExists('[data-uuid="router3"] [data-uuid="endpoint16"]'));
      });

      it("should display the state's name as a link", function() {
        assert(noElExists('[data-uuid="router3"] a.name'));
        state.render();

        assert(oneElExists('[data-uuid="router3"] a.name'));
        assert.equal(
          $('[data-uuid="router3"] a.name').text(),
          'keyword-router');
      });
    });
  });

  describe(".RoutingColumnView", function() {
    var RoutingColumnView = routing.views.RoutingColumnView;

    var diagram,
        column;

    var ToyRoutingColumnView = RoutingColumnView.extend({
      // choose one of the state collections to test with
      id: 'channels',
      collectionName: 'channels'
    });

    function $endpointAt(i) {
      return column.states
        .at(i).endpoints
        .at(0).$el
    }

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();
      column = new ToyRoutingColumnView({diagram: diagram});
    });

    afterEach(function() {
      tearDown();
    });

    describe("when a state is dragged", function() {
      it("should repaint", function() {
        var repainted = false;
        column.on('repaint', function() { repainted = true; });

        // jquery-simulate doesn't seem to be working with jquery ui here,
        // so we are invoking the callback directly
        column.onDrag();

        assert(repainted);
      });
    });

    describe(".render", function() {
      it("should render the states it contains", function() {
        assert(noElExists(column.$('.state')));
        column.render();

        assert(oneElExists(column.$('[data-uuid="channel1"]')));
        assert(oneElExists(column.$('[data-uuid="channel2"]')));
        assert(oneElExists(column.$('[data-uuid="channel3"]')));
      });
    });

    describe(".repaint", function() {
      it("should tell jsPlumb to manage all endpoints in the column", function() {
        diagram.model.set('channels', diagram.model.get('channels').first(3));

        sinon.spy(jsPlumb, 'manage');
        sinon.spy(jsPlumb, 'repaint');
        column.repaint();

        assert.equal($endpointAt(0).attr('id'), jsPlumb.manage.args[0][0]);
        assert.equal($endpointAt(0).get(0), jsPlumb.manage.args[0][1]);

        assert.equal($endpointAt(1).attr('id'), jsPlumb.manage.args[1][0]);
        assert.equal($endpointAt(1).get(0), jsPlumb.manage.args[1][1]);

        assert.equal($endpointAt(2).attr('id'), jsPlumb.manage.args[2][0]);
        assert.equal($endpointAt(2).get(0), jsPlumb.manage.args[2][1]);

        jsPlumb.manage.restore();
        jsPlumb.repaint.restore();

      });

      it("should tell jsPlumb to manage all endpoints in the column", function() {
        diagram.model.set('channels', diagram.model.get('channels').first(3));

        sinon.spy(jsPlumb, 'repaint');
        column.repaint();

        assert($endpointAt(0).is(jsPlumb.repaint.args[0][0]));
        assert($endpointAt(1).is(jsPlumb.repaint.args[1][0]));
        assert($endpointAt(2).is(jsPlumb.repaint.args[2][0]));

        assert.deepEqual(
          _.pick(jsPlumb.repaint.args[0][1], 'left', 'top'),
          $endpointAt(0).offset());

        assert.deepEqual(
          _.pick(jsPlumb.repaint.args[1][1], 'left', 'top'),
          $endpointAt(1).offset());

        assert.deepEqual(
          _.pick(jsPlumb.repaint.args[2][1], 'left', 'top'),
          $endpointAt(2).offset());

        jsPlumb.repaint.restore();
      });

      it("should trigger a 'repaint' event", function(done) {
        column
          .on('repaint', function() { done(); })
          .repaint();
      });
    });
  });

  describe(".RoutingDiagramView", function() {
    var diagram;

    beforeEach(function() {
      setUp();
      diagram = newRoutingDiagram();
    });

    afterEach(function() {
      tearDown();
    });

    describe("on 'error:unsupported' connection events", function() {
      beforeEach(function() {
        diagram.render();
      });

      it("should detach the jsPlumb connection", function(done) {
        var e4 = diagram.endpoints.get('endpoint4'),
            e6 = diagram.endpoints.get('endpoint6');

        diagram.connections.on('error:unsupported', function() {
          assert(noConnections(e4, e6));
          done();
        });

        jsPlumb.connect({source: e4.$el, target: e6.$el});
      });
    });

    describe(".render", function() {
      it("should render the states in its channels column", function() {
        var $channels = $('#diagram #channels');

        assert(noElExists($channels.find('.state')));
        diagram.render();

        assert(oneElExists($channels.find('[data-uuid="channel1"]')));
        assert(oneElExists($channels.find('[data-uuid="channel2"]')));
        assert(oneElExists($channels.find('[data-uuid="channel3"]')));
      });

      it("should render the states in its routers column", function() {
        var $blocks = $('#diagram #routers');

        assert(noElExists($blocks.find('.state')));
        diagram.render();

        assert(oneElExists($blocks.find('[data-uuid="router1"]')));
        assert(oneElExists($blocks.find('[data-uuid="router2"]')));
      });

      it("should render the states in its conversations column", function() {
        var $conversations = $('#diagram #conversations');

        assert(noElExists($conversations.find('.state')));
        diagram.render();

        assert(oneElExists($conversations.find('[data-uuid="conversation1"]')));
        assert(oneElExists($conversations.find('[data-uuid="conversation2"]')));
      });

      it("should render the connections between states across columns",
      function() {
        var e1_e4 = diagram.connections.get('endpoint1-endpoint4');

        assert(_.isEmpty(jsPlumb.getConnections()));
        diagram.render();

        assert.deepEqual(
          jsPlumb.getConnections(),
          [e1_e4.plumbConnection]
        );
      });
    });
  });

  describe(".RoutingView", function() {
    var RoutingView = routing.views.RoutingView,
        RoutingModel = routing.models.RoutingModel;

    var view,
        server;

    beforeEach(function() {
      setUp();
      server = sinon.fakeServer.create();

      view = new RoutingView({
        el: '#routing',
        model: new RoutingModel(modelData),
        sessionId: '123'
      });

      view.save.notifier.animate = false;
      view.reset.notifier.animate = false;

      view.diagram.render();
    });

    afterEach(function() {
      view.remove();
      server.restore();
      tearDown();
    });

    describe("when the save button is clicked", function() {
      it("should issue a save api call with the routing table changes",
      function(done) {
        server.respondWith(function(req) {
          assertRequest(
            req,
            '/api/v1/go/api',
            'update_routing_table',
            ['campaign1', view.model.toJSON()]);

          done();
        });

        // modify the diagram
        view.diagram.connections.remove('endpoint1-endpoint4');
        assert.notDeepEqual(view.model.toJSON(), modelData);

        view.$('#save').click();
        server.respond();
      });

      it("should notify the user if the save was successful", function() {
        server.respondWith(response());

        view.$('#save').click();
        server.respond();

        assert.include(view.save.notifier.$el.text(), "Save successful.");
      });

      it("should notify the user if an error occured", function() {
        server.respondWith(errorResponse('Aaah!'));

        view.$('#save').click();
        server.respond();

        assert.include(view.save.notifier.$el.text(), "Save failed.");
      });
    });

    describe("when the reset button is clicked", function() {
      it("should reset the routing table changes", function(done) {
        assert.deepEqual(view.model.toJSON(), modelData);

        // modify the diagram
        view.diagram.connections.remove('endpoint1-endpoint4');
        assert.notDeepEqual(view.model.toJSON(), modelData);

        view.$('#reset').click();
        view.reset.once('success', function() {
          assert.deepEqual(view.model.toJSON(), modelData);
          done();
        });
      });

      it("should notify the user", function() {
        view.$('#reset').click();
        view.reset.once('success', function() {
          assert.include(view.reset.notifier.$el.text(), "Reset successful.");
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';
import React from 'react';
import { connect } from 'react-redux';
import _ from 'lodash';

import { formatThousands } from '../utils/format';
import { fetchLocations, invalidateAllLocationData, fetchLatestMeasurements } from '../actions/action-creators';
import { getMapColors } from '../utils/colors';
import { getCountryBbox } from '../utils/countries';
import InfoMessage from '../components/info-message';
import LocationCard from '../components/location-card';
import ShareBtn from '../components/share-btn';
import MapComponent from '../components/map';

var Country = React.createClass({
  displayName: 'Country',

  propTypes: {
    params: React.PropTypes.object,

    _invalidateAllLocationData: React.PropTypes.func,
    _fetchLocations: React.PropTypes.func,
    _fetchLatestMeasurements: React.PropTypes.func,

    countries: React.PropTypes.array,
    sources: React.PropTypes.array,
    parameters: React.PropTypes.array,

    latestMeasurements: React.PropTypes.shape({
      fetching: React.PropTypes.bool,
      fetched: React.PropTypes.bool,
      error: React.PropTypes.string,
      data: React.PropTypes.object
    }),

    locations: React.PropTypes.shape({
      fetching: React.PropTypes.bool,
      fetched: React.PropTypes.bool,
      error: React.PropTypes.string,
      data: React.PropTypes.object
    })
  },

  shouldFetchData: function (prevProps) {
    let prevCountry = prevProps.params.name;
    let currCountry = this.props.params.name;

    return prevCountry !== currCountry;
  },

  fetchData: function () {
    this.props._fetchLocations(1, {
      country: this.props.params.name
    }, 1000);
    this.props._fetchLatestMeasurements({country: this.props.params.name, has_geo: 'true'});
  },

  //
  // Start life-cycle methods
  //

  componentDidMount: function () {
    this.fetchData();
  },

  componentDidUpdate: function (prevProps) {
    // this.props._invalidateAllLocationData();
    this.shouldFetchData(prevProps) && this.fetchData();
  },

  //
  // Start render methods
  //

  renderCountryList: function () {
    let {fetched, fetching, error, data: {results}} = this.props.locations;
    if (!fetched && !fetching) {
      return null;
    }

    if (fetching) {
      return (
Data is loading
);
    }

    if (error) {
      return (
        <InfoMessage>

Uhoh, something went wrong.

There was a problem getting the data. If the problem persists let us know.

          Send us an Email
        </InfoMessage>
      );
    }

    let groupped = _(results)
      .sortBy('city')
      .groupBy('city')
      .value();

    let countriesList = _.map(groupped, (locations, k) => (

{k} {locations.length} {locations.length > 1 ? 'locations' : 'location'}

            Download

          {locations.map(o => {
            let countryData = _.find(this.props.countries, {code: o.country});
            let sourceData = _.find(this.props.sources, {name: o.sourceName});
            let params = o.parameters.map(o => _.find(this.props.parameters, {id: o}));
            return <LocationCard
                    key={o.location}
                    name={o.location}
                    city={o.city}
                    countryData={countryData}
                    sourceData={sourceData}
                    totalMeasurements={o.count}
                    parametersList={params}
                    lastUpdate={o.lastUpdated}
                    collectionStart={o.firstUpdated}
                    compact />;
          })}

    ));

    return (

        {countriesList}

    );
  },

  renderMap: function () {
    let {fetched, fetching, error, data: {results}} = this.props.latestMeasurements;
    if (!fetched && !fetching) {
      return null;
    }

    if (fetching) {
      return (
Data is loading
);
    }

    if (error) {
      return (
        <InfoMessage>

Uhoh, something went wrong.

There was a problem getting the data. If the problem persists let us know.

          Send us an Email
        </InfoMessage>
      );
    }

    const mapColors = getMapColors();
    const colorWidth = 100 / mapColors.length;
    const bbox = getCountryBbox(this.props.params.name);

    return (

        <MapComponent
          bbox={bbox}
          zoom={1}
          measurements={results}
          parameter={_.find(this.props.parameters, {id: 'pm25'})}
          disableScrollZoom >

Showing most recent values for PM2.5

                {mapColors.map(o => (
                  <li key={o.label} style={{'backgroundColor': o.color, width: `${colorWidth}%`}} className='color-scale__item'>{o.label}

                ))}

        </MapComponent>

    );
  },

  render: function () {
    let countryData = _.find(this.props.countries, {code: this.props.params.name});
    let sourcesData = _.filter(this.props.sources, {country: this.props.params.name});

    return (

{countryData.name}

                <ShareBtn />

{countryData.cities} areas

{countryData.locations} locations

{formatThousands(countryData.count)} measurements

{sourcesData.length} {sourcesData.length > 1 ? 'sources' : 'source'}

View API Docs

Download

                {this.renderMap()}
                {this.renderCountryList()}

    );
  }
});

// /////////////////////////////////////////////////////////////////// //
// Connect functions

function selector (state) {
  return {
    countries: state.baseData.data.countries,
    sources: state.baseData.data.sources,
    parameters: state.baseData.data.parameters,

    latestMeasurements: state.latestMeasurements,
    locations: state.locations
  };
}

function dispatcher (dispatch) {
  return {
    _fetchLocations: (...args) => dispatch(fetchLocations(...args)),
    _fetchLatestMeasurements: (...args) => dispatch(fetchLatestMeasurements(...args)),
    _invalidateAllLocationData: (...args) => dispatch(invalidateAllLocationData(...args))
  };
}

module.exports = connect(selector, dispatcher)(Country);
<commit_msg>Fix legend on country page<commit_after>'use strict';
import React from 'react';
import { connect } from 'react-redux';
import _ from 'lodash';

import { formatThousands } from '../utils/format';
import { fetchLocations, invalidateAllLocationData, fetchLatestMeasurements } from '../actions/action-creators';
import { generateLegendStops } from '../utils/colors';
import { getCountryBbox } from '../utils/countries';
import InfoMessage from '../components/info-message';
import LocationCard from '../components/location-card';
import ShareBtn from '../components/share-btn';
import MapComponent from '../components/map';

var Country = React.createClass({
  displayName: 'Country',

  propTypes: {
    params: React.PropTypes.object,

    _invalidateAllLocationData: React.PropTypes.func,
    _fetchLocations: React.PropTypes.func,
    _fetchLatestMeasurements: React.PropTypes.func,

    countries: React.PropTypes.array,
    sources: React.PropTypes.array,
    parameters: React.PropTypes.array,

    latestMeasurements: React.PropTypes.shape({
      fetching: React.PropTypes.bool,
      fetched: React.PropTypes.bool,
      error: React.PropTypes.string,
      data: React.PropTypes.object
    }),

    locations: React.PropTypes.shape({
      fetching: React.PropTypes.bool,
      fetched: React.PropTypes.bool,
      error: React.PropTypes.string,
      data: React.PropTypes.object
    })
  },

  shouldFetchData: function (prevProps) {
    let prevCountry = prevProps.params.name;
    let currCountry = this.props.params.name;

    return prevCountry !== currCountry;
  },

  fetchData: function () {
    this.props._fetchLocations(1, {
      country: this.props.params.name
    }, 1000);
    this.props._fetchLatestMeasurements({country: this.props.params.name, has_geo: 'true'});
  },

  //
  // Start life-cycle methods
  //

  componentDidMount: function () {
    this.fetchData();
  },

  componentDidUpdate: function (prevProps) {
    // this.props._invalidateAllLocationData();
    this.shouldFetchData(prevProps) && this.fetchData();
  },

  //
  // Start render methods
  //

  renderCountryList: function () {
    let {fetched, fetching, error, data: {results}} = this.props.locations;
    if (!fetched && !fetching) {
      return null;
    }

    if (fetching) {
      return (
Data is loading
);
    }

    if (error) {
      return (
        <InfoMessage>

Uhoh, something went wrong.

There was a problem getting the data. If the problem persists let us know.

          Send us an Email
        </InfoMessage>
      );
    }

    let groupped = _(results)
      .sortBy('city')
      .groupBy('city')
      .value();

    let countriesList = _.map(groupped, (locations, k) => (

{k} {locations.length} {locations.length > 1 ? 'locations' : 'location'}

            Download

          {locations.map(o => {
            let countryData = _.find(this.props.countries, {code: o.country});
            let sourceData = _.find(this.props.sources, {name: o.sourceName});
            let params = o.parameters.map(o => _.find(this.props.parameters, {id: o}));
            return <LocationCard
                    key={o.location}
                    name={o.location}
                    city={o.city}
                    countryData={countryData}
                    sourceData={sourceData}
                    totalMeasurements={o.count}
                    parametersList={params}
                    lastUpdate={o.lastUpdated}
                    collectionStart={o.firstUpdated}
                    compact />;
          })}

    ));

    return (

        {countriesList}

    );
  },

  renderMap: function () {
    let {fetched, fetching, error, data: {results}} = this.props.latestMeasurements;
    if (!fetched && !fetching) {
      return null;
    }

    if (fetching) {
      return (
Data is loading
);
    }

    if (error) {
      return (
        <InfoMessage>

Uhoh, something went wrong.

There was a problem getting the data. If the problem persists let us know.

          Send us an Email
        </InfoMessage>
      );
    }

    const scaleStops = generateLegendStops('pm25');
    const colorWidth = 100 / scaleStops.length;
    const bbox = getCountryBbox(this.props.params.name);

    return (

        <MapComponent
          bbox={bbox}
          zoom={1}
          measurements={results}
          parameter={_.find(this.props.parameters, {id: 'pm25'})}
          disableScrollZoom >

Showing most recent values for PM2.5

                {scaleStops.map(o => (
                  <li key={o.label} style={{'backgroundColor': o.color, width: `${colorWidth}%`}} className='color-scale__item'>{o.label}

                ))}

        </MapComponent>

    );
  },

  render: function () {
    let countryData = _.find(this.props.countries, {code: this.props.params.name});
    let sourcesData = _.filter(this.props.sources, {country: this.props.params.name});

    return (

{countryData.name}

                <ShareBtn />

{countryData.cities} areas

{countryData.locations} locations

{formatThousands(countryData.count)} measurements

{sourcesData.length} {sourcesData.length > 1 ? 'sources' : 'source'}

View API Docs

Download

                {this.renderMap()}
                {this.renderCountryList()}

    );
  }
});

// /////////////////////////////////////////////////////////////////// //
// Connect functions

function selector (state) {
  return {
    countries: state.baseData.data.countries,
    sources: state.baseData.data.sources,
    parameters: state.baseData.data.parameters,

    latestMeasurements: state.latestMeasurements,
    locations: state.locations
  };
}

function dispatcher (dispatch) {
  return {
    _fetchLocations: (...args) => dispatch(fetchLocations(...args)),
    _fetchLatestMeasurements: (...args) => dispatch(fetchLatestMeasurements(...args)),
    _invalidateAllLocationData: (...args) => dispatch(invalidateAllLocationData(...args))
  };
}

module.exports = connect(selector, dispatcher)(Country);
<|endoftext|>


<commit_before>if (typeof(require) !== 'undefined') {
  // commonjs
  var Harness = require('../test-harness');
  Harness.run('./test/core');
} else if (typeof(load) !== 'undefined') {
  // jsc
  var Harness = load('test-harness.js');
  Harness.run('test/core.js');
}
<commit_msg>added test/extra to harness<commit_after>if (typeof(require) !== 'undefined') {
  // commonjs
  var Harness = require('../test-harness');
  Harness.run('./test/core');
  Harness.run('./test/extra');
} else if (typeof(load) !== 'undefined') {
  // jsc
  var Harness = load('test-harness.js');
  Harness.run('test/core.js');
  Harness.run('test/extra.js');
}
<|endoftext|>


<commit_before>/**
 * 2011 Peter 'Pita' Martischka
 *
 * 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.
 */

var dbWrapper = require("./dbWrapper");
var async = require("async");

/**
 The Constructor
*/
exports.database = function(type, dbSettings, wrapperSettings)
{
  if(!type)
  {
    type = "sqlite3";
    dbSettings = null;
    wrapperSettings = null;
  }

  //saves all settings and require the db module
  this.type = type;
  this.db_module = require("./" + type + "_db");
  this.dbSettings = dbSettings;
  this.wrapperSettings = wrapperSettings;
}

exports.database.prototype.init = function(callback)
{
  var _this = this;

  async.waterfall([
    //initalizie the db driver
    function(callback)
    {
      _this.db = new _this.db_module.database(_this.dbSettings);
      _this.db.init(callback);
    },
    //initalize the db wrapper
    function(callback)
    {
      _this.db = new dbWrapper.database(_this.db, _this.wrapperSettings);
      _this.db.init(callback);
    }
  ],callback);
}

/**
 Wrapper functions
*/

exports.database.prototype.get = function (key, callback)
{
  this.db.get(key, callback);
}

exports.database.prototype.set = function (key, value, callback)
{
  this.db.set(key, value, callback);
}

exports.database.prototype.remove = function (key, callback)
{
  this.db.remove(key, callback);
}

exports.database.prototype.close = function(callback)
{
  this.db.close(callback);
}
<commit_msg>Fixed a little Bug<commit_after>/**
 * 2011 Peter 'Pita' Martischka
 *
 * 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.
 */

var dbWrapper = require("./dbWrapper");
var async = require("async");

/**
 The Constructor
*/
exports.database = function(type, dbSettings, wrapperSettings)
{
  if(!type)
  {
    type = "sqlite";
    dbSettings = null;
    wrapperSettings = null;
  }

  //saves all settings and require the db module
  this.type = type;
  this.db_module = require("./" + type + "_db");
  this.dbSettings = dbSettings;
  this.wrapperSettings = wrapperSettings;
}

exports.database.prototype.init = function(callback)
{
  var _this = this;

  async.waterfall([
    //initalizie the db driver
    function(callback)
    {
      _this.db = new _this.db_module.database(_this.dbSettings);
      _this.db.init(callback);
    },
    //initalize the db wrapper
    function(callback)
    {
      _this.db = new dbWrapper.database(_this.db, _this.wrapperSettings);
      _this.db.init(callback);
    }
  ],callback);
}

/**
 Wrapper functions
*/

exports.database.prototype.get = function (key, callback)
{
  this.db.get(key, callback);
}

exports.database.prototype.set = function (key, value, callback)
{
  this.db.set(key, value, callback);
}

exports.database.prototype.remove = function (key, callback)
{
  this.db.remove(key, callback);
}

exports.database.prototype.close = function(callback)
{
  this.db.close(callback);
}
<|endoftext|>


<commit_before>/* ========================================================================
 * Bootstrap (plugin): validator.js v0.3.0
 * ========================================================================
 * The MIT License (MIT)
 *
 * Copyright (c) 2013 Spiceworks, Inc.
 * Made by Cina Saffary (@1000hz) in the style of Bootstrap 3 era @fat
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * ======================================================================== */

+function ($) {
  'use strict';

  // VALIDATOR CLASS DEFINITION
  // ==========================

  var Validator = function (element, options) {
    this.$element = $(element)
    this.options  = options

    this.toggleSubmit()

    this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', $.proxy(this.validateInput, this))

    this.$element.find('[data-match]').each(function () {
      var $this  = $(this)
      var target = $this.data('match')

      $(target).on('input.bs.validator', function (e) {
        $this.val() && $this.trigger('input')
      })
    })
  }

  Validator.DEFAULTS = {
    delay: 500,
    errors: {
      match: 'Does not match',
      minlength: 'Not long enough'
    }
  }

  Validator.VALIDATORS = {
    native: function ($el) {
      var el = $el[0]
      return el.checkValidity ? el.checkValidity() : true
    },
    match: function ($el) {
      var target = $el.data('match')
      return !$el.val() || $el.val() === $(target).val()
    },
    minlength: function ($el) {
      var minlength = $el.data('minlength')
      return !$el.val() || $el.val().length >= minlength
    }
  }

  Validator.prototype.validateInput = function (e) {
    var $el        = $(e.target)
    var prevErrors = $el.data('bs.validator.errors')
    var errors

    this.$element.trigger(e = $.Event('validate.bs.validator', {relatedTarget: $el[0]}))

    if (e.isDefaultPrevented()) return

    $el.data('bs.validator.errors', errors = this.runValidators($el))

    errors.length ? this.showErrors($el) : this.clearErrors($el)

    if (!prevErrors || errors.toString() !== prevErrors.toString()) {
      e = errors.length
        ? $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors})
        : $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors})

      this.$element.trigger(e)
    }

    this.toggleSubmit()

    this.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]}))
  }

  Validator.prototype.runValidators = function ($el) {
    var errors     = []
    var validators = [Validator.VALIDATORS.native]

    $.each(Validator.VALIDATORS, $.proxy(function (key, validator) {
      if (($el.data(key) || key == 'native') && !validator.call(this, $el)) {
        var error = $el.data(key + '-error')
          || $el.data('error')
          || key == 'native' && $el[0].validationMessage
          || this.options.errors[key]

        !~errors.indexOf(error) && errors.push(error)
      }
    }, this))

    return errors
  }

  Validator.prototype.validate = function () {
    var delay = this.options.delay

    this.options.delay = 0
    this.$element.find(':input').trigger('input')
    this.options.delay = delay

    return this
  }

  Validator.prototype.showErrors = function ($el) {
    function callback() {
      var $group = $el.closest('.form-group')
      var $block = $group.find('.help-block.with-errors')
      var errors = $el.data('bs.validator.errors')

      if (!errors.length) return

      errors = $('<ul/>')
        .addClass('list-unstyled')
        .append($.map(errors, function (error) { return $('<li/>').text(error) }))

      $block.data('bs.validator.originalContent') === undefined && $block.data('bs.validator.originalContent', $block.html())
      $block.empty().append(errors)

      $group.addClass('has-error')
    }

    if (this.options.delay) {
      window.clearTimeout($el.data('bs.validator.timeout'))
      $el.data('bs.timeout', window.setTimeout(callback, this.options.delay))
    } else callback()
  }

  Validator.prototype.clearErrors = function ($el) {
    var $group = $el.closest('.form-group')
    var $block = $group.find('.help-block.with-errors')

    $block.html($block.data('bs.validator.originalContent'))
    $group.removeClass('has-error')
  }

  Validator.prototype.hasErrors = function () {
    function fieldErrors() {
      return !!($(this).data('bs.validator.errors') || []).length
    }

    return !!this.$element.find(':input:enabled').filter(fieldErrors).length
  }

  Validator.prototype.isIncomplete = function () {
    function fieldIncomplete() {
      return this.type === 'checkbox' ? !this.checked                                   :
             this.type === 'radio'    ? !$('[name="' + this.name + '"]:checked').length :
                                        $.trim(this.value) === ''
    }

    return !!this.$element.find(':input[required]:enabled').filter(fieldIncomplete).length
  }

  Validator.prototype.toggleSubmit = function () {
    var $btn = this.$element.find('input[type="submit"], button[type="submit"]')
    $btn.attr('disabled', this.isIncomplete() || this.hasErrors())
  }

  // VALIDATOR PLUGIN DEFINITION
  // ===========================

  var old = $.fn.validator

  $.fn.validator = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option)
      var data    = $this.data('bs.validator')

      if (!data) $this.data('bs.validator', (data = new Validator(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.validator.Constructor = Validator;

  // VALIDATOR NO CONFLICT
  // =====================

  $.fn.validator.noConflict = function () {
    $.fn.validator = old
    return this
  }

  // VALIDATOR DATA-API
  // ==================

  $(window).on('load', function () {
    $('form[data-toggle="validator"]').each(function () {
      var $form = $(this)
      $form.validator($form.data())
    })
  })

}(jQuery);
<commit_msg>Forgot to namespace a data attribute<commit_after>/* ========================================================================
 * Bootstrap (plugin): validator.js v0.3.0
 * ========================================================================
 * The MIT License (MIT)
 *
 * Copyright (c) 2013 Spiceworks, Inc.
 * Made by Cina Saffary (@1000hz) in the style of Bootstrap 3 era @fat
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 * ======================================================================== */

+function ($) {
  'use strict';

  // VALIDATOR CLASS DEFINITION
  // ==========================

  var Validator = function (element, options) {
    this.$element = $(element)
    this.options  = options

    this.toggleSubmit()

    this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', $.proxy(this.validateInput, this))

    this.$element.find('[data-match]').each(function () {
      var $this  = $(this)
      var target = $this.data('match')

      $(target).on('input.bs.validator', function (e) {
        $this.val() && $this.trigger('input')
      })
    })
  }

  Validator.DEFAULTS = {
    delay: 500,
    errors: {
      match: 'Does not match',
      minlength: 'Not long enough'
    }
  }

  Validator.VALIDATORS = {
    native: function ($el) {
      var el = $el[0]
      return el.checkValidity ? el.checkValidity() : true
    },
    match: function ($el) {
      var target = $el.data('match')
      return !$el.val() || $el.val() === $(target).val()
    },
    minlength: function ($el) {
      var minlength = $el.data('minlength')
      return !$el.val() || $el.val().length >= minlength
    }
  }

  Validator.prototype.validateInput = function (e) {
    var $el        = $(e.target)
    var prevErrors = $el.data('bs.validator.errors')
    var errors

    this.$element.trigger(e = $.Event('validate.bs.validator', {relatedTarget: $el[0]}))

    if (e.isDefaultPrevented()) return

    $el.data('bs.validator.errors', errors = this.runValidators($el))

    errors.length ? this.showErrors($el) : this.clearErrors($el)

    if (!prevErrors || errors.toString() !== prevErrors.toString()) {
      e = errors.length
        ? $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors})
        : $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors})

      this.$element.trigger(e)
    }

    this.toggleSubmit()

    this.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]}))
  }

  Validator.prototype.runValidators = function ($el) {
    var errors     = []
    var validators = [Validator.VALIDATORS.native]

    $.each(Validator.VALIDATORS, $.proxy(function (key, validator) {
      if (($el.data(key) || key == 'native') && !validator.call(this, $el)) {
        var error = $el.data(key + '-error')
          || $el.data('error')
          || key == 'native' && $el[0].validationMessage
          || this.options.errors[key]

        !~errors.indexOf(error) && errors.push(error)
      }
    }, this))

    return errors
  }

  Validator.prototype.validate = function () {
    var delay = this.options.delay

    this.options.delay = 0
    this.$element.find(':input').trigger('input')
    this.options.delay = delay

    return this
  }

  Validator.prototype.showErrors = function ($el) {
    function callback() {
      var $group = $el.closest('.form-group')
      var $block = $group.find('.help-block.with-errors')
      var errors = $el.data('bs.validator.errors')

      if (!errors.length) return

      errors = $('<ul/>')
        .addClass('list-unstyled')
        .append($.map(errors, function (error) { return $('<li/>').text(error) }))

      $block.data('bs.validator.originalContent') === undefined && $block.data('bs.validator.originalContent', $block.html())
      $block.empty().append(errors)

      $group.addClass('has-error')
    }

    if (this.options.delay) {
      window.clearTimeout($el.data('bs.validator.timeout'))
      $el.data('bs.validator.timeout', window.setTimeout(callback, this.options.delay))
    } else callback()
  }

  Validator.prototype.clearErrors = function ($el) {
    var $group = $el.closest('.form-group')
    var $block = $group.find('.help-block.with-errors')

    $block.html($block.data('bs.validator.originalContent'))
    $group.removeClass('has-error')
  }

  Validator.prototype.hasErrors = function () {
    function fieldErrors() {
      return !!($(this).data('bs.validator.errors') || []).length
    }

    return !!this.$element.find(':input:enabled').filter(fieldErrors).length
  }

  Validator.prototype.isIncomplete = function () {
    function fieldIncomplete() {
      return this.type === 'checkbox' ? !this.checked                                   :
             this.type === 'radio'    ? !$('[name="' + this.name + '"]:checked').length :
                                        $.trim(this.value) === ''
    }

    return !!this.$element.find(':input[required]:enabled').filter(fieldIncomplete).length
  }

  Validator.prototype.toggleSubmit = function () {
    var $btn = this.$element.find('input[type="submit"], button[type="submit"]')
    $btn.attr('disabled', this.isIncomplete() || this.hasErrors())
  }

  // VALIDATOR PLUGIN DEFINITION
  // ===========================

  var old = $.fn.validator

  $.fn.validator = function (option) {
    return this.each(function () {
      var $this   = $(this)
      var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option)
      var data    = $this.data('bs.validator')

      if (!data) $this.data('bs.validator', (data = new Validator(this, options)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.validator.Constructor = Validator;

  // VALIDATOR NO CONFLICT
  // =====================

  $.fn.validator.noConflict = function () {
    $.fn.validator = old
    return this
  }

  // VALIDATOR DATA-API
  // ==================

  $(window).on('load', function () {
    $('form[data-toggle="validator"]').each(function () {
      var $form = $(this)
      $form.validator($form.data())
    })
  })

}(jQuery);
<|endoftext|>