<commit_before>import React from 'react'
import { connect } from 'react-redux'
import { compose } from 'recompose'

import { updateVideo } from '../../actions/videos'

import { withDatabaseSubscribe } from '../hocs'
import CommentList from '../CommentList'
import PerformanceFrame from '../PerformanceFrame'

const mapStateToProps = ({videos}) => ({
  videos
})

const enhance = compose(
  connect(mapStateToProps),
  withDatabaseSubscribe(
    'value',
    (props) => (`videos/${props.params.videoId}`),
    (props) => (snapshot) => (
      props.dispatch(updateVideo({
        videoId: props.params.videoId,
        videoSnapshot: snapshot.val()
      }))
    )
  ),
)

const styles = {
  videoContainer: {
    height: 'calc(100vh - 56px)',
    display: 'flex',
    flexWrap: 'wrap',
  }
}

const VideoView = ({videos, params}) => (

    {(params.videoId in videos && videos[params.videoId] !== null) ?
      <PerformanceFrame size={{width: 854, height: 480}} layout={{ videoStreams: [{videoId: params.videoId, z_index: 0, scale: 1.0}]}} /> :

{"404 not found"}

    }
    {videos[params.videoId] !== null ?
      <CommentList videoId={params.videoId}/> :

{"duh"}

    }

)

export default enhance(VideoView)
<commit_msg>Fix video view and remove some sub components<commit_after>import * as _ from 'lodash'
import React from 'react'
import {connect} from 'react-redux'
import {compose, withProps} from 'recompose'

import {updateVideo} from '../../actions/videos'
import CommentList from '../CommentList'

import {withDatabaseSubscribe} from '../hocs'

const mapStateToProps = ({videos}) => ({
  videos
})

const enhance = compose(
  connect(mapStateToProps),
  withProps(({match}) => ({
    videoId: match.params.videoId,
  })),
  withDatabaseSubscribe(
    'value',
    (props) => (`videos/${props.videoId}`),
    (props) => (snapshot) => (
      props.dispatch(updateVideo(
        {
          videoId: props.videoId,
          videoSnapshot: snapshot.val()
        }))
    )
  ),
)

const styles = {
  videoContainer: {
    height: 'calc(100vh - 56px)',
    display: 'flex',
    flexWrap: 'wrap',
  }
}

const VideoView = ({videos, videoId}) => (

    {JSON.stringify(_.get(videos, videoId, {}))}
    <CommentList videoId={videoId}/>

)

export default enhance(VideoView)
<|endoftext|>


<commit_before>'use strict';

angular.module('lexicon.settings', ['bellows.services', 'ui.bootstrap', 'palaso.ui.listview',
  'palaso.ui.typeahead', 'palaso.ui.sendReceiveCredentials', 'palaso.ui.notice',
  'palaso.ui.textdrop'])
  .controller('SettingsCtrl', ['$scope', '$filter', 'userService', 'sessionService',
    'silNoticeService', 'lexProjectService', 'lexSendReceiveApi',
  function ($scope, $filter, userService, sessionService,
            notice, lexProjectService, sendReceiveApi) {
    lexProjectService.setBreadcrumbs('settings', $filter('translate')('Project Settings'));

    $scope.rights.canViewSendReceiveProperties = sessionService
      .hasProjectRight(sessionService.domain.PROJECTS, sessionService.operation.VIEW);
    $scope.rights.canEditSendReceiveProperties = sessionService
      .hasProjectRight(sessionService.domain.PROJECTS, sessionService.operation.EDIT);

    $scope.readProject = function () {
      lexProjectService.readProject(function (result) {
        if (result.ok) {
          $.extend($scope.project, result.data.project);
          $scope.sendReceive.showTab =
            ($scope.project.sendReceive && $scope.project.sendReceive.project) ? true : false;
          if ($scope.sendReceive.showTab && !$scope.project.sendReceive.username) {
            $scope.project.sendReceive.username = sessionService.session.username;
          }
        }
      });
    };

    $scope.readProject();

    $scope.updateProject = function () {
      var settings = {
        projectName: $scope.project.projectName,
        interfaceLanguageCode: $scope.project.interfaceLanguageCode,
        featured: $scope.project.featured
      };

      lexProjectService.updateProject(settings, function (result) {
        if (result.ok) {
          notice.push(notice.SUCCESS,
            $scope.project.projectName + ' settings updated successfully.');
        }
      });
    };

    $scope.sendReceive = {};
    $scope.project = {};
    $scope.project.sendReceive = {};

    $scope.resetValidateForm = function resetValidateForm() {
      $scope.project.sendReceive.isUnchecked = true;
    };

    $scope.updateSendReceiveCredentials = function updateSendReceiveCredentials() {
      if (!isFormValid()) {
        return;
      }

      sendReceiveApi.updateSRProject($scope.project.sendReceive.project, function (result) {
        if (result.ok) {
          notice.push(notice.SUCCESS,
            'The LanguageDepot.org project info was updated successfully.');
          $scope.project.sendReceive.password = '';
          $scope.project.sendReceive.passwordStatus = 'unchecked';
        } else {
          notice.push(notice.ERROR,
            'The LanguageDepot.org project info could not be saved. Please try again.');
        }
      });
    };

    function isFormValid() {
      $scope.project.sendReceive.projectStatus = 'unchecked';
      if (!$scope.project.sendReceive.username) {
        return error('Login cannot be empty. Please enter your LanguageDepot.org login username.');
      }

      if (!$scope.project.sendReceive.password) {
        return error('Password cannot be empty. Please enter your LanguageDepot.org password.');
      }

      if ($scope.project.sendReceive.isUnchecked) {
        return neutral();
      }

      if ($scope.project.sendReceive.usernameStatus == 'unknown') {
        return error('The Login dosen\'t exist on LanguageDepot.org. Enter a Login.');
      }

      if ($scope.project.sendReceive.passwordStatus == 'invalid') {
        return error('The Password isn\'t valid on LanguageDepot.org. Enter the Password.');
      }

      $scope.project.sendReceive.projectStatus = 'no_access';
      if (!$scope.project.sendReceive.project) {
        return error('Please select a Project.');
      }

      if ($scope.project.sendReceive.project.role != 'manager') {
        return error('Please select a Project that you are the Manager on LanguageDepot.org.');
      }

      $scope.project.sendReceive.projectStatus = 'ok';
      return ok();
    }

    function makeFormValid(msg) {
      if (!msg) msg = '';
      $scope.formStatus = msg;
      $scope.formStatusClass = 'alert alert-info';
      if (!msg) $scope.formStatusClass = 'neutral';
      return $scope.formValidated = true;
    }

    function makeFormNeutral(msg) {
      if (!msg) msg = '';
      $scope.formStatus = msg;
      $scope.formStatusClass = 'neutral';
      return $scope.formValidated = false;
    }

    function makeFormInvalid(msg) {
      if (!msg) msg = '';
      $scope.formStatus = msg;
      $scope.formStatusClass = 'alert alert-error';
      if (!msg) $scope.formStatusClass = 'neutral';
      return $scope.formValidated = false;
    }

    makeFormNeutral();

    // Shorthand to make things look a touch nicer
    var ok = makeFormValid;
    var neutral = makeFormNeutral;
    var error = makeFormInvalid;

  }])

  ;
<commit_msg>Fix Project Settings not displaying project name<commit_after>'use strict';

angular.module('lexicon.settings', ['bellows.services', 'ui.bootstrap', 'palaso.ui.listview',
  'palaso.ui.typeahead', 'palaso.ui.sendReceiveCredentials', 'palaso.ui.notice',
  'palaso.ui.textdrop'])
  .controller('SettingsCtrl', ['$scope', '$filter', 'userService', 'sessionService',
    'silNoticeService', 'lexProjectService', 'lexSendReceiveApi',
  function ($scope, $filter, userService, sessionService,
            notice, lexProjectService, sendReceiveApi) {
    lexProjectService.setBreadcrumbs('settings', $filter('translate')('Project Settings'));

    $scope.rights.canViewSendReceiveProperties = sessionService
      .hasProjectRight(sessionService.domain.PROJECTS, sessionService.operation.VIEW);
    $scope.rights.canEditSendReceiveProperties = sessionService
      .hasProjectRight(sessionService.domain.PROJECTS, sessionService.operation.EDIT);

    $scope.readProject = function () {
      lexProjectService.readProject(function (result) {
        if (result.ok) {
          $.extend($scope.project, result.data.project);
          $scope.sendReceive.showTab =
            ($scope.project.sendReceive && $scope.project.sendReceive.project) ? true : false;
          if ($scope.sendReceive.showTab && !$scope.project.sendReceive.username) {
            $scope.project.sendReceive.username = sessionService.session.username;
          }
        }
      });
    };

    $scope.readProject();

    $scope.updateProject = function () {
      var settings = {
        projectName: $scope.project.projectName,
        interfaceLanguageCode: $scope.project.interfaceLanguageCode,
        featured: $scope.project.featured
      };

      lexProjectService.updateProject(settings, function (result) {
        if (result.ok) {
          notice.push(notice.SUCCESS,
            $scope.project.projectName + ' settings updated successfully.');
        }
      });
    };

    $scope.sendReceive = {};
    $scope.project = $scope.project || {};
    $scope.project.sendReceive = {};

    $scope.resetValidateForm = function resetValidateForm() {
      $scope.project.sendReceive.isUnchecked = true;
    };

    $scope.updateSendReceiveCredentials = function updateSendReceiveCredentials() {
      if (!isFormValid()) {
        return;
      }

      sendReceiveApi.updateSRProject($scope.project.sendReceive.project, function (result) {
        if (result.ok) {
          notice.push(notice.SUCCESS,
            'The LanguageDepot.org project info was updated successfully.');
          $scope.project.sendReceive.password = '';
          $scope.project.sendReceive.passwordStatus = 'unchecked';
        } else {
          notice.push(notice.ERROR,
            'The LanguageDepot.org project info could not be saved. Please try again.');
        }
      });
    };

    function isFormValid() {
      $scope.project.sendReceive.projectStatus = 'unchecked';
      if (!$scope.project.sendReceive.username) {
        return error('Login cannot be empty. Please enter your LanguageDepot.org login username.');
      }

      if (!$scope.project.sendReceive.password) {
        return error('Password cannot be empty. Please enter your LanguageDepot.org password.');
      }

      if ($scope.project.sendReceive.isUnchecked) {
        return neutral();
      }

      if ($scope.project.sendReceive.usernameStatus == 'unknown') {
        return error('The Login dosen\'t exist on LanguageDepot.org. Enter a Login.');
      }

      if ($scope.project.sendReceive.passwordStatus == 'invalid') {
        return error('The Password isn\'t valid on LanguageDepot.org. Enter the Password.');
      }

      $scope.project.sendReceive.projectStatus = 'no_access';
      if (!$scope.project.sendReceive.project) {
        return error('Please select a Project.');
      }

      if ($scope.project.sendReceive.project.role != 'manager') {
        return error('Please select a Project that you are the Manager on LanguageDepot.org.');
      }

      $scope.project.sendReceive.projectStatus = 'ok';
      return ok();
    }

    function makeFormValid(msg) {
      if (!msg) msg = '';
      $scope.formStatus = msg;
      $scope.formStatusClass = 'alert alert-info';
      if (!msg) $scope.formStatusClass = 'neutral';
      return $scope.formValidated = true;
    }

    function makeFormNeutral(msg) {
      if (!msg) msg = '';
      $scope.formStatus = msg;
      $scope.formStatusClass = 'neutral';
      return $scope.formValidated = false;
    }

    function makeFormInvalid(msg) {
      if (!msg) msg = '';
      $scope.formStatus = msg;
      $scope.formStatusClass = 'alert alert-error';
      if (!msg) $scope.formStatusClass = 'neutral';
      return $scope.formValidated = false;
    }

    makeFormNeutral();

    // Shorthand to make things look a touch nicer
    var ok = makeFormValid;
    var neutral = makeFormNeutral;
    var error = makeFormInvalid;

  }])

  ;
