<commit_before>// ==========================================================================
// Project:  Ember Runtime
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================

// NOTE: this object should never be included directly.  Instead use Ember.
// Ember.Object.  We only define this separately so that Ember.Set can depend on it

var rewatch = Ember.rewatch;
var classToString = Ember.Mixin.prototype.toString;
var set = Ember.set, get = Ember.get;
var o_create = Ember.platform.create,
    o_defineProperty = Ember.platform.defineProperty,
    meta = Ember.meta;

/** @private */
function makeCtor() {

  // Note: avoid accessing any properties on the object since it makes the
  // method a lot faster.  This is glue code so we want it to be as fast as
  // possible.

  var wasApplied = false, initMixins, init = false, hasChains = false;

  var Class = function() {
    if (!wasApplied) { Class.proto(); } // prepare prototype...
    if (initMixins) {
      this.reopen.apply(this, initMixins);
      initMixins = null;
      rewatch(this); // ålways rewatch just in case
      this.init.apply(this, arguments);
    } else {
      if (hasChains) {
        rewatch(this);
      } else {
        Ember.GUID_DESC.value = undefined;
        o_defineProperty(this, Ember.GUID_KEY, Ember.GUID_DESC);
      }
      if (init===false) { init = this.init; } // cache for later instantiations
      Ember.GUID_DESC.value = undefined;
      o_defineProperty(this, '_super', Ember.GUID_DESC);
      init.apply(this, arguments);
    }
  };

  Class.toString = classToString;
  Class.willReopen = function() {
    if (wasApplied) {
      Class.PrototypeMixin = Ember.Mixin.create(Class.PrototypeMixin);
    }

    wasApplied = false;
  };
  Class._initMixins = function(args) { initMixins = args; };

  Class.proto = function() {
    var superclass = Class.superclass;
    if (superclass) { superclass.proto(); }

    if (!wasApplied) {
      wasApplied = true;
      Class.PrototypeMixin.applyPartial(Class.prototype);
      hasChains = !!meta(Class.prototype, false).chains; // avoid rewatch
    }

    return this.prototype;
  };

  return Class;

}

var CoreObject = makeCtor();

CoreObject.PrototypeMixin = Ember.Mixin.create(
/** @scope Ember.CoreObject */ {

  reopen: function() {
    Ember.Mixin._apply(this, arguments, true);
    return this;
  },

  isInstance: true,

  init: function() {},

  isDestroyed: false,

  /**
    Destroys an object by setting the isDestroyed flag and removing its
    metadata, which effectively destroys observers and bindings.

    If you try to set a property on a destroyed object, an exception will be
    raised.

    Note that destruction is scheduled for the end of the run loop and does not
    happen immediately.

    @returns {Ember.Object} receiver
  */
  destroy: function() {
    set(this, 'isDestroyed', true);
    Ember.run.schedule('destroy', this, this._scheduledDestroy);
    return this;
  },

  /**
    Invoked by the run loop to actually destroy the object. This is
    scheduled for execution by the `destroy` method.

    @private
  */
  _scheduledDestroy: function() {
    Ember.destroy(this);
  },

  bind: function(to, from) {
    if (!(from instanceof Ember.Binding)) { from = Ember.Binding.from(from); }
    from.to(to).connect(this);
    return from;
  },

  toString: function() {
    return '<'+this.constructor.toString()+':'+Ember.guidFor(this)+'>';
  }
});

CoreObject.__super__ = null;

var ClassMixin = Ember.Mixin.create({

  ClassMixin: Ember.required(),

  PrototypeMixin: Ember.required(),

  isClass: true,

  isMethod: false,

  extend: function() {
    var Class = makeCtor(), proto;
    Class.ClassMixin = Ember.Mixin.create(this.ClassMixin);
    Class.PrototypeMixin = Ember.Mixin.create(this.PrototypeMixin);

    Class.ClassMixin.ownerConstructor = Class;
    Class.PrototypeMixin.ownerConstructor = Class;

    var PrototypeMixin = Class.PrototypeMixin;
    PrototypeMixin.reopen.apply(PrototypeMixin, arguments);

    Class.superclass = this;
    Class.__super__  = this.prototype;

    proto = Class.prototype = o_create(this.prototype);
    proto.constructor = Class;
    Ember.generateGuid(proto, 'ember');
    meta(proto).proto = proto; // this will disable observers on prototype
    Ember.rewatch(proto); // setup watch chains if needed.

    Class.subclasses = Ember.Set ? new Ember.Set() : null;
    if (this.subclasses) { this.subclasses.add(Class); }

    Class.ClassMixin.apply(Class);
    return Class;
  },

  create: function() {
    var C = this;
    if (arguments.length>0) { this._initMixins(arguments); }
    return new C();
  },

  reopen: function() {
    this.willReopen();
    var PrototypeMixin = this.PrototypeMixin;
    PrototypeMixin.reopen.apply(PrototypeMixin, arguments);
    return this;
  },

  reopenClass: function() {
    var ClassMixin = this.ClassMixin;
    ClassMixin.reopen.apply(ClassMixin, arguments);
    Ember.Mixin._apply(this, arguments, false);
    return this;
  },

  detect: function(obj) {
    if ('function' !== typeof obj) { return false; }
    while(obj) {
      if (obj===this) { return true; }
      obj = obj.superclass;
    }
    return false;
  },

  detectInstance: function(obj) {
    return obj instanceof this;
  },

  /**
    In some cases, you may want to annotate computed properties with additional
    metadata about how they function or what values they operate on. For example,
    computed property functions may close over variables that are then no longer
    available for introspection.

    You can pass a hash of these values to a computed property like this:

        person: function() {
          var personId = this.get('personId');
          return App.Person.create({ id: personId });
        }.property().meta({ type: App.Person })

    Once you've done this, you can retrieve the values saved to the computed
    property from your class like this:

        MyClass.metaForProperty('person');

    This will return the original hash that was passed to `meta()`.
  */
  metaForProperty: function(key) {
    var desc = meta(this.proto(), false).descs[key];

    ember_assert("metaForProperty() could not find a computed property with key '"+key+"'.", !!desc && desc instanceof Ember.ComputedProperty);
    return desc._meta || {};
  },

  /**
    Iterate over each computed property for the class, passing its name
    and any associated metadata (see `metaForProperty`) to the callback.
  */
  eachComputedProperty: function(callback, binding) {
    var proto = this.proto(),
        descs = meta(proto).descs,
        empty = {},
        property;

    for (var name in descs) {
      property = descs[name];

      if (property instanceof Ember.ComputedProperty) {
        callback.call(binding || this, name, property._meta || empty);
      }
    }
  }

});

CoreObject.ClassMixin = ClassMixin;
ClassMixin.apply(CoreObject);

/**
  @class
*/
Ember.CoreObject = CoreObject;

<commit_msg>Move Ember.rewatch of Class.prototype from extend until after Class.PrototypeMixin has been applied during first create.<commit_after>// ==========================================================================
// Project:  Ember Runtime
// Copyright: ©2011 Strobe Inc. and contributors.
// License:   Licensed under MIT license (see license.js)
// ==========================================================================

// NOTE: this object should never be included directly.  Instead use Ember.
// Ember.Object.  We only define this separately so that Ember.Set can depend on it

var rewatch = Ember.rewatch;
var classToString = Ember.Mixin.prototype.toString;
var set = Ember.set, get = Ember.get;
var o_create = Ember.platform.create,
    o_defineProperty = Ember.platform.defineProperty,
    meta = Ember.meta;

/** @private */
function makeCtor() {

  // Note: avoid accessing any properties on the object since it makes the
  // method a lot faster.  This is glue code so we want it to be as fast as
  // possible.

  var wasApplied = false, initMixins, init = false, hasChains = false;

  var Class = function() {
    if (!wasApplied) { Class.proto(); } // prepare prototype...
    if (initMixins) {
      this.reopen.apply(this, initMixins);
      initMixins = null;
      rewatch(this); // ålways rewatch just in case
      this.init.apply(this, arguments);
    } else {
      if (hasChains) {
        rewatch(this);
      } else {
        Ember.GUID_DESC.value = undefined;
        o_defineProperty(this, Ember.GUID_KEY, Ember.GUID_DESC);
      }
      if (init===false) { init = this.init; } // cache for later instantiations
      Ember.GUID_DESC.value = undefined;
      o_defineProperty(this, '_super', Ember.GUID_DESC);
      init.apply(this, arguments);
    }
  };

  Class.toString = classToString;
  Class.willReopen = function() {
    if (wasApplied) {
      Class.PrototypeMixin = Ember.Mixin.create(Class.PrototypeMixin);
    }

    wasApplied = false;
  };
  Class._initMixins = function(args) { initMixins = args; };

  Class.proto = function() {
    var superclass = Class.superclass;
    if (superclass) { superclass.proto(); }

    if (!wasApplied) {
      wasApplied = true;
      Class.PrototypeMixin.applyPartial(Class.prototype);
      Ember.rewatch(Class.prototype); // setup watch chains if needed.
      hasChains = !!meta(Class.prototype, false).chains; // avoid rewatch
    }

    return this.prototype;
  };

  return Class;

}

var CoreObject = makeCtor();

CoreObject.PrototypeMixin = Ember.Mixin.create(
/** @scope Ember.CoreObject */ {

  reopen: function() {
    Ember.Mixin._apply(this, arguments, true);
    return this;
  },

  isInstance: true,

  init: function() {},

  isDestroyed: false,

  /**
    Destroys an object by setting the isDestroyed flag and removing its
    metadata, which effectively destroys observers and bindings.

    If you try to set a property on a destroyed object, an exception will be
    raised.

    Note that destruction is scheduled for the end of the run loop and does not
    happen immediately.

    @returns {Ember.Object} receiver
  */
  destroy: function() {
    set(this, 'isDestroyed', true);
    Ember.run.schedule('destroy', this, this._scheduledDestroy);
    return this;
  },

  /**
    Invoked by the run loop to actually destroy the object. This is
    scheduled for execution by the `destroy` method.

    @private
  */
  _scheduledDestroy: function() {
    Ember.destroy(this);
  },

  bind: function(to, from) {
    if (!(from instanceof Ember.Binding)) { from = Ember.Binding.from(from); }
    from.to(to).connect(this);
    return from;
  },

  toString: function() {
    return '<'+this.constructor.toString()+':'+Ember.guidFor(this)+'>';
  }
});

CoreObject.__super__ = null;

