<commit_before>// Copyright 2002-2012, University of Colorado

/**
 * Represents a trail (path in the graph) from a "root" node down to a descendant node.
 * In a DAG, or with different views, there can be more than one trail up from a node,
 * even to the same root node!
 *
 * This trail also mimics an Array, so trail[0] will be the root, and trail[trail.length-1]
 * will be the end node of the trail.
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

var scenery = scenery || {};

(function(){
  "use strict";

  scenery.Trail = function( nodes ) {
    this.nodes = [];
    this.length = 0;

    // indices[x] stores the index of nodes[x] in nodes[x-1]'s children
    this.indices = null;

    var trail = this;
    if ( nodes ) {
      if ( nodes instanceof scenery.Node ) {
        var node = nodes;

        // add just a single node in
        trail.addDescendant( node );
      } else {
        // process it as an array
        _.each( nodes, function( node ) {
          trail.addDescendant( node );
        } );
      }
    }
  };
  var Trail = scenery.Trail;

  Trail.prototype = {
    constructor: Trail,

    copy: function() {
      return new scenery.Trail( this.nodes.slice( 0 ) );
    },

    isEmpty: function() {
      return this.nodes.length === 0;
    },

    addAncestor: function( node ) {
      this.nodes.unshift( node );

      // mimic an Array
      this.length++;
      for ( var i = 0; i < this.length; i++ ) {
        this[i] = this.nodes[i];
      }
    },

    removeAncestor: function() {
      this.nodes.shift();

      // mimic an Array
      this.length--;
      delete this[this.length];
      for ( var i = 0; i < this.length; i++ ) {
        this[i] = this.nodes[i];
      }
    },

    addDescendant: function( node ) {
      this.nodes.push( node );

      // mimic an Array
      this.length++;
      this[this.length-1] = node;
    },

    removeDescendant: function() {
      this.nodes.pop();

      // mimic an Array
      this.length--;
      delete this[this.length];
    },

    // updates the indices array so that operations can depend on child indices
    reindex: function() {
      this.indices = [];
      for ( var i = 1; i < this.length; i++ ) {
        this.indices.push( _.indexOf( this.nodes[i-1].children, this.nodes[i] ) );
      }
    },

    equals: function( other ) {
      if ( this.length !== other.length ) {
        return false;
      }

      for ( var i = 0; i < this.nodes.length; i++ ) {
        if ( this.nodes[i] !== other.nodes[i] ) {
          return false;
        }
      }

      return true;
    },

    // whether this trail contains the complete 'other' trail, but with added descendants afterwards
    isExtensionOf: function( other ) {
      if ( this.length <= other.length ) {
        return false;
      }

      for ( var i = 0; i < other.nodes.length; i++ ) {
        if ( this.nodes[i] !== other.nodes[i] ) {
          return false;
        }
      }

      return true;
    },

    nodeFromTop: function( offset ) {
      return this.nodes[this.length - 1 - offset];
    },

    lastNode: function() {
      return this.nodeFromTop( 0 );
    },

    // returns the previous graph trail in the order of self-rendering
    previous: function() {
      if ( this.nodes.length <= 1 ) {
        return null;
      }

      var top = this.nodeFromTop( 0 );
      var parent = this.nodeFromTop( 1 );

      var parentIndex = _.indexOf( parent.children, top );
      var arr = this.nodes.slice( 0, this.nodes.length - 1 );
      if ( parentIndex === 0 ) {
        // we were the first child, so give it the trail to the parent
        return new Trail( arr );
      } else {
        // previous child
        arr.push( parent.children[parentIndex-1] );

        // and find its last terminal
        while( arr[arr.length-1].children.length !== 0 ) {
          var last = arr[arr.length-1];
          arr.push( last.children[last.children.length-1] );
        }

        return new Trail( arr );
      }
    },

    // in the order of self-rendering
    next: function() {
      var arr = this.nodes.slice( 0 );

      var top = this.nodeFromTop( 0 );
      if ( top.children.length > 0 ) {
        // if we have children, return the first child
        arr.push( top.children[0] );
        return new Trail( arr );
      } else {
        // walk down and attempt to find the next parent
        var depth = this.nodes.length - 1;

        while ( depth > 0 ) {
          var node = this.nodes[depth];
          var parent = this.nodes[depth-1];

          arr.pop(); // take off the node so we can add the next sibling if it exists

          var index = _.indexOf( parent.children, node );
          if ( index !== parent.children.length - 1 ) {
            // there is another (later) sibling. use that!
            arr.push( parent.children[index+1] );
            return new Trail( arr );
          } else {
            depth--;
          }
        }

        // if we didn't reach a later sibling by now, it doesn't exist
        return null;
      }
    },

    /*
     * Iterates between this trail and the other one, calling listener.enter( node ) and listener.exit( node ).
     * This will be bounded by listener.exit( startNode ) and listener.enter( endNode ),
     * unless the inclusive flag is true, then it will be bounded by listener.enter( startNode ) and listener.exit( endNode ).
     */
    eachBetween: function( other, listener, inclusive, reverseIfNecessary ) {
      var minPath = this;
      var maxPath = other;

      var exclusive = !inclusive;

      if ( reverseIfNecessary ) {
        var comparison = this.compare( other );
        minPath = comparison === -1 ? this : other;
        maxPath = comparison === -1 ? other : this;
      }

      var minSharedLength = Math.min( minPath.nodes.length, maxPath.nodes.length );

      // set to the length so if we don't find a first split, it is after the shared region
      var splitIndex = minSharedLength;
      for ( var i = 0; i < minSharedLength; i++ ) {
        if ( minPath.nodes[i] !== maxPath.nodes[i] ) {
          splitIndex = i;
          break;
        }
      }

      // bail out since one is a subtrail of the other (there is no 'between' from the above definition)
      if ( exclusive && splitIndex === minSharedLength ) {
        return;
      }

      // console.log( 'splitIndex: ' + splitIndex );

      // TODO: remove after debugging
      function dumpstr( node ) {
        var result = '|';
        while ( node.parents.length !== 0 ) {
          result = _.indexOf( node.parents[0].children, node ) + ',' + result;
          node = node.parents[0];
        }
        return result;
      }

      function recurse( node, depth, hasLowBound, hasHighBound ) {
        console.log( 'recurse: ' + dumpstr( node ) + ' ' + hasLowBound + ', ' + hasHighBound + ', ' + depth );
        if ( !hasLowBound && !hasHighBound ) {
          listener.enter( node );
          _.each( node.children, function( child ) {
            recurse( child, depth + 1, false, false );
          } );
          listener.exit( node );
        } else {
          // we are now assured that minPath.nodes[depth] !== maxPath.nodes[depth] (at least as subtrails), so each child is either high-bounded or low-bounded

          if ( !hasLowBound ) {
            listener.enter( node );
          }

          var lowIndex = hasLowBound ? _.indexOf( node.children, minPath.nodes[depth] ) : 0;
          var highIndex = hasHighBound ? _.indexOf( node.children, maxPath.nodes[depth] ) : node.children.length - 1;
          phet.assert( lowIndex !== -1, 'no low index' );
          phet.assert( highIndex !== -1, 'no high index' );

          console.log( 'lowIndex: ' + lowIndex + ', highIndex: ' + highIndex + ', depth: ' + depth + ', minPath.nodes.length: ' + minPath.nodes.length );
          for ( var i = lowIndex; i <= highIndex; i++ ) {
            var child = node.children[i];

            var isOnLowPath = hasLowBound && i === lowIndex;
            var isOnHighPath = hasHighBound && i === highIndex;

            // don't follow the subtree of a start node
            if ( isOnLowPath && minPath.nodes.length - 1 === depth ) {
              listener.exit( child );
              continue;
            }

            // don't follow the subtree of an end node
            if ( isOnHighPath && maxPath.nodes.length - 1 === depth ) {
              listener.enter( child );
              continue;
            }

            recurse( child, depth + 1, hasLowBound && i === lowIndex, hasHighBound && i === highIndex );
          }

          if ( !hasHighBound ) {
            listener.exit( node );
          }
        }
      }

      recurse( minPath.nodes[splitIndex-1], splitIndex, minPath.nodes.length !== splitIndex, maxPath.nodes.length !== splitIndex );
    },

    /* Standard Java-style compare. -1 means this trail is before (under) the other trail, 0 means equal, and 1 means this trail is
     * after (on top of) the other trail.
     * A shorter subtrail will compare as -1.
     */
    compare: function( other ) {
      phet.assert( !this.isEmpty() );
      phet.assert( !other.isEmpty() );
      phet.assert( this.nodes[0] === other.nodes[0] );

      var minIndex = Math.min( this.nodes.length, other.nodes.length );
      for ( var i = 1; i < minIndex; i++ ) {
        if ( this.nodes[i] !== other.nodes[i] ) {
          var myIndex = _.indexOf( this.nodes[i-1].children, this.nodes[i] );
          var otherIndex = _.indexOf( other.nodes[i-1].children, other.nodes[i] );
          phet.assert( myIndex !== otherIndex ); // they should be different if the nodes are different
          if ( myIndex < otherIndex ) {
            return -1;
          } else {
            return 1;
          }
        }
      }

      // we scanned through and no nodes were different (one is a subtrail of the other)
      if ( this.nodes.length < other.nodes.length ) {
        return -1;
      } else if ( this.nodes.length > other.nodes.length ) {
        return 1;
      } else {
        return 0;
      }
    }
  };

})();

<commit_msg>Adding compulsory index tracking to Trail<commit_after>// Copyright 2002-2012, University of Colorado

/**
 * Represents a trail (path in the graph) from a "root" node down to a descendant node.
 * In a DAG, or with different views, there can be more than one trail up from a node,
 * even to the same root node!
 *
 * This trail also mimics an Array, so trail[0] will be the root, and trail[trail.length-1]
 * will be the end node of the trail.
 *
 * @author Jonathan Olson <olsonsjc@gmail.com>
 */

var scenery = scenery || {};