<|endoftext|>


<commit_before>
exports.name = "sotd.processDocument";
exports.check = function (sr, done) {
    var BOILERPLATE_PREFIX = 'This document is governed by the '
    ,   BOILERPLATE_SUFFIX = ' W3C Process Document.'
    ;
    var processDocument = sr.config.processDocument
    ,   $sotd = sr.getSotDSection()
    ,   proc
    ,   procUri;
    if (!$sotd || !$sotd.length) {
        sr.error(exports.name, "no-sotd");
        return done();
    }

    if ('2015' === processDocument) {
        proc = '1 September 2015';
        procUri = 'http://www.w3.org/2015/Process-20150901/';
    }
    else if (processDocument === "2005") {
        proc = "14 October 2005";
        procUri = "http://www.w3.org/2005/10/Process-20051014/";
    }
    else {
        sr.error(exports.name, "not-specified");
        return done();
    }
    var found = false
    ,   boilerplate = BOILERPLATE_PREFIX + proc + BOILERPLATE_SUFFIX
    ,   regex = new RegExp(BOILERPLATE_PREFIX + '.+' + BOILERPLATE_SUFFIX)
    ,   deprecatedBoilerplate = BOILERPLATE_PREFIX + '1 August 2014' + BOILERPLATE_SUFFIX
    ,   deprecatedUri = 'http://www.w3.org/2014/Process-20140801/'
    ;
    $sotd.parent().find("p").each(function () {
        var $p = sr.$(this);
        if (sr.norm($p.text()) === boilerplate && $p.find("a").attr("href") === procUri) {
            if (found) sr.error(exports.name, "multiple-times", { process: proc });
            else {
                sr.metadata('process', procUri);
                found = true;
            }
        }
        else if (deprecatedBoilerplate === sr.norm($p.text()) || deprecatedUri === $p.find('a').attr('href')) {
            sr.error(exports.name, 'deprecated');
        }
        else if (sr.norm($p.text()) !== boilerplate && regex.test($p.text())) {
            sr.error(exports.name, "wrong-process", { process: proc });
        }
        else if (sr.norm($p.text()) === boilerplate && $p.find("a").attr("href") !== procUri) {
            sr.error(exports.name, "wrong-link");
        }
    });
    if (!found) sr.error(exports.name, "not-found", { process: proc });
    done();
};
<commit_msg>Minor fix in coding style (order of operands, quotes)<commit_after>
exports.name = "sotd.processDocument";
exports.check = function (sr, done) {
    var BOILERPLATE_PREFIX = 'This document is governed by the '
    ,   BOILERPLATE_SUFFIX = ' W3C Process Document.'
    ;
    var processDocument = sr.config.processDocument
    ,   $sotd = sr.getSotDSection()
    ,   proc
    ,   procUri;
    if (!$sotd || !$sotd.length) {
        sr.error(exports.name, "no-sotd");
        return done();
    }

    if (processDocument === "2015") {
        proc = "1 September 2015";
        procUri = "http://www.w3.org/2015/Process-20150901/";
    }
    else if (processDocument === "2005") {
        proc = "14 October 2005";
        procUri = "http://www.w3.org/2005/10/Process-20051014/";
    }
    else {
        sr.error(exports.name, "not-specified");
        return done();
    }
    var found = false
    ,   boilerplate = BOILERPLATE_PREFIX + proc + BOILERPLATE_SUFFIX
    ,   regex = new RegExp(BOILERPLATE_PREFIX + '.+' + BOILERPLATE_SUFFIX)
    ,   deprecatedBoilerplate = BOILERPLATE_PREFIX + '1 August 2014' + BOILERPLATE_SUFFIX
    ,   deprecatedUri = 'http://www.w3.org/2014/Process-20140801/'
    ;
    $sotd.parent().find("p").each(function () {
        var $p = sr.$(this);
        if (sr.norm($p.text()) === boilerplate && $p.find("a").attr("href") === procUri) {
            if (found) sr.error(exports.name, "multiple-times", { process: proc });
            else {
                sr.metadata('process', procUri);
                found = true;
            }
        }
        else if (deprecatedBoilerplate === sr.norm($p.text()) || deprecatedUri === $p.find('a').attr('href')) {
            sr.error(exports.name, 'deprecated');
        }
        else if (sr.norm($p.text()) !== boilerplate && regex.test($p.text())) {
            sr.error(exports.name, "wrong-process", { process: proc });
        }
        else if (sr.norm($p.text()) === boilerplate && $p.find("a").attr("href") !== procUri) {
            sr.error(exports.name, "wrong-link");
        }
    });
    if (!found) sr.error(exports.name, "not-found", { process: proc });
    done();
};
<|endoftext|>


<commit_before>/*global IDBKeyRange,indexedDB */