var ClassMixin = Ember.Mixin.create({

  ClassMixin: Ember.required(),

  PrototypeMixin: Ember.required(),

  isClass: true,

  isMethod: false,

  extend: function() {
    var Class = makeCtor(), proto;
    Class.ClassMixin = Ember.Mixin.create(this.ClassMixin);
    Class.PrototypeMixin = Ember.Mixin.create(this.PrototypeMixin);

    Class.ClassMixin.ownerConstructor = Class;
    Class.PrototypeMixin.ownerConstructor = Class;

    var PrototypeMixin = Class.PrototypeMixin;
    PrototypeMixin.reopen.apply(PrototypeMixin, arguments);

    Class.superclass = this;
    Class.__super__  = this.prototype;

    proto = Class.prototype = o_create(this.prototype);
    proto.constructor = Class;
    Ember.generateGuid(proto, 'ember');
    meta(proto).proto = proto; // this will disable observers on prototype

    Class.subclasses = Ember.Set ? new Ember.Set() : null;
    if (this.subclasses) { this.subclasses.add(Class); }

    Class.ClassMixin.apply(Class);
    return Class;
  },

  create: function() {
    var C = this;
    if (arguments.length>0) { this._initMixins(arguments); }
    return new C();
  },

  reopen: function() {
    this.willReopen();
    var PrototypeMixin = this.PrototypeMixin;
    PrototypeMixin.reopen.apply(PrototypeMixin, arguments);
    return this;
  },

  reopenClass: function() {
    var ClassMixin = this.ClassMixin;
    ClassMixin.reopen.apply(ClassMixin, arguments);
    Ember.Mixin._apply(this, arguments, false);
    return this;
  },

  detect: function(obj) {
    if ('function' !== typeof obj) { return false; }
    while(obj) {
      if (obj===this) { return true; }
      obj = obj.superclass;
    }
    return false;
  },

  detectInstance: function(obj) {
    return obj instanceof this;
  },

  /**
    In some cases, you may want to annotate computed properties with additional
    metadata about how they function or what values they operate on. For example,
    computed property functions may close over variables that are then no longer
    available for introspection.

    You can pass a hash of these values to a computed property like this:

        person: function() {
          var personId = this.get('personId');
          return App.Person.create({ id: personId });
        }.property().meta({ type: App.Person })

    Once you've done this, you can retrieve the values saved to the computed
    property from your class like this:

        MyClass.metaForProperty('person');

    This will return the original hash that was passed to `meta()`.
  */
  metaForProperty: function(key) {
    var desc = meta(this.proto(), false).descs[key];

    ember_assert("metaForProperty() could not find a computed property with key '"+key+"'.", !!desc && desc instanceof Ember.ComputedProperty);
    return desc._meta || {};
  },

  /**
    Iterate over each computed property for the class, passing its name
    and any associated metadata (see `metaForProperty`) to the callback.
  */
  eachComputedProperty: function(callback, binding) {
    var proto = this.proto(),
        descs = meta(proto).descs,
        empty = {},
        property;

    for (var name in descs) {
      property = descs[name];

      if (property instanceof Ember.ComputedProperty) {
        callback.call(binding || this, name, property._meta || empty);
      }
    }
  }

});

CoreObject.ClassMixin = ClassMixin;
ClassMixin.apply(CoreObject);

/**
  @class
*/
Ember.CoreObject = CoreObject;

<|endoftext|>


<commit_before>
(function () {
	'use strict';

	angular.module('ppl', ['ngRoute', 'ngCookies'])
	.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
		$locationProvider.html5Mode(true);
		$routeProvider
		.when('/', {
		    templateUrl: '../workout.html',
		    controller: 'workoutController'
		})
		.when('/auth/facebook/callback', {
			templateUrl: '../workout.html',
		    controller: 'workoutController'
		})
		.when('/routines', {
		    templateUrl: '../routines.html',
		    controller: 'routineController'
		})
		.when('/login', {
		    templateUrl: '../login.html',
		    controller: 'loginController'
		});
	}])
	.run(['$rootScope', '$cookies', '$location', 'dataService', function ($rootScope, $cookies, $location, dataService) {
		if(!$cookies.get('connect.sid')) {
			$rootScope.loggedIn = false;
			$rootScope.menu = false;
			$location.path('/login');
		}
		else if (!$rootScope.user){
			$rootScope.loggedIn = true;
			$rootScope.loading = true;
			dataService.userInfo(window.localStorage.getItem("userID"))
			.then(function (payload) {
				$rootScope.user = payload.data;
				$rootScope.loading = false;
			});
		}
	}])
	.service('dataService', function($q, $http){
		return {
			login : function(body) {
				return $http({
					url:'/login',
					method: "POST",
					data: body
				});
			},

			loginFB : function(body) {
				return $http({
					url:'/auth/facebook/login',
					method: "GET"
				});
			},

			routines : function() {
				return $http({
					url:'/routines',
					method: "GET"
				});
			},

			userInfo : function(id) {
				return $http({
					url:'/user/id/' + id,
					method: "GET"
				});
			}
		};
	})
	.controller('loginController', function($scope, dataService, $cookies, $location, $rootScope, $sce) {
		$rootScope.loggedIn = false;
		if($cookies.get('connect.sid')) {
			$rootScope.loggedIn = true;
			$location.path('/');
		}
		$scope.submit = function() {
			var body =
			{
				email: $scope.user,
				password: $scope.pass
			}
			dataService.login(body)
			.then(function (payload) {
				$rootScope.user = angular.copy(payload.data);
				$rootScope.loggedIn = true;
				window.localStorage.setItem("userID", payload.data._id);
				$location.path('/');
			});
		}
		$scope.submitFB = function() {

			dataService.loginFB()
			.then(function (payload) {
				console.log(payload.data);
			});
		}
	})
	.controller('menuController', function($scope, $cookies, $rootScope, $location) {
		$rootScope.menu = false;

		$scope.active = '';

		$scope.goTo = function(where) {
			$rootScope.menu = false;
			$scope.active = where;
			$location.path('/' + where);
		}

		$scope.logout = function() {
			$cookies.remove('connect.sid');
			$rootScope.menu = false;
			$rootScope.loggedIn = false;
			$location.path('/login');
		}
	})
	.controller('routineController', function ($scope, $rootScope, dataService, $location, $cookies) {
		$scope.loading = true;

		dataService.routines()
		.then(function (payload) {
			$scope.loading = false;
			$scope.routines = payload.data;
		})

		$scope.setRoutine = function(routine) {
			$scope.selectedRoutine = routine;
		}

		$scope.selectMuscleMenu = function() {
			for(var x in $scope.selectedRoutine.workouts) {
				for(var y in $scope.selectedRoutine.workouts[x].movements) {
					$scope.selectedRoutine.workouts[x].movements[y].showMuscle = false;
				}
			}

		}
	})
	.controller('workoutController', function ($scope, $rootScope, $cookies, $location, dataService) {

	});

})();
<commit_msg>fix paths to users and routines<commit_after>
(function () {
	'use strict';

	angular.module('ppl', ['ngRoute', 'ngCookies'])
	.config(['$locationProvider', '$routeProvider', function ($locationProvider, $routeProvider) {
		$locationProvider.html5Mode(true);
		$routeProvider
		.when('/', {
		    templateUrl: '../workout.html',
		    controller: 'workoutController'
		})
		.when('/auth/facebook/callback', {
			templateUrl: '../workout.html',
		    controller: 'workoutController'
		})
		.when('/routines', {
		    templateUrl: '../routines.html',
		    controller: 'routineController'
		})
		.when('/login', {
		    templateUrl: '../login.html',
		    controller: 'loginController'
		});
	}])
	.run(['$rootScope', '$cookies', '$location', 'dataService', function ($rootScope, $cookies, $location, dataService) {
		if(!$cookies.get('connect.sid')) {
			$rootScope.loggedIn = false;
			$rootScope.menu = false;
			$location.path('/login');
		}
		else if (!$rootScope.user){
			$rootScope.loggedIn = true;
			$rootScope.loading = true;
			dataService.userInfo(window.localStorage.getItem("userID"))
			.then(function (payload) {
				$rootScope.user = payload.data;
				$rootScope.loading = false;
			});
		}
	}])
	.service('dataService', function($q, $http){
		return {
			login : function(body) {
				return $http({
					url:'/login',
					method: "POST",
					data: body
				});
			},

			loginFB : function(body) {
				return $http({
					url:'/auth/facebook/login',
					method: "GET"
				});
			},

			routines : function() {
				return $http({
					url:'/api/routines',
					method: "GET"
				});
			},

			userInfo : function(id) {
				return $http({
					url:'/api/user/id/' + id,
					method: "GET"
				});
			}
		};
	})
	.controller('loginController', function($scope, dataService, $cookies, $location, $rootScope, $sce) {
		$rootScope.loggedIn = false;
		if($cookies.get('connect.sid')) {
			$rootScope.loggedIn = true;
			$location.path('/');
		}
		$scope.submit = function() {
			var body =
			{
				email: $scope.user,
				password: $scope.pass
			}
			dataService.login(body)
			.then(function (payload) {
				$rootScope.user = angular.copy(payload.data);
				$rootScope.loggedIn = true;
				window.localStorage.setItem("userID", payload.data._id);
				$location.path('/');
			});
		}
		$scope.submitFB = function() {

			dataService.loginFB()
			.then(function (payload) {
				console.log(payload.data);
			});
		}
	})
	.controller('menuController', function($scope, $cookies, $rootScope, $location) {
		$rootScope.menu = false;

		$scope.active = '';

		$scope.goTo = function(where) {
			$rootScope.menu = false;
			$scope.active = where;
			$location.path('/' + where);
		}

		$scope.logout = function() {
			$cookies.remove('connect.sid');
			$rootScope.menu = false;
			$rootScope.loggedIn = false;
			$location.path('/login');
		}
	})
	.controller('routineController', function ($scope, $rootScope, dataService, $location, $cookies) {
		$scope.loading = true;

		dataService.routines()
		.then(function (payload) {
			$scope.loading = false;
			$scope.routines = payload.data;
		})

		$scope.setRoutine = function(routine) {
			$scope.selectedRoutine = routine;
		}

		$scope.selectMuscleMenu = function() {
			for(var x in $scope.selectedRoutine.workouts) {
				for(var y in $scope.selectedRoutine.workouts[x].movements) {
					$scope.selectedRoutine.workouts[x].movements[y].showMuscle = false;
				}
			}

		}
	})
	.controller('workoutController', function ($scope, $rootScope, $cookies, $location, dataService) {

	});

})();
<|endoftext|>


<commit_before>/*
---
name: ART.Alerts
description: Alert popups.
requires: [ART.Window]
provides: [ART.Alert, ART.Confirm, ART.Prompt, ART.Window.AlertTools, ART.Alerts]
...
*/

// Window Widget. Work in progress.

ART.Sheet.define('window.art.alert', {
	'content-background-color': hsb(0, 0, 91),
	'footer-height': 30,
	'height': 140,
	'width': 300,
	'footer-background-color': hsb(0, 0, 91),
	'footer-reflection-color': hsb(0, 0, 91),
	'content-border-bottom-color': hsb(0, 0, 91)
});
ART.Sheet.define('window.art.alert:hidden', {
	'display': 'none'
});

ART.Sheet.define('window.art.alert content', {
	'padding': 20,
	'font-size': 14,
	'text-align': 'center'
}, 'css');

ART.Sheet.define('window.art.alert input.prompt', {
	'width': '100%'
}, 'css');

ART.Sheet.define('window.art.alert buttoncontainer', {
	'float':'right',
	'top':'3px',
	'position':'relative'
}, 'css');

ART.Sheet.define('window.art.alert button.art.confirmations', {
	'padding-right': 15,
	'border':'none'
}, 'css');