(function(){
  "use strict";

  scenery.Trail = function( nodes ) {
    this.nodes = [];
    this.length = 0;

    // indices[x] stores the index of nodes[x] in nodes[x-1]'s children
    this.indices = [];

    var trail = this;
    if ( nodes ) {
      if ( nodes instanceof scenery.Node ) {
        var node = nodes;

        // add just a single node in
        trail.addDescendant( node );
      } else {
        // process it as an array
        _.each( nodes, function( node ) {
          trail.addDescendant( node );
        } );
      }
    }
  };
  var Trail = scenery.Trail;

  Trail.prototype = {
    constructor: Trail,

    copy: function() {
      return new scenery.Trail( this.nodes.slice( 0 ) );
    },

    isEmpty: function() {
      return this.nodes.length === 0;
    },

    addAncestor: function( node, index ) {
      var oldRoot = this.nodes[0];

      this.nodes.unshift( node );
      if ( oldRoot ) {
        this.indices.unshift( index === undefined ? _.indexOf( node.children, oldRoot ) : index );
      }

      // mimic an Array
      this.length++;
      for ( var i = 0; i < this.length; i++ ) {
        this[i] = this.nodes[i];
      }
    },

    removeAncestor: function() {
      this.nodes.shift();
      if ( this.indices.length ) {
        this.indices.shift();
      }

      // mimic an Array
      this.length--;
      delete this[this.length];
      for ( var i = 0; i < this.length; i++ ) {
        this[i] = this.nodes[i];
      }
    },

    addDescendant: function( node, index ) {
      var parent = this.lastNode();

      this.nodes.push( node );
      if ( parent ) {
        this.indices.push( index === undefined ? _.indexOf( parent.children, node ) : index );
      }

      // mimic an Array
      this.length++;
      this[this.length-1] = node;
    },

    removeDescendant: function() {
      this.nodes.pop();
      if ( this.indices.length ) {
        this.indices.pop();
      }

      // mimic an Array
      this.length--;
      delete this[this.length];
    },

    // refreshes the internal index references (important if any children arrays were modified!)
    reindex: function() {
      this.indices = [];
      for ( var i = 1; i < this.length; i++ ) {
        this.indices.push( _.indexOf( this.nodes[i-1].children, this.nodes[i] ) );
      }
    },

    equals: function( other ) {
      if ( this.length !== other.length ) {
        return false;
      }

      for ( var i = 0; i < this.nodes.length; i++ ) {
        if ( this.nodes[i] !== other.nodes[i] ) {
          return false;
        }
      }

      return true;
    },

    // whether this trail contains the complete 'other' trail, but with added descendants afterwards
    isExtensionOf: function( other ) {
      if ( this.length <= other.length ) {
        return false;
      }

      for ( var i = 0; i < other.nodes.length; i++ ) {
        if ( this.nodes[i] !== other.nodes[i] ) {
          return false;
        }
      }

      return true;
    },

    nodeFromTop: function( offset ) {
      return this.nodes[this.length - 1 - offset];
    },

    lastNode: function() {
      return this.nodeFromTop( 0 );
    },

    // returns the previous graph trail in the order of self-rendering
    previous: function() {
      if ( this.nodes.length <= 1 ) {
        return null;
      }

      var top = this.nodeFromTop( 0 );
      var parent = this.nodeFromTop( 1 );

      var parentIndex = _.indexOf( parent.children, top );
      var arr = this.nodes.slice( 0, this.nodes.length - 1 );
      if ( parentIndex === 0 ) {
        // we were the first child, so give it the trail to the parent
        return new Trail( arr );
      } else {
        // previous child
        arr.push( parent.children[parentIndex-1] );

        // and find its last terminal
        while( arr[arr.length-1].children.length !== 0 ) {
          var last = arr[arr.length-1];
          arr.push( last.children[last.children.length-1] );
        }

        return new Trail( arr );
      }
    },

    // in the order of self-rendering
    next: function() {
      var arr = this.nodes.slice( 0 );

      var top = this.nodeFromTop( 0 );
      if ( top.children.length > 0 ) {
        // if we have children, return the first child
        arr.push( top.children[0] );
        return new Trail( arr );
      } else {
        // walk down and attempt to find the next parent
        var depth = this.nodes.length - 1;

        while ( depth > 0 ) {
          var node = this.nodes[depth];
          var parent = this.nodes[depth-1];

          arr.pop(); // take off the node so we can add the next sibling if it exists

          var index = _.indexOf( parent.children, node );
          if ( index !== parent.children.length - 1 ) {
            // there is another (later) sibling. use that!
            arr.push( parent.children[index+1] );
            return new Trail( arr );
          } else {
            depth--;
          }
        }

        // if we didn't reach a later sibling by now, it doesn't exist
        return null;
      }
    },

    /*
     * Iterates between this trail and the other one, calling listener.enter( node ) and listener.exit( node ).
     * This will be bounded by listener.exit( startNode ) and listener.enter( endNode ),
     * unless the inclusive flag is true, then it will be bounded by listener.enter( startNode ) and listener.exit( endNode ).
     */
    eachBetween: function( other, listener, inclusive, reverseIfNecessary ) {
      var minPath = this;
      var maxPath = other;

      var exclusive = !inclusive;

      if ( reverseIfNecessary ) {
        var comparison = this.compare( other );
        minPath = comparison === -1 ? this : other;
        maxPath = comparison === -1 ? other : this;
      }

      var minSharedLength = Math.min( minPath.nodes.length, maxPath.nodes.length );

      // set to the length so if we don't find a first split, it is after the shared region
      var splitIndex = minSharedLength;
      for ( var i = 0; i < minSharedLength; i++ ) {
        if ( minPath.nodes[i] !== maxPath.nodes[i] ) {
          splitIndex = i;
          break;
        }
      }

      // bail out since one is a subtrail of the other (there is no 'between' from the above definition)
      if ( exclusive && splitIndex === minSharedLength ) {
        return;
      }

      // console.log( 'splitIndex: ' + splitIndex );

      // TODO: remove after debugging
      function dumpstr( node ) {
        var result = '|';
        while ( node.parents.length !== 0 ) {
          result = _.indexOf( node.parents[0].children, node ) + ',' + result;
          node = node.parents[0];
        }
        return result;
      }

      function recurse( node, depth, hasLowBound, hasHighBound ) {
        console.log( 'recurse: ' + dumpstr( node ) + ' ' + hasLowBound + ', ' + hasHighBound + ', ' + depth );
        if ( !hasLowBound && !hasHighBound ) {
          listener.enter( node );
          _.each( node.children, function( child ) {
            recurse( child, depth + 1, false, false );
          } );
          listener.exit( node );
        } else {
          // we are now assured that minPath.nodes[depth] !== maxPath.nodes[depth] (at least as subtrails), so each child is either high-bounded or low-bounded

          if ( !hasLowBound ) {
            listener.enter( node );
          }

          var lowIndex = hasLowBound ? _.indexOf( node.children, minPath.nodes[depth] ) : 0;
          var highIndex = hasHighBound ? _.indexOf( node.children, maxPath.nodes[depth] ) : node.children.length - 1;
          phet.assert( lowIndex !== -1, 'no low index' );
          phet.assert( highIndex !== -1, 'no high index' );

          console.log( 'lowIndex: ' + lowIndex + ', highIndex: ' + highIndex + ', depth: ' + depth + ', minPath.nodes.length: ' + minPath.nodes.length );
          for ( var i = lowIndex; i <= highIndex; i++ ) {
            var child = node.children[i];

            var isOnLowPath = hasLowBound && i === lowIndex;
            var isOnHighPath = hasHighBound && i === highIndex;

            // don't follow the subtree of a start node
            if ( isOnLowPath && minPath.nodes.length - 1 === depth ) {
              listener.exit( child );
              continue;
            }

            // don't follow the subtree of an end node
            if ( isOnHighPath && maxPath.nodes.length - 1 === depth ) {
              listener.enter( child );
              continue;
            }

            recurse( child, depth + 1, hasLowBound && i === lowIndex, hasHighBound && i === highIndex );
          }

          if ( !hasHighBound ) {
            listener.exit( node );
          }
        }
      }

      recurse( minPath.nodes[splitIndex-1], splitIndex, minPath.nodes.length !== splitIndex, maxPath.nodes.length !== splitIndex );
    },

    /* Standard Java-style compare. -1 means this trail is before (under) the other trail, 0 means equal, and 1 means this trail is
     * after (on top of) the other trail.
     * A shorter subtrail will compare as -1.
     */
    compare: function( other ) {
      phet.assert( !this.isEmpty() );
      phet.assert( !other.isEmpty() );
      phet.assert( this.nodes[0] === other.nodes[0] );

      var minIndex = Math.min( this.nodes.length, other.nodes.length );
      for ( var i = 1; i < minIndex; i++ ) {
        if ( this.nodes[i] !== other.nodes[i] ) {
          var myIndex = _.indexOf( this.nodes[i-1].children, this.nodes[i] );
          var otherIndex = _.indexOf( other.nodes[i-1].children, other.nodes[i] );
          phet.assert( myIndex !== otherIndex ); // they should be different if the nodes are different
          if ( myIndex < otherIndex ) {
            return -1;
          } else {
            return 1;
          }
        }
      }

      // we scanned through and no nodes were different (one is a subtrail of the other)
      if ( this.nodes.length < other.nodes.length ) {
        return -1;
      } else if ( this.nodes.length > other.nodes.length ) {
        return 1;
      } else {
        return 0;
      }
    }
  };

})();

<|endoftext|>


<commit_before>/**
 * @author Gilles Coomans <gilles.coomans@gmail.com>
 *
 */

if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
define(["require", "deepjs/deep"], function(require, deep){
	deep.compose.dom = deep.compose.dom || {};
	var DomComposer = deep.compose.dom.Composer = new deep.Composer(deep.compose.dom);	// create composer manager for namespace deep.sheet
	var Args = deep.Arguments;
	DomComposer.add("inPlaceEditable", "after", function() {
		return function(entry, options) {
			console.log("In place editable enhancement")
			return Args([entry, options]);
		};
	});
	DomComposer.add("hide", "after", function() {
		return function(entry, options) {
			// console.log("dom hide")
			deep.$(entry).hide();
			return Args([entry, options]);
		};
	});
	DomComposer.add("show", "after", function() {
		return function(entry, options) {
			// console.log("dom show")
			deep.$(entry).show();
			return Args([entry, options]);
		};
	});
	DomComposer.add("fadeIn", "after", function(ms) {
		return function(entry, options) {
			deep.$(entry).fadeIn(ms);
			return Args([entry, options]);
		};
	});
	DomComposer.add("click", "after", function(handler, args) {
		// console.log('csheeter click 1 : ', handler, args);
		return function(entry, context) {
			// console.log("sheeter.click : entry, context, handler, args : ", entry, context, handler, args)
			var $ = deep.$();
			var self = this;
			$(entry).click(function(e){
				if(typeof handler === 'function')
					return handler.call(self, this, e);
				if(e && e.preventDefault)
					e.preventDefault();
				self[handler].apply(self, args || []);
				return false;
			});
		};
	});
	DomComposer.add("each", "after", function(handler) {
		return function(entry, context) {
			var $ = deep.$(),
				promises = [];
			var self = this;
			$(entry).each(function(){
				promises.push(handler.call(self, this));
			});
			return deep.all(promises)
			.when(Args([entry, context]))
		};
	});
	DomComposer.add("find", "after", function(selector) {
		return function(entry, context) {
			return Args([deep.$(entry).find(selector), context]);
		};
	});
	DomComposer.add("directives", "after", function() {
		var argus = Args;
		return function(entry, context) {
			var args = Array.prototype.slice.apply(argus), name = args.shift();
			var directive = deep.ui.directives[name];
			if(!directive)
				return deep.errors.View("missing directive : " + name);
			var $ = deep.$(),
				promises = [],
				self = this;
			args.unshift(this, context);
			$(entry).each(function(){
				args[0] = this;
				var r = directive.apply(self, args);
				if(r && r.then)
					promises.push(r);
			});
			if(promises.length)
				return deep.all(promises)
				.when(Args([entry, context]));
		};
	});
	//____________________________________________________________________ STILL TO IMPLEMENT AND TEST
	DomComposer.add("control", "after", function(controller) {
		return function(entry, context) {
			var $ = deep.$(),
				promises = [];

			$(entry).each(function(node){

			});
			return deep.all(promises)
			.when(Args([entry, context]));
		};
	});
	DomComposer.add("sheet", "after", function() {
		var controllers = Args;
		return function(entry, context) {
			var $ = deep.$(),
				promises = [];

			$(entry).each(function(node){

			});
			return deep.all(promises)
			.when(Args([entry, context]));
		};
	});
	return deep.compose.dom;
});<commit_msg>clean<commit_after>/**
 * @author Gilles Coomans <gilles.coomans@gmail.com>
 *
 */