"use strict";
O.esri.Edit.EditStore = function()
{
    this._db = null;

    // Public properties

    var dbName = "features_store";
    var objectStoreName = "features";
    var dbIndex = "featureId";

    // ENUMs

    this.ADD = "add";
    this.UPDATE = "update";
    this.DELETE = "delete";

    this.isSupported = function()
    {
        if(!window.indexedDB){
            return false;
        }
        return true;
    };

    /**
     * Commit an edit to the database
     * @param operation add, update or delete
     * @param layer the URL of the feature layer
     * @param graphic esri/graphic. The method will serialize to JSON
     * @param callback {true, edit} or {false, error}
     */
    this.pushEdit = function(operation,layer,graphic, callback)
    {

        var edit = {
                id: layer + "/" + graphic.attributes.objectid,
                operation: operation,
                layer: layer,
                graphic: graphic.toJson()
            };

        var transaction = this._db.transaction([objectStoreName],"readwrite");

        transaction.oncomplete = function(event){
            callback(true);
        };

        transaction.onerror = function(event){
            callback(false,event.target.error.message);
        };

        var objectStore = transaction.objectStore(objectStoreName);
        var request = objectStore.put(edit);
        request.onsuccess = function(event){
            //console.log("item added to db " + event.target.result);
        };
    };

    /**
     * Returns all the edits recursively via the callback
     * @param callback {value, message}
     */
    this.getAllEdits = function(callback){

        console.assert(this._db !== null, "indexeddb not initialized");

        if(this._db !== null){
            var transaction = this._db.transaction([objectStoreName])
                .objectStore(objectStoreName)
                .openCursor();

            transaction.onsuccess = function(event)
            {
                var cursor = event.target.result;
                if(cursor){
                    callback(cursor.value,null);
                    cursor.continue();
                }
                else
                {
                    callback(null, "end");
                }
            }.bind(this);
            transaction.onerror = function(err)
            {
                callback(null, err);
            };
        }
        else
        {
            callback(null, "no db");
        }
    };

    /**
     * Update an edit already exists in the database
     * @param operation add, update or delete
     * @param layer the URL of the feature layer
     * @param graphic esri/graphic. The method will serialize to JSON
     * @param callback {true, edit} or {false, error}
     */
    this.updateExistingEdit = function(operation,layer,graphic, callback){

        console.assert(this._db !== null, "indexeddb not initialized");

        var objectStore = this._db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);

        //Let's get the entry associated with the graphic
        var objectStoreGraphicRequest = objectStore.get(graphic.attributes.objectid);
        objectStoreGraphicRequest.onsuccess = function() {

            //Grab the data object returned as a result
            var data = objectStoreGraphicRequest.result;

            //Create a new update object
            var update = {
                id: layer + "/" + graphic.attributes.objectid,
                operation: operation,
                layer: layer,
                graphic: graphic.toJson()
            };

            // Insert the update into the database
            var updateGraphicRequest = objectStore.put(update);

            updateGraphicRequest.onsuccess = function(){
                callback(true);
            }

            updateGraphicRequest.onerror = function(err){
                callback(false,err);
            };
        }
    };

    /**
     * Delete a pending edit's record from the database.
     * IMPORTANT: Be aware of false negatives. See Step 4 in this function.
     *
     * @param layerUrl
     * @param graphic Graphic
     * @param callback {boolean}
     */
    this.delete = function(layerUrl, graphic, callback){

        // NOTE: the implementation of the IndexedDB spec has a major failure with respect to
        // handling deletes. The result of the operation is specified as undefined.
        // What this means is that there is no way to tell if an operation was successful or not.
        //
        // In order to get around this we have to verify if after the attempted deletion operation
        // if the record is or is not in the database. Kinda dumb, but that's how IndexedDB works.
        //http://stackoverflow.com/questions/17137879/is-there-a-way-to-get-information-on-deleted-record-when-calling-indexeddbs-obj

        var db = this._db;
        var deferred = null;
        var self = this;

        var edit = {
            id: layerUrl + "/" + graphic.attributes.objectid,
            operation: null,
            layer: layerUrl,
            graphic: graphic.toJson()
        };

        require(["dojo/Deferred"], function(Deferred){
            deferred = new Deferred();

            // Step 1 - lets see if record exits. If it does then return callback.
            self.editExists(edit).then(function(result){
               if(result.success){
                   // Step 4 - Then we check to see if the record actually exists or not.
                   deferred.then(function(edit){

                           // IF the delete was successful, then the record should return 'false' because it doesn't exist.
                           self.editExists(edit).then(function(results){
                                   results.success == false ? callback(true) : callback(false);
                               },
                               function(){
                                   callback(true); //because we want this test to throw an error. That means item deleted.
                               })
                       },
                       // There was a problem with the delete operation on the database
                       function(err){
                           callback(err);
                       });

                   var objectStore = db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);

                   // Step 2 - go ahead and delete graphic
                   var objectStoreDeleteRequest = objectStore.delete(edit.id);

                   // Step 3 - We know that the onsuccess will always fire unless something serious goes wrong.
                   // So we go ahead and resolve the deferred here.
                   objectStoreDeleteRequest.onsuccess = function() {
                       deferred.resolve(edit);
                   };

                   objectStoreDeleteRequest.onerror = function(msg){
                       deferred.reject({success:false,error:msg});
                   }
               }
            },
            // If there is an error in editExists()
            function(){
                callback(false);
            });
        });
    };

    this.resetEditsQueue = function(callback)
    {
        console.assert(this._db !== null, "indexeddb not initialized");

        var request = this._db.transaction([objectStoreName],"readwrite")
            .objectStore(objectStoreName)
            .clear();
        request.onsuccess = function(event){
            setTimeout(function(){callback(true);},0);
        };
        request.onerror = function(err){
            callback(false,err);
        };
    };

    this.pendingEditsCount = function(callback)
    {
        console.assert(this._db !== null, "indexeddb not initialized");

        var count = 0;

        var objectStore = this._db.transaction([objectStoreName]).objectStore(objectStoreName);
        objectStore.openCursor().onsuccess = function(evt)
        {
            var cursor = evt.target.result;
            if(cursor)
            {
                count++;
                cursor.continue();
            }
            else
            {
                callback(count);
            }
        };
    };

    /**
     * Verify is an edit already exists in the database. Checks the objectId and layerId.
     * @param newEdit {id,operation,layerId,graphicJSON}
     * @returns {deferred} {success: boolean, error: message}
     * @private
     */
    this.editExists = function(newEdit){

        var db = this._db;
        var deferred = null;

        require(["dojo/Deferred"], function(Deferred){
            deferred = new Deferred();

            var objectStore = db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);

            //Get the entry associated with the graphic
            var objectStoreGraphicRequest = objectStore.get(newEdit.id);

            objectStoreGraphicRequest.onsuccess = function() {
                var graphic = objectStoreGraphicRequest.result;
                if(graphic && (graphic.id == newEdit.id)){
                    deferred.resolve({success:true,error:null});
                }
                else{
                    deferred.reject({success:false,error:"Layer id is not a match."});
                }
            };

            objectStoreGraphicRequest.onerror = function(msg){
                deferred.reject({success:false,error:msg});
            }
        });

        //We return a deferred object so that when calling this function you can chain it with a then() statement.
        return deferred;
    };

    /**
     * Returns the approximate size of the database in bytes
     * @param callback  {usage, error} Whereas, the usage Object is {sizeBytes: number, editCount: number}
     */
    this.getUsage = function(callback)
    {
        console.assert(this._db !== null, "indexeddb not initialized");

        var usage = { sizeBytes: 0, editCount: 0 };

        var transaction = this._db.transaction([objectStoreName])
            .objectStore(objectStoreName)
            .openCursor();

        console.log("dumping keys");

        transaction.onsuccess = function(event)
        {
            var cursor = event.target.result;
            if(cursor)
            {
                var storedObject = cursor.value;
                var json = JSON.stringify(storedObject);
                usage.sizeBytes += json.length;
                usage.editCount += 1;
                cursor.continue();
            }
            else
            {
                callback(usage,null);
            }
        };
        transaction.onerror = function(err)
        {
            callback(null,err);
        };
    };

    // internal methods

    //
    // graphic serialization/deserialization
    //
    this._serialize = function(graphic)
    {
        // keep only attributes and geometry, that are the values that get sent to the server by applyEdits()
        // see http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Apply_Edits_Feature_Service_Layer/02r3000000r6000000/
        // use graphic's built-in serializing method
        var json = graphic.toJson();
        var jsonClean =
        {
            attributes: json.attributes,
            geometry: json.geometry
        };
        return JSON.stringify(jsonClean);
    };

    this._deserialize = function(json)
    {
        var graphic;

        require(["esri/graphic"],function(Graphic){
            graphic = new Graphic(JSON.parse(json));
        });

        return graphic;
    };

    this.init = function(callback)
    {
        console.log("init editsStore.js");

        var request = indexedDB.open(dbName, 11);
        callback = callback || function(success) { console.log("EditsStore::init() success:", success); }.bind(this);

        request.onerror = function(event)
        {
            console.log("indexedDB error: " + event.target.errorCode);
            callback(false,event.target.errorCode);
        }.bind(this);

        request.onupgradeneeded = function(event)
        {
            var db = event.target.result;

            if( db.objectStoreNames.contains(objectStoreName))
            {
                db.deleteObjectStore(objectStoreName);
            }

            var objectStore = db.createObjectStore(objectStoreName, { keyPath: "id" });
            objectStore.createIndex(dbIndex,dbIndex, {unique: false});
        }.bind(this);

        request.onsuccess = function(event)
        {
            this._db = event.target.result;
            console.log("database opened successfully");
            callback(true);
        }.bind(this);
    };

    ///
    /// DEPRECATED
    ///

    /**
     * Deprecated @ v2.5. Use pendingEditsCount() instead.
     */
    this.hasPendingEdits = function()
    {
        return "DEPRECATED at v2.5!";
    };

    /**
     * Deprecated @ v2.5. Use public function editExists() instead.
     */
    this._isEditDuplicated = function(newEdit,edits){
        return "DEPRECATED at v2.5!";
    };
};

<commit_msg>removed unused code<commit_after>/*global IDBKeyRange,indexedDB */