ART.Popup.DefaultManager.setLayer('alerts', 99);
(function(){

var holder = new Element('div', {
	styles: {
		position: 'absolute',
		visibility: 'hidden',
		zIndex: -1
	}
});
var tmp = new Element('div').inject(holder);

ART.Alert = new Class({

	Extends: ART.Window,

	name: 'window',

	options: {
		close: false,
		minimize: false,
		maximize: false,
		className: 'art alert',
		resizable: false,
		windowManagerLayer: 'alerts',
		destroyOnClose: true,
		autosize: true,
		buttons: [
			{
				text: 'Ok'
			}
		]
	},

	initialize: function(){
		this.parent.apply(this, arguments);

		this.addEvent('show', function(){
			var button = this.alertButtons[0];
			if (button) button.focus();
		}.bind(this));

		new ART.Keyboard(this, this.options.keyboardOptions);

		this.attachKeys({
			'keyup:esc': function(e) {
				this.hide();
			}.bind(this)
		});
	},

	draw: function(newSheet){
		var cs = this.currentSheet;
		var sheet = this.parent(newSheet);

		if (!this.content) return;

		var style = ART.Sheet.lookup(this.toString() + ' content', 'css');
		if (style.margin || style.padding) {
			if (Browser.Engine.trident) holder.inject(document.body);
			tmp.setStyles(style);
			var w = 0,
					h = 0;
			['margin', 'padding'].each(function(space) {
				['Top', 'Left', 'Bottom', 'Right'].each(function(side, i) {
					if (i%2) w += tmp.getStyle(space+side).toInt();
					else h += tmp.getStyle(space+side).toInt();
				});
			});

			tmp.style.cssText = '';
			if (Browser.Engine.trident) holder.dispose();

			style.width = this.contentSize.x - w; //border is hard coded to 1 on each side
			style.height = this.contentSize.y - h; //border is hard coded to 1 on each side
		}
		this.content.setStyles(style);
		this.footer.setStyles(ART.Sheet.lookup(this.toString() + ' footer', 'css'));
	},

	makeButtons: function(){
		this.parent();
		this.buttoncontainer = new Element('div', {
				'class': 'buttoncontainer'
			}).setStyles(ART.Sheet.lookup(this.toString() + ' buttoncontainer', 'css')).inject(this.footer);
		this.alertButtons = this.options.buttons.map(function(button){
			button.className = ((button.className || '') + ' art confirmations').trim();
			var b = new ART.Button(button);
			b.addEvent('press', function(e){
				if (document.id(b).hasClass(this.options.closeClass)) {
					if (e) e.preventDefault();
					this.hide();
				}
			}.bind(this));

			button.properties = button.properties || {};
			if (!button.properties['class']) button.properties['class'] = this.options.closeClass;

			var klass = button.properties['class'];
			delete button.properties['class'];
			klass.split(' ').each(function(className) {
				b.addClass(className);
			});
			document.id(b).set(button.properties);

			b.inject(this, this.buttoncontainer);

			document.id(b).setStyles(ART.Sheet.lookup(b.toString(), 'css'));
			return b;
		}, this);
		var first = this.alertButtons[0];
		if (first) first.focus();
	}

});

ART.alert = function(caption, content, callback, options) {
	return new ART.Alert(
		$extend(options || {}, {
			caption: caption,
			content: content,
			onHide: callback || $empty
		})
	);
};

ART.Confirm = new Class({

	Extends: ART.Alert,

	options: {
		className: 'art alert confirm',
		resizable: false,
		buttons: [
			{
				text: 'Cancel'
			},
			{
				text: 'Ok',
				onPress: function(){
					this.parentWidget.fireEvent('confirm');
				}
			}
		]
	}
});
ART.confirm = function(caption, content, callback, options) {
	return new ART.Confirm(
		$extend(options || {}, {
			caption: caption,
			content: content,
			onConfirm: callback || $empty
		})
	);
};

var isVisible = function(element){
	var w = element.offsetWidth,
		h = element.offsetHeight;
	isVis = (w == 0 && h == 0) ? false : (w > 0 && h > 0) ? true : element.getStyle('display') != 'none';
};

ART.Prompt = new Class({

	Extends: ART.Confirm,

	options: {
		buttons: [
			{
				text: 'Cancel'
			},
			{
				text: 'Ok',
				onPress: function(){
					this.parentWidget.fireEvent('confirm', this.parentWidget.getPromptValue());
				}
			}
		]
	},
	initialize: function(){
		this.parent.apply(this, arguments);
		this.addEvent('show', function(){
			(function(){
				var input = this.content.getElements('input, textarea').filter(function(el) {
					return el.get('type') != 'hidden' && isVisible(el);
				})[0];
				if (input) input.select();
			}).delay(100, this);
		});
		this.makePromptInput();
	},
	makePromptInput: function(){
		if (!this.content.getElement('form') && !this.content.getElements('input, textarea, select').length) {
			var styles = ART.Sheet.lookup(this.toString() + ' input.prompt');
			this.inputContainer = new Element('div', {
				'class': 'inputContainer',
				styles: {
					position: 'relative'
				}
			}).inject(this.content);
			this.input = new Element('input', {
				value: this.options.defaultValue || '',
				type: 'text',
				styles: styles,
				events: {
					keydown: function(e) {
						if (e.key == 'enter') {
							this.fireEvent('confirm', this.getPromptValue());
							this.hide();
							Keyboard.stop(e);
						}
					}.bind(this)
				}
			}).inject(this.inputContainer);
		}
	},
	getPromptValue: function(){
		if (this.input) return this.input.get('value');
		var form = this.content.getElement('form');
		return form ? form.toQueryString() : this.content.toQueryString();
	},
	setContent: function(){
		if (this.inputContainer) this.inputContainer.dispose();
		this.parent.apply(this, arguments);
		if (this.inputContainer) this.inputContainer.inject(this.content);
		if (this.options.autosize) this.autosize();
		return this;
	},
	show: function(){
		this.parent.apply(this, arguments);
		this.alertButtons[0].blur();
		var input = this.content.getElement('input, textarea');
		if (input) (function(){ input.select(); }).delay(5);
		return this;
	}
});

ART.prompt = function(caption, content, callback, options) {
	return new ART.Prompt(
		$extend(options || {}, {
			caption: caption,
			content: content,
			onConfirm: callback || $empty
		})
	);
};

ART.Window.AlertTools = new Class({

	Implements: ART.WindowTools,

	alerts: {},

	alert: function(caption, content, callback, options, alerter){
		alerter = alerter || ART.alert;
		var win = this.getWindow();
		var currentKb = win.keyboard.activeKB;
		if (win && !win.alertManager) {
			win.alertManager = new ART.WindowManager(win);
			win.alertManager.setLayer('alerts', 99);
		}
		var winsize = win.getSize();
		options = $merge({
			relativeTo: document.id(win) || document.id(this),
			mask: true,
			maskOptions: {
				inject: {
					target: document.id(this.getWindow().content),
					where: 'after'
				}
			},
			constrainToContainer: true,
			width: (winsize.width * 0.9).toInt(),
			max: {
				height: (winsize.height * 0.9).toInt(),
				width: (winsize.width * 0.9).toInt()
			}
		}, options);
		options.windowManager = win ? win.alertManager : null;
		var alert = alerter(caption, content, callback, options);
		alert.inject(win || this, document.id(win) || document.id(this), 'bottom').show();
		var enableKB = function(){
			win.keyboard.activate(win.alertManager.keyboard);
			alert.keyboard.activate();
		};
		enableKB();
		if (win) {
			win.fireEvent('alert', alert);
			var shader = function() {
				alert.setState('hidden', true);
			};
			var unshader = function() {
				alert.setState('hidden', false);
			};
			alert.addEvents({
				destroy: function(){
					win.removeEvents({
						shade: shader,
						unshade: unshader
					});
					win.keyboard.activate(currentKb);
				},
				hide: function(){
					win.keyboard.activate(currentKb);
					win.fireEvent('endAlert');
				},
				show: function(){
					enableKB();
					win.fireEvent('alert');
				}
			});
			win.addEvents({
				shade: shader,
				unshade: unshader
			});
		}
		return alert;
	},
	confirm: function(cap, cont, fn, opt) {
		return this.alert(cap, cont, fn, opt, ART.confirm);
	},
	prompt: function(cap, cont, fn, opt) {
		return this.alert(cap, cont, fn, opt, ART.prompt);
	}
});

ART.Window.implement(new ART.Window.AlertTools);

})();<commit_msg>fixing focus state for windows in windows fixing close button which was closing the window before the button was pressed.<commit_after>/*
---
name: ART.Alerts
description: Alert popups.
requires: [ART.Window]
provides: [ART.Alert, ART.Confirm, ART.Prompt, ART.Window.AlertTools, ART.Alerts]
...
*/

// Window Widget. Work in progress.

ART.Sheet.define('window.art.alert', {
	'content-background-color': hsb(0, 0, 91),
	'footer-height': 30,
	'height': 140,
	'width': 300,
	'footer-background-color': hsb(0, 0, 91),
	'footer-reflection-color': hsb(0, 0, 91),
	'content-border-bottom-color': hsb(0, 0, 91)
});
ART.Sheet.define('window.art.alert:hidden', {
	'display': 'none'
});

ART.Sheet.define('window.art.alert content', {
	'padding': 20,
	'font-size': 14,
	'text-align': 'center'
}, 'css');

ART.Sheet.define('window.art.alert input.prompt', {
	'width': '100%'
}, 'css');

ART.Sheet.define('window.art.alert buttoncontainer', {
	'float':'right',
	'top':'3px',
	'position':'relative'
}, 'css');

ART.Sheet.define('window.art.alert button.art.confirmations', {
	'padding-right': 15,
	'border':'none'
}, 'css');