if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}
define(["require", "deepjs/deep"], function(require, deep){
	deep.compose.dom = deep.compose.dom || {};
	var DomComposer = deep.compose.dom.Composer = new deep.Composer(deep.compose.dom);	// create composer manager for namespace deep.sheet
	var Args = deep.Arguments;
	DomComposer.add("inPlaceEditable", "after", function() {
		return function(entry, options) {
			console.log("In place editable enhancement")
			return Args([entry, options]);
		};
	});
	DomComposer.add("hide", "after", function() {
		return function(entry, options) {
			// console.log("dom hide")
			deep.$(entry).hide();
			return Args([entry, options]);
		};
	});
	DomComposer.add("show", "after", function() {
		return function(entry, options) {
			// console.log("dom show")
			deep.$(entry).show();
			return Args([entry, options]);
		};
	});
	DomComposer.add("fadeIn", "after", function(ms) {
		return function(entry, options) {
			deep.$(entry).fadeIn(ms);
			return Args([entry, options]);
		};
	});
	DomComposer.add("click", "after", function(handler, args) {
		// console.log('csheeter click 1 : ', handler, args);
		return function(entry, context) {
			// console.log("sheeter.click : entry, context, handler, args : ", entry, context, handler, args)
			var $ = deep.$();
			var self = this;
			$(entry).click(function(e){
				if(typeof handler === 'function')
					return handler.call(self, this, e);
				if(e && e.preventDefault)
					e.preventDefault();
				self[handler].apply(self, args || []);
				return false;
			});
		};
	});
	DomComposer.add("each", "after", function(handler) {
		return function(entry, context) {
			var $ = deep.$(),
				promises = [];
			var self = this;
			$(entry).each(function(){
				promises.push(handler.call(self, this));
			});
			return deep.all(promises)
			.when(Args([entry, context]))
		};
	});
	DomComposer.add("find", "after", function(selector) {
		return function(entry, context) {
			return Args([deep.$(entry).find(selector), context]);
		};
	});
	DomComposer.add("directives", "after", function() {
		var argus = Args;
		return function(entry, context) {
			var args = Array.prototype.slice.apply(argus), name = args.shift();
			var directive = deep.ui.directives[name];
			if(!directive)
				return deep.errors.View("missing directive : " + name);
			var $ = deep.$(),
				promises = [],
				self = this;
			args.unshift(this, context);
			$(entry).each(function(){
				args[0] = this;
				var r = directive.apply(self, args);
				if(r && r.then)
					promises.push(r);
			});
			if(promises.length)
				return deep.all(promises)
				.when(Args([entry, context]));
		};
	});
	//____________________________________________________________________ STILL TO IMPLEMENT AND TEST
	DomComposer.add("control", "after", function(controller) {
		return function(entry, context) {
			var $ = deep.$(),
				promises = [];

			$(entry).each(function(node){

			});
			return deep.all(promises)
			.when(Args([entry, context]));
		};
	});
	DomComposer.add("sheet", "after", function() {
		var controllers = Args;
		return function(entry, context) {
			var $ = deep.$(),
				promises = [];

			$(entry).each(function(node){

			});
			return deep.all(promises)
			.when(Args([entry, context]));
		};
	});
	return deep.compose.dom;
});<|endoftext|>


<commit_before>'use strict';

var _ = require('underscore');
var utils = require('../utils');
var RequestExecutor = require('./RequestExecutor');
var Resource = require('../resource/Resource');
var InstanceResource = require('../resource/InstanceResource');
var instantiate = require('../resource/ResourceFactory').instantiate;

//Caching
var CacheHandler = require('../cache/CacheHandler');

/**
 * # DataStore
 *
 * A `DataStore` interacts with the REST API server on behalf of SDK users.
 *
 * The DataStore delegates raw request execution to an internal [RequestExecutor](RequestExecutor.js.html) instance.  In future SDK releases, the DataStore will also coordinate with a caching layer, reducing round trips to the server.
 *
 * It is important that the DataStore acts as an intermediary, decoupling SDK users from raw request logic:  because interaction goes through the DataStore, additional features (like caching) can be added at any point in the future without requiring changes to SDK users' code.
 * @since 0.1
 * @class DataStore
 */

/**
 * Creates a new `DataStore` instance using the specified (required) `config`.
 *
 * The required `config` argument must contain a `requestExecutor` instance or contain values that may be used to construct a `RequestExecutor` instance (like an `apiKey`).
 *
 * @param {Object} config required configuration object that either provides a `requestExecutor` or values that may be used to instantiate a `RequestExecutor`.
 * @param {Object} config.cacheOptions - cache manager options
 * @class DataStore
 * @constructor
 * @api public
 * @version 0.1
 * @see RequestExecutor
 */
function DataStore(config) {
  if (!config) {
    throw new Error('config argument is required.');
  }
  this.requestExecutor = config.requestExecutor || new RequestExecutor(config);
  this.cacheHandler = config.cacheHandler || new CacheHandler(config);
}
utils.inherits(DataStore, Object);

DataStore.prototype._request = {};

function isResourceCtor(obj) {
  return obj && (obj instanceof Function) && utils.isAssignableFrom(Resource, obj);
}

DataStore.prototype._wrapGetResourceResponse =
  function wrapGetResourceResponse(err, data, InstanceCtor, query, cb) {
  if (err) {
    return cb(err, null);
  }

  var instance = null;
  if (data) {
    instance = instantiate(InstanceCtor, data, query, this);
  }
  return cb(null, instance);
};

/**
 * Queries the server for a resource by `href`, providing the result to `callback`.
 *
 * @param {String} href the URI of the resource to acquire.  This must always be the first argument.
 * @param {Object} query [optional=undefined] name/value pairs to use as query parameters to `href`
 * @param {Function} instanceCtor [optional=InstanceResource] The Constructor function to invoke for any Instance Resource returned by the server.  If the resource returned by the server is a single resource, this function is used to construct the resource.  If the resource returned by the server is a collection, `instanceCtor` is used to construct each resource in the collection's `items` field.
 * @param {Function} callback the callback function to invoke with the constructed Resource. `callback`'s first argument is an `Error`, the second is the constructed resource.  `callback` must always be the last argument.
 * @return {void} no return value; the acquired resource is instead provided to `callback`.
 * @method getResource
 * @class DataStore
 * @api public
 * @version 0.1
 */
DataStore.prototype.getResource = function getResource(/* href, [query], [InstanceConstructor], callback */) {
  var _this = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();

  _this = _.clone(_this);

  _this._request = {
    href: href,
    query: (args.length > 0 && !(args[0] instanceof Function)) ? args.shift() : {},
    InstanceCtor: (args.length > 0 && isResourceCtor(args[0])) ? args.shift() : InstanceResource
  };

  return _this.exec(callback);
};

/**
 * Gets collection
 * @param {string|object} [query] - optional query
 * @param {function} [cb]
 */
DataStore.prototype.search = function (query, options, cb) {
  if (!query || typeof query === 'function') {
    throw new Error('Missing query argument in find request');
  }
  if (typeof options === 'function') {
    cb = options;
    options = query;
  }
  options = options || {};

  if (typeof query === 'string' && query.length > 0) {
    this._request.rawSearch = query;
  }

  if (_.isObject(query)) {
    this._request.search = query;
  }

  this._request.limit = options.limit;
  this._request.offset = options.offset;

  return this.exec(cb);
};

/**
 *
 * @param orderQuery - 'name', 'name asc', {field: -1} === 'field desc'
 */
DataStore.prototype.orderBy = function (orderQuery, cb) {
  var order = {};

  function isOrderDirection(word) {
    return (word === 'asc') || (word === 'desc');
  }

  if (typeof orderQuery === 'string') {
    var words = orderQuery.split(' ');
    for (var i = 0; i < words.length; i++) {
      if (isOrderDirection(words[i])) {
        continue;
      }
      order[words[i]] = ((i + 1) < words.length) && isOrderDirection(words[i + 1]) ?
        words[i + 1] : 'asc';
    }
  }
  if (_.isObject(orderQuery)) {
    _.each(orderQuery, function (val, field) {
      orderQuery[field] = (
        (val === -1) || (val === false) || (val === 'desc')) ? 'desc' : 'asc';
    });
  }

  this._request.order = order;
  return this.exec(cb);
};

/**
 *
 * @param {string|object} expand - 'tenant directory' | {tenant:true} |
 * {tenant: {offset:0, limit:15}}
 * @param {function} cb
 */
DataStore.prototype.expand = function (expand, cb) {
  var exp = {};
  if (typeof expand === 'string') {
    var words = expand.split(' ');
    _.each(words, function (word) {
      exp[word] = true;
    });
  }

  if (_.isObject(expand)) {
    exp = expand;
  }
  this._request.expand = exp;
  return this.exec(cb);
};

// return object, do not bind to collection
DataStore.prototype.lean = function (lean) {
  this._request.lean = lean !== false;
  return this;
};

DataStore.prototype._buildRequestQuery = function(){
  var queryStringObj = {};
  if (this._request.rawSearch) {
    queryStringObj.q = this._request.rawSearch;
  }

  if (this._request.search) {
    _.each(this._request.search, function (val, name) {
      queryStringObj[name] = val;
    });
  }

  if (this._request.limit) {
    queryStringObj.limit = this._request.limit;
  }

  if (this._request.offset) {
    queryStringObj.offset = this._request.offset;
  }

  if (this._request.order) {
    var orderByBuf = [];
    _.each(this._request.order, function(direction, name){
      orderByBuf.push(name + (direction !== 'asc' ? ' desc': ''));
    });
    queryStringObj.orderBy = orderByBuf.join(',');
  }

  if (this._request.expand){
    var expandBuf = [];
    _.each(this._request.expand, function(val, name){
      if (val === true || val === 1){
        return expandBuf.push(name);
      }
      return expandBuf.push(name + '(offset:'+val.offset+',limit:'+val.limit+')');
    });

    queryStringObj.expand = expandBuf.join(',');
  }
  return queryStringObj;
};