"use strict";
O.esri.Edit.EditStore = function()
{
    this._db = null;

    // Public properties

    var dbName = "features_store";
    var objectStoreName = "features";
    var dbIndex = "featureId";

    // ENUMs

    this.ADD = "add";
    this.UPDATE = "update";
    this.DELETE = "delete";

    this.isSupported = function()
    {
        if(!window.indexedDB){
            return false;
        }
        return true;
    };

    /**
     * Commit an edit to the database
     * @param operation add, update or delete
     * @param layer the URL of the feature layer
     * @param graphic esri/graphic. The method will serialize to JSON
     * @param callback {true, edit} or {false, error}
     */
    this.pushEdit = function(operation,layer,graphic, callback)
    {

        var edit = {
                id: layer + "/" + graphic.attributes.objectid,
                operation: operation,
                layer: layer,
                graphic: graphic.toJson()
            };

        var transaction = this._db.transaction([objectStoreName],"readwrite");

        transaction.oncomplete = function(event){
            callback(true);
        };

        transaction.onerror = function(event){
            callback(false,event.target.error.message);
        };

        var objectStore = transaction.objectStore(objectStoreName);
        objectStore.put(edit);
    };

    /**
     * Returns all the edits recursively via the callback
     * @param callback {value, message}
     */
    this.getAllEdits = function(callback){

        console.assert(this._db !== null, "indexeddb not initialized");

        if(this._db !== null){
            var transaction = this._db.transaction([objectStoreName])
                .objectStore(objectStoreName)
                .openCursor();

            transaction.onsuccess = function(event)
            {
                var cursor = event.target.result;
                if(cursor){
                    callback(cursor.value,null);
                    cursor.continue();
                }
                else
                {
                    callback(null, "end");
                }
            }.bind(this);
            transaction.onerror = function(err)
            {
                callback(null, err);
            };
        }
        else
        {
            callback(null, "no db");
        }
    };

    /**
     * Update an edit already exists in the database
     * @param operation add, update or delete
     * @param layer the URL of the feature layer
     * @param graphic esri/graphic. The method will serialize to JSON
     * @param callback {true, edit} or {false, error}
     */
    this.updateExistingEdit = function(operation,layer,graphic, callback){

        console.assert(this._db !== null, "indexeddb not initialized");

        var objectStore = this._db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);

        //Let's get the entry associated with the graphic
        var objectStoreGraphicRequest = objectStore.get(graphic.attributes.objectid);
        objectStoreGraphicRequest.onsuccess = function() {

            //Grab the data object returned as a result
            var data = objectStoreGraphicRequest.result;

            //Create a new update object
            var update = {
                id: layer + "/" + graphic.attributes.objectid,
                operation: operation,
                layer: layer,
                graphic: graphic.toJson()
            };

            // Insert the update into the database
            var updateGraphicRequest = objectStore.put(update);

            updateGraphicRequest.onsuccess = function(){
                callback(true);
            }

            updateGraphicRequest.onerror = function(err){
                callback(false,err);
            };
        }
    };

    /**
     * Delete a pending edit's record from the database.
     * IMPORTANT: Be aware of false negatives. See Step 4 in this function.
     *
     * @param layerUrl
     * @param graphic Graphic
     * @param callback {boolean}
     */
    this.delete = function(layerUrl, graphic, callback){

        // NOTE: the implementation of the IndexedDB spec has a major failure with respect to
        // handling deletes. The result of the operation is specified as undefined.
        // What this means is that there is no way to tell if an operation was successful or not.
        //
        // In order to get around this we have to verify if after the attempted deletion operation
        // if the record is or is not in the database. Kinda dumb, but that's how IndexedDB works.
        //http://stackoverflow.com/questions/17137879/is-there-a-way-to-get-information-on-deleted-record-when-calling-indexeddbs-obj

        var db = this._db;
        var deferred = null;
        var self = this;

        var edit = {
            id: layerUrl + "/" + graphic.attributes.objectid,
            operation: null,
            layer: layerUrl,
            graphic: graphic.toJson()
        };

        require(["dojo/Deferred"], function(Deferred){
            deferred = new Deferred();

            // Step 1 - lets see if record exits. If it does then return callback.
            self.editExists(edit).then(function(result){
               if(result.success){
                   // Step 4 - Then we check to see if the record actually exists or not.
                   deferred.then(function(edit){

                           // IF the delete was successful, then the record should return 'false' because it doesn't exist.
                           self.editExists(edit).then(function(results){
                                   results.success == false ? callback(true) : callback(false);
                               },
                               function(){
                                   callback(true); //because we want this test to throw an error. That means item deleted.
                               })
                       },
                       // There was a problem with the delete operation on the database
                       function(err){
                           callback(err);
                       });

                   var objectStore = db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);

                   // Step 2 - go ahead and delete graphic
                   var objectStoreDeleteRequest = objectStore.delete(edit.id);

                   // Step 3 - We know that the onsuccess will always fire unless something serious goes wrong.
                   // So we go ahead and resolve the deferred here.
                   objectStoreDeleteRequest.onsuccess = function() {
                       deferred.resolve(edit);
                   };

                   objectStoreDeleteRequest.onerror = function(msg){
                       deferred.reject({success:false,error:msg});
                   }
               }
            },
            // If there is an error in editExists()
            function(){
                callback(false);
            });
        });
    };

    this.resetEditsQueue = function(callback)
    {
        console.assert(this._db !== null, "indexeddb not initialized");

        var request = this._db.transaction([objectStoreName],"readwrite")
            .objectStore(objectStoreName)
            .clear();
        request.onsuccess = function(event){
            setTimeout(function(){callback(true);},0);
        };
        request.onerror = function(err){
            callback(false,err);
        };
    };

    this.pendingEditsCount = function(callback)
    {
        console.assert(this._db !== null, "indexeddb not initialized");

        var count = 0;

        var objectStore = this._db.transaction([objectStoreName]).objectStore(objectStoreName);
        objectStore.openCursor().onsuccess = function(evt)
        {
            var cursor = evt.target.result;
            if(cursor)
            {
                count++;
                cursor.continue();
            }
            else
            {
                callback(count);
            }
        };
    };

    /**
     * Verify is an edit already exists in the database. Checks the objectId and layerId.
     * @param newEdit {id,operation,layerId,graphicJSON}
     * @returns {deferred} {success: boolean, error: message}
     * @private
     */
    this.editExists = function(newEdit){

        var db = this._db;
        var deferred = null;

        require(["dojo/Deferred"], function(Deferred){
            deferred = new Deferred();

            var objectStore = db.transaction([objectStoreName],"readwrite").objectStore(objectStoreName);

            //Get the entry associated with the graphic
            var objectStoreGraphicRequest = objectStore.get(newEdit.id);

            objectStoreGraphicRequest.onsuccess = function() {
                var graphic = objectStoreGraphicRequest.result;
                if(graphic && (graphic.id == newEdit.id)){
                    deferred.resolve({success:true,error:null});
                }
                else{
                    deferred.reject({success:false,error:"Layer id is not a match."});
                }
            };

            objectStoreGraphicRequest.onerror = function(msg){
                deferred.reject({success:false,error:msg});
            }
        });

        //We return a deferred object so that when calling this function you can chain it with a then() statement.
        return deferred;
    };

    /**
     * Returns the approximate size of the database in bytes
     * @param callback  {usage, error} Whereas, the usage Object is {sizeBytes: number, editCount: number}
     */
    this.getUsage = function(callback)
    {
        console.assert(this._db !== null, "indexeddb not initialized");

        var usage = { sizeBytes: 0, editCount: 0 };

        var transaction = this._db.transaction([objectStoreName])
            .objectStore(objectStoreName)
            .openCursor();

        console.log("dumping keys");

        transaction.onsuccess = function(event)
        {
            var cursor = event.target.result;
            if(cursor)
            {
                var storedObject = cursor.value;
                var json = JSON.stringify(storedObject);
                usage.sizeBytes += json.length;
                usage.editCount += 1;
                cursor.continue();
            }
            else
            {
                callback(usage,null);
            }
        };
        transaction.onerror = function(err)
        {
            callback(null,err);
        };
    };

    // internal methods

    //
    // graphic serialization/deserialization
    //
    this._serialize = function(graphic)
    {
        // keep only attributes and geometry, that are the values that get sent to the server by applyEdits()
        // see http://resources.arcgis.com/en/help/arcgis-rest-api/index.html#/Apply_Edits_Feature_Service_Layer/02r3000000r6000000/
        // use graphic's built-in serializing method
        var json = graphic.toJson();
        var jsonClean =
        {
            attributes: json.attributes,
            geometry: json.geometry
        };
        return JSON.stringify(jsonClean);
    };

    this._deserialize = function(json)
    {
        var graphic;

        require(["esri/graphic"],function(Graphic){
            graphic = new Graphic(JSON.parse(json));
        });

        return graphic;
    };

    this.init = function(callback)
    {
        console.log("init editsStore.js");

        var request = indexedDB.open(dbName, 11);
        callback = callback || function(success) { console.log("EditsStore::init() success:", success); }.bind(this);

        request.onerror = function(event)
        {
            console.log("indexedDB error: " + event.target.errorCode);
            callback(false,event.target.errorCode);
        }.bind(this);

        request.onupgradeneeded = function(event)
        {
            var db = event.target.result;

            if( db.objectStoreNames.contains(objectStoreName))
            {
                db.deleteObjectStore(objectStoreName);
            }

            var objectStore = db.createObjectStore(objectStoreName, { keyPath: "id" });
            objectStore.createIndex(dbIndex,dbIndex, {unique: false});
        }.bind(this);

        request.onsuccess = function(event)
        {
            this._db = event.target.result;
            console.log("database opened successfully");
            callback(true);
        }.bind(this);
    };

    ///
    /// DEPRECATED
    ///

    /**
     * Deprecated @ v2.5. Use pendingEditsCount() instead.
     */
    this.hasPendingEdits = function()
    {
        return "DEPRECATED at v2.5!";
    };

    /**
     * Deprecated @ v2.5. Use public function editExists() instead.
     */
    this._isEditDuplicated = function(newEdit,edits){
        return "DEPRECATED at v2.5!";
    };
};

<|endoftext|>


<commit_before>/**
 * af.actionsheet - an actionsheet for html5 mobile apps
 * Copyright 2012 - Intel
 */