ART.Popup.DefaultManager.setLayer('alerts', 99);
(function(){

var holder = new Element('div', {
	styles: {
		position: 'absolute',
		visibility: 'hidden',
		zIndex: -1
	}
});
var tmp = new Element('div').inject(holder);

ART.Alert = new Class({

	Extends: ART.Window,

	name: 'window',

	options: {
		close: false,
		minimize: false,
		maximize: false,
		className: 'art alert',
		resizable: false,
		windowManagerLayer: 'alerts',
		destroyOnClose: true,
		autosize: true,
		buttons: [
			{
				text: 'Ok'
			}
		]
	},

	initialize: function(){
		this.parent.apply(this, arguments);

		this.addEvent('show', function(){
			var button = this.alertButtons[0];
			if (button) button.focus();
		}.bind(this));

		new ART.Keyboard(this, this.options.keyboardOptions);

		this.attachKeys({
			'keyup:esc': function(e) {
				this.hide();
			}.bind(this)
		});
	},

	draw: function(newSheet){
		var cs = this.currentSheet;
		var sheet = this.parent(newSheet);

		if (!this.content) return;

		var style = ART.Sheet.lookup(this.toString() + ' content', 'css');
		if (style.margin || style.padding) {
			if (Browser.Engine.trident) holder.inject(document.body);
			tmp.setStyles(style);
			var w = 0,
					h = 0;
			['margin', 'padding'].each(function(space) {
				['Top', 'Left', 'Bottom', 'Right'].each(function(side, i) {
					if (i%2) w += tmp.getStyle(space+side).toInt();
					else h += tmp.getStyle(space+side).toInt();
				});
			});

			tmp.style.cssText = '';
			if (Browser.Engine.trident) holder.dispose();

			style.width = this.contentSize.x - w; //border is hard coded to 1 on each side
			style.height = this.contentSize.y - h; //border is hard coded to 1 on each side
		}
		this.content.setStyles(style);
		this.footer.setStyles(ART.Sheet.lookup(this.toString() + ' footer', 'css'));
	},

	makeButtons: function(){
		this.parent();
		this.buttoncontainer = new Element('div', {
				'class': 'buttoncontainer'
			}).setStyles(ART.Sheet.lookup(this.toString() + ' buttoncontainer', 'css')).inject(this.footer);
		this.alertButtons = this.options.buttons.map(function(button){
			button.className = ((button.className || '') + ' art confirmations').trim();
			var b = new ART.Button(button);
			b.addEvent('press', function(e){
				if (document.id(b).hasClass(this.options.closeClass)) {
					if (e) e.stopPropagation();
					this.hide();
				}
			}.bind(this));

			button.properties = button.properties || {};
			if (!button.properties['class']) button.properties['class'] = this.options.closeClass;

			var klass = button.properties['class'];
			delete button.properties['class'];
			klass.split(' ').each(function(className) {
				b.addClass(className);
			});
			document.id(b).set(button.properties);

			b.inject(this, this.buttoncontainer);

			document.id(b).setStyles(ART.Sheet.lookup(b.toString(), 'css'));
			return b;
		}, this);
		var first = this.alertButtons[0];
		if (first) first.focus();
	}

});

ART.alert = function(caption, content, callback, options) {
	return new ART.Alert(
		$extend(options || {}, {
			caption: caption,
			content: content,
			onHide: callback || $empty
		})
	);
};

ART.Confirm = new Class({

	Extends: ART.Alert,

	options: {
		className: 'art alert confirm',
		resizable: false,
		buttons: [
			{
				text: 'Cancel'
			},
			{
				text: 'Ok',
				onPress: function(){
					this.parentWidget.fireEvent('confirm');
				}
			}
		]
	}
});
ART.confirm = function(caption, content, callback, options) {
	return new ART.Confirm(
		$extend(options || {}, {
			caption: caption,
			content: content,
			onConfirm: callback || $empty
		})
	);
};

var isVisible = function(element){
	var w = element.offsetWidth,
		h = element.offsetHeight;
	isVis = (w == 0 && h == 0) ? false : (w > 0 && h > 0) ? true : element.getStyle('display') != 'none';
};

ART.Prompt = new Class({

	Extends: ART.Confirm,

	options: {
		buttons: [
			{
				text: 'Cancel'
			},
			{
				text: 'Ok',
				onPress: function(){
					this.parentWidget.fireEvent('confirm', this.parentWidget.getPromptValue());
				}
			}
		]
	},
	initialize: function(){
		this.parent.apply(this, arguments);
		this.addEvent('show', function(){
			(function(){
				var input = this.content.getElements('input, textarea').filter(function(el) {
					return el.get('type') != 'hidden' && isVisible(el);
				})[0];
				if (input) input.select();
			}).delay(100, this);
		});
		this.makePromptInput();
	},
	makePromptInput: function(){
		if (!this.content.getElement('form') && !this.content.getElements('input, textarea, select').length) {
			var styles = ART.Sheet.lookup(this.toString() + ' input.prompt');
			this.inputContainer = new Element('div', {
				'class': 'inputContainer',
				styles: {
					position: 'relative'
				}
			}).inject(this.content);
			this.input = new Element('input', {
				value: this.options.defaultValue || '',
				type: 'text',
				styles: styles,
				events: {
					keydown: function(e) {
						if (e.key == 'enter') {
							this.fireEvent('confirm', this.getPromptValue());
							this.hide();
							Keyboard.stop(e);
						}
					}.bind(this)
				}
			}).inject(this.inputContainer);
		}
	},
	getPromptValue: function(){
		if (this.input) return this.input.get('value');
		var form = this.content.getElement('form');
		return form ? form.toQueryString() : this.content.toQueryString();
	},
	setContent: function(){
		if (this.inputContainer) this.inputContainer.dispose();
		this.parent.apply(this, arguments);
		if (this.inputContainer) this.inputContainer.inject(this.content);
		if (this.options.autosize) this.autosize();
		return this;
	}
});

ART.prompt = function(caption, content, callback, options) {
	return new ART.Prompt(
		$extend(options || {}, {
			caption: caption,
			content: content,
			onConfirm: callback || $empty
		})
	);
};

ART.Window.AlertTools = new Class({

	Implements: ART.WindowTools,

	alerts: {},

	alert: function(caption, content, callback, options, alerter){
		alerter = alerter || ART.alert;
		var win = this.getWindow();
		var currentKb = win.keyboard.activeKB;
		if (win && !win.alertManager) {
			win.alertManager = new ART.WindowManager(win);
			win.alertManager.setLayer('alerts', 99);
		}
		var winsize = win.getSize();
		options = $merge({
			relativeTo: document.id(win) || document.id(this),
			mask: true,
			maskOptions: {
				inject: {
					target: document.id(this.getWindow().content),
					where: 'after'
				}
			},
			constrainToContainer: true,
			width: (winsize.width * 0.9).toInt(),
			max: {
				height: (winsize.height * 0.9).toInt(),
				width: (winsize.width * 0.9).toInt()
			}
		}, options);
		options.windowManager = win ? win.alertManager : null;
		var alert = alerter(caption, content, callback, options);
		alert.inject(win || this, document.id(win) || document.id(this), 'bottom').show();
		var enableKB = function(){
			win.keyboard.activate(win.alertManager.keyboard);
			alert.keyboard.activate();
		};
		enableKB();
		if (win) {
			win.fireEvent('alert', alert);
			var shader = function() {
				alert.setState('hidden', true);
			};
			var unshader = function() {
				alert.setState('hidden', false);
			};
			alert.addEvents({
				destroy: function(){
					win.removeEvents({
						shade: shader,
						unshade: unshader
					});
					win.keyboard.activate(currentKb);
				},
				hide: function(){
					win.keyboard.activate(currentKb);
					win.fireEvent('endAlert');
				},
				show: function(){
					enableKB();
					win.fireEvent('alert');
				}
			});
			win.addEvents({
				shade: shader,
				unshade: unshader
			});
			win.focus();
			alert.focus();
			var button = alert.alertButtons[0];
			if (button) button.focus();
		}
		return alert;
	},
	confirm: function(cap, cont, fn, opt) {
		return this.alert(cap, cont, fn, opt, ART.confirm);
	},
	prompt: function(cap, cont, fn, opt) {
		return this.alert(cap, cont, fn, opt, ART.prompt);
	}
});

ART.Window.implement(new ART.Window.AlertTools);

})();<|endoftext|>


<commit_before>
var cluster = require('cluster');

var express = require('express');
var app = express();

var db = require('./db').connect();
var fs = require('fs');

var keys = require('./keys');
var lang_module = require('./lang');

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

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

exports.collect = function(intervalObject)
{
	// console.log("collect");

	var options = {
		host: GLOBAL.fbcomments_server_ip,
		port: GLOBAL.fbcomments_server_port,
		path: '/collect',
		method: 'POST',
		headers: {
			'Content-Type': 'application/json'
		}
	};

	fs.readFile(GLOBAL.private_dir_path + '/fbcomments_config.json', function (err, data)
	{
		if (err)
		{
			// can't collect comments
		}
		else
		{
			var config = JSON.parse(data);
			var clientID = config.clientID;
			var clientSecret = config.clientSecret;

			db.hgetall("fbcomments",function(error,fbcommentInfos)
			{
				if (error || !fbcommentInfos)
				{
					// to nothing
				}
				else
				{
					/* SAMPLE
					{ postUpdate: 1416785465120,
					  fbPostID: 'xxx',
					  postID: '1',
					  since: 0 }
					*/

					var now = Date.now();
					var maxTime = (15 * 24 * 60 * 60 * 1000);

					// to destroy entries that are too old
					var multi = db.multi();

					Object.keys(fbcommentInfos).forEach(function(key)
					{
						var entry = JSON.parse(fbcommentInfos[key]);

						if (parseInt(entry.postUpdate)+ maxTime > now)
						{
							var request_body = {};
							request_body.clientID = clientID
							request_body.clientSecret = clientSecret;
							request_body.postID = entry.postID;
							request_body.fbPostID = entry.fbPostID;
							request_body.since = entry.since;
							request_body.postUpdate = entry.postUpdate;

							// console.dir(request_body);

							tools.send_http_request(options, collectCallback, request_body);
						}
						else
						{
							// expired, stop collecting comments for this post
							multi.hdel("fbcomments",request_body.postID);
						}

					});

					multi.exec();
				}
			});

		}
	});
}

function collectCallback(success,statusCode,comments)
{
	// comments.success
	// comments.data [{name,message,created_time}]
	// comments.req (initial req body without clientID & clientSecret)

	if (success)
	{
		if (comments.success)
		{
			// console.log("collectCallback: " + success + " code: " + statusCode + " comments: " + comments.data.length);

			if (comments.data.length > 0)
			{
				// console.dir(comments.req);
				// console.log("to insert in post " + comments.req.postID + ":");

				var older = 0;

				for (var i = 0; i < comments.data.length; i++)
				{
					var comment = comments.data[i];
					// console.log(comment.name + " " + comment.created_time);

					if (parseInt(comment.created_time) > older) older = comment.created_time;

					// com {name,content,timestamp,postID}

					comment.name = decodeURIComponent(comment.name);
					comment.content = decodeURIComponent(comment.message);
					delete comment.message;
					comment.timestamp = comment.created_time * 1000; // facebook uses time in seconds
					comment.from = "facebook"; // to know it comes from facebook
					delete comment.created_time;
					comment.postID = comments.req.postID;

					posts.postInternalComment(comment,function(success)
					{
						// console.log("postInternalComment " + success);
					});
				}

				// update since value to avoid getting these comments again
				// console.log("since: " + older);

				var fbcommentInfos = {};
				fbcommentInfos.postUpdate = comments.req.postUpdate;
				fbcommentInfos.fbPostID = comments.req.fbPostID;
				fbcommentInfos.postID = comments.req.postID;
				fbcommentInfos.since = older;

				// console.dir(fbcommentInfos);

				db.hset("fbcomments",comments.req.postID,JSON.stringify(fbcommentInfos));
			}

		}
		else
		{
			//console.log("collectCallback: " + success + " but no comments");
		}
	}
	else
	{
		//console.log("collectCallback: " + success);
	}

}

<commit_msg>Quick fix in app/srv/modules/fbcomments.js<commit_after>
var cluster = require('cluster');

var express = require('express');
var app = express();

var db = require('./db').connect();
var fs = require('fs');

var keys = require('./keys');
var lang_module = require('./lang');

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

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

exports.collect = function(intervalObject)
{
	// console.log("collect");

	var options = {
		host: GLOBAL.fbcomments_server_ip,
		port: GLOBAL.fbcomments_server_port,
		path: '/collect',
		method: 'POST',
		headers: {
			'Content-Type': 'application/json'
		}
	};

	fs.readFile(GLOBAL.private_dir_path + '/fbcomments_config.json', function (err, data)
	{
		if (err)
		{
			// can't collect comments
		}
		else
		{
			var config = JSON.parse(data);
			var clientID = config.clientID;
			var clientSecret = config.clientSecret;

			db.hgetall("fbcomments",function(error,fbcommentInfos)
			{
				if (error || !fbcommentInfos)
				{
					// to nothing
				}
				else
				{
					/* SAMPLE
					{ postUpdate: 1416785465120,
					  fbPostID: 'xxx',
					  postID: '1',
					  since: 0 }
					*/

					var now = Date.now();
					var maxTime = (15 * 24 * 60 * 60 * 1000);

					// to destroy entries that are too old
					var multi = db.multi();

					Object.keys(fbcommentInfos).forEach(function(key)
					{
						var entry = JSON.parse(fbcommentInfos[key]);

						if (parseInt(entry.postUpdate)+ maxTime > now)
						{
							var request_body = {};
							request_body.clientID = clientID
							request_body.clientSecret = clientSecret;
							request_body.postID = entry.postID;
							request_body.fbPostID = entry.fbPostID;
							request_body.since = entry.since;
							request_body.postUpdate = entry.postUpdate;

							// console.dir(request_body);

							tools.send_http_request(options, collectCallback, request_body);
						}
						else
						{
							// expired, stop collecting comments for this post
							multi.hdel("fbcomments",entry.postID);
						}

					});

					multi.exec();
				}
			});

		}
	});
}

