<commit_before>/*global io*/
import DS from 'ember-data';
import Ember from 'ember';
import SailsBaseAdapter from 'ember-data-sails/adapters/sails-base';

/**
 * Adapter for SailsJS sockets
 *
 * @since 0.0.1
 * @class SailsSocketAdapter
 * @extends SailsBaseAdapter
 * @constructor
 */
export default SailsBaseAdapter.extend({
  /**
   * Holds the descriptors for each event listened on the socket
   * @since 0.0.1
   * @property _socketListeners
   * @type Object<Object>
   * @private
   */
  _socketListeners: null,

  /**
   * @inheritDoc
   */
  init: function () {
    this._super();
    this._socketListeners = {};
    this.socketAddListener('connect', this._handleSocketConnect);
  },

  /**
   * @inheritDoc
   */
  destroy: function () {
    Ember.keys(this._socketListeners).map(this.socketRemoveListener, this);
    this._super();
  },

  /**
   * Adds an event listener to the socket with some meta
   *
   * @since 0.0.1
   * @method socketAddListener
   * @param {String} event The event to listen to
   * @param {Function|String} callback The method to be called (will be bound on the adapter)
   * @param {mixed} [metadata] SOme metadata to store and get passed over the callback
   * @param (Boolean} [autoReAttach] Whether to re-attach the listener after a reconnection
   * @chainable
   */
  socketAddListener: function (event, callback, metadata, autoReAttach) {
    var def = this._socketListeners[event];
    if (def) {
      this._log('info', 'already listening for ' + event, def);
      return;
    }
    callback = typeof callback === 'string' ? this[callback] : callback;
    def = this._socketListeners[event] = {data: metadata, event: event, autoReAttach: !!autoReAttach};
    def.callback = callback.bind(this, def);
    io.socket.addListener(event, def.callback);
    this._log('debug', 'listening for ' + event, def);
    return this;
  },

  /**
   * Remove an event listener and stop listening for that even on the socket
   *
   * @since 0.0.1
   * @method socketRemoveListener
   * @param {String} event The event to stop listening for
   * @chainable
   */
  socketRemoveListener: function (event) {
    var def = this._socketListeners[event];
    if (!def) {
      this._log('info', 'not listening for ' + event + ' yet');
      return;
    }
    delete this._socketListeners[event];
    io.socket.removeListener(event, def.callback);
    this._log('debug', 'stop listening for ' + event, def);
    return this;
  },

  /**
   * Re-attach all listeners on the socket
   *
   * @since 0.0.1
   * @method socketRebindListeners
   * @chainable
   */
  socketRebindListeners: function () {
    var meta;
    for (var event in this._socketListeners) {
      meta = this._socketListeners[event];
      if (meta.autoReAttach) {
        try {
          io.socket.removeListener(event, meta.callback);
        }
        catch (e) {
          // noop
        }
        io.socket.addListener(event, meta.callback);
        this._log('info', 're-attached listener for ' + event, meta);
      }
    }
    return this;
  },

  /**
   * Finds whether the socket is listening for an event or not
   *
   * @since 0.0.1
   * @method socketIsListening
   * @param {String} event The event to test
   * @returns {Boolean} Returns `true` if we're listening for that event, else `false`
   */
  socketIsListening: function (event) {
    return !!this._socketListeners[event];
  },

  /**
   * @since 0.0.1
   * @method ajax
   * @inheritDoc
   */
  ajax: function (url, method, data) {
    return this.socket(url, method, data);
  },

  /**
   * Send a message over the socket
   *
   * @since 0.0.1
   * @method socket
   * @param {String} url The HTTP URL to fake
   * @param {String} method The HTTP method to fake
   * @param {Object} data The data to send
   * @returns {Ember.RSVP.Promise} A promise resolving to the result or an error
   */
  socket: function (url, method, data) {
    method = method.toLowerCase();
    var self = this, req = data;
    if (method !== 'get') {
      this.checkCSRF(data);
    }
    return new Ember.RSVP.Promise(function (resolve, reject) {
      io.socket[method](url, data, function (data) {
        var res = data, cb = reject, level = 'warning';
        if (self.isErrorObject(data)) {
          if (data.errors) {
            level = 'error';
            res = new DS.InvalidError(self.formatError(data));
          }
        }
        else {
          cb = resolve;
          level = 'info';
        }
        self._log(level, 'socket request: ' + method + ' ' + url, {request: req, response: data});
        cb(res);
      });
    });
  },

  /**
   * @since 0.0.1
   * @method buildUrl
   * @inheritDoc
   */
  buildURL: function (type) {
    this._listenToSocket(type);
    return this._super.apply(this, arguments);
  },

  /**
   * @since 0.0.1
   * @method createRecord
   * @inheritDoc
   */
  createRecord: function (store, type, record) {
    var serializer = store.serializerFor(type.typeKey);
    var data = serializer.serialize(record, { includeId: true });
    var self = this;
    return this.ajax(this.buildURL(type.typeKey, null, record), "POST", data).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method updateRecord
   * @inheritDoc
   */
  updateRecord: function (store, type, record) {
    var serializer = store.serializerFor(type.typeKey);
    var data = serializer.serialize(record, { includeId: true });
    var self = this;
    return this.ajax(
      this.buildURL(type.typeKey, data.id, record), "PUT", data
    ).then(
      function (payload) {
        return self._newPayload(store, type, payload);
      }
    );
  },

  /**
   * @since 0.0.1
   * @method find
   * @inheritDoc
   */
  find: function (store, type/*, id, record*/) {
    var self = this;
    return this._super.apply(arguments).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method findAll
   * @inheritDoc
   */
  findAll: function (store, type/*, sinceToken*/) {
    var self = this;
    return this._super.apply(this, arguments).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method findBelongsTo
   * @inheritDoc
   */
  findBelongsTo: function (/*store, record, url*/) {
    // TODO: check what is returning Sails in that case
    return this._super.apply(this, arguments);
  },

  /**
   * @since 0.0.1
   * @method findHasMany
   * @inheritDoc
   */
  findHasMany: function (/*store, record, url*/) {
    // TODO: check what is returning Sails in that case
    return this._super.apply(this, arguments);
  },

  /**
   * @since 0.0.1
   * @method findMany
   * @inheritDoc
   */
  findMany: function (store, type, ids/*, records*/) {
    return this.findQuery(store, type, {where: {id: ids}});
  },

  /**
   * @since 0.0.1
   * @method findQuery
   * @inheritDoc
   */
  findQuery: function (store, type, query) {
    var self = this;
    return this.ajax(this.buildURL(type.typeKey), 'GET', query).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method deleteRecord
   * @inheritDoc
   */
  deleteRecord: function (store, type, record) {
    var self = this;
    return this.ajax(
      this.buildURL(type.typeKey, record.get('id'), record),
      'DELETE',
      {}
    ).then(function (payload) {
        return self._newPayload(store, type, payload);
      }
    );
  },

  /**
   * Handle `connect` event of the socket
   *
   * @since 0.0.1
   * @method _handleSocketConnect
   * @private
   */
  _handleSocketConnect: function () {
    this.csrfToken = null;
    this.socketRebindListeners();
    if (this.useCSRF) {
      // on connection we need to re-new the CSRF
      io.socket.get('/csrfToken', function (tokenObject) {
        this._log('debug', 'got new CSRF token', tokenObject);
        this.csrfToken = tokenObject._csrf;
      }.bind(this));
    }
  },

  /**
   * Handle reception of messages over the socket
   * @since 0.0.1
   * @method _handleSocketMessage
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketMessage: function (meta, message) {
    var method = '_handleSocketRecord' + message.verb.capitalize();
    this._log('debug', 'new event ' + meta.event + ':' + message.verb + ', message:', message);
    if (this[method]) {
      Ember.run.next(this, method, meta, message);
    }
    else {
      this._log('notice', 'nothing to handle message with verb ' + message.verb);
    }
  },

  /**
   * Handle a created record message
   *
   * @since 0.0.1
   * @method _handleSocketRecordCreated
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketRecordCreated: function (meta, message) {
    var type = meta.data.type,
      store = meta.data.store,
      record = message.data;
    if (!record.id && message.id) {
      record.id = message.id;
    }
    store.pushPayload(store, this._newPayload(store, type, record));
  },

  /**
   * Handle a updated record message
   *
   * @since 0.0.1
   * @method _handleSocketRecordUpdated
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketRecordUpdated: Ember.aliasMethod('_handleSocketRecordCreated'),

  /**
   * Handle a destroyed record message
   *
   * @since 0.0.1
   * @method _handleSocketRecordDestroyed
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketRecordDestroyed: function (meta, message) {
    var type = meta.data.type,
      store = meta.data.store,
      record = store.getById(type.typeKey, message.id);
    if (record && typeof record.get('dirtyType') === 'undefined') {
      record.unloadRecord();
    }
  },

  /**
   * Listen to socket message for a given model
   *
   * @since 0.0.1
   * @method _listenToSocket
   * @param {String} model The model name to listen for events
   * @private
   */
  _listenToSocket: function (model) {
    var eventName = Ember.String.camelize(model).toLowerCase();
    if (this.socketIsListening(eventName)) {
      return;
    }
    var store = this.container.lookup('store:main');
    var type = store.modelFor(model);
    this.socketAddListener(eventName, this._handleSocketMessage, {store: store, type: type}, true);
  }
});
<commit_msg>Fetching CSRF token once connected<commit_after>/*global io*/
import DS from 'ember-data';
import Ember from 'ember';
import SailsBaseAdapter from 'ember-data-sails/adapters/sails-base';

/**
 * Adapter for SailsJS sockets
 *
 * @since 0.0.1
 * @class SailsSocketAdapter
 * @extends SailsBaseAdapter
 * @constructor
 */
export default SailsBaseAdapter.extend({
  /**
   * Holds the descriptors for each event listened on the socket
   * @since 0.0.1
   * @property _socketListeners
   * @type Object<Object>
   * @private
   */
  _socketListeners: null,

  /**
   * @since 0.0.1
   * @inheritDoc
   */
  init: function () {
    this._super();
    this._socketListeners = {};
    this.fetchCsrfToken();
    this.socketAddListener('connect', this._handleSocketConnect);
  },

  /**
   * @since 0.0.1
   * @inheritDoc
   */
  destroy: function () {
    Ember.keys(this._socketListeners).map(this.socketRemoveListener, this);
    this._super();
  },

  /**
   * Adds an event listener to the socket with some meta
   *
   * @since 0.0.1
   * @method socketAddListener
   * @param {String} event The event to listen to
   * @param {Function|String} callback The method to be called (will be bound on the adapter)
   * @param {mixed} [metadata] SOme metadata to store and get passed over the callback
   * @param (Boolean} [autoReAttach] Whether to re-attach the listener after a reconnection
   * @chainable
   */
  socketAddListener: function (event, callback, metadata, autoReAttach) {
    var def = this._socketListeners[event];
    if (def) {
      this._log('info', 'already listening for ' + event, def);
      return;
    }
    callback = typeof callback === 'string' ? this[callback] : callback;
    def = this._socketListeners[event] = {data: metadata, event: event, autoReAttach: !!autoReAttach};
    def.callback = callback.bind(this, def);
    io.socket.addListener(event, def.callback);
    this._log('debug', 'listening for ' + event, def);
    return this;
  },

  /**
   * Remove an event listener and stop listening for that even on the socket
   *
   * @since 0.0.1
   * @method socketRemoveListener
   * @param {String} event The event to stop listening for
   * @chainable
   */
  socketRemoveListener: function (event) {
    var def = this._socketListeners[event];
    if (!def) {
      this._log('info', 'not listening for ' + event + ' yet');
      return;
    }
    delete this._socketListeners[event];
    io.socket.removeListener(event, def.callback);
    this._log('debug', 'stop listening for ' + event, def);
    return this;
  },

  /**
   * Re-attach all listeners on the socket
   *
   * @since 0.0.1
   * @method socketRebindListeners
   * @chainable
   */
  socketRebindListeners: function () {
    var meta;
    for (var event in this._socketListeners) {
      meta = this._socketListeners[event];
      if (meta.autoReAttach) {
        try {
          io.socket.removeListener(event, meta.callback);
        }
        catch (e) {
          // noop
        }
        io.socket.addListener(event, meta.callback);
        this._log('info', 're-attached listener for ' + event, meta);
      }
    }
    return this;
  },

  /**
   * Finds whether the socket is listening for an event or not
   *
   * @since 0.0.1
   * @method socketIsListening
   * @param {String} event The event to test
   * @returns {Boolean} Returns `true` if we're listening for that event, else `false`
   */
  socketIsListening: function (event) {
    return !!this._socketListeners[event];
  },

  /**
   * @since 0.0.1
   * @method ajax
   * @inheritDoc
   */
  ajax: function (url, method, data) {
    return this.socket(url, method, data);
  },

  /**
   * Send a message over the socket
   *
   * @since 0.0.1
   * @method socket
   * @param {String} url The HTTP URL to fake
   * @param {String} method The HTTP method to fake
   * @param {Object} data The data to send
   * @returns {Ember.RSVP.Promise} A promise resolving to the result or an error
   */
  socket: function (url, method, data) {
    method = method.toLowerCase();
    var self = this, req = data;
    if (method !== 'get') {
      this.checkCSRF(data);
    }
    return new Ember.RSVP.Promise(function (resolve, reject) {
      io.socket[method](url, data, function (data) {
        var res = data, cb = reject, level = 'warning';
        if (self.isErrorObject(data)) {
          if (data.errors) {
            level = 'error';
            res = new DS.InvalidError(self.formatError(data));
          }
        }
        else {
          cb = resolve;
          level = 'info';
        }
        self._log(level, 'socket request: ' + method + ' ' + url, {request: req, response: data});
        cb(res);
      });
    });
  },

  /**
   * @since 0.0.1
   * @method buildUrl
   * @inheritDoc
   */
  buildURL: function (type) {
    this._listenToSocket(type);
    return this._super.apply(this, arguments);
  },

  /**
   * @since 0.0.1
   * @method createRecord
   * @inheritDoc
   */
  createRecord: function (store, type, record) {
    var serializer = store.serializerFor(type.typeKey);
    var data = serializer.serialize(record, { includeId: true });
    var self = this;
    return this.ajax(this.buildURL(type.typeKey, null, record), "POST", data).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method updateRecord
   * @inheritDoc
   */
  updateRecord: function (store, type, record) {
    var serializer = store.serializerFor(type.typeKey);
    var data = serializer.serialize(record, { includeId: true });
    var self = this;
    return this.ajax(
      this.buildURL(type.typeKey, data.id, record), "PUT", data
    ).then(
      function (payload) {
        return self._newPayload(store, type, payload);
      }
    );
  },

  /**
   * @since 0.0.1
   * @method find
   * @inheritDoc
   */
  find: function (store, type/*, id, record*/) {
    var self = this;
    return this._super.apply(arguments).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method findAll
   * @inheritDoc
   */
  findAll: function (store, type/*, sinceToken*/) {
    var self = this;
    return this._super.apply(this, arguments).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method findBelongsTo
   * @inheritDoc
   */
  findBelongsTo: function (/*store, record, url*/) {
    // TODO: check what is returning Sails in that case
    return this._super.apply(this, arguments);
  },

  /**
   * @since 0.0.1
   * @method findHasMany
   * @inheritDoc
   */
  findHasMany: function (/*store, record, url*/) {
    // TODO: check what is returning Sails in that case
    return this._super.apply(this, arguments);
  },

  /**
   * @since 0.0.1
   * @method findMany
   * @inheritDoc
   */
  findMany: function (store, type, ids/*, records*/) {
    return this.findQuery(store, type, {where: {id: ids}});
  },

  /**
   * @since 0.0.1
   * @method findQuery
   * @inheritDoc
   */
  findQuery: function (store, type, query) {
    var self = this;
    return this.ajax(this.buildURL(type.typeKey), 'GET', query).then(function (payload) {
      return self._newPayload(store, type, payload);
    });
  },

  /**
   * @since 0.0.1
   * @method deleteRecord
   * @inheritDoc
   */
  deleteRecord: function (store, type, record) {
    var self = this;
    return this.ajax(
      this.buildURL(type.typeKey, record.get('id'), record),
      'DELETE',
      {}
    ).then(function (payload) {
        return self._newPayload(store, type, payload);
      }
    );
  },

  /**
   * Fetches the CSRF token
   *
   * @since 0.0.3
   * @method fetchCsrfToken
   */
  fetchCsrfToken: function () {
    // on connection we need to re-new the CSRF
    io.socket.get('/csrfToken', function (tokenObject) {
      this._log('debug', 'got new CSRF token', tokenObject);
      this.csrfToken = tokenObject._csrf;
    }.bind(this));
  },

  /**
   * Handle `connect` event of the socket
   *
   * @since 0.0.1
   * @method _handleSocketConnect
   * @private
   */
  _handleSocketConnect: function () {
    this.csrfToken = null;
    this.socketRebindListeners();
    if (this.useCSRF) {
      this.fetchCsrfToken();
    }
  },

  /**
   * Handle reception of messages over the socket
   * @since 0.0.1
   * @method _handleSocketMessage
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketMessage: function (meta, message) {
    var method = '_handleSocketRecord' + message.verb.capitalize();
    this._log('debug', 'new event ' + meta.event + ':' + message.verb + ', message:', message);
    if (this[method]) {
      Ember.run.next(this, method, meta, message);
    }
    else {
      this._log('notice', 'nothing to handle message with verb ' + message.verb);
    }
  },

  /**
   * Handle a created record message
   *
   * @since 0.0.1
   * @method _handleSocketRecordCreated
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketRecordCreated: function (meta, message) {
    var type = meta.data.type,
      store = meta.data.store,
      record = message.data;
    if (!record.id && message.id) {
      record.id = message.id;
    }
    store.pushPayload(store, this._newPayload(store, type, record));
  },

  /**
   * Handle a updated record message
   *
   * @since 0.0.1
   * @method _handleSocketRecordUpdated
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketRecordUpdated: Ember.aliasMethod('_handleSocketRecordCreated'),

  /**
   * Handle a destroyed record message
   *
   * @since 0.0.1
   * @method _handleSocketRecordDestroyed
   * @param {Object} meta The meta containing `data`, `event`, `autoReAttach` and `callback`
   * @param {Object} message The message received
   * @private
   */
  _handleSocketRecordDestroyed: function (meta, message) {
    var type = meta.data.type,
      store = meta.data.store,
      record = store.getById(type.typeKey, message.id);
    if (record && typeof record.get('dirtyType') === 'undefined') {
      record.unloadRecord();
    }
  },

  /**
   * Listen to socket message for a given model
   *
   * @since 0.0.1
   * @method _listenToSocket
   * @param {String} model The model name to listen for events
   * @private
   */
  _listenToSocket: function (model) {
    var eventName = Ember.String.camelize(model).toLowerCase();
    if (this.socketIsListening(eventName)) {
      return;
    }
    var store = this.container.lookup('store:main');
    var type = store.modelFor(model);
    this.socketAddListener(eventName, this._handleSocketMessage, {store: store, type: type}, true);
  }
});
<|endoftext|>


<commit_before>var _ = require('../util').lodash,
    Property = require('./property').Property,

    QueryParam;

/**
 * @typedef QueryParam~definition
 * @property {String} key The name ("key") of the query parameter.
 * @property {String} value The value of the parameter.
 */
_.inherit((
    /**
     * Represents a URL query parameter, which can exist in request URL or POST data.
     * @constructor
     * @extends {Property}
     *
     * @param {FormParam~definition|String} options Pass the initial definition of the query parameter. In case of
     * string, the query parameter is parsed using {@link QueryParam.parseSingle}.
     */
    QueryParam = function PostmanQueryParam (options) {
        if (_.isString(options)) {
            options = QueryParam.parseSingle(options);
        }

        this.key = _.get(options, 'key') || '';
        this.value = _.get(options, 'value') || '';
    }), Property);

_.extend(QueryParam.prototype, /** @lends QueryParam.prototype */ {
    /**
     * Converts the QueryParameter to a single param string
     * @returns {String}
     */
    toString: function () {
        return this.key + '=' + this.value;
    }
});

_.extend(QueryParam, /** @lends QueryParam */ {

    /**
     * Defines the name of this property for internal use.
     * @private
     * @readOnly
     * @type {String}
     */
    _postman_propertyName: 'QueryParam',

    /**
     * Parse a query string into an array of objects, where each object contains a key and a value.
     *
     * @param query {String}
     * @returns {Array}
     */
    parse: function (query) {
        return _.isString(query) ? query.split('&').map(QueryParam.parseSingle) : [];
    },

    /**
     * Parses a single query parameter.
     *
     * @param param
     * @returns {{key: string, value: string}}
     */
    parseSingle: function (param) {
        var index = param.indexOf('='),
            key,
            value;

        (index < 0) && (index = param.length);

        key = param.substr(0, index);
        value = param.substr(index + 1);

        return {
            key: _.trim(key),
            value: _.trim(value)
        };
    },

    /**
     * Create a query string from array of parameters (or object of key-values). This function ensures that
     * the double braces "{{" and "}}" are not URL-encoded on unparsing, which allows for variable-substitution.
     *
     * @param params
     * @param {Object=} options
     * @param {Boolean} options.encode - Enables URL encoding of the parameters
     * @returns {string}
     */
    unparse: function (params, options) {
        var qs,
            encode = options && options.encode;

        if (!_.isArray(params)) {
            params = _.reduce(params, function (accumulator, value, key) {
                accumulator.push({ key: key, value: value });
                return accumulator;
            }, []);
        }

        qs = (encode) ? _.reduce(params, function (accumulator, param) {
            if (accumulator.length > 0) {
                accumulator += '&';
            }
            accumulator += encodeURI(param.key + '=' + param.value);
            return accumulator;
        }, '') : _.reduce(params, function (accumulator, param) {
            if (accumulator.length > 0) {
                accumulator += '&';
            }
            accumulator += (param.key + '=' + param.value);
            return accumulator;
        }, '');

        // Special handling to ensure "{{" and "}}" are not URL encoded in the final query-string.
        (options && options.encode) && (qs = qs.replace(/%7B%7B/g, '{{')) && (qs = qs.replace(/%7D%7D/g, '}}'));
        return qs;
    },
    /**
     * Takes a query param and converts to string
     *
     * @param {Object} obj
     * @returns {String}
     */
    unparseSingle: function (obj) {
        if (!obj) { return ''; }
        var unparsed = obj.key || '';
        // if the value is not null, then we add the value
        (obj.value != null) && (unparsed += ('=' + (obj.value || '')));
        return unparsed;
    }
});

module.exports = {
    QueryParam: QueryParam
};
<commit_msg>Updated the function of single query param parsing to (1) not trim anything and (2) if value is missing, store it as undefined. These are useful in retaining integrity during unparsing<commit_after>var _ = require('../util').lodash,
    Property = require('./property').Property,

    QueryParam;

/**
 * @typedef QueryParam~definition
 * @property {String} key The name ("key") of the query parameter.
 * @property {String} value The value of the parameter.
 */
_.inherit((
    /**
     * Represents a URL query parameter, which can exist in request URL or POST data.
     * @constructor
     * @extends {Property}
     *
     * @param {FormParam~definition|String} options Pass the initial definition of the query parameter. In case of
     * string, the query parameter is parsed using {@link QueryParam.parseSingle}.
     */
    QueryParam = function PostmanQueryParam (options) {
        if (_.isString(options)) {
            options = QueryParam.parseSingle(options);
        }

        this.key = _.get(options, 'key') || '';
        this.value = _.get(options, 'value') || '';
    }), Property);

_.extend(QueryParam.prototype, /** @lends QueryParam.prototype */ {
    /**
     * Converts the QueryParameter to a single param string
     * @returns {String}
     */
    toString: function () {
        return this.key + '=' + this.value;
    }
});

_.extend(QueryParam, /** @lends QueryParam */ {

    /**
     * Defines the name of this property for internal use.
     * @private
     * @readOnly
     * @type {String}
     */
    _postman_propertyName: 'QueryParam',

    /**
     * Parse a query string into an array of objects, where each object contains a key and a value.
     *
     * @param query {String}
     * @returns {Array}
     */
    parse: function (query) {
        return _.isString(query) ? query.split('&').map(QueryParam.parseSingle) : [];
    },

    /**
     * Parses a single query parameter.
     *
     * @param param
     * @returns {{key: string, value: string}}
     */
    parseSingle: function (param) {
        var index = _.isString(param) ? param.indexOf('=') : -1,
            paramObj = {};

        // this means that there was no value for this key (not even blank, so we store this info) and the value is set
        // to null
        if (index < 0) {
            paramObj.key = param.substr(0, param.length);
            paramObj.value = null;
        }
        else {
            paramObj.key = param.substr(0, index);
            paramObj.value = param.substr(index + 1);
        }

        return paramObj;
    },

    /**
     * Create a query string from array of parameters (or object of key-values). This function ensures that
     * the double braces "{{" and "}}" are not URL-encoded on unparsing, which allows for variable-substitution.
     *
     * @param params
     * @param {Object=} options
     * @param {Boolean} options.encode - Enables URL encoding of the parameters
     * @returns {string}
     */
    unparse: function (params, options) {
        var qs,
            encode = options && options.encode;

        if (!_.isArray(params)) {
            params = _.reduce(params, function (accumulator, value, key) {
                accumulator.push({ key: key, value: value });
                return accumulator;
            }, []);
        }

        qs = (encode) ? _.reduce(params, function (accumulator, param) {
            if (accumulator.length > 0) {
                accumulator += '&';
            }
            accumulator += encodeURI(param.key + '=' + param.value);
            return accumulator;
        }, '') : _.reduce(params, function (accumulator, param) {
            if (accumulator.length > 0) {
                accumulator += '&';
            }
            accumulator += (param.key + '=' + param.value);
            return accumulator;
        }, '');

        // Special handling to ensure "{{" and "}}" are not URL encoded in the final query-string.
        (options && options.encode) && (qs = qs.replace(/%7B%7B/g, '{{')) && (qs = qs.replace(/%7D%7D/g, '}}'));
        return qs;
    },
    /**
     * Takes a query param and converts to string
     *
     * @param {Object} obj
     * @returns {String}
     */
    unparseSingle: function (obj) {
        if (!obj) { return ''; }
        var unparsed = obj.key || '';
        // if the value is not null, then we add the value
        (obj.value != null) && (unparsed += ('=' + (obj.value || '')));
        return unparsed;
    }
});

module.exports = {
    QueryParam: QueryParam
};
<|endoftext|>


<commit_before>/**
 * GeoWizard JS 1.0
 *
 * @Developed by batux
 *
 * @ContactPerson Batuhan Duzgun
 * @Email batuhan.duzgun@windowslive.com
 *
 * @Copyright (c) 2017
 */

var geoWizard = (function() {

	var self = this;

	self.geoWizardApiFunctions = {};

	self.map = null;
	self.exportedGeoJson = '';
	self.maxZoomLevel = 7;
	self.minZoomLevel = 2;

	self.mapOptions = {
		zoom : 8,
		center : new google.maps.LatLng(40.9761726, 28.8142807),
		disableDefaultUI : true
	}

	self.dataStyle = {
		editable: true,
		draggable: true
	}

	self.StorageType = {
		'WEB_SQL': 'websql',
		'LOCAL_STORAGE': 'local_storage'
	}

	self.drawingProjectDb = null;

	self.databaseConfiguration = {
		databaseName: "drawing_project_db",
		databaseVersion: "0.1",
		databaseDescription: "Google Maps Drawing Project Database",
		drawingProjectDDLSql: "CREATE TABLE IF NOT EXISTS drawing_project (id INTEGER PRIMARY KEY ASC, project_guid TEXT, json_text TEXT)",
		drawingProjectIndexDDLSql: "CREATE TABLE IF NOT EXISTS drawing_project_index (id INTEGER PRIMARY KEY ASC, project_guid TEXT, storage_type TEXT)",
		drawingProjectDbSize: 1024 * 1024
	}

	self.drawingModes = [ google.maps.drawing.OverlayType.MARKER,
        					  google.maps.drawing.OverlayType.POLYGON,
        					  google.maps.drawing.OverlayType.POLYLINE,
        					  google.maps.drawing.OverlayType.RECTANGLE ];

	self.drawingManagerConfiguration = {
			drawingControl: true,
			geometryBag: [],
			drawingControlOptions: {
				position: google.maps.ControlPosition.TOP_CENTER,
				drawingModes: self.drawingModes
		    }
	}

	self.exportApiFunction = function(apiFunctionName, apiFunction) {

		if(!apiFunctionName && !apiFunction) {
			return;
		}

		if(typeof apiFunctionName === 'string') {
			self.geoWizardApiFunctions[apiFunctionName] = apiFunction;
		}
	}

	self.createRectangle = function(geometry) {

		var b = geometry.getBounds(),
          	p = [ b.getSouthWest(), {
						              'lat': b.getSouthWest().lat(),
						              'lng': b.getNorthEast().lng()
						            },
			      b.getNorthEast(), {
						              'lng': b.getSouthWest().lng(),
						              'lat': b.getNorthEast().lat()
						            }
	            ];

		  var rectangle = new google.maps.Data.Polygon([p]);

		  return rectangle;
	}

	self.createPolygon = function(geometry) {

		var polygon = new google.maps.Data.Polygon([geometry.getPath().getArray()]);

		return polygon;
	}

	self.createPolyLine = function(geometry) {

		var pointList = [];

		var geometryBoundary = geometry.getPath().b;

		for(var i=0; i < geometryBoundary.length; i++) {

			var latlngItem = geometryBoundary[i];
			pointList[i] = { 'lat': latlngItem.lat(), 'lng': latlngItem.lng() };
		}

		var polyLine = new google.maps.Data.LineString(pointList);

		return polyLine;
	}

	self.createPoint = function(geometry) {

		var point = new google.maps.Data.Point({
	        lat: geometry.position.lat(),
	        lng: geometry.position.lng()
	    });

		return point;
	}

	self.createFeature = function(geometry) {

		if(!geometry) {
			return null;
		}

		var feauture = new google.maps.Data.Feature({
	          geometry: geometry
	    });

		return feauture;
	}

	self.drawingCallback = function(event) {

		var type = event.type;
		var geometry = event.overlay;
		var feauture = null;

		if(type == google.maps.drawing.OverlayType.RECTANGLE) {

			var rectangle = self.createRectangle(geometry);

			feauture = self.createFeature(rectangle);
		}
		else if(type == google.maps.drawing.OverlayType.POLYGON) {

			var polygon = self.createPolygon(geometry);

			feauture = self.createFeature(polygon);
		}
		else if(type == google.maps.drawing.OverlayType.MARKER) {

			var point = self.createPoint(geometry);

			feauture = self.createFeature(point);
		}
		else if(type == google.maps.drawing.OverlayType.POLYLINE) {

			var polyline = self.createPolyLine(geometry);

			feauture = self.createFeature(polyline);
		}

		if(feauture) {
			self.map.data.add(feauture);
		}

		self.drawingManagerConfiguration.geometryBag.push(geometry);
	}

	self.clearAllFeaturesFromDataLayer = function(map) {

		if(!map) {
			map = self.getMap();
		}

		map.data.forEach(function(feature) {
		    map.data.remove(feature);
		});
	}

	self.clearAllDrawingsOnMap = function(geometryBag) {

		if(!geometryBag && !geometryBag.length) {
			return;
		}

		for(var i=0; i < geometryBag.length; i++) {
			  geometryBag[i].setMap(null);
		}
	}

	self.checkBrowserCompabilityOfWebSql = function() {

		if (window.openDatabase) {
			return true;
		}

		return false;
	}

	self.openWebSqlDatabase = function() {

		if(self.checkBrowserCompabilityOfWebSql()) {

			self.drawingProjectDb = openDatabase(self.databaseConfiguration.databaseName,
					   self.databaseConfiguration.databaseVersion,
					   self.databaseConfiguration.databaseDescription,
					   self.databaseConfiguration.drawingProjectDbSize);
		}
	}

	self.createTable = function(sql) {

		self.drawingProjectDb.transaction(function (transaction) {
			transaction.executeSql(sql);
	    });
	}

	self.prepareDatabase = function() {

		self.openWebSqlDatabase();

		if(self.drawingProjectDb) {
			self.createTable(self.databaseConfiguration.drawingProjectDDLSql);
			self.createTable(self.databaseConfiguration.drawingProjectIndexDDLSql);
		}
	}

	self.insertToDatabase = function(sql, values) {

		self.drawingProjectDb.transaction(function (transaction) {
			transaction.executeSql(sql, values);
		});
	}

	self.selectFromDatabase = function(sql, values, resultCallback) {

		self.drawingProjectDb.transaction(function (transaction) {
			transaction.executeSql(sql, values, resultCallback, null);
		});
	}

	self.insertToLocalStorage = function(projectGuid, jsonText) {

		localStorage.setItem(projectGuid, jsonText);
	}

	self.createGuidPart = function S4() {
	    return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
	}

	self.createGuid = function() {

		var guid = (self.createGuidPart() + self.createGuidPart() + "-" + self.createGuidPart() + "-4" + self.createGuidPart().substr(0,3)).toLowerCase();
		return guid;
	}

	self.setMap = function(map) {
		self.map = map;
	}

	self.getMap = function() {
		return self.map;
	}

	// API
	self.useDefaultMap = function() {
		self.map = new google.maps.Map(document.getElementById('map'), self.mapOptions);
		self.bindDrawingManagerToMap(self.map);
	}

	// API
	self.bindDrawingManagerToMap = function(map) {

		self.setMap(map);

		self.drawingManager = new google.maps.drawing.DrawingManager(self.drawingManagerConfiguration);

		self.drawingManager.setMap(self.getMap());

		google.maps.event.addListener(self.drawingManager, 'overlaycomplete', self.drawingCallback);
	}

	// API
	self.exportGeoJsonFromDataLayer = function(exportCallback, map) {

		if(!map) {
			map = self.getMap();
		}

		map.data.toGeoJson(function(feature) {

		    var featureAsGeoJson = JSON.stringify(feature);
		    self.exportedGeoJson = featureAsGeoJson;

		    if(exportCallback) {
		    		exportCallback.call(null, self.exportedGeoJson);
		    }

		});
	}

	// API
	self.importGeoJsonFromDataLayer = function(geoJsonAsText, map) {

		if(!map) {
			map = self.getMap();
		}

		var geometryBag = self.drawingManagerConfiguration.geometryBag;

		self.clearAllDrawingsOnMap(geometryBag);

		self.clearAllFeaturesFromDataLayer(map);

		var response = self.generateFeatureListFromGeoJson(geoJsonAsText);

	    map.data.addGeoJson(response.featureList)
	}

	// API
	self.generateFeatureListFromGeoJson = function(geoJsonAsText) {

		if(!geoJsonAsText) {
			return;
		}

		var featureList = null;
		var processMessage = "Successfull!";

		try {
			featureList = JSON.parse(geoJsonAsText);
		}
		catch (error) {
			processMessage = error;
			console.log(processMessage);
		}

		var response = {
			'featureList': featureList,
			'processMessage': processMessage
		};

		return response;
	}

	// API
	self.prepareDrawedGeometriesFromMap = function() {
		return self.drawingManagerConfiguration.geometryBag;
	}

	// API
	self.prepareFeaturesFromDataLayer = function(featureResultCallback, map) {

		if(featureResultCallback) {

			if(!map) {
				map = self.getMap();
			}

			var featureList = [];

			map.data.forEach(function(feature) {
				featureList.push(feature);
			});

			featureResultCallback.call(null, featureList);
		}
	}

	// API
	self.clearMapGeometries = function(map) {

		if(!map) {
			map = self.getMap();
		}

		var geometryBag = self.drawingManagerConfiguration.geometryBag;

		self.clearAllDrawingsOnMap(geometryBag);

		self.clearAllFeaturesFromDataLayer(map);
	}

	// API
	self.saveDrawingProject = function(geoJsonAsText, storageType) {

		if(storageType == self.StorageType.WEB_SQL) {

			if(!self.drawingProjectDb) {
				self.prepareDatabase();
			}

			var guid = self.createGuid();

			self.insertToDatabase('INSERT INTO drawing_project (project_guid, json_text) VALUES (?, ?)', [guid, geoJsonAsText]);

			self.insertToDatabase('INSERT INTO drawing_project_index (project_guid, storage_type) VALUES (?, ?)', [guid, storageType]);

		}
		else if(storageType == self.StorageType.LOCAL_STORAGE) {

			var guid = self.createGuid();

			self.insertToDatabase('INSERT INTO drawing_project_index (project_guid, storage_type) VALUES (?, ?)', [guid, storageType]);

			self.insertToLocalStorage(guid, geoJsonAsText);
		}
	}

	// API
	self.queryLastDrawingProjectFromDatabase = function(resultCallback) {

		var queryResultCallback = function (transaction, results) {

			if(resultCallback) {
				resultCallback.call(null, results.rows);
			}
		}

		self.selectFromDatabase('SELECT * FROM drawing_project ORDER BY id ASC LIMIT 1', [], queryResultCallback);
	}

	// API
	self.queryAllDrawingProjectsFromDatabase = function(resultCallback) {

		var queryResultCallback = function (transaction, results) {

			if(resultCallback) {
				resultCallback.call(null, results.rows);
			}
		}

		self.selectFromDatabase('SELECT * FROM drawing_project', [], queryResultCallback);
	}

	// API
	self.queryLocalStorageGuidsFromDatabase = function(resultCallback) {

		var queryResultCallback = function (transaction, results) {

			if(resultCallback) {
				resultCallback.call(null, results.rows);
			}
		}

		self.selectFromDatabase('SELECT * FROM drawing_project_index WHERE storage_type=?', [self.StorageType.LOCAL_STORAGE], queryResultCallback);
	}

	self.exportApiFunction('useDefaultMap', self.useDefaultMap);
	self.exportApiFunction('clearMapGeometries', self.clearMapGeometries);
	self.exportApiFunction('saveDrawingProject', self.saveDrawingProject);
	self.exportApiFunction('queryLastDrawingProjectFromDatabase', self.queryLastDrawingProjectFromDatabase);
	self.exportApiFunction('queryAllDrawingProjectsFromDatabase', self.queryAllDrawingProjectsFromDatabase);
	self.exportApiFunction('queryLocalStorageGuidsFromDatabase', self.queryLocalStorageGuidsFromDatabase);
	self.exportApiFunction('bindDrawingManagerToMap', self.bindDrawingManagerToMap);
	self.exportApiFunction('exportGeoJsonFromDataLayer', self.exportGeoJsonFromDataLayer);
	self.exportApiFunction('importGeoJsonFromDataLayer', self.importGeoJsonFromDataLayer);
	self.exportApiFunction('generateFeatureListFromGeoJson', self.generateFeatureListFromGeoJson);
	self.exportApiFunction('prepareDrawedGeometriesFromMap', self.prepareDrawedGeometriesFromMap);
	self.exportApiFunction('prepareFeaturesFromDataLayer', self.prepareFeaturesFromDataLayer);
	self.exportApiFunction('StorageType', self.StorageType);

	return geoWizardApiFunctions;

})();

<commit_msg>Comments were updated !<commit_after>/**
 * GeoWizard JS 1.0
 *
 * @Developed by batux
 *
 * @ContactPerson Batuhan Duzgun
 * @Email batuhan.duzgun@windowslive.com
 *
 * @Copyright (c) 2017
 */

var geoWizard = (function() {

	var self = this;

	self.geoWizardApiFunctions = {};

	self.map = null;
	self.exportedGeoJson = '';
	self.maxZoomLevel = 7;
	self.minZoomLevel = 2;

	self.mapOptions = {
		zoom : 8,
		center : new google.maps.LatLng(40.9761726, 28.8142807),
		disableDefaultUI : true
	}

	self.dataStyle = {
		editable: true,
		draggable: true
	}

	self.StorageType = {
		'WEB_SQL': 'websql',
		'LOCAL_STORAGE': 'local_storage'
	}

	self.drawingProjectDb = null;

	self.databaseConfiguration = {
		databaseName: "drawing_project_db",
		databaseVersion: "0.1",
		databaseDescription: "Google Maps Drawing Project Database",
		drawingProjectDDLSql: "CREATE TABLE IF NOT EXISTS drawing_project (id INTEGER PRIMARY KEY ASC, project_guid TEXT, json_text TEXT)",
		drawingProjectIndexDDLSql: "CREATE TABLE IF NOT EXISTS drawing_project_index (id INTEGER PRIMARY KEY ASC, project_guid TEXT, storage_type TEXT)",
		drawingProjectDbSize: 1024 * 1024
	}

	self.drawingModes = [ google.maps.drawing.OverlayType.MARKER,
        					  google.maps.drawing.OverlayType.POLYGON,
        					  google.maps.drawing.OverlayType.POLYLINE,
        					  google.maps.drawing.OverlayType.RECTANGLE ];

	self.drawingManagerConfiguration = {
			drawingControl: true,
			geometryBag: [],
			drawingControlOptions: {
				position: google.maps.ControlPosition.TOP_CENTER,
				drawingModes: self.drawingModes
		    }
	}

	self.exportApiFunction = function(apiFunctionName, apiFunction) {

		if(!apiFunctionName && !apiFunction) {
			return;
		}

		if(typeof apiFunctionName === 'string') {
			self.geoWizardApiFunctions[apiFunctionName] = apiFunction;
		}
	}

	self.createRectangle = function(geometry) {

		var b = geometry.getBounds(),
          	p = [ b.getSouthWest(), {
						              'lat': b.getSouthWest().lat(),
						              'lng': b.getNorthEast().lng()
						            },
			      b.getNorthEast(), {
						              'lng': b.getSouthWest().lng(),
						              'lat': b.getNorthEast().lat()
						            }
	            ];

		  var rectangle = new google.maps.Data.Polygon([p]);

		  return rectangle;
	}

	self.createPolygon = function(geometry) {

		var polygon = new google.maps.Data.Polygon([geometry.getPath().getArray()]);

		return polygon;
	}

	self.createPolyLine = function(geometry) {

		var pointList = [];

		var geometryBoundary = geometry.getPath().b;

		for(var i=0; i < geometryBoundary.length; i++) {

			var latlngItem = geometryBoundary[i];
			pointList[i] = { 'lat': latlngItem.lat(), 'lng': latlngItem.lng() };
		}

		var polyLine = new google.maps.Data.LineString(pointList);

		return polyLine;
	}

	self.createPoint = function(geometry) {

		var point = new google.maps.Data.Point({
	        lat: geometry.position.lat(),
	        lng: geometry.position.lng()
	    });

		return point;
	}

	self.createFeature = function(geometry) {

		if(!geometry) {
			return null;
		}

		var feauture = new google.maps.Data.Feature({
	          geometry: geometry
	    });

		return feauture;
	}

	self.drawingCallback = function(event) {

		var type = event.type;
		var geometry = event.overlay;
		var feauture = null;

		if(type == google.maps.drawing.OverlayType.RECTANGLE) {

			var rectangle = self.createRectangle(geometry);

			feauture = self.createFeature(rectangle);
		}
		else if(type == google.maps.drawing.OverlayType.POLYGON) {

			var polygon = self.createPolygon(geometry);

			feauture = self.createFeature(polygon);
		}
		else if(type == google.maps.drawing.OverlayType.MARKER) {

			var point = self.createPoint(geometry);

			feauture = self.createFeature(point);
		}
		else if(type == google.maps.drawing.OverlayType.POLYLINE) {

			var polyline = self.createPolyLine(geometry);

			feauture = self.createFeature(polyline);
		}

		if(feauture) {
			self.map.data.add(feauture);
		}

		self.drawingManagerConfiguration.geometryBag.push(geometry);
	}

	self.clearAllFeaturesFromDataLayer = function(map) {

		if(!map) {
			map = self.getMap();
		}

		map.data.forEach(function(feature) {
		    map.data.remove(feature);
		});
	}

	self.clearAllDrawingsOnMap = function(geometryBag) {

		if(!geometryBag && !geometryBag.length) {
			return;
		}

		for(var i=0; i < geometryBag.length; i++) {
			  geometryBag[i].setMap(null);
		}
	}

	self.checkBrowserCompabilityOfWebSql = function() {

		if (window.openDatabase) {
			return true;
		}

		return false;
	}

	self.openWebSqlDatabase = function() {

		if(self.checkBrowserCompabilityOfWebSql()) {

			self.drawingProjectDb = openDatabase(self.databaseConfiguration.databaseName,
					   self.databaseConfiguration.databaseVersion,
					   self.databaseConfiguration.databaseDescription,
					   self.databaseConfiguration.drawingProjectDbSize);
		}
	}

	self.createTable = function(sql) {

		self.drawingProjectDb.transaction(function (transaction) {
			transaction.executeSql(sql);
	    });
	}

	self.prepareDatabase = function() {

		self.openWebSqlDatabase();

		if(self.drawingProjectDb) {
			self.createTable(self.databaseConfiguration.drawingProjectDDLSql);
			self.createTable(self.databaseConfiguration.drawingProjectIndexDDLSql);
		}
	}

	self.insertToDatabase = function(sql, values) {

		self.drawingProjectDb.transaction(function (transaction) {
			transaction.executeSql(sql, values);
		});
	}

	self.selectFromDatabase = function(sql, values, resultCallback) {

		self.drawingProjectDb.transaction(function (transaction) {
			transaction.executeSql(sql, values, resultCallback, null);
		});
	}

	self.insertToLocalStorage = function(projectGuid, jsonText) {

		localStorage.setItem(projectGuid, jsonText);
	}

	self.createGuidPart = function S4() {
	    return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
	}

	self.createGuid = function() {

		var guid = (self.createGuidPart() + self.createGuidPart() + "-" + self.createGuidPart() + "-4" + self.createGuidPart().substr(0,3)).toLowerCase();
		return guid;
	}

	self.setMap = function(map) {
		self.map = map;
	}

	self.getMap = function() {
		return self.map;
	}

	// Exported API Function
	self.useDefaultMap = function() {
		self.map = new google.maps.Map(document.getElementById('map'), self.mapOptions);
		self.bindDrawingManagerToMap(self.map);
	}

	// Exported API Function
	self.bindDrawingManagerToMap = function(map) {

		self.setMap(map);

		self.drawingManager = new google.maps.drawing.DrawingManager(self.drawingManagerConfiguration);

		self.drawingManager.setMap(self.getMap());

		google.maps.event.addListener(self.drawingManager, 'overlaycomplete', self.drawingCallback);
	}

	// Exported API Function
	self.exportGeoJsonFromDataLayer = function(exportCallback, map) {

		if(!map) {
			map = self.getMap();
		}

		map.data.toGeoJson(function(feature) {

		    var featureAsGeoJson = JSON.stringify(feature);
		    self.exportedGeoJson = featureAsGeoJson;

		    if(exportCallback) {
		    		exportCallback.call(null, self.exportedGeoJson);
		    }

		});
	}

	// Exported API Function
	self.importGeoJsonFromDataLayer = function(geoJsonAsText, map) {

		if(!map) {
			map = self.getMap();
		}

		var geometryBag = self.drawingManagerConfiguration.geometryBag;

		self.clearAllDrawingsOnMap(geometryBag);

		self.clearAllFeaturesFromDataLayer(map);

		var response = self.generateFeatureListFromGeoJson(geoJsonAsText);

	    map.data.addGeoJson(response.featureList)
	}

	// Exported API Function
	self.generateFeatureListFromGeoJson = function(geoJsonAsText) {

		if(!geoJsonAsText) {
			return;
		}

		var featureList = null;
		var processMessage = "Successfull!";

		try {
			featureList = JSON.parse(geoJsonAsText);
		}
		catch (error) {
			processMessage = error;
			console.log(processMessage);
		}

		var response = {
			'featureList': featureList,
			'processMessage': processMessage
		};

		return response;
	}

	// Exported API Function
	self.prepareDrawedGeometriesFromMap = function() {
		return self.drawingManagerConfiguration.geometryBag;
	}

	// Exported API Function
	self.prepareFeaturesFromDataLayer = function(featureResultCallback, map) {

		if(featureResultCallback) {

			if(!map) {
				map = self.getMap();
			}

			var featureList = [];

			map.data.forEach(function(feature) {
				featureList.push(feature);
			});

			featureResultCallback.call(null, featureList);
		}
	}

	// Exported API Function
	self.clearMapGeometries = function(map) {

		if(!map) {
			map = self.getMap();
		}

		var geometryBag = self.drawingManagerConfiguration.geometryBag;

		self.clearAllDrawingsOnMap(geometryBag);

		self.clearAllFeaturesFromDataLayer(map);
	}

	// Exported API Function
	self.saveDrawingProject = function(geoJsonAsText, storageType) {

		if(storageType == self.StorageType.WEB_SQL) {

			if(!self.drawingProjectDb) {
				self.prepareDatabase();
			}

			var guid = self.createGuid();

			self.insertToDatabase('INSERT INTO drawing_project (project_guid, json_text) VALUES (?, ?)', [guid, geoJsonAsText]);

			self.insertToDatabase('INSERT INTO drawing_project_index (project_guid, storage_type) VALUES (?, ?)', [guid, storageType]);

		}
		else if(storageType == self.StorageType.LOCAL_STORAGE) {

			var guid = self.createGuid();

			self.insertToDatabase('INSERT INTO drawing_project_index (project_guid, storage_type) VALUES (?, ?)', [guid, storageType]);

			self.insertToLocalStorage(guid, geoJsonAsText);
		}
	}

	// Exported API Function
	self.queryLastDrawingProjectFromDatabase = function(resultCallback) {

		var queryResultCallback = function (transaction, results) {

			if(resultCallback) {
				resultCallback.call(null, results.rows);
			}
		}

		self.selectFromDatabase('SELECT * FROM drawing_project ORDER BY id ASC LIMIT 1', [], queryResultCallback);
	}

	// Exported API Function
	self.queryAllDrawingProjectsFromDatabase = function(resultCallback) {

		var queryResultCallback = function (transaction, results) {

			if(resultCallback) {
				resultCallback.call(null, results.rows);
			}
		}

		self.selectFromDatabase('SELECT * FROM drawing_project', [], queryResultCallback);
	}

	// Exported API Function
	self.queryLocalStorageGuidsFromDatabase = function(resultCallback) {

		var queryResultCallback = function (transaction, results) {

			if(resultCallback) {
				resultCallback.call(null, results.rows);
			}
		}

		self.selectFromDatabase('SELECT * FROM drawing_project_index WHERE storage_type=?', [self.StorageType.LOCAL_STORAGE], queryResultCallback);
	}

	self.exportApiFunction('useDefaultMap', self.useDefaultMap);
	self.exportApiFunction('clearMapGeometries', self.clearMapGeometries);
	self.exportApiFunction('saveDrawingProject', self.saveDrawingProject);
	self.exportApiFunction('queryLastDrawingProjectFromDatabase', self.queryLastDrawingProjectFromDatabase);
	self.exportApiFunction('queryAllDrawingProjectsFromDatabase', self.queryAllDrawingProjectsFromDatabase);
	self.exportApiFunction('queryLocalStorageGuidsFromDatabase', self.queryLocalStorageGuidsFromDatabase);
	self.exportApiFunction('bindDrawingManagerToMap', self.bindDrawingManagerToMap);
	self.exportApiFunction('exportGeoJsonFromDataLayer', self.exportGeoJsonFromDataLayer);
	self.exportApiFunction('importGeoJsonFromDataLayer', self.importGeoJsonFromDataLayer);
	self.exportApiFunction('generateFeatureListFromGeoJson', self.generateFeatureListFromGeoJson);
	self.exportApiFunction('prepareDrawedGeometriesFromMap', self.prepareDrawedGeometriesFromMap);
	self.exportApiFunction('prepareFeaturesFromDataLayer', self.prepareFeaturesFromDataLayer);
	self.exportApiFunction('StorageType', self.StorageType);

	return geoWizardApiFunctions;

})();

<|endoftext|>


<commit_before>enyo.kind({
	name: "MainView", kind: enyo.VFlexBox,
	published: {
		headerContent: "",
		UgcCounty: "",
		UgcZone: ""
	},
	components: [
		{kind: "Pane", flex: 1, components: [
			{kind: "VFlexBox", components: [
				{name: "City", kind: "PageHeader", content: "Selected City"},
					{kind: "Scroller", flex: 1, components: [
						{kind: "DividerDrawer", caption: "ALERTS", components: [
							{kind: "VirtualRepeater", name: "alertsVR", onSetupRow: "setupAlert", components: [
								{kind: "Item", name: "alertItem", components: [
									// {name: "alertEvent"},
									{align: "center", layoutKind: "HFlexLayout", components: [
										{content: "URGENCY:", className: "enyo-item-ternary", style: "margin-right: 2px"},
										{name: "alertUrgency", className: "enyo-item-ternary", style: "margin-right: 8px"},
										{content: "SEVERITY:", className: "enyo-item-ternary", style: "margin-right: 2px"},
										{name: "alertSeverity", className: "enyo-item-ternary", style: "margin-right: 8px"},
										{content: "CERTAINTY:", className: "enyo-item-ternary", style: "margin-right: 2px"},
										{name: "alertCertainty", className: "enyo-item-ternary", style: "margin-right: 8px"}
										]},
									{name: "alertTitle"},
									{name: "alertSummary", className: "enyo-item-ternary"}
									/*
									{align: "center", layoutKind: "HFlexLayout", components: [
										{content: "Alert Id:", style: "margin-right: 8px"},
										{name: "alertId"}
										]}
									*/
									// {name: "alertURL", className: "enyo-item-ternary"}
									]}
							]}
						]},
						// This drawer will show the current conditions on the leftmost side,
						// while the hour-by-hour forecast stretches out to the right,
						// switching to a long-range day-by-day forecast.
						{kind: "DividerDrawer", caption: "CURRENT CONDITIONS & FORECAST", components: [
							{name: "ccf", flex: 1, content: "Current Conditions & Forecast"}
							// {kind: "wbScroller", name: "ccf_scroller", flex: 1, height: "70px"}
						]},
						{kind: "DividerDrawer", caption: "MAPS", components: [
							{name: "Maps", flex: 1, content: "Maps"}
						]},
						// History drawer will allow the user to scroll back and forth
						// in a timeline, displaying past observations by the day, and/or hour.
						{kind: "DividerDrawer", caption: "HISTORY", components: [
							{name: "History", flex: 1, content: "History"}
						]}
					]}
			]}
		]},
		{kind: enyo.ApplicationEvents,
			onWindowActivated: "wakeup",
			onWindowDeactivated: "sleep",
			onWindowParamsChange: "windowParamsChangeHandler"
		}

	],
	create: function() {
		this.inherited(arguments);
		this.headerContentChanged();
		this.alertData = [];
		var currentTime = new Date();
		var current_timestamp = currentTime.getTime();
		this.getAlertData(this.UgcZone, this.UgcCounty, current_timestamp);

		/*
		enyo.log("ccf_scroller destroying views...");
		this.$.ccf_scroller.destroyViews();
		enyo.log("ccf_scroller creating view...");
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item 1"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px", onclick: "scrollerClick"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item 2"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item 3"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		*/
		enyo.log("MainView create function executed.  UgcCounty: " + this.UgcCounty + "; UgcZone: " + this.UgcZone);
	},

	getAlertData: function(inUgcZone, inUgcCounty, inTstamp) {
		// open application database to retrieve data we want to display
		this.wbDB = openDatabase("ext:WeatherBulletinUSADB", "1", "", "25000000");
		var that = this;
		enyo.log('getAlertData - reading alerts from database for ' + this.UgcZone + ' or ' +
						this.UgcCounty + ' timestamp: ' + inTstamp);
		this.wbDB.transaction(
			function(transaction) {
				transaction.executeSql('SELECT DISTINCT CAPAlert.alertId, CAPAlert.updated_tstamp, CAPAlert.published_tstamp, ' +
														'CAPAlert.title, CAPAlert.url, CAPAlert.summary, CAPAlert.event, ' +
														'CAPAlert.effective_tstamp, CAPAlert.expiration_tstamp, ' +
														'CAPAlert.download_tstamp, CAPAlert.status, CAPAlert.msgType, ' +
														'CAPAlert.category, CAPAlert.urgency, CAPAlert.severity, ' +
														'CAPAlert.certainty, CAPAlert.areaDesc, ' +
														'alertUGC.ugc ' +
												 'FROM CAPAlert, alertUGC, latestCAPAlert ' +
				                        'WHERE CAPAlert.alertId = alertUGC.alertId ' +
												  'AND CAPAlert.alertId = latestCAPAlert.alertId ' +
												  'AND CAPAlert.download_tstamp = latestCAPAlert.latest_dl_tstamp ' +
												  'AND CAPAlert.download_tstamp = alertUGC.download_tstamp ' +
												  'AND (alertUGC.ugc = ? OR alertUGC.ugc = ?) ' +
												  'AND CAPAlert.effective_tstamp <= ? ' +
												  'AND CAPAlert.expiration_tstamp >= ? ' +
											'ORDER BY CAPAlert.published_tstamp ASC;',
				[that.UgcZone, that.UgcCounty, inTstamp, inTstamp],
				that.mVDataHandler.bind(that), that.handleSqlError.bind(that));

		);

	},

	headerContentChanged: function() {
		this.$.City.setContent(this.headerContent);
	},

	clickDone: function() {
		enyo.log("MainView - executing clickDone...");
		this.doBack();
	},

	backHandler: function(inSender, e) {
		enyo.log("MainPane backHandler.  Value from " + inSender + " view is: " + e);
		this.$.MainPane.back();
   },

	setupAlert: function(inSender, inIndex) {
		enyo.log("Setting up alert item: " + inIndex);
		enyo.log(enyo.json.stringify(this.alertData));
		if (inIndex < this.alertData.length) {
			// this.$.alertEvent.setContent(this.alertData[inIndex].event);
			this.$.alertUrgency.setContent(this.alertData[inIndex].urgency);
			this.$.alertSeverity.setContent(this.alertData[inIndex].severity);
			this.$.alertCertainty.setContent(this.alertData[inIndex].certainty);
			this.$.alertTitle.setContent(this.alertData[inIndex].title);
			this.$.alertSummary.setContent(this.alertData[inIndex].summary);
			// this.$.alertId.setContent(this.alertData[inIndex].alertId);
			// this.$.alertURL.setContent(this.alertData[inIndex].url);
			return true;
			}
	},

	ShowPrefsView: function(inSender) {
		enyo.log("Selecting Prefs view from main view...");
		this.$.MainPane.selectViewByName("PrefsView");
	},

	ShowInitView: function(inSender) {
		enyo.log("Selecting Init view from main view...");
		this.$.MainPane.selectViewByName("InitView");
	},

	wakeup: function() {
		enyo.log("wakeup function called for MainWindow from MainView.");
	},

	windowParamsChangeHandler: function() {
		enyo.log("enyo.windowParams: " + enyo.json.stringify(enyo.windowParams));
		if (enyo.windowParams.view === 'MainView') {
			enyo.log("Switching to MainView...");
			this.$.MainPane.selectViewByName("MainWBView");
		}
	},
	mVDataHandler: function(transaction, results) {
		enyo.log("MainView - retrieving SQL query results...");
		for (i=0; i<results.rows.length; i=i+1) {
			var row = results.rows.item(i);
			this.alertData.push(row);
			enyo.log("Saving alert data for: " + row.title);
			// this.$.AlertContent.setContent(row.title);
		}
		this.$.alertsVR.render();
	},

	handleSqlError: function(transaction, error) {
		enyo.log("MainView - SQL statement error: [" + error.code + "] " + error.message);
		/*
		if (error.message.indexOf("no such table") !== -1) {
			this.ShowInitView();
			}
		*/
	},

	scrollerClick: function(inSender, inEvent) {
		enyo.log("function scrollerClick called...");
	}
});

<commit_msg>1. Fixed syntax error in MainView.js<commit_after>enyo.kind({
	name: "MainView", kind: enyo.VFlexBox,
	published: {
		headerContent: "",
		UgcCounty: "",
		UgcZone: ""
	},
	components: [
		{kind: "Pane", flex: 1, components: [
			{kind: "VFlexBox", components: [
				{name: "City", kind: "PageHeader", content: "Selected City"},
					{kind: "Scroller", flex: 1, components: [
						{kind: "DividerDrawer", caption: "ALERTS", components: [
							{kind: "VirtualRepeater", name: "alertsVR", onSetupRow: "setupAlert", components: [
								{kind: "Item", name: "alertItem", components: [
									// {name: "alertEvent"},
									{align: "center", layoutKind: "HFlexLayout", components: [
										{content: "URGENCY:", className: "enyo-item-ternary", style: "margin-right: 2px"},
										{name: "alertUrgency", className: "enyo-item-ternary", style: "margin-right: 8px"},
										{content: "SEVERITY:", className: "enyo-item-ternary", style: "margin-right: 2px"},
										{name: "alertSeverity", className: "enyo-item-ternary", style: "margin-right: 8px"},
										{content: "CERTAINTY:", className: "enyo-item-ternary", style: "margin-right: 2px"},
										{name: "alertCertainty", className: "enyo-item-ternary", style: "margin-right: 8px"}
										]},
									{name: "alertTitle"},
									{name: "alertSummary", className: "enyo-item-ternary"}
									/*
									{align: "center", layoutKind: "HFlexLayout", components: [
										{content: "Alert Id:", style: "margin-right: 8px"},
										{name: "alertId"}
										]}
									*/
									// {name: "alertURL", className: "enyo-item-ternary"}
									]}
							]}
						]},
						// This drawer will show the current conditions on the leftmost side,
						// while the hour-by-hour forecast stretches out to the right,
						// switching to a long-range day-by-day forecast.
						{kind: "DividerDrawer", caption: "CURRENT CONDITIONS & FORECAST", components: [
							{name: "ccf", flex: 1, content: "Current Conditions & Forecast"}
							// {kind: "wbScroller", name: "ccf_scroller", flex: 1, height: "70px"}
						]},
						{kind: "DividerDrawer", caption: "MAPS", components: [
							{name: "Maps", flex: 1, content: "Maps"}
						]},
						// History drawer will allow the user to scroll back and forth
						// in a timeline, displaying past observations by the day, and/or hour.
						{kind: "DividerDrawer", caption: "HISTORY", components: [
							{name: "History", flex: 1, content: "History"}
						]}
					]}
			]}
		]},
		{kind: enyo.ApplicationEvents,
			onWindowActivated: "wakeup",
			onWindowDeactivated: "sleep",
			onWindowParamsChange: "windowParamsChangeHandler"
		}

	],
	create: function() {
		this.inherited(arguments);
		this.headerContentChanged();
		this.alertData = [];
		var currentTime = new Date();
		var current_timestamp = currentTime.getTime();
		this.getAlertData(this.UgcZone, this.UgcCounty, current_timestamp);

		/*
		enyo.log("ccf_scroller destroying views...");
		this.$.ccf_scroller.destroyViews();
		enyo.log("ccf_scroller creating view...");
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item 1"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px", onclick: "scrollerClick"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item 2"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item 3"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		this.$.ccf_scroller.createView({
			components: [
				{content: "Scroller item"},
				{kind: enyo.HFlexBox, components: [
					{kind: "Image", src: "../images/sample-icon.png", height: "48px"}
				]}
			]
		});
		*/
		enyo.log("MainView create function executed.  UgcCounty: " + this.UgcCounty + "; UgcZone: " + this.UgcZone);
	},

	getAlertData: function(inUgcZone, inUgcCounty, inTstamp) {
		// open application database to retrieve data we want to display
		this.wbDB = openDatabase("ext:WeatherBulletinUSADB", "1", "", "25000000");
		var that = this;
		enyo.log('getAlertData - reading alerts from database for ' + this.UgcZone + ' or ' +
						this.UgcCounty + ' timestamp: ' + inTstamp);
		this.wbDB.transaction(
			function(transaction) {
				transaction.executeSql('SELECT DISTINCT CAPAlert.alertId, CAPAlert.updated_tstamp, CAPAlert.published_tstamp, ' +
														'CAPAlert.title, CAPAlert.url, CAPAlert.summary, CAPAlert.event, ' +
														'CAPAlert.effective_tstamp, CAPAlert.expiration_tstamp, ' +
														'CAPAlert.download_tstamp, CAPAlert.status, CAPAlert.msgType, ' +
														'CAPAlert.category, CAPAlert.urgency, CAPAlert.severity, ' +
														'CAPAlert.certainty, CAPAlert.areaDesc, ' +
														'alertUGC.ugc ' +
												 'FROM CAPAlert, alertUGC, latestCAPAlert ' +
				                        'WHERE CAPAlert.alertId = alertUGC.alertId ' +
												  'AND CAPAlert.alertId = latestCAPAlert.alertId ' +
												  'AND CAPAlert.download_tstamp = latestCAPAlert.latest_dl_tstamp ' +
												  'AND CAPAlert.download_tstamp = alertUGC.download_tstamp ' +
												  'AND (alertUGC.ugc = ? OR alertUGC.ugc = ?) ' +
												  'AND CAPAlert.effective_tstamp <= ? ' +
												  'AND CAPAlert.expiration_tstamp >= ? ' +
											'ORDER BY CAPAlert.published_tstamp ASC;',
				[that.UgcZone, that.UgcCounty, inTstamp, inTstamp],
				that.mVDataHandler.bind(that), that.handleSqlError.bind(that));
			}
		);

	},

	headerContentChanged: function() {
		this.$.City.setContent(this.headerContent);
	},

	clickDone: function() {
		enyo.log("MainView - executing clickDone...");
		this.doBack();
	},

	backHandler: function(inSender, e) {
		enyo.log("MainPane backHandler.  Value from " + inSender + " view is: " + e);
		this.$.MainPane.back();
   },

	setupAlert: function(inSender, inIndex) {
		enyo.log("Setting up alert item: " + inIndex);
		enyo.log(enyo.json.stringify(this.alertData));
		if (inIndex < this.alertData.length) {
			// this.$.alertEvent.setContent(this.alertData[inIndex].event);
			this.$.alertUrgency.setContent(this.alertData[inIndex].urgency);
			this.$.alertSeverity.setContent(this.alertData[inIndex].severity);
			this.$.alertCertainty.setContent(this.alertData[inIndex].certainty);
			this.$.alertTitle.setContent(this.alertData[inIndex].title);
			this.$.alertSummary.setContent(this.alertData[inIndex].summary);
			// this.$.alertId.setContent(this.alertData[inIndex].alertId);
			// this.$.alertURL.setContent(this.alertData[inIndex].url);
			return true;
			}
	},

	ShowPrefsView: function(inSender) {
		enyo.log("Selecting Prefs view from main view...");
		this.$.MainPane.selectViewByName("PrefsView");
	},

	ShowInitView: function(inSender) {
		enyo.log("Selecting Init view from main view...");
		this.$.MainPane.selectViewByName("InitView");
	},

	wakeup: function() {
		enyo.log("wakeup function called for MainWindow from MainView.");
	},

	windowParamsChangeHandler: function() {
		enyo.log("enyo.windowParams: " + enyo.json.stringify(enyo.windowParams));
		if (enyo.windowParams.view === 'MainView') {
			enyo.log("Switching to MainView...");
			this.$.MainPane.selectViewByName("MainWBView");
		}
	},
	mVDataHandler: function(transaction, results) {
		enyo.log("MainView - retrieving SQL query results...");
		for (i=0; i<results.rows.length; i=i+1) {
			var row = results.rows.item(i);
			this.alertData.push(row);
			enyo.log("Saving alert data for: " + row.title);
			// this.$.AlertContent.setContent(row.title);
		}
		this.$.alertsVR.render();
	},

	handleSqlError: function(transaction, error) {
		enyo.log("MainView - SQL statement error: [" + error.code + "] " + error.message);
		/*
		if (error.message.indexOf("no such table") !== -1) {
			this.ShowInitView();
			}
		*/
	},

	scrollerClick: function(inSender, inEvent) {
		enyo.log("function scrollerClick called...");
	}
});

<|endoftext|>


<commit_before>var _ = function (check) {
  return check;
};

var polyglot = new Polyglot({
  phrases: {
    'to get started, press the translate! button below.': 'ในการเริ่มต้นกด -แปล!- ปุ่ม',
    'translated by:': 'ผู้แปล:',
    'translate!': 'แปล!',
    'title:': 'หัวข้อ:',
    'language:': 'ภาษา:',
    previous: 'ก่อน',
    'random story': 'เรื่องแบบสุ่ม',
    next: 'ก่อน',
    'story id:': 'ID เรื่อง:',
    'review': 'ตรวจสอบการทำงานของคุณ',
    'review submission': 'ตรวจสอบการทำงานของคุณ',
    'your name': 'ชื่อของคุณ',
    'your email': 'อีเมลของคุณ',
    'send translation': 'ส่งการแปล',
    'your translation': 'การแปลของคุณ',
    'loading epub': 'โหลด ePUB'
  }
});

_ = function (word, vars) {
  return polyglot.t(word.toLowerCase(), vars);
};

$(function() {
  if (window.location.href.indexOf('thai') > -1) {
    $(".translate").each(function(i, item) {
      if ($(item).text()) {
        $(item).text(_($(item).text().toLowerCase()));
      }
      if ($(item).attr('title')) {
        $(item).attr('title', _( $(item).attr('title')));
      }
      if ($(item).attr('placeholder')) {
        $(item).attr('placeholder', _( $(item).attr('placeholder')));
      }
    });
  }
});
<commit_msg>run translation only when needed<commit_after>var polyglot = new Polyglot({
  phrases: {
    'to get started, press the translate! button below.': 'ในการเริ่มต้นกด -แปล!- ปุ่ม',
    'translated by:': 'ผู้แปล:',
    'translate!': 'แปล!',
    'title:': 'หัวข้อ:',
    'language:': 'ภาษา:',
    previous: 'ก่อน',
    'random story': 'เรื่องแบบสุ่ม',
    next: 'ก่อน',
    'story id:': 'ID เรื่อง:',
    'review': 'ตรวจสอบการทำงานของคุณ',
    'review submission': 'ตรวจสอบการทำงานของคุณ',
    'your name': 'ชื่อของคุณ',
    'your email': 'อีเมลของคุณ',
    'send translation': 'ส่งการแปล',
    'your translation': 'การแปลของคุณ',
    'loading epub': 'โหลด ePUB'
  }
});

var _ = function (word, vars) {
  if (window.location.href.indexOf('thai') > -1) {
    return polyglot.t(word.toLowerCase(), vars);
  } else {
    return word;
  }
};

$(function() {
  if (window.location.href.indexOf('thai') > -1) {
    $(".translate").each(function(i, item) {
      if ($(item).text()) {
        $(item).text(_($(item).text().toLowerCase()));
      }
      if ($(item).attr('title')) {
        $(item).attr('title', _( $(item).attr('title')));
      }
      if ($(item).attr('placeholder')) {
        $(item).attr('placeholder', _( $(item).attr('placeholder')));
      }
    });
  }
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @jest-environment jsdom
 */
/* eslint-env browser*/

describe('toEqual', () => {
  describe('duck type', () => {
    // https://github.com/facebook/jest/issues/7786

    const createElement = (name, ...childNodes) => ({
      childNodes,
      nodeType: 1,
      tagName: name.toUpperCase(),
    });

    const createTextNode = data => ({
      data,
      nodeType: 3,
    });

    const createDocumentFragment = (...children) => ({
      children,
      nodeType: 11,
    });

    describe('Text', () => {
      test('isNot false', () => {
        const data = 'deep equal';

        const a = createTextNode(data);
        const b = createTextNode(data);

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const a = createTextNode('not deep equal a');
        const b = createTextNode('not deep equal b');

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('Element', () => {
      test('isNot false', () => {
        const name = 'span';
        const data = 'deep equal';

        const a = createElement(name, createTextNode(data));
        const b = createElement(name, createTextNode(data));

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const data = 'not deep equal';

        const a = createElement('strong', createTextNode(data));
        const b = createElement('span', createTextNode(data));

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('Fragment', () => {
      test('isNot false', () => {
        const name1 = 'strong';
        const name2 = 'span';
        const data1 = 'deep';
        const data2 = 'equal';

        const a = createDocumentFragment(
          createElement(name1, createTextNode(data1)),
          createElement(name2, createTextNode(data2)),
        );
        const b = createDocumentFragment(
          createElement(name1, createTextNode(data1)),
          createElement(name2, createTextNode(data2)),
        );

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const name = 'span';
        const data1 = 'not';
        const data2 = 'deep equal';

        const a = createDocumentFragment(
          createElement('strong', createTextNode(data1)),
          createElement(name, createTextNode(data2)),
        );
        const b = createDocumentFragment(
          createElement(name, createTextNode(data1)),
          createElement(name, createTextNode(data2)),
        );

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });
  });

  describe('document', () => {
    describe('createTextNode', () => {
      test('isNot false', () => {
        const data = 'deep equal';

        const a = document.createTextNode(data);
        const b = document.createTextNode(data);

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const a = document.createTextNode('not deep equal a');
        const b = document.createTextNode('not deep equal b');

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('createElement', () => {
      test('isNot false', () => {
        const name = 'span';
        const data = 'deep equal';

        const a = document.createElement(name);
        const b = document.createElement(name);
        a.appendChild(document.createTextNode(data));
        b.appendChild(document.createTextNode(data));

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const data = 'not deep equal';

        const a = document.createElement('strong');
        const b = document.createElement('span');
        a.appendChild(document.createTextNode(data));
        b.appendChild(document.createTextNode(data));

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('createDocumentFragment', () => {
      test('isNot false', () => {
        const name1 = 'strong';
        const name2 = 'span';
        const data1 = 'deep';
        const data2 = 'equal';

        const aSpan1 = document.createElement(name1);
        const bSpan1 = document.createElement(name1);
        aSpan1.appendChild(document.createTextNode(data1));
        bSpan1.appendChild(document.createTextNode(data1));

        const aSpan2 = document.createElement(name2);
        const bSpan2 = document.createElement(name2);
        aSpan2.appendChild(document.createTextNode(data2));
        bSpan2.appendChild(document.createTextNode(data2));

        const a = document.createDocumentFragment();
        const b = document.createDocumentFragment();
        a.appendChild(aSpan1);
        a.appendChild(aSpan2);
        b.appendChild(bSpan1);
        b.appendChild(bSpan2);

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const name = 'span';
        const data1 = 'not';
        const data2 = 'deep equal';

        const aSpan1 = document.createElement('strong');
        const bSpan1 = document.createElement(name);
        aSpan1.appendChild(document.createTextNode(data1));
        bSpan1.appendChild(document.createTextNode(data1));

        const aSpan2 = document.createElement(name);
        const bSpan2 = document.createElement(name);
        aSpan2.appendChild(document.createTextNode(data2));
        bSpan2.appendChild(document.createTextNode(data2));

        const a = document.createDocumentFragment();
        const b = document.createDocumentFragment();
        a.appendChild(aSpan1);
        a.appendChild(aSpan2);
        b.appendChild(bSpan1);
        b.appendChild(bSpan2);
        console.log(a.innerHTML);

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });
  });
});
<commit_msg>chore: remove console.log<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @jest-environment jsdom
 */
/* eslint-env browser*/

describe('toEqual', () => {
  describe('duck type', () => {
    // https://github.com/facebook/jest/issues/7786

    const createElement = (name, ...childNodes) => ({
      childNodes,
      nodeType: 1,
      tagName: name.toUpperCase(),
    });

    const createTextNode = data => ({
      data,
      nodeType: 3,
    });

    const createDocumentFragment = (...children) => ({
      children,
      nodeType: 11,
    });

    describe('Text', () => {
      test('isNot false', () => {
        const data = 'deep equal';

        const a = createTextNode(data);
        const b = createTextNode(data);

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const a = createTextNode('not deep equal a');
        const b = createTextNode('not deep equal b');

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('Element', () => {
      test('isNot false', () => {
        const name = 'span';
        const data = 'deep equal';

        const a = createElement(name, createTextNode(data));
        const b = createElement(name, createTextNode(data));

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const data = 'not deep equal';

        const a = createElement('strong', createTextNode(data));
        const b = createElement('span', createTextNode(data));

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('Fragment', () => {
      test('isNot false', () => {
        const name1 = 'strong';
        const name2 = 'span';
        const data1 = 'deep';
        const data2 = 'equal';

        const a = createDocumentFragment(
          createElement(name1, createTextNode(data1)),
          createElement(name2, createTextNode(data2)),
        );
        const b = createDocumentFragment(
          createElement(name1, createTextNode(data1)),
          createElement(name2, createTextNode(data2)),
        );

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const name = 'span';
        const data1 = 'not';
        const data2 = 'deep equal';

        const a = createDocumentFragment(
          createElement('strong', createTextNode(data1)),
          createElement(name, createTextNode(data2)),
        );
        const b = createDocumentFragment(
          createElement(name, createTextNode(data1)),
          createElement(name, createTextNode(data2)),
        );

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });
  });

  describe('document', () => {
    describe('createTextNode', () => {
      test('isNot false', () => {
        const data = 'deep equal';

        const a = document.createTextNode(data);
        const b = document.createTextNode(data);

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const a = document.createTextNode('not deep equal a');
        const b = document.createTextNode('not deep equal b');

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('createElement', () => {
      test('isNot false', () => {
        const name = 'span';
        const data = 'deep equal';

        const a = document.createElement(name);
        const b = document.createElement(name);
        a.appendChild(document.createTextNode(data));
        b.appendChild(document.createTextNode(data));

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const data = 'not deep equal';

        const a = document.createElement('strong');
        const b = document.createElement('span');
        a.appendChild(document.createTextNode(data));
        b.appendChild(document.createTextNode(data));

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });

    describe('createDocumentFragment', () => {
      test('isNot false', () => {
        const name1 = 'strong';
        const name2 = 'span';
        const data1 = 'deep';
        const data2 = 'equal';

        const aSpan1 = document.createElement(name1);
        const bSpan1 = document.createElement(name1);
        aSpan1.appendChild(document.createTextNode(data1));
        bSpan1.appendChild(document.createTextNode(data1));

        const aSpan2 = document.createElement(name2);
        const bSpan2 = document.createElement(name2);
        aSpan2.appendChild(document.createTextNode(data2));
        bSpan2.appendChild(document.createTextNode(data2));

        const a = document.createDocumentFragment();
        const b = document.createDocumentFragment();
        a.appendChild(aSpan1);
        a.appendChild(aSpan2);
        b.appendChild(bSpan1);
        b.appendChild(bSpan2);

        expect(a).toEqual(b);
        expect(b).toEqual(a);
      });

      test('isNot true', () => {
        const name = 'span';
        const data1 = 'not';
        const data2 = 'deep equal';

        const aSpan1 = document.createElement('strong');
        const bSpan1 = document.createElement(name);
        aSpan1.appendChild(document.createTextNode(data1));
        bSpan1.appendChild(document.createTextNode(data1));

        const aSpan2 = document.createElement(name);
        const bSpan2 = document.createElement(name);
        aSpan2.appendChild(document.createTextNode(data2));
        bSpan2.appendChild(document.createTextNode(data2));

        const a = document.createDocumentFragment();
        const b = document.createDocumentFragment();
        a.appendChild(aSpan1);
        a.appendChild(aSpan2);
        b.appendChild(bSpan1);
        b.appendChild(bSpan2);

        expect(a).not.toEqual(b);
        expect(b).not.toEqual(a);
      });
    });
  });
});
<|endoftext|>