(function($) {
    $.fn["actionsheet"] = function(opts) {
        var tmp;
        for (var i = 0; i < this.length; i++) {
            tmp = new actionsheet(this[i], opts);
        }
        return this.length == 1 ? tmp : this;
    };
    var actionsheet = (function() {
        var actionsheet = function(elID, opts) {
            if (typeof elID == "string" || elID instanceof String) {
                this.el = document.getElementById(elID);
            } else {
                this.el = elID;
            }
            if (!this.el) {
                alert("Could not find element for actionsheet " + elID);
                return;
            }

            if (this instanceof actionsheet) {
                if(typeof(opts)=="object"){
                for (var j in opts) {
                    this[j] = opts[j];
                }
                }
            } else {
                return new actionsheet(elID, opts);
            }

          //  try {
                var that = this;
                var markStart = '

';
                var markEnd = '

';
                var markup;
                if (typeof opts == "string") {
                    markup = $(markStart + opts +"Cancel"+markEnd);
                } else if (typeof opts == "object") {
                    markup = $(markStart + markEnd);
                    var container = $(markup.children().get());
                    opts.push({text:"Cancel",cssClasses:"cancel"});
                    for (var i = 0; i < opts.length; i++) {
                        var item = $('' + (opts[i].text || "TEXT NOT ENTERED") + '');
                        item[0].onclick = (opts[i].handler || function() {});
                        if (opts[i].cssClasses && opts[i].cssClasses.length > 0)
                            item.addClass(opts[i].cssClasses);
                        container.append(item);
                    }
                }
                $(elID).find("#af_actionsheet").remove();
                $(elID).find("#af_action_mask").remove();
                actionsheetEl = $(elID).append(markup);

                markup.vendorCss("Transition","all 0ms");
                markup.cssTranslate("0,0");
                markup.css("top",window.innerHeight+"px");
                this.el.style.overflow = "hidden";
                markup.on("click", "a",function(){that.hideSheet();});
                this.activeSheet=markup;
                $(elID).append('
');
                setTimeout(function(){
                    markup.vendorCss("Transition","all 300ms");
                    markup.cssTranslate("0,"+(-(markup.height()))+"px");
                 },10);

        };
        actionsheet.prototype = {
            activeSheet:null,
            hideSheet: function() {
                var that=this;
                this.activeSheet.off("click","a",function(){that.hideSheet();});
                $(this.el).find("#af_action_mask").remove();
                this.activeSheet.vendorCss("Transition","all 0ms");
                var markup = this.activeSheet;
                var theEl = this.el;
                setTimeout(function(){
                    markup.vendorCss("Transition","all 300ms");
                    markup.cssTranslate("0,0px");
                    setTimeout(function(){
                        markup.remove();
                        markup=null;
                        theEl.style.overflow = "none";
                    },500);
                },10);
            }
        };
        return actionsheet;
    })();
})(af);
<commit_msg>Fix action sheet event bubbling.<commit_after>/**
 * af.actionsheet - an actionsheet for html5 mobile apps
 * Copyright 2012 - Intel
 */
(function($) {
    $.fn["actionsheet"] = function(opts) {
        var tmp;
        for (var i = 0; i < this.length; i++) {
            tmp = new actionsheet(this[i], opts);
        }
        return this.length == 1 ? tmp : this;
    };
    var actionsheet = (function() {
        var actionsheet = function(elID, opts) {
            if (typeof elID == "string" || elID instanceof String) {
                this.el = document.getElementById(elID);
            } else {
                this.el = elID;
            }
            if (!this.el) {
                alert("Could not find element for actionsheet " + elID);
                return;
            }

            if (this instanceof actionsheet) {
                if (typeof(opts) == "object") {
                    for (var j in opts) {
                        this[j] = opts[j];
                    }
                }
            } else {
                return new actionsheet(elID, opts);
            }

            //  try {
            var that = this;
            var markStart = '

';
            var markEnd = '

';
            var markup;
            if (typeof opts == "string") {
                markup = $(markStart + opts + "Cancel" + markEnd);
            } else if (typeof opts == "object") {
                markup = $(markStart + markEnd);
                var container = $(markup.children().get());
                opts.push({
                    text: "Cancel",
                    cssClasses: "cancel"
                });
                for (var i = 0; i < opts.length; i++) {
                    var item = $('' + (opts[i].text || "TEXT NOT ENTERED") + '');
                    item[0].onclick = (opts[i].handler || function() {});
                    if (opts[i].cssClasses && opts[i].cssClasses.length > 0)
                        item.addClass(opts[i].cssClasses);
                    container.append(item);
                }
            }
            $(elID).find("#af_actionsheet").remove();
            $(elID).find("#af_action_mask").remove();
            actionsheetEl = $(elID).append(markup);

            markup.vendorCss("Transition", "all 0ms");
            markup.cssTranslate("0,0");
            markup.css("top", window.innerHeight + "px");
            this.el.style.overflow = "hidden";
            markup.on("click", "a", function() {
                that.hideSheet();
                return false;
            });
            this.activeSheet = markup;
            $(elID).append('
');
            setTimeout(function() {
                markup.vendorCss("Transition", "all 300ms");
                markup.cssTranslate("0," + (-(markup.height())) + "px");
            }, 10);

        };
        actionsheet.prototype = {
            activeSheet: null,
            hideSheet: function() {
                var that = this;
                this.activeSheet.off("click", "a", function() {
                    that.hideSheet();
                });
                $(this.el).find("#af_action_mask").remove();
                this.activeSheet.vendorCss("Transition", "all 0ms");
                var markup = this.activeSheet;
                var theEl = this.el;
                setTimeout(function() {
                    markup.vendorCss("Transition", "all 300ms");
                    markup.cssTranslate("0,0px");
                    setTimeout(function() {
                        markup.remove();
                        markup = null;
                        theEl.style.overflow = "none";
                    }, 500);
                }, 10);
            }
        };
        return actionsheet;
    })();
})(af);<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// 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.

'use strict';

var inherits = require('util').inherits;

var TChannelPeer = require('./peer');
var TChannelSelfConnection = require('./self_connection');

function TChannelSelfPeer(channel) {
    if (!(this instanceof TChannelSelfPeer)) {
        return new TChannelSelfPeer(channel);
    }
    var self = this;
    TChannelPeer.call(self, channel, channel.hostPort);
}
inherits(TChannelSelfPeer, TChannelPeer);

TChannelSelfPeer.prototype.connect = function connect() {
    var self = this;
    while (self.connections[0] &&
           self.connections[0].closing) {
        self.connections[0].shift();
    }
    var conn = self.connections[0];
    if (!conn) {
        conn = TChannelSelfConnection(self.channel);
        self.addConnection(conn);
    }
    return conn;
};

TChannelSelfPeer.prototype.makeOutSocket = function makeOutSocket() {
    throw new Error('refusing to make self out socket');
};

TChannelSelfPeer.prototype.makeOutConnection = function makeOutConnection(/* socket */) {
    throw new Error('refusing to make self out connection');
};

module.exports = TChannelSelfPeer;
<commit_msg>TChannelSelfPeer: fix bug<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// 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.

'use strict';

var inherits = require('util').inherits;

var TChannelPeer = require('./peer');
var TChannelSelfConnection = require('./self_connection');

function TChannelSelfPeer(channel) {
    if (!(this instanceof TChannelSelfPeer)) {
        return new TChannelSelfPeer(channel);
    }
    var self = this;
    TChannelPeer.call(self, channel, channel.hostPort);
}
inherits(TChannelSelfPeer, TChannelPeer);

TChannelSelfPeer.prototype.connect = function connect() {
    var self = this;
    while (self.connections[0] &&
           self.connections[0].closing) {
        self.connections.shift();
    }
    var conn = self.connections[0];
    if (!conn) {
        conn = TChannelSelfConnection(self.channel);
        self.addConnection(conn);
    }
    return conn;
};

TChannelSelfPeer.prototype.makeOutSocket = function makeOutSocket() {
    throw new Error('refusing to make self out socket');
};

TChannelSelfPeer.prototype.makeOutConnection = function makeOutConnection(/* socket */) {
    throw new Error('refusing to make self out connection');
};

module.exports = TChannelSelfPeer;
<|endoftext|>


<commit_before>var bundle = require('../'),
	Bundle = require('../Bundle.js').Bundle,
	bundleChecker = require('../BundleCheck.js').BundleCheck,
	should = require('should'),
	gutil = require('gulp-util'),
	PluginError = gutil.PluginError,
	config = require('../package.json'),
	fixtures = require('./fixtures').fixtures,
	gulpTaskFactory = require('../GulpTaskFactory').gulpTaskFactory,
	cp = require('child_process'),
	junk = require('junk'),
	BundleTest = function() {
		var self = this,
			Bundle = require('../Bundle').Bundle,
			gutil = require('gulp-util'),
			PluginError = gutil.PluginError;
		self.isValid = true;

		self.bundle = new Bundle(0, [0, 'blahblahblah.js']);

		if (self.bundle.getName() === undefined) {
			self.isValid = false;
			throw new PluginError(config.name, 'Bundle test has failed, missing name');
		}

		if(self.bundle.isLast() === undefined) {
			self.isValid = false;
			throw new PluginError(config.name, 'Bundle test has failed missing isLast');
		}
	},
	bundleTest = new BundleTest(),
	fs = require('fs'),
	config2 = require('../sample-options'),
	path = require('path');
	require('mocha');
	bundle(config2);

describe('gulp-bundle-files', function() {

	//noinspection JSUnresolvedFunction
	var fixture = new fixtures();

	describe('bundle()', function() {
		it('should throw, No uglify settings', function() {
			(function() {
				gulpTaskFactory('uglify', fixture.get('bad-uglify'));
			}).should.throw(
				new PluginError(config.name, 'No uglify settings')
			);
		});

		it('should pass, upon creation bundleTest will return true if all is well', function() {
			bundleTest.isValid.should.equal(true);
		});

		it('should pass, upon creation a bundle should have getName as a function', function() {
			var getNameType = typeof bundleTest.bundle.getName;
			getNameType.should.equal('function');
		});

		it('should pass, upon creation a bundle should have getName as a function', function() {
			var isLastType = typeof bundleTest.bundle.isLast;
			isLastType.should.equal('function');
		});

		it('should pass, getName should return ', function() {
			bundleTest.bundle.getName().should.equal(0);
		});

		it('should pass, isLast should return true', function() {
			bundleTest.bundle.isLast().should.equal(true);
		});

		it('should throw, fixture with bad file', function() {
			(function() {
				fixture.get('bag-uglify');
			}).should.throw(
				new TypeError('Path must be a string. Received undefined')
			);
		});

		it('should throw, bundle checker doesn\'t work', function() {
			(function() {
				var bundles = fixture.get('bundles');
				bundleChecker(Object.keys(bundles.files), bundles.files, true);
			}).should.throw(
				new PluginError(config.name, 'Bundle check is not working')
			);
		});

		it('should throw, No concat settings', function() {
			(function() {
				gulpTaskFactory('concat', fixture.get('bad-concat'));
			}).should.throw(
				new PluginError(config.name, 'No concat settings')
			);
		});

		it('should throw, when destination folder is missing', function() {
			(function() {
				bundle(fixture.get('no-options'));
			}).should.throw(
				new PluginError(config.name, 'Missing destinationFolder gulp-bundle-files')
			);
		});

		it('should throw, bundle does not have any items', function() {
			(function() {
				Bundle(0, fixture.get('no-items'));
			}).should.throw(
				new PluginError(config.name, 'No items passed into bundle')
			);
		});

		it('should throw, when files is not array or object', function() {
			(function() {
				bundle(fixture.get('incorrect-format-of-files'));
			}).should.throw(
				new PluginError(config.name, 'File input in wrong format, please use an array or object.')
			);
		});

		it('should throw, when options.files has no bundles', function() {
			(function() {
				bundle(fixture.get('no-bundles'));
			}).should.throw(
				new PluginError(config.name, 'No file input stored in options.files.')
			);
		});

		it('should throw, when bundle is missing files', function() {
			(function() {
				bundle(fixture.get('full-options'), true);
			}).should.throw(
				new PluginError(config.name, 'Error creating bundle, bundles are missing files.')
			);
		});

		it('should throw, when unable to create bundle, missing bundle name', function() {
			(function() {
				bundle(fixture.get('no-bundle-name'));
			}).should.throw(
				new PluginError(config.name, 'Error creating bundle: no bundle name')
			);
		});

		it('should throw, when unable to find items for a bundle', function() {
			(function() {
				bundle(fixture.get('no-bundle-contents'));
			}).should.throw(
				new PluginError(config.name, 'No files inside named bundle')
			);
		});

		it('should pass, gulp should run with sample config and result in 2 built JS files', function(done) {
			this.timeout(15000);
			cp.exec('gulp', function(error, stdout, stderror) {
				if(error == null) {
					fs.readdir(path.join(__dirname, '/../dist/js'), function(err, files) {
						if(err) {
							throw err;
						}
						files = files.filter(junk.not);

						if(files.length == 3) {
							files.forEach(function(element, index) {
								if(!fs.existsSync(path.join('../dist/', element))) {
									return false;
								}
							});
						}
					});
				}
				done();
			});
		});

		it('should pass, gulp should run with sample config and result in 1 built CSS files', function(done) {
			this.timeout(15000);
			cp.exec('gulp', function(error, stdout, stderror) {
				if(error == null) {
					fs.readdir(path.join(__dirname, '/../dist/css'), function(err, files) {
						if(err) {
							throw err;
						}
						files = files.filter(junk.not);

						if(files.length == 2) {
							files.forEach(function(element, index) {
								if(!fs.existsSync(path.join('../dist/', element))) {
									return false;
								}
							});
						}
					});
				}
				done();
			});
		});
	});
});
<commit_msg>Updating tests that call gulp to just bundle, so we don't run tests in a loop.<commit_after>var bundle = require('../'),
	Bundle = require('../Bundle.js').Bundle,
	bundleChecker = require('../BundleCheck.js').BundleCheck,
	should = require('should'),
	gutil = require('gulp-util'),
	PluginError = gutil.PluginError,
	config = require('../package.json'),
	fixtures = require('./fixtures').fixtures,
	gulpTaskFactory = require('../GulpTaskFactory').gulpTaskFactory,
	cp = require('child_process'),
	junk = require('junk'),
	BundleTest = function() {
		var self = this,
			Bundle = require('../Bundle').Bundle,
			gutil = require('gulp-util'),
			PluginError = gutil.PluginError;
		self.isValid = true;

		self.bundle = new Bundle(0, [0, 'blahblahblah.js']);

		if (self.bundle.getName() === undefined) {
			self.isValid = false;
			throw new PluginError(config.name, 'Bundle test has failed, missing name');
		}

		if(self.bundle.isLast() === undefined) {
			self.isValid = false;
			throw new PluginError(config.name, 'Bundle test has failed missing isLast');
		}
	},
	bundleTest = new BundleTest(),
	fs = require('fs'),
	config2 = require('../sample-options'),
	path = require('path');
	require('mocha');
	bundle(config2);

describe('gulp-bundle-files', function() {

	//noinspection JSUnresolvedFunction
	var fixture = new fixtures();

	describe('bundle()', function() {
		it('should throw, No uglify settings', function() {
			(function() {
				gulpTaskFactory('uglify', fixture.get('bad-uglify'));
			}).should.throw(
				new PluginError(config.name, 'No uglify settings')
			);
		});

		it('should pass, upon creation bundleTest will return true if all is well', function() {
			bundleTest.isValid.should.equal(true);
		});

		it('should pass, upon creation a bundle should have getName as a function', function() {
			var getNameType = typeof bundleTest.bundle.getName;
			getNameType.should.equal('function');
		});

		it('should pass, upon creation a bundle should have getName as a function', function() {
			var isLastType = typeof bundleTest.bundle.isLast;
			isLastType.should.equal('function');
		});

		it('should pass, getName should return ', function() {
			bundleTest.bundle.getName().should.equal(0);
		});

		it('should pass, isLast should return true', function() {
			bundleTest.bundle.isLast().should.equal(true);
		});

		it('should throw, fixture with bad file', function() {
			(function() {
				fixture.get('bag-uglify');
			}).should.throw(
				new TypeError('Path must be a string. Received undefined')
			);
		});

		it('should throw, bundle checker doesn\'t work', function() {
			(function() {
				var bundles = fixture.get('bundles');
				bundleChecker(Object.keys(bundles.files), bundles.files, true);
			}).should.throw(
				new PluginError(config.name, 'Bundle check is not working')
			);
		});

		it('should throw, No concat settings', function() {
			(function() {
				gulpTaskFactory('concat', fixture.get('bad-concat'));
			}).should.throw(
				new PluginError(config.name, 'No concat settings')
			);
		});

		it('should throw, when destination folder is missing', function() {
			(function() {
				bundle(fixture.get('no-options'));
			}).should.throw(
				new PluginError(config.name, 'Missing destinationFolder gulp-bundle-files')
			);
		});

		it('should throw, bundle does not have any items', function() {
			(function() {
				Bundle(0, fixture.get('no-items'));
			}).should.throw(
				new PluginError(config.name, 'No items passed into bundle')
			);
		});

		it('should throw, when files is not array or object', function() {
			(function() {
				bundle(fixture.get('incorrect-format-of-files'));
			}).should.throw(
				new PluginError(config.name, 'File input in wrong format, please use an array or object.')
			);
		});

		it('should throw, when options.files has no bundles', function() {
			(function() {
				bundle(fixture.get('no-bundles'));
			}).should.throw(
				new PluginError(config.name, 'No file input stored in options.files.')
			);
		});

		it('should throw, when bundle is missing files', function() {
			(function() {
				bundle(fixture.get('full-options'), true);
			}).should.throw(
				new PluginError(config.name, 'Error creating bundle, bundles are missing files.')
			);
		});

		it('should throw, when unable to create bundle, missing bundle name', function() {
			(function() {
				bundle(fixture.get('no-bundle-name'));
			}).should.throw(
				new PluginError(config.name, 'Error creating bundle: no bundle name')
			);
		});

		it('should throw, when unable to find items for a bundle', function() {
			(function() {
				bundle(fixture.get('no-bundle-contents'));
			}).should.throw(
				new PluginError(config.name, 'No files inside named bundle')
			);
		});

		it('should pass, gulp should run with sample config and result in 2 built JS files', function(done) {
			this.timeout(15000);
			cp.exec('gulp bundle', function(error, stdout, stderror) {
				if(error == null) {
					fs.readdir(path.join(__dirname, '/../dist/js'), function(err, files) {
						if(err) {
							throw err;
						}
						files = files.filter(junk.not);

						if(files.length == 3) {
							files.forEach(function(element, index) {
								if(!fs.existsSync(path.join('../dist/', element))) {
									return false;
								}
							});
						}
					});
				}
				done();
			});
		});

		it('should pass, gulp should run with sample config and result in 1 built CSS files', function(done) {
			this.timeout(15000);
			cp.exec('gulp bundle', function(error, stdout, stderror) {
				if(error == null) {
					fs.readdir(path.join(__dirname, '/../dist/css'), function(err, files) {
						if(err) {
							throw err;
						}
						files = files.filter(junk.not);

						if(files.length == 2) {
							files.forEach(function(element, index) {
								if(!fs.existsSync(path.join('../dist/', element))) {
									return false;
								}
							});
						}
					});
				}
				done();
			});
		});
	});
});
<|endoftext|>


<commit_before>/*global pushDomEvents */
var isiOS = navigator.userAgent.match(/(iPhone|iPod|iPad)/i),
    isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1 ? 1 : 0,
    minimumScrollYOffset = isAndroid ? 1 : 0;

Thorax.Util.scrollTo = function(x, y) {
  y = y || minimumScrollYOffset;
  function _scrollTo() {
    window.scrollTo(x, y);
  }
  if (isiOS) {
    // a defer is required for ios
    _.defer(_scrollTo);
  } else {
    _scrollTo();
  }
  return [x, y];
};

Thorax.LayoutView.on('change:view:end', function(newView, oldView, options) {
  options.scroll && Thorax.Util.scrollTo(0, 0);
});

Thorax.Util.scrollToTop = function() {
  // android will use height of 1 because of minimumScrollYOffset in scrollTo()
  return this.scrollTo(0, 0);
};

pushDomEvents([
  'singleTap', 'doubleTap', 'longTap',
  'swipe',
  'swipeUp', 'swipeDown',
  'swipeLeft', 'swipeRight'
]);

//built in dom events
Thorax.View.on({
  'submit form': function(/* event */) {
    // Hide any virtual keyboards that may be lingering around
    var focused = $(':focus')[0];
    focused && focused.blur();
  }
});
<commit_msg>Protect from missing options<commit_after>/*global pushDomEvents */
var isiOS = navigator.userAgent.match(/(iPhone|iPod|iPad)/i),
    isAndroid = navigator.userAgent.toLowerCase().indexOf("android") > -1 ? 1 : 0,
    minimumScrollYOffset = isAndroid ? 1 : 0;

Thorax.Util.scrollTo = function(x, y) {
  y = y || minimumScrollYOffset;
  function _scrollTo() {
    window.scrollTo(x, y);
  }
  if (isiOS) {
    // a defer is required for ios
    _.defer(_scrollTo);
  } else {
    _scrollTo();
  }
  return [x, y];
};

Thorax.LayoutView.on('change:view:end', function(newView, oldView, options) {
  options && options.scroll && Thorax.Util.scrollTo(0, 0);
});

Thorax.Util.scrollToTop = function() {
  // android will use height of 1 because of minimumScrollYOffset in scrollTo()
  return this.scrollTo(0, 0);
};

pushDomEvents([
  'singleTap', 'doubleTap', 'longTap',
  'swipe',
  'swipeUp', 'swipeDown',
  'swipeLeft', 'swipeRight'
]);

//built in dom events
Thorax.View.on({
  'submit form': function(/* event */) {
    // Hide any virtual keyboards that may be lingering around
    var focused = $(':focus')[0];
    focused && focused.blur();
  }
});
<|endoftext|>


<commit_before>module.exports = function($window, $q) {

    var Service = {};

    var navigator = $window.navigator;

    Service.getUserMediaEnabled = (
        navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia ||
        navigator.mediaDevices && navigator.mediaDevices.getUserMedia
    );

    var promisifiedOldGetUserMedia = function(constraints, successCallback, errorCallback) {

        // First get ahold of getUserMedia, if present
        var getUserMedia = (navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia);

        // Some browsers just don't implement it - return a rejected promise with an error
        // to keep a consistent interface
        if(!getUserMedia) {
            return $q.defer().reject(new Error('getUserMedia is not implemented in this browser'));
        }

        // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
        return $q(function(successCallback, errorCallback) {
            getUserMedia.call(navigator, constraints, successCallback, errorCallback);
        });

    };

    // Older browsers might not implement mediaDevices at all, so we set an empty object first
    if(navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {};
    }

    // Some browsers partially implement mediaDevices. We can't just assign an object
    // with getUserMedia as it would overwrite existing properties.
    // Here, we will just add the getUserMedia property if it's missing.
    if(navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = promisifiedOldGetUserMedia;
    }

    $window.navigator.mediaDevices.getUserMedia = navigator.mediaDevices.getUserMedia;

    Service.getNavigator = function() {
        return $window.navigator;
    };

    return Service;
};<commit_msg>properly use mediaDevices api<commit_after>module.exports = function($window, $q) {

    // https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia

    var Service = {};

    var navigator = $window.navigator;

    Service.getUserMediaEnabled = (
        navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia ||
        navigator.mediaDevices && navigator.mediaDevices.getUserMedia
    );

    var promisifiedOldGetUserMedia = function(constraints, successCallback, errorCallback) {

        // First get ahold of getUserMedia, if present
        var getUserMedia = (navigator.getUserMedia ||
        navigator.webkitGetUserMedia ||
        navigator.mozGetUserMedia);

        // Some browsers just don't implement it - return a rejected promise with an error
        // to keep a consistent interface
        if(!getUserMedia) {
            return $q.defer().reject(new Error('getUserMedia is not implemented in this browser'));
        }

        // Otherwise, wrap the call to the old navigator.getUserMedia with a Promise
        return $q(function(successCallback, errorCallback) {
            getUserMedia.call(navigator, constraints, successCallback, errorCallback);
        });

    };

    // Older browsers might not implement mediaDevices at all, so we set an empty object first
    if(navigator.mediaDevices === undefined) {
        navigator.mediaDevices = {};
    }

    // Some browsers partially implement mediaDevices. We can't just assign an object
    // with getUserMedia as it would overwrite existing properties.
    // Here, we will just add the getUserMedia property if it's missing.
    if(navigator.mediaDevices.getUserMedia === undefined) {
        navigator.mediaDevices.getUserMedia = promisifiedOldGetUserMedia;
    }

    $window.navigator.mediaDevices.getUserMedia = navigator.mediaDevices.getUserMedia;

    Service.getNavigator = function() {
        return $window.navigator;
    };

    return Service;
};<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { uniqueId } from 'lodash';
import SprkAccordionItem from './components/SprkAccordionItem/SprkAccordionItem';

class SprkAccordion extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: props.children.map(item => ({ id: uniqueId('accordion-item-'), ...item })),
    };
  }

  render() {
    const {
      idString,
      additionalClasses,
      ...other
    } = this.props;
    const { items } = this.state;
    return (
      <ul
        className={classnames('sprk-c-Accordion sprk-o-VerticalList', additionalClasses)}
        data-id={idString}
        {...other}
      >
        {items.map(item => (
          <SprkAccordionItem
            {...item.props}
            key={item.id}
            id={item.id}
          />
        ))}
      </ul>
    );
  }
}