function collectCallback(success,statusCode,comments)
{
	// comments.success
	// comments.data [{name,message,created_time}]
	// comments.req (initial req body without clientID & clientSecret)

	if (success)
	{
		if (comments.success)
		{
			// console.log("collectCallback: " + success + " code: " + statusCode + " comments: " + comments.data.length);

			if (comments.data.length > 0)
			{
				// console.dir(comments.req);
				// console.log("to insert in post " + comments.req.postID + ":");

				var older = 0;

				for (var i = 0; i < comments.data.length; i++)
				{
					var comment = comments.data[i];
					// console.log(comment.name + " " + comment.created_time);

					if (parseInt(comment.created_time) > older) older = comment.created_time;

					// com {name,content,timestamp,postID}

					comment.name = decodeURIComponent(comment.name);
					comment.content = decodeURIComponent(comment.message);
					delete comment.message;
					comment.timestamp = comment.created_time * 1000; // facebook uses time in seconds
					comment.from = "facebook"; // to know it comes from facebook
					delete comment.created_time;
					comment.postID = comments.req.postID;

					posts.postInternalComment(comment,function(success)
					{
						// console.log("postInternalComment " + success);
					});
				}

				// update since value to avoid getting these comments again
				// console.log("since: " + older);

				var fbcommentInfos = {};
				fbcommentInfos.postUpdate = comments.req.postUpdate;
				fbcommentInfos.fbPostID = comments.req.fbPostID;
				fbcommentInfos.postID = comments.req.postID;
				fbcommentInfos.since = older;

				// console.dir(fbcommentInfos);

				db.hset("fbcomments",comments.req.postID,JSON.stringify(fbcommentInfos));
			}

		}
		else
		{
			//console.log("collectCallback: " + success + " but no comments");
		}
	}
	else
	{
		//console.log("collectCallback: " + success);
	}

}

<|endoftext|>


<commit_before>var utils = require('cordova/utils'),
    event = require('./event'),
    common = require('./Common'),
    BaseClass = require('./BaseClass');

/*****************************************************************************
 * HTMLInfoWindow Class
 *****************************************************************************/
var HTMLInfoWindow = function() {
    var self = this;
    BaseClass.apply(self);

    var frame = document.createElement("div");
    frame.style.overflow="visible";
    frame.style.position="absolute";
    frame.style.display = "inline-block";
    self.set("frame", frame);

    var contentBox = document.createElement("div");
    contentBox.style.display = "inline-block";
    contentBox.style.padding = "5px";

    var contentFrame = document.createElement("div");
    contentFrame.style.display = "block";
    contentFrame.style.position = "relative";
    contentFrame.style.backgroundColor = "white";
    contentFrame.style.border = "1px solid rgb(204, 204, 204)";
    contentFrame.style.left = "0px";
    contentFrame.style.right = "0px";
    contentFrame.style.zIndex = "1";  // In order to set higher depth than the map div certainly
    frame.appendChild(contentFrame);
    contentFrame.appendChild(contentBox);

    var tailFrame = document.createElement("div");
    tailFrame.style.position = "relative";
    tailFrame.style.marginTop = "-1px";
    frame.appendChild(tailFrame);

    var tailLeft = document.createElement("div");
    tailLeft.style.position = "absolute";
    tailLeft.style.left = "50%";
    tailLeft.style.height = "0px";
    tailLeft.style.width = "0px";
    tailLeft.style.marginLeft = "-15px";
    tailLeft.style.borderWidth = "15px 15px 0px";
    tailLeft.style.borderColor = "rgb(204, 204, 204) transparent transparent";
    tailLeft.style.borderStyle = "solid";
    tailFrame.appendChild(tailLeft);

    var tailRight = document.createElement("div");
    tailRight.style.position = "absolute";
    tailRight.style.left = "50%";
    tailRight.style.height = "0px";
    tailRight.style.width = "0px";
    tailRight.style.marginLeft = "-14px";
    tailRight.style.borderTopWidth = "14px";
    tailRight.style.borderLeftWidth = "14px";
    tailRight.style.borderRightWidth = "14px";
    tailRight.style.borderColor = "rgb(255, 255, 255) transparent transparent";
    tailRight.style.borderStyle = "solid";
    tailFrame.appendChild(tailRight);

    var calculate = function() {

      var marker = self.get("marker");
      var map = marker.getMap();

      var div = map.getDiv();

      var frame = self.get("frame");
      var contentFrame = frame.firstChild;
      var contentBox = contentFrame.firstChild;
      contentBox.style.minWidth = "100px";
      contentBox.style.minHeight = "50px";

      var content = self.get("content");
      if (typeof content === "string") {
          contentBox.style.whiteSpace="pre-wrap";
          contentBox.innerHTML = content;
      } else {
          if (!content) {
            contentBox.innerText = "";
          } else if (content.nodeType === 1) {
            contentBox.appendChild(content);
          } else {
            contentBox.innerText = content;
          }
      }

      // Insert the contents to this HTMLInfoWindow
      if (!frame.parentNode) {
          div.appendChild(frame);
      }

      // Adjust the HTMLInfoWindow size
      var contentsWidth = contentBox.offsetWidth + 10; // padding 5px x 2
      self.set("contentsWidth", contentsWidth);
      var contentsHeight = contentBox.offsetHeight;
      self.set("contentsHeight", contentsHeight );
      contentFrame.style.width = contentsWidth + "px";
      contentFrame.style.height = contentsHeight + "px";
      frame.style.width = contentsWidth  + "px";
      frame.style.height = (contentsHeight+ 15) + "px";

      var infoOffset = {
        y : 0.25,
        x : 0.5
      };

      var iconSize = {
        width: 28,
        height: 60
      };
      var icon = marker.get("icon");
      if (typeof icon === "object") {
          if (typeof icon.size === "object") {
              iconSize.width = icon.size.width;
              iconSize.height = icon.size.height;
          }
          if (typeof icon.url === "string" && icon.url.indexOf("data:image/") === 0) {
              var img = document.createElement("img");
              img.src = icon.url;
              iconSize.width = img.width;
              iconSize.height = img.height;
          }

      }
      var infoWindowAnchor = marker.get("infoWindowAnchor");
      if (utils.isArray(infoWindowAnchor)) {
        infoOffset.x = infoWindowAnchor[0] / icon.size.width;
        infoOffset.x = infoOffset.x > 1 ? 1 : infoOffset.x;
        infoOffset.x = infoOffset.x < 0 ? 0 : infoOffset.x;
        infoOffset.y = infoWindowAnchor[1] / icon.size.height;
        infoOffset.y = infoOffset.y > 1 ? 1 : infoOffset.y;
        infoOffset.y = infoOffset.y < 0 ? 0 : infoOffset.y;
      }
      infoOffset.y *= iconSize.height;
      infoOffset.x = (infoOffset.x - 0.5) * iconSize.width;

      //console.log("contentsSize = " + contentsWidth + ", " + contentsHeight);
      //console.log("iconSize = " + iconSize.width + ", " + iconSize.height);
      //console.log("infoOffset = " + infoOffset.x + ", " + infoOffset.y);

      var offsetX = contentsWidth / 2  - infoOffset.x;
      var offsetY = contentsHeight  - infoOffset.y + iconSize.height;

      self.set("offsetX", offsetX);
      self.set("offsetY", offsetY);

      //console.log("offset = " + self.get("offsetX") + ", " + self.get("offsetY"));
      var infoPosition = map.get("infoPosition");
      self.trigger("infoPosition_changed", "", infoPosition);
    };

    var isInfoOpenFired = false;

    self.on("infoPosition_changed", function(ignore, point) {

        var x = point.x - self.get("offsetX");
        var y = point.y - self.get("offsetY");
        //console.log("offset = " + x + ", " + y);

        frame.style.left = x + "px";
        frame.style.top =  y + "px";

        if (!isInfoOpenFired) {
            isInfoOpenFired = true;
            self.trigger(event.INFO_OPEN);
        }

        cordova.fireDocumentEvent('plugin_touch', {});
    });
    self.on(event.INFO_CLOSE, function() {
        isInfoOpenFired = false;
    });
    self.on("infoWindowAnchor_changed", calculate);
    self.on("icon_changed", calculate);

    self.set("isInfoWindowVisible", false);

};

utils.extend(HTMLInfoWindow, BaseClass);

HTMLInfoWindow.prototype.isInfoWindowShown = function() {
    return this.get("isInfoWindowVisible") === true;
};

HTMLInfoWindow.prototype.close = function() {
    var self = this;

    var marker = self.get("marker");
    if (marker) {
      marker.off("isInfoWindowVisible_changed");
    }
    if (!self.isInfoWindowShown() || !marker) {
      return;
    }
    marker.set("infoWindow", undefined);
    this.set('marker', undefined);

    var map = marker.getMap();
    map.off("infoPosition_changed");
    marker.off("icon_changed");
    marker.off("infoWindowAnchor_changed");
    self.trigger(event.INFO_CLOSE);
    marker.off(event.INFO_CLOSE, self.close);  //This event listener is assigned in the open method. So detach it.
    map.set("active_marker_id", null);

    var div = map.getDiv();
    var frame = self.get("frame");
    div.removeChild(frame);

    // Remove the contents from this HTMLInfoWindow
    var contentFrame = frame.firstChild;
    var contentBox = contentFrame.firstChild;
    contentBox.innerHTML = "";
};

HTMLInfoWindow.prototype.setContent = function(content) {
    var self = this;
    var prevContent = self.get("content");
    self.set("content", content);
    var marker = self.get("marker");
    if (content !== prevContent && marker && marker.isInfoWindowShown()) {
      self.trigger("infoWindowAnchor_changed");
    }
};

HTMLInfoWindow.prototype.open = function(marker) {
    if (!marker) {
        return;
    }
    if (marker._objectInstance) {
      // marker is an instance of the ionic-native wrapper plugin.
      marker = marker._objectInstance;
    }

    var map = marker.getMap();
    var self = this,
      markerId = marker.getId();

    marker.set("infoWindow", self);

    map.fromLatLngToPoint(marker.getPosition(), function(point) {
        map.set("infoPosition", {x: point[0], y: point[1]});

        map.bindTo("infoPosition", self);
        marker.bindTo("infoWindowAnchor", self);
        marker.bindTo("isInfoWindowVisible", self);
        marker.bindTo("icon", self);
        marker.one(event.INFO_CLOSE, self.close.bind(self));
        self.set("marker", marker);
        self.set("isInfoWindowVisible", true);
        map.set("active_marker_id", marker.getId());
        self.trigger.call(self, "infoWindowAnchor_changed");
    });
};

HTMLInfoWindow.prototype.setBackgroundColor = function(backgroundColor) {
  this.get("frame").children[0].style.backgroundColor = backgroundColor;
  this.get("frame").children[1].children[0].style.borderColor = backgroundColor + " rgba(0,0,0,0) rgba(0,0,0,0)";
  this.get("frame").children[1].children[1].style.borderColor = backgroundColor + " rgba(0,0,0,0) rgba(0,0,0,0)";
};

module.exports = HTMLInfoWindow;
<commit_msg>Bug fix: InfoWindow setContent() Stopped Working #1748<commit_after>var utils = require('cordova/utils'),
    event = require('./event'),
    common = require('./Common'),
    BaseClass = require('./BaseClass');

/*****************************************************************************
 * HTMLInfoWindow Class
 *****************************************************************************/