/**
 *
 * @param callback
 * @returns {object}
 */
DataStore.prototype.exec = function executeRequest(callback){
  var _this = this;

  if (!callback){
    return _this;
  }

  var qs = _.extend({}, _this._request.query, _this._buildRequestQuery());
  var request = {
    uri: _this._request.href,
    qs: qs
  };

  var ctor = _this._request.InstanceCtor;
  var query = _this._request.query;

  function doRequest(){
    _this.requestExecutor.execute(request, function onGetResourceRequestResult(err, body) {
      if (!err && body) {
        _this.cacheHandler.put(_this._request.href, body, utils.noop);
      }

      _this._wrapGetResourceResponse(err, body, ctor, query, callback);
    });
  }

  if (_this._request.query){
    return doRequest();
  }

  _this.cacheHandler.get(_this._request.href, function onCacheResult(err, entry) {
    if (err || entry) {
      _this._wrapGetResourceResponse(err, entry, ctor, query, callback);
      return;
    }

    //not cached, query the server:
    doRequest();
  });
};

/**
 * Creates a new resource on the server as a child of the specified `parentHref` location (must be a collection resource endpoint).
 *
 * @param {String} parentHref the URI of the parent collection under which the new resource will be created as a child.  This must always be the first argument.
 * @param {Object=undefined} query  name/value pairs to use as query parameters to `parentHref`.
 * @param {Object} data the resource (name/value pairs) to send to the server.
 * @param {Function=InstanceResource} instanceCtor (optional, defaults to ``)  The Constructor function to invoke for any instance resource returned by the server.  If the request result is a single resource, this function is used to construct the resource.  If the request result is a collection, the `instanceCtor` is used to construct each resource in the collection's `items` field.
 * @param {Function} callback the callback function to invoke with the constructed Resource. `callback`'s first argument is an `Error`, the second is the constructed resource. `callback` must always be the last argument.
 * @return {void} no return value; the acquired resource is instead provided to `callback`.
 * @method createResource
 * @class DataStore
 * @api public
 * @version 0.1
 */
DataStore.prototype.createResource = function createResource(/* parentHref, [query], data, [InstanceConstructor], callback */) {

  var _this = this;
  var args = Array.prototype.slice.call(arguments);

  var parentHref = args.shift();
  var callback = args.pop();
  var ctor = (args.length > 0 && (args[args.length -1] instanceof Function)) ? args.pop() : InstanceResource;
  var data = args.pop();
  var query = (args.length > 0) ? args.pop() : null;

  if (!utils.isAssignableFrom(InstanceResource, ctor)) {
    throw new Error("If specifying a constructor function, it must be for class equal to or a subclass of InstanceResource.");
  }

  var request = {uri: parentHref, method: 'POST'};
  if (query) {
    request.query = query;
  }
  if (data) {
    request.body = data;
  }

  _this.requestExecutor.execute(request, function onCreateResourceRequestResult(err, body) {
    if (err) {
      return callback(err, null);
    }

    var returnedResource = instantiate(ctor, body, null, _this);

    //cache for future use:
    _this.cacheHandler.put(body.href, body, utils.noop);

    return callback(null, returnedResource);
  });
};

DataStore.prototype.saveResource = function saveResource(resource, callback) {

  var _this = this;

  var href = utils.valueOf(resource.href);

  var request = {uri: href, method: 'POST', body: resource};

  _this.requestExecutor.execute(request, function onSaveResourceRequestResult(err, body) {
    if (err) {
      return callback(err, null);
    }

    var returnedResource = instantiate(resource.constructor, body, null, _this);

    //cache for future use:
    _this.cacheHandler.put(body.href, body, false, utils.noop);

    return callback(null, returnedResource);
  });
};

DataStore.prototype.deleteResource = function deleteResource(resource, callback) {

  var _this = this;

  var href = utils.valueOf(resource.href);

  //remove from cache:
  _this.cacheHandler.remove(href, utils.noop);

  var request = {uri: href, method: 'DELETE'};

  this.requestExecutor.execute(request, function onDeleteResourceRequestResult(err) {
    if (err) {
      return callback(err, null);
    }
    return callback(null, null); //no body for the callback
  });
};

module.exports = DataStore;<commit_msg>resolved issue when request was not hitting cache<commit_after>'use strict';

var _ = require('underscore');
var utils = require('../utils');
var RequestExecutor = require('./RequestExecutor');
var Resource = require('../resource/Resource');
var InstanceResource = require('../resource/InstanceResource');
var instantiate = require('../resource/ResourceFactory').instantiate;

//Caching
var CacheHandler = require('../cache/CacheHandler');

/**
 * # DataStore
 *
 * A `DataStore` interacts with the REST API server on behalf of SDK users.
 *
 * The DataStore delegates raw request execution to an internal [RequestExecutor](RequestExecutor.js.html) instance.  In future SDK releases, the DataStore will also coordinate with a caching layer, reducing round trips to the server.
 *
 * It is important that the DataStore acts as an intermediary, decoupling SDK users from raw request logic:  because interaction goes through the DataStore, additional features (like caching) can be added at any point in the future without requiring changes to SDK users' code.
 * @since 0.1
 * @class DataStore
 */

/**
 * Creates a new `DataStore` instance using the specified (required) `config`.
 *
 * The required `config` argument must contain a `requestExecutor` instance or contain values that may be used to construct a `RequestExecutor` instance (like an `apiKey`).
 *
 * @param {Object} config required configuration object that either provides a `requestExecutor` or values that may be used to instantiate a `RequestExecutor`.
 * @param {Object} config.cacheOptions - cache manager options
 * @class DataStore
 * @constructor
 * @api public
 * @version 0.1
 * @see RequestExecutor
 */
function DataStore(config) {
  if (!config) {
    throw new Error('config argument is required.');
  }
  this.requestExecutor = config.requestExecutor || new RequestExecutor(config);
  this.cacheHandler = config.cacheHandler || new CacheHandler(config);
}
utils.inherits(DataStore, Object);

DataStore.prototype._request = {};

function isResourceCtor(obj) {
  return obj && (obj instanceof Function) && utils.isAssignableFrom(Resource, obj);
}

DataStore.prototype._wrapGetResourceResponse =
  function wrapGetResourceResponse(err, data, InstanceCtor, query, cb) {
  if (err) {
    return cb(err, null);
  }

  var instance = null;
  if (data) {
    instance = instantiate(InstanceCtor, data, query, this);
  }
  return cb(null, instance);
};

/**
 * Queries the server for a resource by `href`, providing the result to `callback`.
 *
 * @param {String} href the URI of the resource to acquire.  This must always be the first argument.
 * @param {Object} query [optional=undefined] name/value pairs to use as query parameters to `href`
 * @param {Function} instanceCtor [optional=InstanceResource] The Constructor function to invoke for any Instance Resource returned by the server.  If the resource returned by the server is a single resource, this function is used to construct the resource.  If the resource returned by the server is a collection, `instanceCtor` is used to construct each resource in the collection's `items` field.
 * @param {Function} callback the callback function to invoke with the constructed Resource. `callback`'s first argument is an `Error`, the second is the constructed resource.  `callback` must always be the last argument.
 * @return {void} no return value; the acquired resource is instead provided to `callback`.
 * @method getResource
 * @class DataStore
 * @api public
 * @version 0.1
 */
DataStore.prototype.getResource = function getResource(/* href, [query], [InstanceConstructor], callback */) {
  var _this = this;
  var args = Array.prototype.slice.call(arguments);
  var href = args.shift();
  var callback = args.pop();

  _this = _.clone(_this);

  _this._request = {
    href: href,
    query: (args.length > 0 && !(args[0] instanceof Function)) ? args.shift() : {},
    InstanceCtor: (args.length > 0 && isResourceCtor(args[0])) ? args.shift() : InstanceResource
  };

  return _this.exec(callback);
};

/**
 * Gets collection
 * @param {string|object} [query] - optional query
 * @param {function} [cb]
 */
DataStore.prototype.search = function (query, options, cb) {
  if (!query || typeof query === 'function') {
    throw new Error('Missing query argument in find request');
  }
  if (typeof options === 'function') {
    cb = options;
    options = query;
  }
  options = options || {};

  if (typeof query === 'string' && query.length > 0) {
    this._request.rawSearch = query;
  }

  if (_.isObject(query)) {
    this._request.search = query;
  }

  this._request.limit = options.limit;
  this._request.offset = options.offset;

  return this.exec(cb);
};

/**
 *
 * @param orderQuery - 'name', 'name asc', {field: -1} === 'field desc'
 */
DataStore.prototype.orderBy = function (orderQuery, cb) {
  var order = {};

  function isOrderDirection(word) {
    return (word === 'asc') || (word === 'desc');
  }

  if (typeof orderQuery === 'string') {
    var words = orderQuery.split(' ');
    for (var i = 0; i < words.length; i++) {
      if (isOrderDirection(words[i])) {
        continue;
      }
      order[words[i]] = ((i + 1) < words.length) && isOrderDirection(words[i + 1]) ?
        words[i + 1] : 'asc';
    }
  }
  if (_.isObject(orderQuery)) {
    _.each(orderQuery, function (val, field) {
      orderQuery[field] = (
        (val === -1) || (val === false) || (val === 'desc')) ? 'desc' : 'asc';
    });
  }

  this._request.order = order;
  return this.exec(cb);
};

/**
 *
 * @param {string|object} expand - 'tenant directory' | {tenant:true} |
 * {tenant: {offset:0, limit:15}}
 * @param {function} cb
 */
DataStore.prototype.expand = function (expand, cb) {
  var exp = {};
  if (typeof expand === 'string') {
    var words = expand.split(' ');
    _.each(words, function (word) {
      exp[word] = true;
    });
  }

  if (_.isObject(expand)) {
    exp = expand;
  }
  this._request.expand = exp;
  return this.exec(cb);
};

// return object, do not bind to collection
DataStore.prototype.lean = function (lean) {
  this._request.lean = lean !== false;
  return this;
};

DataStore.prototype._buildRequestQuery = function(){
  var queryStringObj = {};
  if (this._request.rawSearch) {
    queryStringObj.q = this._request.rawSearch;
  }

  if (this._request.search) {
    _.each(this._request.search, function (val, name) {
      queryStringObj[name] = val;
    });
  }

  if (this._request.limit) {
    queryStringObj.limit = this._request.limit;
  }

  if (this._request.offset) {
    queryStringObj.offset = this._request.offset;
  }

  if (this._request.order) {
    var orderByBuf = [];
    _.each(this._request.order, function(direction, name){
      orderByBuf.push(name + (direction !== 'asc' ? ' desc': ''));
    });
    queryStringObj.orderBy = orderByBuf.join(',');
  }

  if (this._request.expand){
    var expandBuf = [];
    _.each(this._request.expand, function(val, name){
      if (val === true || val === 1){
        return expandBuf.push(name);
      }
      return expandBuf.push(name + '(offset:'+val.offset+',limit:'+val.limit+')');
    });

    queryStringObj.expand = expandBuf.join(',');
  }
  return queryStringObj;
};