SprkAccordion.defaultProps = {
  idString: '',
  additionalClasses: '',
};

SprkAccordion.propTypes = {
  // Value added to accordion container as additional classes
  additionalClasses: PropTypes.string,
  // Expects SprkAccordionItem as children
  children: PropTypes.node.isRequired,
  // An optional id for automated testing
  idString: PropTypes.string,
};

export default SprkAccordion;
<commit_msg>add check for non-sprkaccordionitem element<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import { uniqueId } from 'lodash';
import SprkAccordionItem from './components/SprkAccordionItem/SprkAccordionItem';

class SprkAccordion extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: props.children.map(item => ({ id: uniqueId('accordion-item-'), ...item })),
    };
  }

  render() {
    const {
      idString,
      additionalClasses,
      ...other
    } = this.props;
    const { items } = this.state;
    return (
      <ul
        className={classnames('sprk-c-Accordion sprk-o-VerticalList', additionalClasses)}
        data-id={idString}
        {...other}
      >
        {items.map((item) => {
          if (item.type.name !== SprkAccordionItem.name) return null;
          return (
            <SprkAccordionItem
              {...item.props}
              key={item.id}
              id={item.id}
            />
          );
        })}
      </ul>
    );
  }
}

SprkAccordion.defaultProps = {
  idString: '',
  additionalClasses: '',
};