var HTMLInfoWindow = function() {
    var self = this;
    BaseClass.apply(self);

    var frame = document.createElement("div");
    frame.style.overflow="visible";
    frame.style.position="absolute";
    frame.style.display = "inline-block";
    self.set("frame", frame);

    var contentBox = document.createElement("div");
    contentBox.style.display = "inline-block";
    contentBox.style.padding = "5px";

    var contentFrame = document.createElement("div");
    contentFrame.style.display = "block";
    contentFrame.style.position = "relative";
    contentFrame.style.backgroundColor = "white";
    contentFrame.style.border = "1px solid rgb(204, 204, 204)";
    contentFrame.style.left = "0px";
    contentFrame.style.right = "0px";
    contentFrame.style.zIndex = "1";  // In order to set higher depth than the map div certainly
    frame.appendChild(contentFrame);
    contentFrame.appendChild(contentBox);

    var tailFrame = document.createElement("div");
    tailFrame.style.position = "relative";
    tailFrame.style.marginTop = "-1px";
    frame.appendChild(tailFrame);

    var tailLeft = document.createElement("div");
    tailLeft.style.position = "absolute";
    tailLeft.style.left = "50%";
    tailLeft.style.height = "0px";
    tailLeft.style.width = "0px";
    tailLeft.style.marginLeft = "-15px";
    tailLeft.style.borderWidth = "15px 15px 0px";
    tailLeft.style.borderColor = "rgb(204, 204, 204) transparent transparent";
    tailLeft.style.borderStyle = "solid";
    tailFrame.appendChild(tailLeft);

    var tailRight = document.createElement("div");
    tailRight.style.position = "absolute";
    tailRight.style.left = "50%";
    tailRight.style.height = "0px";
    tailRight.style.width = "0px";
    tailRight.style.marginLeft = "-14px";
    tailRight.style.borderTopWidth = "14px";
    tailRight.style.borderLeftWidth = "14px";
    tailRight.style.borderRightWidth = "14px";
    tailRight.style.borderColor = "rgb(255, 255, 255) transparent transparent";
    tailRight.style.borderStyle = "solid";
    tailFrame.appendChild(tailRight);

    var calculate = function() {

      var marker = self.get("marker");
      var map = marker.getMap();

      var div = map.getDiv();

      var frame = self.get("frame");
      var contentFrame = frame.firstChild;
      var contentBox = contentFrame.firstChild;
      contentBox.style.minWidth = "100px";
      contentBox.style.minHeight = "50px";

      var content = self.get("content");
      if (typeof content === "string") {
          contentBox.style.whiteSpace="pre-wrap";
          contentBox.innerHTML = content;
      } else {
          if (!content) {
            contentBox.innerText = "";
          } else if (content.nodeType === 1) {
            contentBox.appendChild(content);
          } else {
            contentBox.innerText = content;
          }
      }

      // Insert the contents to this HTMLInfoWindow
      if (!frame.parentNode) {
          div.appendChild(frame);
      }

      // Adjust the HTMLInfoWindow size
      var contentsWidth = contentBox.offsetWidth + 10; // padding 5px x 2
      self.set("contentsWidth", contentsWidth);
      var contentsHeight = contentBox.offsetHeight;
      self.set("contentsHeight", contentsHeight );
      contentFrame.style.width = contentsWidth + "px";
      contentFrame.style.height = contentsHeight + "px";
      frame.style.width = contentsWidth  + "px";
      frame.style.height = (contentsHeight+ 15) + "px";

      var infoOffset = {
        y : 0.25,
        x : 0.5
      };

      var iconSize = {
        width: 28,
        height: 60
      };
      var icon = marker.get("icon");
      if (typeof icon === "object") {
          if (typeof icon.size === "object") {
              iconSize.width = icon.size.width;
              iconSize.height = icon.size.height;
          }
          if (typeof icon.url === "string" && icon.url.indexOf("data:image/") === 0) {
              var img = document.createElement("img");
              img.src = icon.url;
              iconSize.width = img.width;
              iconSize.height = img.height;
          }

      }
      var infoWindowAnchor = marker.get("infoWindowAnchor");
      if (utils.isArray(infoWindowAnchor)) {
        infoOffset.x = infoWindowAnchor[0] / icon.size.width;
        infoOffset.x = infoOffset.x > 1 ? 1 : infoOffset.x;
        infoOffset.x = infoOffset.x < 0 ? 0 : infoOffset.x;
        infoOffset.y = infoWindowAnchor[1] / icon.size.height;
        infoOffset.y = infoOffset.y > 1 ? 1 : infoOffset.y;
        infoOffset.y = infoOffset.y < 0 ? 0 : infoOffset.y;
      }
      infoOffset.y *= iconSize.height;
      infoOffset.x = (infoOffset.x - 0.5) * iconSize.width;

      //console.log("contentsSize = " + contentsWidth + ", " + contentsHeight);
      //console.log("iconSize = " + iconSize.width + ", " + iconSize.height);
      //console.log("infoOffset = " + infoOffset.x + ", " + infoOffset.y);

      var offsetX = contentsWidth / 2  - infoOffset.x;
      var offsetY = contentsHeight  - infoOffset.y + iconSize.height;

      self.set("offsetX", offsetX);
      self.set("offsetY", offsetY);

      //console.log("offset = " + self.get("offsetX") + ", " + self.get("offsetY"));
      var infoPosition = map.get("infoPosition");
      self.trigger("infoPosition_changed", "", infoPosition);
    };

    var isInfoOpenFired = false;

    self.on("infoPosition_changed", function(ignore, point) {

        var x = point.x - self.get("offsetX");
        var y = point.y - self.get("offsetY");
        //console.log("offset = " + x + ", " + y);

        frame.style.left = x + "px";
        frame.style.top =  y + "px";

        if (!isInfoOpenFired) {
            isInfoOpenFired = true;
            self.trigger(event.INFO_OPEN);
        }

        cordova.fireDocumentEvent('plugin_touch', {});
    });
    self.on(event.INFO_CLOSE, function() {
        isInfoOpenFired = false;
    });
    self.on("infoWindowAnchor_changed", calculate);
    self.on("icon_changed", calculate);

    self.set("isInfoWindowVisible", false);

};

utils.extend(HTMLInfoWindow, BaseClass);

HTMLInfoWindow.prototype.isInfoWindowShown = function() {
    return this.get("isInfoWindowVisible") === true;
};

HTMLInfoWindow.prototype.close = function() {
    var self = this;

    var marker = self.get("marker");
    if (marker) {
      self.off("isInfoWindowVisible_changed");
    }
    if (!self.isInfoWindowShown() || !marker) {
      return;
    }
    marker.set("infoWindow", undefined);
    this.set('marker', undefined);

    var map = marker.getMap();
    map.off("infoPosition_changed");
    marker.off("icon_changed");
    marker.off("infoWindowAnchor_changed");
    self.trigger(event.INFO_CLOSE);
    marker.off(event.INFO_CLOSE, self.close);  //This event listener is assigned in the open method. So detach it.
    map.set("active_marker_id", null);

    var div = map.getDiv();
    var frame = self.get("frame");
    div.removeChild(frame);

    // Remove the contents from this HTMLInfoWindow
    var contentFrame = frame.firstChild;
    var contentBox = contentFrame.firstChild;
    contentBox.innerHTML = "";
};

HTMLInfoWindow.prototype.setContent = function(content) {
    var self = this;
    var prevContent = self.get("content");
    self.set("content", content);
    var marker = self.get("marker");
    if (content !== prevContent && marker && marker.isInfoWindowShown()) {
      self.trigger("infoWindowAnchor_changed");
    }
};

HTMLInfoWindow.prototype.open = function(marker) {
    if (!marker) {
        return;
    }
    if (marker._objectInstance) {
      // marker is an instance of the ionic-native wrapper plugin.
      marker = marker._objectInstance;
    }

    var map = marker.getMap();
    var self = this,
      markerId = marker.getId();

    marker.set("infoWindow", self);

    map.fromLatLngToPoint(marker.getPosition(), function(point) {
        map.set("infoPosition", {x: point[0], y: point[1]});

        map.bindTo("infoPosition", self);
        marker.bindTo("infoWindowAnchor", self);
        self.bindTo("isInfoWindowVisible", marker);
        marker.bindTo("icon", self);
        marker.one(event.INFO_CLOSE, self.close.bind(self));
        self.set("marker", marker);
        marker.set("isInfoWindowVisible", true);
        map.set("active_marker_id", marker.getId());
        self.trigger.call(self, "infoWindowAnchor_changed");
    });
};

HTMLInfoWindow.prototype.setBackgroundColor = function(backgroundColor) {
  this.get("frame").children[0].style.backgroundColor = backgroundColor;
  this.get("frame").children[1].children[0].style.borderColor = backgroundColor + " rgba(0,0,0,0) rgba(0,0,0,0)";
  this.get("frame").children[1].children[1].style.borderColor = backgroundColor + " rgba(0,0,0,0) rgba(0,0,0,0)";
};

module.exports = HTMLInfoWindow;
<|endoftext|>


<commit_before>/*
---
name: ART.Button
description: Base Button Class
requires: [ART.Sheet, ART.Widget, ART/ART.Rectangle, ART/ART.Font, Touch/Touch, ART/Moderna]
provides: ART.Button
...
*/

ART.Sheet.define('button.art', {
	'border-color': ['hsb(0, 0, 0, 0.6)', 'hsb(0, 0, 0, 0.7)'],
	'reflection-color': ['hsb(0, 0, 100)', 'hsb(0, 0, 0, 0)'],
	'background-color': ['hsb(0, 0, 90)', 'hsb(0, 0, 70)'],
	'shadow-color': 'hsb(0, 0, 0, 0.18)',
	'border-radius': [4, 4, 4, 4],
	'font-family': 'Moderna',
	'font-variant': 'normal',
	'font-size': 12,
	'font-color': 'hsb(0, 0, 5)',
	'padding': [6, 8, 5, 8],
	'display': 'inline-block',
	'cursor': 'pointer',

	'glyph': false,
	'glyph-stroke': 2,
	'glyph-color': hsb(0, 0, 0, 0.8),
	'glyph-height': 10,
	'glyph-width': 10,
	'glyph-top': 2,
	'glyph-left': 2,
	'glyph-bottom': 2,
	'glyph-right': 2
});

ART.Sheet.define('button.art:focused', {
	'background-color': ['hsb(0, 0, 95)', 'hsb(0, 0, 75)'],
	'border-color': ['hsb(205, 80, 100)', 'hsb(205, 100, 95)']
});

ART.Sheet.define('button.art:active', {
	'border-color': ['hsb(0, 0, 0, 0.7)', 'hsb(0, 0, 0, 0.8)'],
	'reflection-color': ['hsb(0, 0, 50)', 'hsb(0, 0, 0, 0)'],
	'background-color': ['hsb(0, 0, 60)', 'hsb(0, 0, 70)']
});

ART.Sheet.define('button.art:disabled', {
	'background-color': ['hsb(0, 0, 95)', 'hsb(0, 0, 75)'],
	'border-color': ['hsb(0, 0, 0, 0.4)', 'hsb(0, 0, 0, 0.5)'],
	'font-color': 'hsb(0, 0, 5, 0.5)',
	'glyph-color': 'hsb(0, 0, 5, 0.5)'
});