/**
 *
 * @param callback
 * @returns {object}
 */
DataStore.prototype.exec = function executeRequest(callback){
  var _this = this;

  if (!callback){
    return _this;
  }

  var qs = _.extend({}, _this._request.query, _this._buildRequestQuery());
  var request = {
    uri: _this._request.href,
    qs: qs
  };

  var ctor = _this._request.InstanceCtor;
  var query = _this._request.query;

  function doRequest(){
    _this.requestExecutor.execute(request, function onGetResourceRequestResult(err, body) {
      if (!err && body) {
        _this.cacheHandler.put(_this._request.href, body, utils.noop);
      }

      _this._wrapGetResourceResponse(err, body, ctor, query, callback);
    });
  }

  if (_this._request.query && Object.keys(_this._request.query).length > 0){
    return doRequest();
  }

  _this.cacheHandler.get(_this._request.href, function onCacheResult(err, entry) {
    if (err || entry) {
      _this._wrapGetResourceResponse(err, entry, ctor, query, callback);
      return;
    }

    //not cached, query the server:
    doRequest();
  });
};

/**
 * Creates a new resource on the server as a child of the specified `parentHref` location (must be a collection resource endpoint).
 *
 * @param {String} parentHref the URI of the parent collection under which the new resource will be created as a child.  This must always be the first argument.
 * @param {Object=undefined} query  name/value pairs to use as query parameters to `parentHref`.
 * @param {Object} data the resource (name/value pairs) to send to the server.
 * @param {Function=InstanceResource} instanceCtor (optional, defaults to ``)  The Constructor function to invoke for any instance resource returned by the server.  If the request result is a single resource, this function is used to construct the resource.  If the request result is a collection, the `instanceCtor` is used to construct each resource in the collection's `items` field.
 * @param {Function} callback the callback function to invoke with the constructed Resource. `callback`'s first argument is an `Error`, the second is the constructed resource. `callback` must always be the last argument.
 * @return {void} no return value; the acquired resource is instead provided to `callback`.
 * @method createResource
 * @class DataStore
 * @api public
 * @version 0.1
 */
DataStore.prototype.createResource = function createResource(/* parentHref, [query], data, [InstanceConstructor], callback */) {

  var _this = this;
  var args = Array.prototype.slice.call(arguments);

  var parentHref = args.shift();
  var callback = args.pop();
  var ctor = (args.length > 0 && (args[args.length -1] instanceof Function)) ? args.pop() : InstanceResource;
  var data = args.pop();
  var query = (args.length > 0) ? args.pop() : null;

  if (!utils.isAssignableFrom(InstanceResource, ctor)) {
    throw new Error("If specifying a constructor function, it must be for class equal to or a subclass of InstanceResource.");
  }

  var request = {uri: parentHref, method: 'POST'};
  if (query) {
    request.query = query;
  }
  if (data) {
    request.body = data;
  }

  _this.requestExecutor.execute(request, function onCreateResourceRequestResult(err, body) {
    if (err) {
      return callback(err, null);
    }

    var returnedResource = instantiate(ctor, body, null, _this);

    //cache for future use:
    _this.cacheHandler.put(body.href, body, utils.noop);

    return callback(null, returnedResource);
  });
};

DataStore.prototype.saveResource = function saveResource(resource, callback) {

  var _this = this;

  var href = utils.valueOf(resource.href);

  var request = {uri: href, method: 'POST', body: resource};

  _this.requestExecutor.execute(request, function onSaveResourceRequestResult(err, body) {
    if (err) {
      return callback(err, null);
    }

    var returnedResource = instantiate(resource.constructor, body, null, _this);

    //cache for future use:
    _this.cacheHandler.put(body.href, body, false, utils.noop);

    return callback(null, returnedResource);
  });
};

DataStore.prototype.deleteResource = function deleteResource(resource, callback) {

  var _this = this;

  var href = utils.valueOf(resource.href);

  //remove from cache:
  _this.cacheHandler.remove(href, utils.noop);

  var request = {uri: href, method: 'DELETE'};

  this.requestExecutor.execute(request, function onDeleteResourceRequestResult(err) {
    if (err) {
      return callback(err, null);
    }
    return callback(null, null); //no body for the callback
  });
};

module.exports = DataStore;<|endoftext|>


<commit_before>import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
import Loadable from 'react-loadable'

import configureStore from 'redux/configureStore'

import './index.css'
import * as serviceWorker from './serviceWorker'

const { store, persistor } = configureStore()

const Load = Loadable({
  loader: () => import('components/App'),
  loading: () => <div />,
})

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <Load />
    </PersistGate>
  </Provider>,
  document.getElementById('root')
)

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
// serviceWorker.unregister()
serviceWorker.register()
<commit_msg>change wait to load App<commit_after>import React from 'react'
import ReactDOM from 'react-dom'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'

import configureStore from 'redux/configureStore'

import './index.css'
import * as serviceWorker from './serviceWorker'
import App from 'components/App'

const { store, persistor } = configureStore()

ReactDOM.render(
  <Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
      <App />
    </PersistGate>
  </Provider>,
  document.getElementById('root')
)

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
// serviceWorker.unregister()
serviceWorker.register()
<|endoftext|>


<commit_before>"use strict";
/*
 * Utility helper functions for the client and server side
 */
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}

define([], function () {

    //return utility functions
    return {
        /*
         * Determines if the app runs in debug or release mode
         */
        DEBUG : false,

        /*
         * Define the server to connect to
         * Value is either IP of the host, or "self" for connecting to the host where the page loaded from
         */
        ServerIP : "self",

        /*
         * Port number of socket.io server
         */
        ServerPort : 8081,

        /*
         * Type of storage used by the server, possible values are:
         * "test" - mean that it will open the test project file and never saves anything to that
         * "mongodirty" - means that it will use the mongo as source of data, but it will simply left out the versioning
         */
        StorageType : "test",

        /*
         * location of the mongoDB server
         */
        MongoDBLocation : 'localhost',
        MongoDBPort : 27017,

        AutoSave : true,
        /*
         * Generated a GUID
         */
        guid: function () {
            var S4 = function () {
                return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
            };

            //return GUID
            return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
        },

        copy: function (object) {
            return JSON.parse(JSON.stringify(object));
        },
        insertIntoArray: function (list, item) {
            if (list instanceof Array) {
                if (list.indexOf(item) === -1) {
                    list.push(item);
                    return true;
                }
                return false;
            }
            return false;
        },
        removeFromArray: function (list, item) {
            var index = list.indexOf(item);
            if (index === -1) {
                return false;
            } else {
                list.splice(index, 1);
                return true;
            }
        },
        mergeArrays: function (one, two) {
            var three = [], i;
            for (i in one) {
                three.push(one[i]);
            }
            for (i in two) {
                if (one.indexOf(two[i]) === -1) {
                    three.push(two[i]);
                }
            }
            return three;
        },
        standalone: {
            ServerIP: "self",
            ServerPort: 8081,
            ProjectIP: "self",
            ProjectPort: 8082,
            ProjectName: "testp",
            BranchName: "basic"
        },
        assert : function (cond) {
            if( !cond ) {
                var error = new Error("ASSERT failed");
                var message = "ASSERT failed at " + error.stack;

                if( console && !process ) {
                    console.log(message);
                }
                throw error;
            }
        },
        timestamp : function(){
            return "" + (new Date()).getTime();
        },
        hashbasedconfig: {
            inuse          : true,
            serverlocation : "http://localhost",
            dataport       : 888,
            rootport       : 999,
            mongosrv       : "http://localhost:8081/data",
            rootsrv        : "http://localhost:8081/root",
            project        : "hash",
            branch         : "test"
        },
        combinedserver: {
            port            : 8081,
            mongosrv        : "/datamongo",
            rootsrv         : "/root",
            logsrv          : "/log",
            mongoip         : "129.59.105.195",
            mongoport       : 27017/*888*/,
            mongocollection : "roby", /*possible collections currently: basic,SFdemo, IFV*/
            mongodatabase   : "demo",
            mongoopt        : {
                'auto_reconnect' : true,
                'poolSize'       : 1
            },
            logging         : false,
            logfile         : "comblog.log",
            cache           : true,
            faulttolerant   : true,
            timelog         : false,
            socketiopar     : {
                'reconnection delay' : 10,
                'max reconnection attempts' : 50
            },
            srvsocketpar    : {
                'heartbeat timeout'  : 240,
                'heartbeat interval' : 60,
                'log level'          : 1
            },

        }

    };
});
<commit_msg>reset default config values<commit_after>"use strict";
/*
 * Utility helper functions for the client and server side
 */
if (typeof define !== 'function') {
    var define = require('amdefine')(module);
}

define([], function () {

    //return utility functions
    return {
        /*
         * Determines if the app runs in debug or release mode
         */
        DEBUG : false,

        /*
         * Define the server to connect to
         * Value is either IP of the host, or "self" for connecting to the host where the page loaded from
         */
        ServerIP : "self",

        /*
         * Port number of socket.io server
         */
        ServerPort : 8081,

        /*
         * Type of storage used by the server, possible values are:
         * "test" - mean that it will open the test project file and never saves anything to that
         * "mongodirty" - means that it will use the mongo as source of data, but it will simply left out the versioning
         */
        StorageType : "test",

        /*
         * location of the mongoDB server
         */
        MongoDBLocation : 'localhost',
        MongoDBPort : 27017,

        AutoSave : true,
        /*
         * Generated a GUID
         */
        guid: function () {
            var S4 = function () {
                return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
            };

            //return GUID
            return (S4() + S4() + "-" + S4() + "-" + S4() + "-" + S4() + "-" + S4() + S4() + S4());
        },

        copy: function (object) {
            return JSON.parse(JSON.stringify(object));
        },
        insertIntoArray: function (list, item) {
            if (list instanceof Array) {
                if (list.indexOf(item) === -1) {
                    list.push(item);
                    return true;
                }
                return false;
            }
            return false;
        },
        removeFromArray: function (list, item) {
            var index = list.indexOf(item);
            if (index === -1) {
                return false;
            } else {
                list.splice(index, 1);
                return true;
            }
        },
        mergeArrays: function (one, two) {
            var three = [], i;
            for (i in one) {
                three.push(one[i]);
            }
            for (i in two) {
                if (one.indexOf(two[i]) === -1) {
                    three.push(two[i]);
                }
            }
            return three;
        },
        standalone: {
            ServerIP: "self",
            ServerPort: 8081,
            ProjectIP: "self",
            ProjectPort: 8082,
            ProjectName: "testp",
            BranchName: "basic"
        },
        assert : function (cond) {
            if( !cond ) {
                var error = new Error("ASSERT failed");
                var message = "ASSERT failed at " + error.stack;

                if( console && !process ) {
                    console.log(message);
                }
                throw error;
            }
        },
        timestamp : function(){
            return "" + (new Date()).getTime();
        },
        hashbasedconfig: {
            inuse          : true,
            serverlocation : "http://localhost",
            dataport       : 888,
            rootport       : 999,
            mongosrv       : "http://localhost:8081/data",
            rootsrv        : "http://localhost:8081/root",
            project        : "hash",
            branch         : "test"
        },
        combinedserver: {
            port            : 80,
            mongosrv        : "/datamongo",
            rootsrv         : "/root",
            logsrv          : "/log",
            mongoip         : "129.59.105.195",
            mongoport       : 27017/*888*/,
            mongocollection : "IFV", /*possible collections currently: basic,SFdemo, IFV*/
            mongodatabase   : "demo",
            mongoopt        : {
                'auto_reconnect' : true,
                'poolSize'       : 1
            },
            logging         : false,
            logfile         : "comblog.log",
            cache           : true,
            faulttolerant   : true,
            timelog         : false,
            socketiopar     : {
                'reconnection delay' : 10,
                'max reconnection attempts' : 50
            },
            srvsocketpar    : {
                'heartbeat timeout'  : 240,
                'heartbeat interval' : 60,
                'log level'          : 1
            },

        }

    };
});
<|endoftext|>