SprkAccordion.propTypes = {
  // Value added to accordion container as additional classes
  additionalClasses: PropTypes.string,
  // Expects SprkAccordionItem as children
  children: PropTypes.node.isRequired,
  // An optional id for automated testing
  idString: PropTypes.string,
};

export default SprkAccordion;
<|endoftext|>


<commit_before>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import {
  find,
  findAll,
  scrollTo
} from 'ember-native-dom-helpers';

import getNumbers from 'dummy/lib/get-numbers';

import waitForRender from 'dummy/tests/helpers/wait-for-render';
import {
  testScenarios,

  dynamicSimpleScenarioFor,
  staticSimpleScenarioFor,
  simpleScenariosFor,
  scenariosFor,
  standardTemplate
} from 'dummy/tests/helpers/test-scenarios';

moduleForComponent('vertical-collection', 'Integration | Basic Tests', {
  integration: true
});

testScenarios(
  'The collection Renders',
  scenariosFor(getNumbers(0, 1)),
  standardTemplate,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('.vertical-item').length, 1);
  }
);

testScenarios(
  'The collection Renders when content is empty',
  scenariosFor([]),
  standardTemplate,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('.vertical-item').length, 0);
  }
);

testScenarios(
  'The collection renders with a key path set',
  scenariosFor([{ id: 1 }, { id: 2 }, { id: 3 }], { key: 'id' }),
  standardTemplate,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('.vertical-item').length, 3);
  }
);

testScenarios(
  'The collection renders correct number of components with bufferSize set',
  scenariosFor(getNumbers(0, 10), { estimateHeight: 200, bufferSize: 1 }),
  standardTemplate,

  async function(assert) {
    assert.expect(3);

    // Should render 2 components to be able to cover the whole scroll space, and 1
    // extra buffer component on the bottom
    assert.equal(findAll('.vertical-item').length, 2);

    await scrollTo('.scrollable', 0, 200);

    // Should render a buffer on both sides
    assert.equal(findAll('.vertical-item').length, 3);

    await scrollTo('.scrollable', 0, 2000);

    // Back to 3 items because at the bottom
    assert.equal(findAll('.vertical-item').length, 2);
  }
);

testScenarios(
  'The collection renders with containerSelector set',
  simpleScenariosFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          staticHeight=true
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 20px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('vertical-item').length, 5);
  }
);

testScenarios(
  'The collection renders in the correct initial position when offset',
  staticSimpleScenarioFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          staticHeight=true
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 20px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  async function(assert) {
    assert.expect(3);

    let occludedBoundaries = findAll('occluded-content');

    assert.equal(occludedBoundaries[0].getAttribute('style'), 'height: 0px;', 'Occluded height above is correct');
    assert.equal(occludedBoundaries[1].getAttribute('style'), 'height: 100px;', 'Occluded height below is correct');
    assert.equal(findAll('vertical-item').length, 5, 'Rendered correct number of items');
  }
);

testScenarios(
  'The collection renders in the correct initial position with dynamic heights',
  dynamicSimpleScenarioFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 28px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  async function(assert) {
    assert.expect(3);

    let occludedBoundaries = findAll('occluded-content');

    assert.equal(occludedBoundaries[0].getAttribute('style'), 'height: 0px;', 'Occluded height above is correct');
    assert.equal(occludedBoundaries[1].getAttribute('style'), 'height: 100px;', 'Occluded height below is correct');
    assert.equal(findAll('vertical-item').length, 5, 'Rendered correct number of items');
  }
);

testScenarios(
  'The collection renders when yielded item has conditional',
  simpleScenariosFor([{ shouldRender: true }]),

  hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=10
        containerSelector="body"
        as |item|
      }}

          Content
          {{#if item.shouldRender}}

              Conditional Content

          {{/if}}

      {{/vertical-collection}}

  `,

  async function(assert) {
    assert.ok(true, 'No errors were thrown in the process');
  }
);

test('The collection renders the initialRenderCount correctly', async function(assert) {
  assert.expect(5);
  this.set('items', getNumbers(0, 10));

  this.render(hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=50
        initialRenderCount=1
        as |item i|
      }}
        <vertical-item style="height: 50px">
          {{item.number}} {{i}}
        </vertical-item>
      {{/vertical-collection}}

  `);

  requestAnimationFrame(() => {
    assert.equal(findAll('vertical-item').length, 1, 'correct number of items rendered on initial pass');
    assert.equal(find('vertical-item').textContent.trim(), '0 0', 'correct item rendered');
  });

  await waitForRender();

  assert.equal(findAll('vertical-item').length, 10, 'correctly updates the number of items rendered on second pass');
  assert.equal(find('vertical-item:first-of-type').textContent.trim(), '0 0', 'correct first item rendered');
  assert.equal(find('vertical-item:last-of-type').textContent.trim(), '9 9', 'correct last item rendered');
});

test('The collection renders the initialRenderCount correctly if idForFirstItem is set', async function(assert) {
  assert.expect(5);
  this.set('items', getNumbers(0, 100));

  this.render(hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=50
        initialRenderCount=1
        idForFirstItem="20"
        key="number"
        as |item i|
      }}
        <vertical-item style="height: 50px">
          {{item.number}} {{i}}
        </vertical-item>
      {{/vertical-collection}}

  `);

  requestAnimationFrame(() => {
    assert.equal(findAll('vertical-item').length, 1, 'correct number of items rendered on initial pass');
    assert.equal(find('vertical-item').textContent.trim(), '20 20', 'correct item rendered');
  });

  await waitForRender();

  assert.equal(findAll('vertical-item').length, 12, 'correctly updates the number of items rendered on second pass');
  assert.equal(find('vertical-item:first-of-type').textContent.trim(), '19 19', 'correct first item rendered');
  assert.equal(find('vertical-item:last-of-type').textContent.trim(), '30 30', 'correct last item rendered');
});

test('The collection renders the initialRenderCount correctly if the count is more than the number of items', async function(assert) {
  assert.expect(4);
  this.set('items', getNumbers(0, 1));

  this.render(hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=50
        initialRenderCount=5
        as |item i|
      }}
        <vertical-item style="height: 50px">
          {{item.number}} {{i}}
        </vertical-item>
      {{/vertical-collection}}

  `);

  requestAnimationFrame(() => {
    assert.equal(findAll('vertical-item').length, 1, 'correct number of items rendered on initial pass');
    assert.equal(find('vertical-item').textContent.trim(), '0 0', 'correct item rendered');
  });

  await waitForRender();

  assert.equal(findAll('vertical-item').length, 1, 'correctly updates the number of items rendered on second pass');
  assert.equal(find('vertical-item').textContent.trim(), '0 0', 'correct first item rendered');
});

testScenarios(
  'The collection renders based on max height of the scroll parent',
  simpleScenariosFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          staticHeight=staticHeight
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 20px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  function(assert) {
    assert.equal(findAll('vertical-item').length, 10);
  }
);
<commit_msg>test(offscreen): Adds test for starting offscreen (#113)<commit_after>import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import {
  find,
  findAll,
  scrollTo
} from 'ember-native-dom-helpers';

import getNumbers from 'dummy/lib/get-numbers';

import waitForRender from 'dummy/tests/helpers/wait-for-render';
import {
  testScenarios,

  dynamicSimpleScenarioFor,
  staticSimpleScenarioFor,
  simpleScenariosFor,
  scenariosFor,
  standardTemplate
} from 'dummy/tests/helpers/test-scenarios';

moduleForComponent('vertical-collection', 'Integration | Basic Tests', {
  integration: true
});

testScenarios(
  'The collection Renders',
  scenariosFor(getNumbers(0, 1)),
  standardTemplate,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('.vertical-item').length, 1);
  }
);

testScenarios(
  'The collection Renders when content is empty',
  scenariosFor([]),
  standardTemplate,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('.vertical-item').length, 0);
  }
);

testScenarios(
  'The collection renders with a key path set',
  scenariosFor([{ id: 1 }, { id: 2 }, { id: 3 }], { key: 'id' }),
  standardTemplate,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('.vertical-item').length, 3);
  }
);

testScenarios(
  'The collection renders correct number of components with bufferSize set',
  scenariosFor(getNumbers(0, 10), { estimateHeight: 200, bufferSize: 1 }),
  standardTemplate,

  async function(assert) {
    assert.expect(3);

    // Should render 2 components to be able to cover the whole scroll space, and 1
    // extra buffer component on the bottom
    assert.equal(findAll('.vertical-item').length, 2);

    await scrollTo('.scrollable', 0, 200);

    // Should render a buffer on both sides
    assert.equal(findAll('.vertical-item').length, 3);

    await scrollTo('.scrollable', 0, 2000);

    // Back to 3 items because at the bottom
    assert.equal(findAll('.vertical-item').length, 2);
  }
);

testScenarios(
  'The collection renders with containerSelector set',
  simpleScenariosFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          staticHeight=true
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 20px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  async function(assert) {
    assert.expect(1);
    assert.equal(findAll('vertical-item').length, 5);
  }
);

testScenarios(
  'The collection renders in the correct initial position when offset',
  staticSimpleScenarioFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          staticHeight=true
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 20px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  async function(assert) {
    assert.expect(3);

    let occludedBoundaries = findAll('occluded-content');

    assert.equal(occludedBoundaries[0].getAttribute('style'), 'height: 0px;', 'Occluded height above is correct');
    assert.equal(occludedBoundaries[1].getAttribute('style'), 'height: 100px;', 'Occluded height below is correct');
    assert.equal(findAll('vertical-item').length, 5, 'Rendered correct number of items');
  }
);