(function(){

var Button = ART.Button = new Class({

	Extends: ART.Widget,

	name: 'button',

	options: {
		//text: null,
		//glyph: null,
		tabIndex: null
	},

	initialize: function(options){
		this.parent(options);

		this.shadowLayer = new ART.Rectangle;
		this.borderLayer = new ART.Rectangle;
		this.reflectionLayer = new ART.Rectangle;
		this.backgroundLayer = new ART.Rectangle;
		this.canvas.grab(this.shadowLayer, this.borderLayer, this.reflectionLayer, this.backgroundLayer);

		var element = this.element, self = this;

		var mouseleave;

		element.addEvents({

			keydown: function(event){
				if (event.key.match(/space|enter/)) self.activate();
			},

			keyup: function(event){
				if (event.key.match(/space|enter/) && self.deactivate()) self.fireEvent('press', event);
			},

			mouseleave: function(){
				mouseleave = true;
			}

		});

		this.touch = new Touch(this.element);

		this.touch.addEvents({

			start: function(event){

				self.fireEvent('press:start', event);
				mouseleave = false;
				self.activate();
			},

			end: function(event){
				if (self.deactivate() && !mouseleave) self.fireEvent('press', event);
			},

			cancel: function(event){
				if (self.deactivate()) self.fireEvent('press', event);
			}

		});

	},

	draw: function(newSheet){
		var sheet = this.parent(newSheet);
		var cs = this.currentSheet;
		if (sheet.display) {
			if (sheet.display == "none") {
				document.id(this).setStyle('display', 'none');
				return;
			} else {
				document.id(this).setStyle('display', cs.display);
			}
		}
		if (sheet.cursor) document.id(this).setStyle('cursor', cs.cursor);
		// if (Hash.getLength(sheet)) console.log('»', this._classNames.join(' '), ':', 'Drawing', Hash.getLength(sheet), 'properties', Hash.getKeys(sheet));
		var fontChanged = !!(sheet.fontFamily || sheet.fontVariant || sheet.fontSize || sheet.text);
		var boxChanged = !!(sheet.width || sheet.height || sheet.padding || sheet.borderRadius || fontChanged || sheet.pill);

		if (sheet.glyph || (this.options.glyph && !this.glyphLayer)){
			if (sheet.glyph) this.options.glyph = sheet.glyph;
			if (!this.glyphLayer) this.glyphLayer = new ART.Shape;
			this.makeGlyph(this.options.glyph, true);
			this.canvas.grab(this.glyphLayer);
			boxChanged = true;
		} else if (this.options.text || sheet.text){
			if (!this.textLayer) {
				this.textLayer = new ART.Font;
				fontChanged = true;
				this.canvas.grab(this.textLayer);
			}
			if (fontChanged) this.setText(sheet.text || this.options.text, true);
		}

		var width, height;

		if (boxChanged){
			this.resize(cs.width, cs.height + 1);

			var brt = cs.borderRadius[0], brr = cs.borderRadius[1];
			var brb = cs.borderRadius[2], brl = cs.borderRadius[3];

			var pill = ((cs.width < cs.height) ? cs.width : cs.height) / 2;
			this.shadowLayer.draw(cs.width, cs.height, cs.pill ? pill : cs.borderRadius).translate(0, 1);
			this.borderLayer.draw(cs.width, cs.height, cs.pill ? pill : cs.borderRadius);
			this.reflectionLayer.draw(cs.width - 2, cs.height - 2, cs.pill ? pill - 1 : [brt - 1, brr - 1, brb - 1, brl - 1]).translate(1, 1);
			this.backgroundLayer.draw(cs.width - 2, cs.height - 3, cs.pill ? pill - 1 : [brt - 1, brr - 1, brb - 1, brl - 1]).translate(1, 2);
			if (this.textLayer) this.textLayer.translate(cs.padding[3], cs.padding[0]);
			if (this.glyphLayer) this.glyphLayer.translate(cs.glyphLeft, cs.glyphTop);
		}

		if (sheet.shadowColor) this.shadowLayer.fill.apply(this.shadowLayer, $splat(cs.shadowColor));
		if (sheet.borderColor) this.borderLayer.fill.apply(this.borderLayer, $splat(cs.borderColor));
		if (sheet.reflectionColor) this.reflectionLayer.fill.apply(this.reflectionLayer, $splat(cs.reflectionColor));
		if (sheet.backgroundColor) this.backgroundLayer.fill.apply(this.backgroundLayer, $splat(cs.backgroundColor));
		if (sheet.glyphColor && this.glyphLayer) this.glyphLayer.fill.apply(this.glyphLayer, $splat(cs.glyphColor));
		else if (sheet.fontColor && this.textLayer) this.textLayer.fill.apply(this.textLayer, $splat(cs.fontColor));

		return this;

	},

	enable: function(){
		if (!this.parent()) return false;
		this.touch.attach();
		return true;
	},

	disable: function(){
		if (!this.parent()) return false;
		this.touch.detach();
		return true;
	},

	makeGlyph: function(glyph, noDraw){
		var cs = this.currentSheet;
		if (!this.glyphLayer) return;
		this.glyphLayer.draw(glyph);
		this.glyphBounds = this.glyphLayer.measure();
		if (!cs.width) cs.width = (this.glyphBounds.right + cs.glyphLeft + cs.glyphRight).round();
		if (!cs.height) cs.height = (this.glyphBounds.bottom + cs.glyphTop + cs.glyphBottom).round();
		if (!noDraw) this.deferDraw();
	},

	setText: function(text, noDraw){
		var cs = this.currentSheet;
		if (!this.textLayer || !text) return;
		this.options.text = text;
		this.textLayer.draw(cs.fontFamily, cs.fontVariant, text, cs.fontSize);
		this.textBox = this.textLayer.measure();
		cs.width = Math.round(this.textBox.width) + cs.padding[1] + cs.padding[3];
		cs.height = Math.round(this.textBox.height) + cs.padding[0] + cs.padding[2];
		if (!noDraw) this.deferDraw();
	}

});

})();
<commit_msg>Touch doesn't extend events<commit_after>/*
---
name: ART.Button
description: Base Button Class
requires: [ART.Sheet, ART.Widget, ART/ART.Rectangle, ART/ART.Font, Touch/Touch, ART/Moderna]
provides: ART.Button
...
*/

ART.Sheet.define('button.art', {
	'border-color': ['hsb(0, 0, 0, 0.6)', 'hsb(0, 0, 0, 0.7)'],
	'reflection-color': ['hsb(0, 0, 100)', 'hsb(0, 0, 0, 0)'],
	'background-color': ['hsb(0, 0, 90)', 'hsb(0, 0, 70)'],
	'shadow-color': 'hsb(0, 0, 0, 0.18)',
	'border-radius': [4, 4, 4, 4],
	'font-family': 'Moderna',
	'font-variant': 'normal',
	'font-size': 12,
	'font-color': 'hsb(0, 0, 5)',
	'padding': [6, 8, 5, 8],
	'display': 'inline-block',
	'cursor': 'pointer',

	'glyph': false,
	'glyph-stroke': 2,
	'glyph-color': hsb(0, 0, 0, 0.8),
	'glyph-height': 10,
	'glyph-width': 10,
	'glyph-top': 2,
	'glyph-left': 2,
	'glyph-bottom': 2,
	'glyph-right': 2
});

ART.Sheet.define('button.art:focused', {
	'background-color': ['hsb(0, 0, 95)', 'hsb(0, 0, 75)'],
	'border-color': ['hsb(205, 80, 100)', 'hsb(205, 100, 95)']
});

ART.Sheet.define('button.art:active', {
	'border-color': ['hsb(0, 0, 0, 0.7)', 'hsb(0, 0, 0, 0.8)'],
	'reflection-color': ['hsb(0, 0, 50)', 'hsb(0, 0, 0, 0)'],
	'background-color': ['hsb(0, 0, 60)', 'hsb(0, 0, 70)']
});

ART.Sheet.define('button.art:disabled', {
	'background-color': ['hsb(0, 0, 95)', 'hsb(0, 0, 75)'],
	'border-color': ['hsb(0, 0, 0, 0.4)', 'hsb(0, 0, 0, 0.5)'],
	'font-color': 'hsb(0, 0, 5, 0.5)',
	'glyph-color': 'hsb(0, 0, 5, 0.5)'
});

(function(){

var Button = ART.Button = new Class({

	Extends: ART.Widget,

	name: 'button',

	options: {
		//text: null,
		//glyph: null,
		tabIndex: null
	},

	initialize: function(options){
		this.parent(options);

		this.shadowLayer = new ART.Rectangle;
		this.borderLayer = new ART.Rectangle;
		this.reflectionLayer = new ART.Rectangle;
		this.backgroundLayer = new ART.Rectangle;
		this.canvas.grab(this.shadowLayer, this.borderLayer, this.reflectionLayer, this.backgroundLayer);

		var element = this.element, self = this;

		var mouseleave;

		element.addEvents({

			keydown: function(event){
				if (event.key.match(/space|enter/)) self.activate();
			},

			keyup: function(event){
				if (event.key.match(/space|enter/) && self.deactivate()) self.fireEvent('press', event);
			},

			mouseleave: function(){
				mouseleave = true;
			}

		});

		this.touch = new Touch(this.element);

		this.touch.addEvents({

			start: function(event){
				self.fireEvent('press:start', new Event(event));
				mouseleave = false;
				self.activate();
			},

			end: function(event){
				if (self.deactivate() && !mouseleave) self.fireEvent('press', new Event(event));
			},

			cancel: function(event){
				if (self.deactivate()) self.fireEvent('press', new Event(event));
			}

		});

	},

	draw: function(newSheet){
		var sheet = this.parent(newSheet);
		var cs = this.currentSheet;
		if (sheet.display) {
			if (cs.display == "none") {
				document.id(this).setStyle('display', 'none');
				return;
			} else {
				document.id(this).setStyle('display', cs.display);
			}
		}
		if (sheet.cursor) document.id(this).setStyle('cursor', cs.cursor);
		// if (Hash.getLength(sheet)) console.log('»', this._classNames.join(' '), ':', 'Drawing', Hash.getLength(sheet), 'properties', Hash.getKeys(sheet));
		var fontChanged = !!(sheet.fontFamily || sheet.fontVariant || sheet.fontSize || sheet.text);
		var boxChanged = !!(sheet.width || sheet.height || sheet.padding || sheet.borderRadius || fontChanged || sheet.pill);

		if (sheet.glyph || (this.options.glyph && !this.glyphLayer)){
			if (sheet.glyph) this.options.glyph = sheet.glyph;
			if (!this.glyphLayer) this.glyphLayer = new ART.Shape;
			this.makeGlyph(this.options.glyph, true);
			this.canvas.grab(this.glyphLayer);
			boxChanged = true;
		} else if (this.options.text || sheet.text){
			if (!this.textLayer) {
				this.textLayer = new ART.Font;
				fontChanged = true;
				this.canvas.grab(this.textLayer);
			}
			if (fontChanged) this.setText(sheet.text || this.options.text, true);
		}

		var width, height;

		if (boxChanged){
			this.resize(cs.width, cs.height + 1);

			var brt = cs.borderRadius[0], brr = cs.borderRadius[1];
			var brb = cs.borderRadius[2], brl = cs.borderRadius[3];

			var pill = ((cs.width < cs.height) ? cs.width : cs.height) / 2;
			this.shadowLayer.draw(cs.width, cs.height, cs.pill ? pill : cs.borderRadius).translate(0, 1);
			this.borderLayer.draw(cs.width, cs.height, cs.pill ? pill : cs.borderRadius);
			this.reflectionLayer.draw(cs.width - 2, cs.height - 2, cs.pill ? pill - 1 : [brt - 1, brr - 1, brb - 1, brl - 1]).translate(1, 1);
			this.backgroundLayer.draw(cs.width - 2, cs.height - 3, cs.pill ? pill - 1 : [brt - 1, brr - 1, brb - 1, brl - 1]).translate(1, 2);
			if (this.textLayer) this.textLayer.translate(cs.padding[3], cs.padding[0]);
			if (this.glyphLayer) this.glyphLayer.translate(cs.glyphLeft, cs.glyphTop);
		}

		if (sheet.shadowColor) this.shadowLayer.fill.apply(this.shadowLayer, $splat(cs.shadowColor));
		if (sheet.borderColor) this.borderLayer.fill.apply(this.borderLayer, $splat(cs.borderColor));
		if (sheet.reflectionColor) this.reflectionLayer.fill.apply(this.reflectionLayer, $splat(cs.reflectionColor));
		if (sheet.backgroundColor) this.backgroundLayer.fill.apply(this.backgroundLayer, $splat(cs.backgroundColor));
		if (sheet.glyphColor && this.glyphLayer) this.glyphLayer.fill.apply(this.glyphLayer, $splat(cs.glyphColor));
		else if (sheet.fontColor && this.textLayer) this.textLayer.fill.apply(this.textLayer, $splat(cs.fontColor));

		return this;

	},

	enable: function(){
		if (!this.parent()) return false;
		this.touch.attach();
		return true;
	},

	disable: function(){
		if (!this.parent()) return false;
		this.touch.detach();
		return true;
	},

	makeGlyph: function(glyph, noDraw){
		var cs = this.currentSheet;
		if (!this.glyphLayer) return;
		this.glyphLayer.draw(glyph);
		this.glyphBounds = this.glyphLayer.measure();
		if (!cs.width) cs.width = (this.glyphBounds.right + cs.glyphLeft + cs.glyphRight).round();
		if (!cs.height) cs.height = (this.glyphBounds.bottom + cs.glyphTop + cs.glyphBottom).round();
		if (!noDraw) this.deferDraw();
	},

	setText: function(text, noDraw){
		var cs = this.currentSheet;
		if (!this.textLayer || !text) return;
		this.options.text = text;
		this.textLayer.draw(cs.fontFamily, cs.fontVariant, text, cs.fontSize);
		this.textBox = this.textLayer.measure();
		cs.width = Math.round(this.textBox.width) + cs.padding[1] + cs.padding[3];
		cs.height = Math.round(this.textBox.height) + cs.padding[0] + cs.padding[2];
		if (!noDraw) this.deferDraw();
	}

});

})();
<|endoftext|>