<commit_before>/**
 * Shopware 4
 * Copyright © shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */
/**
 * Shopware SwagConnect Plugin
 *
 * @category Shopware
 * @package Shopware\Plugins\SwagConnect
 * @copyright Copyright (c) shopware AG (http://www.shopware.de)
 */
//{namespace name=backend/connect/view/main}
//{block name="backend/connect/view/config/import/form"}
Ext.define('Shopware.apps.Connect.view.config.import.Form', {
    extend: 'Ext.form.Panel',
    alias: 'widget.connect-config-import-form',

    border: false,
    layout: 'anchor',
    autoScroll: true,
    region: 'center',
    bodyPadding: 10,

    /**
     * Contains the field set defaults.
     */
    defaults: {
        labelWidth: 170,
        anchor: '100%'
    },

    snippets: {
        save: '{s name=config/save}Save{/s}',
        cancel: '{s name=config/cancel}Cancel{/s}',
        importPicturesLabel: '{s name=config/import/pictures_label}Load product images during first import{/s}',
        importPicturesHelp: '{s name=config/import/pictures_help}Der Import von Bildern kann den Import verlangsamen. Wenn Sie viele Produkte importieren möchten, sollten Sie diese Option nicht aktivieren und die Bilder über den CronJob oder »Geänderte Produkte« importieren.{/s}',
        overwritePropertiesLabel: '{s name=config/import/overwrite_properties}Folgende Felder beim Produkt-Aktualisierung überschreiben{/s}',
        overwritePropertiesHelp: '{s name=config/import/overwrite_properties_help}Die hier ausgewählten Felder werden automatisch überschrieben, wenn der Quellshop diese ändert. Sie können auf Artikel-Ebene Ausnahmen definieren.{/s}',
        overwriteProductName: '{s name=config/import/overwrite_product_name}Product name{/s}',
        overwriteProductPrice: '{s name=config/import/overwrite_product_price}Price{/s}',
        overwriteProductImages: '{s name=config/import/overwrite_product_images}Image{/s}',
        overwriteProductShortDescription: '{s name=config/import/overwrite_product_short_description}Short description{/s}',
        overwriteProductLongDescription: '{s name=config/import/overwrite_product_long_description}Long description{/s}',
        articleImagesLimitImportLabel: '{s name=config/import/pictures_limit_label}Number of products per image import pass{/s}',
        productImportSettingsTitle: '{s name=config/import/product_import_settings_title}Produktbeschreibungen{/s}',
        productImportImageSettingsTitle: '{s name=config/import/image_settings_title}Produktbilder{/s}',
        productImportUnitsTitle: '{s name=config/import/units_title}Maßeinheiten{/s}',
        hideAssignedUnitsLabel: '{s name=config/import/hide_assigned_units}zugewiesene Maßeinheiten ausblenden{/s}',
        takeOverUnits: '{s name=config/import/take_over_units}Maßeinheiten übernehmen{/s}',
        takeOverUnitsTooltip: '{s name=config/import/take_over_units_tooltip}Übernehmen nicht zugeordnete Masseinheiten in ihren Shop{/s}'
    },

    initComponent: function() {
        var me = this;

        me.items = me.createElements();
        me.dockedItems = [{
            xtype: 'toolbar',
            dock: 'bottom',
            ui: 'shopware-ui',
            cls: 'shopware-toolbar',
            items: me.getFormButtons()
        }];

        me.importConfigStore = Ext.create('Shopware.apps.Connect.store.config.Import').load({
            callback: function() {
                me.populateForm();
            }
        });

        me.callParent(arguments);
    },

    /**
     * Creates form elements
     * @return Array
     */
    createElements: function() {

        var me = this,
            configFieldset = me.getConfigFieldset(),
            elements = [];

        elements.push(configFieldset);

        return elements;
    },

    /**
     * Returns form buttons, save and cancel
     * @returns Array
     */
    getFormButtons: function() {
        var me = this,
            buttons = ['->'];

        var saveButton = Ext.create('Ext.button.Button', {
            text: me.snippets.save,
            action:'save-import-config',
            cls:'primary'
        });

        var cancelButton = Ext.create('Ext.button.Button', {
            text: me.snippets.cancel,
            handler: function(btn) {
                btn.up('window').close();
            }
        });

        buttons.push(cancelButton);
        buttons.push(saveButton);

        return buttons;
    },

    /**
     * Creates the field set
     * @return Ext.form.FieldSet
     */
    getConfigFieldset: function() {
        var me = this,
            items = [],
            elements = me.createElements();

        items.push(elements);

        var fieldset = Ext.create('Ext.form.FieldSet', {
            layout: 'column',
            border: false,
            items: items
        });

        return fieldset;
    },

    /**
     * Creates the field set items
     * @return Array
     */
    createElements: function () {
        var me = this;

        var categoriesStore = Ext.create('Shopware.apps.Base.store.CategoryTree');
        categoriesStore.load();

        me.imageLimitImportField = Ext.create('Ext.form.field.Number', {
            name: 'articleImagesLimitImport',
            fieldLabel: me.snippets.articleImagesLimitImportLabel,
            labelWidth: me.defaults.labelWidth
        });

        var container = Ext.create('Ext.container.Container', {
            padding: '0 20 0 0',
            flex: 1,
            layout: 'vbox',
            border: false,
            items: [
                {
                    xtype: 'container',
                    html: '
' + me.snippets.productImportSettingsTitle  + '
',
                    width: 400,
                    height: 30
                },
                {
                    xtype      : 'fieldcontainer',
                    fieldLabel : me.snippets.overwritePropertiesLabel,
                    defaultType: 'checkboxfield',
                    labelWidth: me.defaults.labelWidth,
                    items: [
                        {
                            boxLabel  : me.snippets.overwriteProductName,
                            name      : 'overwriteProductName',
                            inputValue: 1,
                            helpText: me.snippets.overwritePropertiesHelp,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductPrice,
                            name      : 'overwriteProductPrice',
                            inputValue: 1,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductImages,
                            name      : 'overwriteProductImage',
                            inputValue: 1,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductShortDescription,
                            name      : 'overwriteProductShortDescription',
                            inputValue: 1,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductLongDescription,
                            name      : 'overwriteProductLongDescription',
                            inputValue: 1,
                            uncheckedValue: 0
                        }
                    ]
                },
                {
                    xtype: 'container',
                    html: '
' + me.snippets.productImportImageSettingsTitle  + '
',
                    width: 400,
                    height: 30
                },
                {
                    xtype      : 'fieldcontainer',
                    defaultType: 'checkboxfield',
                    margin: '0 0 0 50',
                    labelWidth: me.defaults.labelWidth,
                    items: [
                        {
                            xtype: 'checkbox',
                            name: 'importImagesOnFirstImport',
                            fieldLabel: me.snippets.importPicturesLabel,
                            helpText: me.snippets.importPicturesHelp,
                            inputValue: 1,
                            uncheckedValue: 0,
                            labelWidth: me.defaults.labelWidth,
                            listeners:{
                                change: function(checkbox, newValue, oldValue, opts){
                                    me.enableImageImportLimit(checkbox);
                                },
                                beforeRender: function(checkbox, opts) {
                                    me.enableImageImportLimit(checkbox);
                                }
                            }
                        }, me.imageLimitImportField
                    ]
                },
                {
                    xtype: 'container',
                    html: '
' + me.snippets.productImportUnitsTitle  + '
',
                    margin: '20px 0 0 0',
                    width: 400,
                    height: 30
                },
                Ext.create('Shopware.apps.Connect.view.config.import.UnitsMapping'),
                {
                    xtype: 'checkbox',
                    name: 'hideAssignedUnits',
                    boxLabel: me.snippets.hideAssignedUnitsLabel,
                    labelWidth: me.defaults.labelWidth
                },
                {
                    xtype: 'button',
                    text: me.snippets.takeOverUnits,
                    action: 'adoptUnits',
                    tooltip: me.snippets.takeOverUnitsTooltip
                }
            ]
        });

        return [ container ];
    },

    /**
     * Populate import config form
     */
    populateForm: function() {
        var me = this,
            record = me.importConfigStore.getAt(0);

        if (!record) {
            record = Ext.create('Shopware.apps.Connect.model.config.Import');
        }
        me.loadRecord(record);
    },

    /**
     * Enable / disable number of products which are proceed
     * by images cron at the same time.
     * It depends on import images on first import of products
     *
     * @param checkbox
     */
    enableImageImportLimit: function(checkbox) {
        var me = this;

        me.imageLimitImportField.setDisabled(checkbox.getValue());
    }
});
//{/block}

<commit_msg>CON-2449 Replaced text input with combobox<commit_after>/**
 * Shopware 4
 * Copyright © shopware AG
 *
 * According to our dual licensing model, this program can be used either
 * under the terms of the GNU Affero General Public License, version 3,
 * or under a proprietary license.
 *
 * The texts of the GNU Affero General Public License with an additional
 * permission and of our proprietary license can be found at and
 * in the LICENSE file you have received along with this program.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * "Shopware" is a registered trademark of shopware AG.
 * The licensing of the program under the AGPLv3 does not imply a
 * trademark license. Therefore any rights, title and interest in
 * our trademarks remain entirely with us.
 */
/**
 * Shopware SwagConnect Plugin
 *
 * @category Shopware
 * @package Shopware\Plugins\SwagConnect
 * @copyright Copyright (c) shopware AG (http://www.shopware.de)
 */