testScenarios(
  'The collection renders in the correct initial position with dynamic heights',
  dynamicSimpleScenarioFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 28px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  async function(assert) {
    assert.expect(3);

    let occludedBoundaries = findAll('occluded-content');

    assert.equal(occludedBoundaries[0].getAttribute('style'), 'height: 0px;', 'Occluded height above is correct');
    assert.equal(occludedBoundaries[1].getAttribute('style'), 'height: 100px;', 'Occluded height below is correct');
    assert.equal(findAll('vertical-item').length, 5, 'Rendered correct number of items');
  }
);

testScenarios(
  'The collection renders when yielded item has conditional',
  simpleScenariosFor([{ shouldRender: true }]),

  hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=10
        containerSelector="body"
        as |item|
      }}

          Content
          {{#if item.shouldRender}}

              Conditional Content

          {{/if}}

      {{/vertical-collection}}

  `,

  async function(assert) {
    assert.ok(true, 'No errors were thrown in the process');
  }
);

test('The collection renders the initialRenderCount correctly', async function(assert) {
  assert.expect(5);
  this.set('items', getNumbers(0, 10));

  this.render(hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=50
        initialRenderCount=1
        as |item i|
      }}
        <vertical-item style="height: 50px">
          {{item.number}} {{i}}
        </vertical-item>
      {{/vertical-collection}}

  `);

  requestAnimationFrame(() => {
    assert.equal(findAll('vertical-item').length, 1, 'correct number of items rendered on initial pass');
    assert.equal(find('vertical-item').textContent.trim(), '0 0', 'correct item rendered');
  });

  await waitForRender();

  assert.equal(findAll('vertical-item').length, 10, 'correctly updates the number of items rendered on second pass');
  assert.equal(find('vertical-item:first-of-type').textContent.trim(), '0 0', 'correct first item rendered');
  assert.equal(find('vertical-item:last-of-type').textContent.trim(), '9 9', 'correct last item rendered');
});

test('The collection renders the initialRenderCount correctly if idForFirstItem is set', async function(assert) {
  assert.expect(5);
  this.set('items', getNumbers(0, 100));

  this.render(hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=50
        initialRenderCount=1
        idForFirstItem="20"
        key="number"
        as |item i|
      }}
        <vertical-item style="height: 50px">
          {{item.number}} {{i}}
        </vertical-item>
      {{/vertical-collection}}

  `);

  requestAnimationFrame(() => {
    assert.equal(findAll('vertical-item').length, 1, 'correct number of items rendered on initial pass');
    assert.equal(find('vertical-item').textContent.trim(), '20 20', 'correct item rendered');
  });

  await waitForRender();

  assert.equal(findAll('vertical-item').length, 12, 'correctly updates the number of items rendered on second pass');
  assert.equal(find('vertical-item:first-of-type').textContent.trim(), '19 19', 'correct first item rendered');
  assert.equal(find('vertical-item:last-of-type').textContent.trim(), '30 30', 'correct last item rendered');
});

test('The collection renders the initialRenderCount correctly if the count is more than the number of items', async function(assert) {
  assert.expect(4);
  this.set('items', getNumbers(0, 1));

  this.render(hbs`

      {{#vertical-collection ${'items'}
        estimateHeight=50
        initialRenderCount=5
        as |item i|
      }}
        <vertical-item style="height: 50px">
          {{item.number}} {{i}}
        </vertical-item>
      {{/vertical-collection}}

  `);

  requestAnimationFrame(() => {
    assert.equal(findAll('vertical-item').length, 1, 'correct number of items rendered on initial pass');
    assert.equal(find('vertical-item').textContent.trim(), '0 0', 'correct item rendered');
  });

  await waitForRender();

  assert.equal(findAll('vertical-item').length, 1, 'correctly updates the number of items rendered on second pass');
  assert.equal(find('vertical-item').textContent.trim(), '0 0', 'correct first item rendered');
});

testScenarios(
  'The collection renders based on max height of the scroll parent',
  simpleScenariosFor(getNumbers(0, 10)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          staticHeight=staticHeight
          bufferSize=0

          as |item i|}}
          <vertical-item style="height: 20px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  function(assert) {
    assert.equal(findAll('vertical-item').length, 10);
  }
);

testScenarios(
  'The collection renders in the correctly when starting offscreen',
  scenariosFor(getNumbers(0, 100)),

  hbs`

        {{#vertical-collection ${'items'}
          containerSelector=".scrollable"
          estimateHeight=20
          bufferSize=2

          as |item i|}}
          <vertical-item style="height: 20px">
            {{item.number}} {{i}}
          </vertical-item>
        {{/vertical-collection}}

  `,

  async function(assert) {
    assert.expect(2);

    assert.equal(findAll('vertical-item').length, 7, 'Rendered correct number of items');

    await scrollTo('.scrollable', 0, 500);

    assert.equal(findAll('vertical-item').length, 9, 'Rendered correct number of items');
  }
);
<|endoftext|>


<commit_before>/*******************
 * This is the pubsub driver that should tell caspa about the melted status
 *
 *******************/

_ = require('underscore');
mbc = require('mbc-common');

defaults = { // copied from caspa/models.App.Status
    _id: 1,
    piece: {
        previous: null,
        curent: null,
        next: null
    },
    show: {
        previous: null,
        current: null,
        next: null,
    },
    source: null,
    no_air: false
};

function CaspaDriver() {
    var self = this;
    this.status = _.clone(defaults);
    this.channel = "mostoStatus";
    this.publisher = mbc.pubsub();

    CaspaDriver.prototype.setStatus = function(status) {
        // this overrides this.status with the values passed by status
        this.status = _.extend(this.status, status);
        this.publish(status);
    };
    CaspaDriver.prototype.publish = function(status) {
        this.publisher.publish({backend: this.channel, model: status});
    };
    CaspaDriver.prototype.publishStatus = function(status) {
        this.publisher.publish({backend: "mostoStatus", model: status})
    };
}

exports = module.exports = function() {
    driver = new CaspaDriver();
    return driver;
};
<commit_msg>make CaspaDriver into an EventEmitter<commit_after>/*******************
 * This is the pubsub driver that should tell caspa about the melted status
 *
 *******************/
events = require('events');
utils = require('utils');
_ = require('underscore');
mbc = require('mbc-common');

defaults = { // copied from caspa/models.App.Status
    _id: 1,
    piece: {
        previous: null,
        curent: null,
        next: null
    },
    show: {
        previous: null,
        current: null,
        next: null,
    },
    source: null,
    no_air: false
};

function CaspaDriver() {
    events.EventEmitter.call(this);
    var self = this;
    this.status = _.clone(defaults);
    this.channel = "mostoStatus";
    this.publisher = mbc.pubsub();

    CaspaDriver.prototype.setStatus = function(status) {
        // this overrides this.status with the values passed by status
        this.status = _.extend(this.status, status);
        this.publish(status);
    };
    CaspaDriver.prototype.publish = function(status) {
        this.publisher.publish({backend: this.channel, model: status});
    };
    CaspaDriver.prototype.publishStatus = function(status) {
        this.publisher.publish({backend: "mostoStatus", model: status})
    };
}

util.inherits(CaspaDriver, events.EventEmitter);

exports = module.exports = function() {
    driver = new CaspaDriver();
    return driver;
};
<|endoftext|>


<commit_before>'use strict';

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

// Lambda Handler
module.exports.handler = function(event, context) {

  // Check event for dry run, which prevents actual deletion
  // check logs to see what would have been deleted
  console.log(event);
  if(event.dryRun){
    process.env.DRY_RUN = true;
  } else {
    process.env.DRY_RUN = false;
  }

  if(!process.env.AWS_ACCOUNT_ID){
    console.warn('WARN: NO AWS_ACCOUNT_ID, defaulting to current account');
    process.env.AWS_ACCOUNT_ID = context.invoked_function_arn.split(':')[4];
  }

  if(!process.env.REPO_REGION){
    console.warn('WARN: NO REPO_REGION, defaulting to us-east-1');
    process.env.AWS_REGION = 'us-east-1';
  }

  if(!process.env.ECS_REGION){
    console.warn('WARN: NO ECS_REGION, defaulting to us-east-1');
    process.env.AWS_REGION = 'us-east-1';
  }

  if(!process.env.REPO_AGE_THRESHOLD){
    console.warn('WARN: NO REPO_AGE_THRESHOLD, defaulting to 90 days');
    process.env.AWS_REGION = 90;
  }

  if(!process.env.REPO_TO_CLEAN){
    console.error('ERROR: NO REPO_TO_CLEAN, must be set');
    return context.fail(new Error('Must set REPO_TO_CLEAN'));
  }

  var params = {
    repositoryName: process.env.REPO_TO_CLEAN
  };

  lib.getRepoImages(params)
    .then(lib.filterImagesByDateThreshold)
    .then(lib.filterOutActiveImages)
    .then(lib.deleteImages)
    .then(context.succeed)
    .catch(context.fail);
};
<commit_msg>Update handler.js<commit_after>'use strict';

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

// Lambda Handler
module.exports.handler = function(event, context) {

  // Check event for dry run, which prevents actual deletion
  // check logs to see what would have been deleted
  console.log(event);
  if(event.dryRun){
    process.env.DRY_RUN = true;
  } else {
    process.env.DRY_RUN = false;
  }

  if(!process.env.AWS_ACCOUNT_ID){
    console.warn('WARN: NO AWS_ACCOUNT_ID, defaulting to current account');
    process.env.AWS_ACCOUNT_ID = context.invoked_function_arn.split(':')[4];
  }

  if(!process.env.REPO_REGION){
    console.warn('WARN: NO REPO_REGION, defaulting to us-east-1');
    process.env.AWS_REGION = 'us-east-1';
  }

  if(!process.env.ECS_REGION){
    console.warn('WARN: NO ECS_REGION, defaulting to us-east-1');
    process.env.AWS_REGION = 'us-east-1';
  }

  if(!process.env.REPO_AGE_THRESHOLD){
    console.warn('WARN: NO REPO_AGE_THRESHOLD, defaulting to 90 days');
    process.env.REPO_AGE_THRESHOLD = 90;
  }

  if(!process.env.REPO_TO_CLEAN){
    console.error('ERROR: NO REPO_TO_CLEAN, must be set');
    return context.fail(new Error('Must set REPO_TO_CLEAN'));
  }

  var params = {
    repositoryName: process.env.REPO_TO_CLEAN
  };

  lib.getRepoImages(params)
    .then(lib.filterImagesByDateThreshold)
    .then(lib.filterOutActiveImages)
    .then(lib.deleteImages)
    .then(context.succeed)
    .catch(context.fail);
};
<|endoftext|>