<commit_before>// A defaultable module, used by the test suite
//
// Copyright 2011 Iris Couch
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

require('../../defaultable')(module,
  { 'original': 'value'
  , 'should'  : 'be replaced'
  }, function(module, exports, DEFS, require) {

console.error('MOD LOADING: ' + JSON.stringify(DEFS));
exports.get = function(val) {
  console.error('MOD get: ' + val + ' => ' + JSON.stringify(DEFS[val]))
  return DEFS[val];
}

exports.req = require;

})
<commit_msg>Remove debugging code<commit_after>// A defaultable module, used by the test suite
//
// Copyright 2011 Iris Couch
//
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//
//        http://www.apache.org/licenses/LICENSE-2.0
//
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.

require('../../defaultable')(module,
  { 'original': 'value'
  , 'should'  : 'be replaced'
  }, function(module, exports, DEFS, require) {

exports.get = function(val) {
  return DEFS[val];
}

exports.req = require;

})
<|endoftext|>


<commit_before>/**
 * Utility functions.
 */

function serializeToJSON(arr) {
    // Convert form data to a proper json value
    var json = {};
    $.each(arr, function(_, pair){
        json[pair.name] = pair.value;
    });
    return json;
}

function guid() {
    // Credit: http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
    }
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4();
}

function normalizeName(name) {
    return name.replace(/#/gi, '').replace(/\./gi, '').replace(/ /gi, '_');
}
<commit_msg>Fix a bug with bad names used as query selectors.<commit_after>/**
 * Utility functions.
 */

function serializeToJSON(arr) {
    // Convert form data to a proper json value
    var json = {};
    $.each(arr, function(_, pair){
        json[pair.name] = pair.value;
    });
    return json;
}

function guid() {
    // Credit: http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
    function s4() {
        return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
    }
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4();
}

function normalizeName(name) {
    return 'id_' + name.replace(/#/gi, '').replace(/\./gi, '').replace(/ /gi, '_');
}
<|endoftext|>


<commit_before>/**
 * Jasmine test specification for Observable-JS
 */
describe('Observable-JS', function(){

	var clock = {
		count	: 0,
		tick	: function(){
			return ++this.count;
		}
	};

	it('Tests creating an observable object', function(){
		Observable.create(clock);
		expect(clock.subscribe).toBeDefined();
		expect(clock.unsubscribe).toBeDefined();
		expect(clock.signal).toBeDefined();
	});

	it('Tests subscribing to an observable object', function(){
		var count = 0, message = '';
		var listener = clock.subscribe('tick');
		listener.onNext = function(tick){
			count = tick.count;
		};
		listener.onError = function(error){
			message = error.message;
		};

		clock.signal(Observable.NEXT, 'tick', { count : clock.tick() });
		clock.signal(Observable.ERROR, 'tick', { message : 'Error!' });
		expect(count).toEqual(clock.count);
		expect(message).toEqual('Error!');
	});

	it('Tests signaling using different streams', function(){
		var count = 0, message = '', complete = false;
		var	listener = clock.subscribe('tock', {
			onNext: function(tick){
				count = tick.count;
			}
		});
		listener.onError = function(error){
			message = error.message;
		};
		listener.onComplete = function(){
			complete = true;
		};

		clock.signal(Observable.NEXT, 'tock', { count : clock.tick() });
		clock.signal(Observable.ERROR, 'tock', { message : 'Error: Forgot how to count!' });
		clock.signal(Observable.COMPLETE, 'tock');

		expect(count).toEqual(clock.count);
		expect(message).toEqual('Error: Forgot how to count!');
		expect(complete).toBeTruthy();
	});

	it('Tests unsubscribing from an observer', function(){
		var count = 0;
		var listener = clock.subscribe('tick',{
			onNext: function(tick){
				count = tick.count;
			}
		});

		clock.unsubscribe(listener);
		clock.signal(Observable.NEXT, 'tick', { count : clock.tick() });
		expect(count).toBe(0);
	});

	it('Tests unsubscribing from an observer before subscribing', function(){
		expect(clock.unsubscribe({})).toBeFalsy();
		expect(clock.unsubscribe()).toBeTruthy();
	});

	it('Tests expected errors from an observer', function(){
		var source = Observable.create({}, { data : {}});
		var delegate = {};

		expect(function(){return source.subscribe('pass');}).not.toThrow();
		expect(function(){return source.subscribe(123);}).toThrow();

	});

});
<commit_msg>Added async test case<commit_after>/**
 * Jasmine test specification for Observable-JS
 */
describe('Observable-JS', function(){

	var clock = {
		count	: 0,
		tick	: function(){
			return ++this.count;
		}
	};

	it('Tests creating an observable object', function(){
		Observable.create(clock);
		expect(clock.subscribe).toBeDefined();
		expect(clock.unsubscribe).toBeDefined();
		expect(clock.signal).toBeDefined();
	});

	it('Tests subscribing to an observable object', function(){
		var count = 0, message = '';
		var listener = clock.subscribe('tick');
		listener.onNext = function(tick){
			count = tick.count;
		};
		listener.onError = function(error){
			message = error.message;
		};

		clock.signal(Observable.NEXT, 'tick', { count : clock.tick() });
		clock.signal(Observable.ERROR, 'tick', { message : 'Error!' });
		expect(count).toEqual(clock.count);
		expect(message).toEqual('Error!');
	});

	it('Tests signaling using different streams', function(){
		var count = 0, message = '', complete = false;
		var	listener = clock.subscribe('tock', {
			onNext: function(tick){
				count = tick.count;
			}
		});
		listener.onError = function(error){
			message = error.message;
		};
		listener.onComplete = function(){
			complete = true;
		};

		clock.signal(Observable.NEXT, 'tock', { count : clock.tick() });
		clock.signal(Observable.ERROR, 'tock', { message : 'Error: Forgot how to count!' });
		clock.signal(Observable.COMPLETE, 'tock');

		expect(count).toEqual(clock.count);
		expect(message).toEqual('Error: Forgot how to count!');
		expect(complete).toBeTruthy();
	});

	it('Tests unsubscribing from an observer', function(){
		var count = 0;
		var listener = clock.subscribe('tick',{
			onNext: function(tick){
				count = tick.count;
			}
		});

		clock.unsubscribe(listener);
		clock.signal(Observable.NEXT, 'tick', { count : clock.tick() });
		expect(count).toBe(0);
	});

	it('Tests unsubscribing from an observer before subscribing', function(){
		expect(clock.unsubscribe({})).toBeFalsy();
		expect(clock.unsubscribe()).toBeTruthy();
	});

	it('Tests expected errors from an observer', function(){
		var source = Observable.create({}, { data : {}});
		var delegate = {};

		expect(function(){return source.subscribe('pass');}).not.toThrow();
		expect(function(){return source.subscribe(123);}).toThrow();

	});

	it('Tests async signals', function(){
		var source = Observable.create({}, { data : {async : true}});
		var expected = [], actual = [];

		source.subscribe('data', {
			onNext : function(data){
				actual.push(data.value);
			}
		});

		for(var i = 0; i < 100; i++){
			expected.push(i);
			setTimeout(function(){
				source.signal(Observable.NEXT, 'data', {value : i});
			}, i);
		}

		// Wait at least 300ms before checking the output so that all async events
		// have completed
		setTimeout(function(){
			expect(actual).toEqual(expected);
		}, 300);
	});

});
<|endoftext|>


<commit_before>$(document).ready(function() {

  function updateProgressBar(pct) {
      $('#progress-bar').width(pct+"%");
  }

  function updateUI() {
      $.get("/status/"+window.installID, function(resp) {
          console.log(resp);
          if (resp.status == 'waiting for ssh') {
              $('#status-line').text('Waiting for SSH…');
              updateProgressBar(15);
          } else if (resp.status == 'waiting for http') {
              $('#status-line').text('Waiting for HTTP…');
              updateProgressBar(35);
          } else if (resp.status == 'creating client token') {
              $('#status-line').text('Creating client token…');
              updateProgressBar(95);
          } else if (resp.status == 'done') {
              $('#status-line').text('Install complete');
              updateProgressBar(100);
              $('#open-dashboard').href('http://' + resp.client_token + '@' + resp.ip_address + '/dashboard');
              $('#core-info').show();
          } else if (resp.status == 'failed') {
              $('status-line').text('Install failed');
              updateProgressBar(0);
          }

          setTimeout(updateUI, 1000);
      });
  }

  updateUI();
});
<commit_msg>animate?<commit_after>$(document).ready(function() {

  function updateProgressBar(pct) {
      $('#progress-bar').animate({width: pct+'%'}, 400);
  }

  function updateUI() {
      $.get("/status/"+window.installID, function(resp) {
          console.log(resp);
          if (resp.status == 'waiting for ssh') {
              $('#status-line').text('Waiting for SSH…');
              updateProgressBar(15);
          } else if (resp.status == 'waiting for http') {
              $('#status-line').text('Waiting for HTTP…');
              updateProgressBar(35);
          } else if (resp.status == 'creating client token') {
              $('#status-line').text('Creating client token…');
              updateProgressBar(95);
          } else if (resp.status == 'done') {
              $('#status-line').text('Install complete');
              updateProgressBar(100);
              $('#open-dashboard').href('http://' + resp.client_token + '@' + resp.ip_address + '/dashboard');
              $('#core-info').show();
          } else if (resp.status == 'failed') {
              $('status-line').text('Install failed');
              updateProgressBar(0);
          }

          setTimeout(updateUI, 1000);
      });
  }

  updateUI();
});
<|endoftext|>