//{namespace name=backend/connect/view/main}
//{block name="backend/connect/view/config/import/form"}
Ext.define('Shopware.apps.Connect.view.config.import.Form', {
    extend: 'Ext.form.Panel',
    alias: 'widget.connect-config-import-form',

    border: false,
    layout: 'anchor',
    autoScroll: true,
    region: 'center',
    bodyPadding: 10,

    /**
     * Contains the field set defaults.
     */
    defaults: {
        labelWidth: 170,
        anchor: '100%'
    },

    snippets: {
        save: '{s name=config/save}Save{/s}',
        cancel: '{s name=config/cancel}Cancel{/s}',
        importPicturesLabel: '{s name=config/import/pictures_label}Load product images during first import{/s}',
        importPicturesHelp: '{s name=config/import/pictures_help}Der Import von Bildern kann den Import verlangsamen. Wenn Sie viele Produkte importieren möchten, sollten Sie diese Option nicht aktivieren und die Bilder über den CronJob oder »Geänderte Produkte« importieren.{/s}',
        overwritePropertiesLabel: '{s name=config/import/overwrite_properties}Folgende Felder beim Produkt-Aktualisierung überschreiben{/s}',
        overwritePropertiesHelp: '{s name=config/import/overwrite_properties_help}Die hier ausgewählten Felder werden automatisch überschrieben, wenn der Quellshop diese ändert. Sie können auf Artikel-Ebene Ausnahmen definieren.{/s}',
        overwriteProductName: '{s name=config/import/overwrite_product_name}Product name{/s}',
        overwriteProductPrice: '{s name=config/import/overwrite_product_price}Price{/s}',
        overwriteProductImages: '{s name=config/import/overwrite_product_images}Image{/s}',
        overwriteProductShortDescription: '{s name=config/import/overwrite_product_short_description}Short description{/s}',
        overwriteProductLongDescription: '{s name=config/import/overwrite_product_long_description}Long description{/s}',
        articleImagesLimitImportLabel: '{s name=config/import/pictures_limit_label}Number of products per image import pass{/s}',
        productImportSettingsTitle: '{s name=config/import/product_import_settings_title}Produktbeschreibungen{/s}',
        productImportImageSettingsTitle: '{s name=config/import/image_settings_title}Produktbilder{/s}',
        productImportUnitsTitle: '{s name=config/import/units_title}Maßeinheiten{/s}',
        hideAssignedUnitsLabel: '{s name=config/import/hide_assigned_units}zugewiesene Maßeinheiten ausblenden{/s}',
        takeOverUnits: '{s name=config/import/take_over_units}Maßeinheiten übernehmen{/s}',
        takeOverUnitsTooltip: '{s name=config/import/take_over_units_tooltip}Übernehmen nicht zugeordnete Masseinheiten in ihren Shop{/s}'
    },

    initComponent: function() {
        var me = this;

        me.items = me.createElements();
        me.dockedItems = [{
            xtype: 'toolbar',
            dock: 'bottom',
            ui: 'shopware-ui',
            cls: 'shopware-toolbar',
            items: me.getFormButtons()
        }];

        me.importConfigStore = Ext.create('Shopware.apps.Connect.store.config.Import').load({
            callback: function() {
                me.populateForm();
            }
        });

        me.callParent(arguments);
    },

    /**
     * Creates form elements
     * @return Array
     */
    createElements: function() {

        var me = this,
            configFieldset = me.getConfigFieldset(),
            elements = [];

        elements.push(configFieldset);

        return elements;
    },

    /**
     * Returns form buttons, save and cancel
     * @returns Array
     */
    getFormButtons: function() {
        var me = this,
            buttons = ['->'];

        var saveButton = Ext.create('Ext.button.Button', {
            text: me.snippets.save,
            action:'save-import-config',
            cls:'primary'
        });

        var cancelButton = Ext.create('Ext.button.Button', {
            text: me.snippets.cancel,
            handler: function(btn) {
                btn.up('window').close();
            }
        });

        buttons.push(cancelButton);
        buttons.push(saveButton);

        return buttons;
    },

    /**
     * Creates the field set
     * @return Ext.form.FieldSet
     */
    getConfigFieldset: function() {
        var me = this,
            items = [],
            elements = me.createElements();

        items.push(elements);

        var fieldset = Ext.create('Ext.form.FieldSet', {
            layout: 'column',
            border: false,
            items: items
        });

        return fieldset;
    },

    /**
     * Creates the field set items
     * @return Array
     */
    createElements: function () {
        var me = this;

        var categoriesStore = Ext.create('Shopware.apps.Base.store.CategoryTree');
        categoriesStore.load();

        var numStore = Ext.create('Ext.data.Store', {
            fields: ['name', 'value'],
            data : [
                { name: '5', value: '5' },
                { name: '25', value: '25' },
                { name: '50', value: '50' },
                { name: '100', value: '100' },
                { name: '150', value: '150' }
            ]
        });

        me.imageLimitImportField = Ext.create('Ext.form.field.ComboBox', {
            name: 'articleImagesLimitImport',
            fieldLabel: me.snippets.articleImagesLimitImportLabel,
            labelWidth: me.defaults.labelWidth,
            editable: false,
            valueField: 'value',
            displayField: 'name',
            store: numStore
        });

        var container = Ext.create('Ext.container.Container', {
            padding: '0 20 0 0',
            flex: 1,
            layout: 'vbox',
            border: false,
            items: [
                {
                    xtype: 'container',
                    html: '
' + me.snippets.productImportSettingsTitle  + '
',
                    width: 400,
                    height: 30
                },
                {
                    xtype      : 'fieldcontainer',
                    fieldLabel : me.snippets.overwritePropertiesLabel,
                    defaultType: 'checkboxfield',
                    labelWidth: me.defaults.labelWidth,
                    items: [
                        {
                            boxLabel  : me.snippets.overwriteProductName,
                            name      : 'overwriteProductName',
                            inputValue: 1,
                            helpText: me.snippets.overwritePropertiesHelp,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductPrice,
                            name      : 'overwriteProductPrice',
                            inputValue: 1,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductImages,
                            name      : 'overwriteProductImage',
                            inputValue: 1,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductShortDescription,
                            name      : 'overwriteProductShortDescription',
                            inputValue: 1,
                            uncheckedValue: 0
                        }, {
                            boxLabel  : me.snippets.overwriteProductLongDescription,
                            name      : 'overwriteProductLongDescription',
                            inputValue: 1,
                            uncheckedValue: 0
                        }
                    ]
                },
                {
                    xtype: 'container',
                    html: '
' + me.snippets.productImportImageSettingsTitle  + '
',
                    width: 400,
                    height: 30
                },
                {
                    xtype      : 'fieldcontainer',
                    defaultType: 'checkboxfield',
                    margin: '0 0 0 50',
                    labelWidth: me.defaults.labelWidth,
                    items: [
                        {
                            xtype: 'checkbox',
                            name: 'importImagesOnFirstImport',
                            fieldLabel: me.snippets.importPicturesLabel,
                            helpText: me.snippets.importPicturesHelp,
                            inputValue: 1,
                            uncheckedValue: 0,
                            labelWidth: me.defaults.labelWidth,
                            listeners:{
                                change: function(checkbox, newValue, oldValue, opts){
                                    me.enableImageImportLimit(checkbox);
                                },
                                beforeRender: function(checkbox, opts) {
                                    me.enableImageImportLimit(checkbox);
                                }
                            }
                        }, me.imageLimitImportField
                    ]
                },
                {
                    xtype: 'container',
                    html: '
' + me.snippets.productImportUnitsTitle  + '
',
                    margin: '20px 0 0 0',
                    width: 400,
                    height: 30
                },
                Ext.create('Shopware.apps.Connect.view.config.import.UnitsMapping'),
                {
                    xtype: 'checkbox',
                    name: 'hideAssignedUnits',
                    boxLabel: me.snippets.hideAssignedUnitsLabel,
                    labelWidth: me.defaults.labelWidth
                },
                {
                    xtype: 'button',
                    text: me.snippets.takeOverUnits,
                    action: 'adoptUnits',
                    tooltip: me.snippets.takeOverUnitsTooltip
                }
            ]
        });

        return [ container ];
    },

    /**
     * Populate import config form
     */
    populateForm: function() {
        var me = this,
            record = me.importConfigStore.getAt(0);

        if (!record) {
            record = Ext.create('Shopware.apps.Connect.model.config.Import');
        }
        me.loadRecord(record);
    },

    /**
     * Enable / disable number of products which are proceed
     * by images cron at the same time.
     * It depends on import images on first import of products
     *
     * @param checkbox
     */
    enableImageImportLimit: function(checkbox) {
        var me = this;

        me.imageLimitImportField.setDisabled(checkbox.getValue());
    }
});
//{/block}

<|endoftext|>


<commit_before>/**
  * LzKeyboardKernel.js
  *
  * @copyright Copyright 2007,2008 Laszlo Systems, Inc.  All Rights Reserved.
  *            Use is subject to license terms.
  *
  * @topic Kernel
  * @subtopic DHTML
  * @author Max Carlson <max@openlaszlo.org>
  */

// Receives keyboard events from the runtime
var LzKeyboardKernel = {
    __downKeysHash: {alt: false, control: false, shift: false}
    ,__keyboardEvent: function ( e ){
        if (!e) e = window.event;
        var delta = {};
        var dirty = false;
        var k = e['keyCode'];
        var t = e.type;
        var dh = LzKeyboardKernel.__downKeysHash;
        // TODO: really, all control characters should be skipped...
        // skip shift, ctrl, option keys to prevent duplicate sending - see LPP-4267
        if (k >= 0 && k != 16 && k != 17 && k != 18) {
            // TODO: add mapping to flash character codes?
            var s = String.fromCharCode(k).toLowerCase();
            if (t == 'keyup') {
                if (dh[s] != false) {
                    delta[s] = false;
                    dirty = true;
                }
                dh[s] = false;
            } else if (t == 'keydown') {
                if (dh[s] != true) {
                    delta[s] = true;
                    dirty = true;
                }
                dh[s] = true;
            }
        }
        if (dh['alt'] != e['altKey']) {
            delta['alt'] = e['altKey'];
            dirty = true;
            if (LzSprite.prototype.quirks['alt_key_sends_control']) {
                delta['control'] = delta['alt'];
            }
        }
        if (dh['control'] != e['ctrlKey']) {
            delta['control'] = e['ctrlKey'];
            dirty = true;
        }
        if (dh['shift'] != e['shiftKey']) {
            delta['shift'] = e['shiftKey'];
            dirty = true;
        }

        dh['alt'] = e['altKey']
        dh['control'] = e['ctrlKey']
        dh['shift'] = e['shiftKey']
        if (dirty && LzKeyboardKernel.__scope && LzKeyboardKernel.__scope[LzKeyboardKernel.__callback]) {
            LzKeyboardKernel.__scope[LzKeyboardKernel.__callback](delta, k, 'on' + t);
        }

        // cancel bubbling
        if (k >= 0) {
            if (k == 9) {
                //Debug.write('canceling tab');
                e.cancelBubble = true;
                e.returnValue = false;
                return false;
            } else if (LzKeyboardKernel.__cancelKeys && (k == 13 || k == 0 || k == 37 || k == 38 || k == 39 || k == 40) ) {
                //Debug.write('canceling key', k, t);
                // cancel event bubbling for enter, space(scroll) and arrow keys
                e.cancelBubble = true;
                e.returnValue = false;
                return false;
            }
        }
        //Debug.write('downKeysHash', t, k, dh, delta);
    }

    ,__callback: null
    ,__scope: null
    ,__cancelKeys: true
    ,setCallback: function (scope, keyboardcallback) {
        this.__scope = scope;
        this.__callback = keyboardcallback;
        this.setKeyboardControl(true);
    }
    ,setKeyboardControl: function (dhtmlKeyboardControl) {
        var kc = null;
        var ck = (lz && lz.embed && lz.embed.options && lz.embed.options.cancelkeyboardcontrol != true) || true;
        if (ck && dhtmlKeyboardControl) {
            //console.log('setKeyboardControl' + dhtmlKeyboardControl);
            kc = LzKeyboardKernel.__keyboardEvent;
        }
        // can't use lz.embed.attachEventHandler because we need to cancel events selectively
        if (LzSprite.prototype.quirks.keyboardlistentotop) {
            var doc = window.top.document;
        } else {
            var doc = document;
        }
        doc.onkeydown = kc;
        doc.onkeyup = kc;
        doc.onkeypress = kc;
    }
    // Called by lz.Keys when the last focusable element was reached.
    ,gotLastFocus: function () {
        //console.log('gotLastFocus', canvas.sprite.__LZdiv.mouseisover);
        if (! canvas.sprite.__LZdiv.mouseisover) LzKeyboardKernel.setKeyboardControl(false);
    }
}
<commit_msg>Change 20080616-maxcarlson-R by maxcarlson@Roboto on 2008-06-16 15:27:14 PDT     in /Users/maxcarlson/openlaszlo/trunk-clean     for http://svn.openlaszlo.org/openlaszlo/trunk<commit_after>/**
  * LzKeyboardKernel.js
  *
  * @copyright Copyright 2007,2008 Laszlo Systems, Inc.  All Rights Reserved.
  *            Use is subject to license terms.
  *
  * @topic Kernel
  * @subtopic DHTML
  * @author Max Carlson <max@openlaszlo.org>
  */

// Receives keyboard events from the runtime
var LzKeyboardKernel = {
    __downKeysHash: {alt: false, control: false, shift: false}
    ,__keyboardEvent: function ( e ){
        if (!e) e = window.event;
        var delta = {};
        var dirty = false;
        var k = e['keyCode'];
        var t = e.type;
        var dh = LzKeyboardKernel.__downKeysHash;
        // TODO: really, all control characters should be skipped...
        // skip shift, ctrl, option keys to prevent duplicate sending - see LPP-4267
        if (k >= 0 && k != 16 && k != 17 && k != 18) {
            // TODO: add mapping to flash character codes?
            var s = String.fromCharCode(k).toLowerCase();
            if (t == 'keyup') {
                if (dh[s] != false) {
                    delta[s] = false;
                    dirty = true;
                }
                dh[s] = false;
            } else if (t == 'keydown') {
                if (dh[s] != true) {
                    delta[s] = true;
                    dirty = true;
                }
                dh[s] = true;
            }
        }
        if (dh['alt'] != e['altKey']) {
            delta['alt'] = e['altKey'];
            dirty = true;
            if (LzSprite.prototype.quirks['alt_key_sends_control']) {
                delta['control'] = delta['alt'];
            }
        }
        if (dh['control'] != e['ctrlKey']) {
            delta['control'] = e['ctrlKey'];
            dirty = true;
        }
        if (dh['shift'] != e['shiftKey']) {
            delta['shift'] = e['shiftKey'];
            dirty = true;
        }

        dh['alt'] = e['altKey']
        dh['control'] = e['ctrlKey']
        dh['shift'] = e['shiftKey']
        if (dirty && LzKeyboardKernel.__scope && LzKeyboardKernel.__scope[LzKeyboardKernel.__callback]) {
            LzKeyboardKernel.__scope[LzKeyboardKernel.__callback](delta, k, 'on' + t);
        }

        // cancel bubbling
        if (k >= 0) {
            if (k == 9) {
                //Debug.write('canceling tab');
                e.cancelBubble = true;
                e.returnValue = false;
                return false;
            } else if (LzKeyboardKernel.__cancelKeys && (k == 13 || k == 0 || k == 37 || k == 38 || k == 39 || k == 40) ) {
                //Debug.write('canceling key', k, t);
                // cancel event bubbling for enter, space(scroll) and arrow keys
                e.cancelBubble = true;
                e.returnValue = false;
                return false;
            }
        }
        //Debug.write('downKeysHash', t, k, dh, delta);
    }

    ,__callback: null
    ,__scope: null
    ,__cancelKeys: true
    ,setCallback: function (scope, keyboardcallback) {
        this.__scope = scope;
        this.__callback = keyboardcallback;
        this.setKeyboardControl(true);
    }
    ,setKeyboardControl: function (dhtmlKeyboardControl) {
        var handler = null;
        var setcontrol = (lz && lz.embed && lz.embed.options && lz.embed.options.cancelkeyboardcontrol != true) || true;
        if (setcontrol && dhtmlKeyboardControl) {
            //console.log('setKeyboardControl' + dhtmlKeyboardControl);
            handler = LzKeyboardKernel.__keyboardEvent;
        }
        if ( LzInputTextSprite.prototype.__focusedSprite ) {
            // hide any focused inputtexts
            LzInputTextSprite.prototype.__focusedSprite.__hide();
        }
        // can't use lz.embed.attachEventHandler because we need to cancel events selectively
        if (LzSprite.prototype.quirks.keyboardlistentotop) {
            var doc = window.top.document;
        } else {
            var doc = document;
        }
        doc.onkeydown = handler;
        doc.onkeyup = handler;
        doc.onkeypress = handler;
    }
    // Called by lz.Keys when the last focusable element was reached.
    ,gotLastFocus: function () {
        //console.log('gotLastFocus', canvas.sprite.__LZdiv.mouseisover);
        if (! canvas.sprite.__LZdiv.mouseisover) LzKeyboardKernel.setKeyboardControl(false);
    }
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('mano').i18n.bind('Official: Revision: Notifications');

module.exports = function (stepName) {
	var businessProcessInstances = require('mano').db.BusinessProcess.instances
		.filterByKey('isFromEregistrations', true)
	  , notification = {};

	stepName = stepName || 'revision';

	notification.trigger = businessProcessInstances
		.filterByKeyPath('processingSteps/map/' + stepName + '/isSentBack', true);
	notification.preTrigger = businessProcessInstances
		.filterByKeyPath('processingSteps/map/' + stepName + '/isReady', true);

	notification.subject = _("M05 You must correct some elements in your application");
	notification.text = _("Email message greeting ${ fullName }\n\n")
		+ _("M05 Revision sent back\n\n"
			+ "Name of company: ${ businessName }\n\n"
			+ "${ rejectedUploads }\n\n")
		+ _("Email message signature") + "\n";

	notification.resolveGetters = true;

	notification.variables = {
		fullName: function () {
			return this.businessProcess.user.fullName;
		},
		businessName: function () {
			return this.businessProcess.businessName;
		},
		rejectedUploads: function () {
			var paymentReceiptUploads = this.paymentReceiptUploads
			  , requirementUploads    = this.requirementUploads
			  , result                = [];

			if (requirementUploads.rejected.size) {
				result.push(_("Issues with uploaded documents:"));
				requirementUploads.rejected.forEach(function (requirementUpload) {
					result.push("- " + requirementUpload.document.label);
					if (requirementUpload.rejectReasons.size > 1) {
						requirementUpload.rejectReasons.forEach(function (reason) {
							result.push("    - " + reason);
						});
					} else {
						result.push("    " + requirementUpload.rejectReasons.first);
					}
				});
			}
			if (paymentReceiptUploads.rejected.size) {
				result.push(_("Issues with uploaded payment receipts:"));
				paymentReceiptUploads.rejected.forEach(function (paymentReceiptUpload) {
					result.push("- " + paymentReceiptUpload.document.label);
					result.push("    " + paymentReceiptUpload.rejectReasonMemo);
				});
			}
			return result.join('\n');
		}
	};

	return notification;
};
<commit_msg>Issue #1042. Fixed problem with revision sent back notification.<commit_after>'use strict';

var _ = require('mano').i18n.bind('Official: Revision: Notifications');

module.exports = function (stepName) {
	var businessProcessInstances = require('mano').db.BusinessProcess.instances
		.filterByKey('isFromEregistrations', true)
	  , notification = {};

	stepName = stepName || 'revision';

	notification.trigger = businessProcessInstances
		.filterByKeyPath('processingSteps/map/' + stepName + '/isSentBack', true);
	notification.preTrigger = businessProcessInstances
		.filterByKeyPath('processingSteps/map/' + stepName + '/isReady', true);

	notification.subject = _("M05 You must correct some elements in your application");
	notification.text = _("Email message greeting ${ fullName }\n\n")
		+ _("M05 Revision sent back\n\n"
			+ "Name of company: ${ businessName }\n\n"
			+ "${ rejectedUploads }\n\n")
		+ _("Email message signature") + "\n";

	notification.resolveGetters = true;

	notification.variables = {
		fullName: function () {
			return this.businessProcess.user.fullName;
		},
		businessName: function () {
			return this.businessProcess.businessName;
		},
		rejectedUploads: function () {
			var processingStep        = this.businessProcess.processingSteps.map[stepName]
			  , paymentReceiptUploads = processingStep.paymentReceiptUploads
			  , requirementUploads    = processingStep.requirementUploads
			  , result                = [];

			if (requirementUploads.rejected.size) {
				result.push(_("Issues with uploaded documents:"));
				requirementUploads.rejected.forEach(function (requirementUpload) {
					result.push("- " + requirementUpload.document.label);
					if (requirementUpload.rejectReasons.size > 1) {
						requirementUpload.rejectReasons.forEach(function (reason) {
							result.push("    - " + reason);
						});
					} else {
						result.push("    " + requirementUpload.rejectReasons.first);
					}
				});
			}
			if (paymentReceiptUploads.rejected.size) {
				result.push(_("Issues with uploaded payment receipts:"));
				paymentReceiptUploads.rejected.forEach(function (paymentReceiptUpload) {
					result.push("- " + paymentReceiptUpload.document.label);
					result.push("    " + paymentReceiptUpload.rejectReasonMemo);
				});
			}
			return result.join('\n');
		}
	};

	return notification;
};
<|endoftext|>